fix: provider settings UI, OpenRouter model field, merge resolution, i18n
This commit is contained in:
@@ -72,16 +72,19 @@ function fallbackModelsEqual(a?: string[], b?: string[]): boolean {
|
||||
return left.length === right.length && left.every((model, index) => model === right[index]);
|
||||
}
|
||||
|
||||
function getAuthModeLabel(authMode: ProviderAccount['authMode']): string {
|
||||
function getAuthModeLabel(
|
||||
authMode: ProviderAccount['authMode'],
|
||||
t: (key: string) => string
|
||||
): string {
|
||||
switch (authMode) {
|
||||
case 'api_key':
|
||||
return 'API Key';
|
||||
return t('aiProviders.authModes.apiKey');
|
||||
case 'oauth_device':
|
||||
return 'OAuth Device';
|
||||
return t('aiProviders.authModes.oauthDevice');
|
||||
case 'oauth_browser':
|
||||
return 'OAuth Browser';
|
||||
return t('aiProviders.authModes.oauthBrowser');
|
||||
case 'local':
|
||||
return 'Local';
|
||||
return t('aiProviders.authModes.local');
|
||||
default:
|
||||
return authMode;
|
||||
}
|
||||
@@ -174,14 +177,6 @@ export function ProvidersSettings() {
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
{accounts.length > 0 && (
|
||||
<ProviderAccountsOverview
|
||||
accounts={accounts}
|
||||
vendors={vendors}
|
||||
defaultAccountId={defaultAccountId}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="flex justify-end">
|
||||
<Button size="sm" onClick={() => setShowAddDialog(true)}>
|
||||
<Plus className="h-4 w-4 mr-2" />
|
||||
@@ -259,58 +254,6 @@ export function ProvidersSettings() {
|
||||
);
|
||||
}
|
||||
|
||||
function ProviderAccountsOverview({
|
||||
accounts,
|
||||
vendors,
|
||||
defaultAccountId,
|
||||
}: {
|
||||
accounts: ProviderAccount[];
|
||||
vendors: ProviderVendorInfo[];
|
||||
defaultAccountId: string | null;
|
||||
}) {
|
||||
const vendorMap = new Map(vendors.map((vendor) => [vendor.id, vendor]));
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader className="pb-3">
|
||||
<CardTitle>Provider Accounts</CardTitle>
|
||||
<CardDescription>
|
||||
Account-aware provider metadata is now available and will back the next UI migration step.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
{accounts.map((account) => {
|
||||
const vendor = vendorMap.get(account.vendorId);
|
||||
|
||||
return (
|
||||
<div
|
||||
key={account.id}
|
||||
className="flex items-center justify-between rounded-lg border p-3"
|
||||
>
|
||||
<div className="min-w-0">
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-medium truncate">{account.label}</span>
|
||||
<Badge variant="secondary">{vendor?.name || account.vendorId}</Badge>
|
||||
<Badge variant="outline">{getAuthModeLabel(account.authMode)}</Badge>
|
||||
{account.id === defaultAccountId || account.isDefault ? (
|
||||
<Badge>Default</Badge>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="mt-1 text-sm text-muted-foreground truncate">
|
||||
{account.model || 'No model selected'}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground">
|
||||
{vendor?.supportsMultipleAccounts ? 'multi-account ready' : 'singleton vendor'}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
interface ProviderCardProps {
|
||||
item: ProviderListItem;
|
||||
allProviders: ProviderListItem[];
|
||||
@@ -466,9 +409,14 @@ function ProviderCard({
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-semibold">{account.label}</span>
|
||||
<Badge variant="secondary">{vendor?.name || account.vendorId}</Badge>
|
||||
<Badge variant="outline">{getAuthModeLabel(account.authMode)}</Badge>
|
||||
<Badge variant="outline">{getAuthModeLabel(account.authMode, t)}</Badge>
|
||||
</div>
|
||||
<div className="mt-1 space-y-0.5">
|
||||
<p className="text-xs text-muted-foreground capitalize">{account.vendorId}</p>
|
||||
<p className="text-xs text-muted-foreground truncate">
|
||||
{t('aiProviders.dialog.modelId')}: {account.model || t('aiProviders.card.none')}
|
||||
</p>
|
||||
</div>
|
||||
<span className="text-xs text-muted-foreground capitalize">{account.vendorId}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
"aiProviders": {
|
||||
"title": "AI Providers",
|
||||
"description": "Configure your AI model providers and API keys",
|
||||
"overview": {
|
||||
"title": "Provider Accounts",
|
||||
"description": "A summary of the provider accounts and models currently configured.",
|
||||
"noModelSelected": "No model selected",
|
||||
"multiAccountReady": "Multi-account ready",
|
||||
"singletonVendor": "Single-account vendor"
|
||||
},
|
||||
"authModes": {
|
||||
"apiKey": "API Key",
|
||||
"oauthDevice": "OAuth Device",
|
||||
"oauthBrowser": "OAuth Browser",
|
||||
"local": "Local"
|
||||
},
|
||||
"sections": {
|
||||
"model": "Model Settings",
|
||||
"fallback": "Fallback Settings"
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
"aiProviders": {
|
||||
"title": "AI プロバイダー",
|
||||
"description": "AI モデルプロバイダーと API キーを設定",
|
||||
"overview": {
|
||||
"title": "プロバイダーアカウント",
|
||||
"description": "現在設定されているプロバイダーアカウントとモデルの概要です。",
|
||||
"noModelSelected": "モデル未選択",
|
||||
"multiAccountReady": "複数アカウント対応",
|
||||
"singletonVendor": "単一アカウントのプロバイダー"
|
||||
},
|
||||
"authModes": {
|
||||
"apiKey": "API キー",
|
||||
"oauthDevice": "OAuth デバイス",
|
||||
"oauthBrowser": "OAuth ブラウザ",
|
||||
"local": "ローカル"
|
||||
},
|
||||
"sections": {
|
||||
"model": "モデル設定",
|
||||
"fallback": "フォールバック設定"
|
||||
|
||||
@@ -13,6 +13,19 @@
|
||||
"aiProviders": {
|
||||
"title": "AI 模型提供商",
|
||||
"description": "配置 AI 模型提供商和 API 密钥",
|
||||
"overview": {
|
||||
"title": "提供商账户",
|
||||
"description": "这里汇总当前已配置的 provider 账户与模型信息。",
|
||||
"noModelSelected": "未选择模型",
|
||||
"multiAccountReady": "支持多账户",
|
||||
"singletonVendor": "单例提供商"
|
||||
},
|
||||
"authModes": {
|
||||
"apiKey": "API 密钥",
|
||||
"oauthDevice": "OAuth 设备登录",
|
||||
"oauthBrowser": "OAuth 浏览器登录",
|
||||
"local": "本地"
|
||||
},
|
||||
"sections": {
|
||||
"model": "模型配置",
|
||||
"fallback": "回退配置"
|
||||
|
||||
Reference in New Issue
Block a user