@fonlan/dsh-model-router 0.3.3 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["useCallback","useSyncExternalStore","useState","useMemo","useSyncExternalStore","useState","useRef","useId","useCallback","useMemo","IconChevronDownOutline14","IconChevronRightOutline14","IconCheckOutline16","Toast","IconWarningOutline16"],"sources":["../../../src/client/locales.ts","../../../src/client/api.ts","../../../src/client/settings-card.tsx","../../../src/client/model-seat.tsx","../../../src/client/index.tsx"],"sourcesContent":["// Locale namespace = the plugin's cordis id (kebab). DSH flat namespace keys\n// (settings + locale) use the internal id `model-router`; the scoped npm\n// package name is reserved for package-bound identifiers (exported `name`,\n// module-loader id, the /plugins/<pkg>/… route base).\nexport const LOCALE_NS = 'model-router'\n\nexport const zh = {\n settingsTitle: '模型路由',\n settingsCardDescription: '模型聚合、提供商切换与优先级顺序',\n expand: '展开',\n collapse: '收起',\n readOnly: '本部署的设置为只读。',\n loading: '加载中…',\n loadFailed: '加载失败:{message}',\n retry: '重试',\n refresh: '刷新',\n empty: '没有可路由的提供商或模型,请先在设置中添加提供商。',\n modelsCount: '共 {count} 个模型',\n activeBadge: '当前',\n noCredential: '未配置 API 密钥,不可选',\n dragHint: '拖拽调整优先级顺序',\n switchFailed: '切换失败:{message}',\n reorderFailed: '排序失败:{message}',\n providerCount: '{count} 个提供商',\n seatLabel: '模型选择(含提供商切换)',\n menuAria: '模型、提供商与推理等级',\n menuModel: '模型',\n menuProvider: '提供商',\n menuEffort: '推理等级',\n triggerFallback: '选择模型',\n triggerSelectAria: '选择模型',\n triggerAria: '选择模型,当前 {model}',\n triggerAriaEffort: '选择模型,当前 {model},推理等级 {effort}',\n effortProviderDefault: 'Default',\n statusLoading: '正在刷新模型列表…',\n errorAction: '模型操作失败:{message}',\n actionReload: '重新加载',\n warningGroupLoad: '{name} 加载失败:{message}',\n emptyModels: '没有可用的模型。',\n emptyEfforts: '当前模型未提供推理等级。',\n routeMenuTitle: '{model} · 选择提供商',\n routeLoading: '加载路由…',\n noCredentialShort: '未配置凭据',\n globalRouteHint: '切换后对所有会话的后续请求生效',\n showQuickSwitchLabel: '在模型选择菜单中显示提供商切换',\n showQuickSwitchDescription: '开启后,当当前模型是 model-router 路由时,模型选择弹出菜单会显示提供商列表入口,可直接切换该模型的激活提供商。',\n ignorePrefixLabel: '匹配时忽略模型 ID 前缀',\n ignorePrefixDescription: '开启后,deepseek/deepseek-v4-flash 与 deepseek-v4-flash 视为同一模型,统一显示不带前缀的模型 id(默认开启)。',\n sortTitle: '模型显示顺序',\n sortDescription: '模型选择列表中 model-router 分组内模型的排列方式。',\n sortModeCustom: '自定义',\n sortModeName: '按名称',\n sortModeRecent: '最近使用',\n sortModeDescCustom: '按下方拖拽的手动顺序排列',\n sortModeDescName: '按模型名称排序(数字感知)',\n sortModeDescRecent: '最近用过的模型排在最前',\n sortCustomHint: '拖拽调整模型在模型选择列表中的显示顺序',\n sortFailed: '排序设置失败:{message}',\n}\n\nexport const en = {\n settingsTitle: 'Model Router',\n settingsCardDescription: 'Model aggregation, provider switching and preference order',\n expand: 'Expand',\n collapse: 'Collapse',\n readOnly: 'This deployment stores settings read-only.',\n loading: 'Loading…',\n loadFailed: 'Load failed: {message}',\n retry: 'Retry',\n refresh: 'Refresh',\n empty: 'No routable providers or models yet — add providers in settings first.',\n modelsCount: '{count} models',\n activeBadge: 'active',\n noCredential: 'No API key configured — not selectable',\n dragHint: 'Drag to adjust preference order',\n switchFailed: 'Switch failed: {message}',\n reorderFailed: 'Reorder failed: {message}',\n providerCount: '{count} providers',\n seatLabel: 'Model selection (with provider switching)',\n menuAria: 'Model, provider and reasoning effort',\n menuModel: 'Model',\n menuProvider: 'Provider',\n menuEffort: 'Effort',\n triggerFallback: 'Select model',\n triggerSelectAria: 'Select model',\n triggerAria: 'Select model, current {model}',\n triggerAriaEffort: 'Select model, current {model}, reasoning effort {effort}',\n effortProviderDefault: 'Default',\n statusLoading: 'Refreshing model list…',\n errorAction: 'Model operation failed: {message}',\n actionReload: 'Reload',\n warningGroupLoad: '{name} failed to load: {message}',\n emptyModels: 'No models available.',\n emptyEfforts: 'This model provides no reasoning effort levels.',\n routeMenuTitle: '{model} · Choose provider',\n routeLoading: 'Loading routes…',\n noCredentialShort: 'No credentials',\n globalRouteHint: 'Changes apply to subsequent requests in all sessions',\n showQuickSwitchLabel: 'Show provider switching in the model picker',\n showQuickSwitchDescription: 'When enabled, the model picker menu shows a provider list entry that switches the active provider, for model-router routes.',\n ignorePrefixLabel: 'Ignore model ID prefix when matching',\n ignorePrefixDescription: 'When enabled, deepseek/deepseek-v4-flash and deepseek-v4-flash are treated as the same model and shown without the prefix (on by default).',\n sortTitle: 'Model display order',\n sortDescription: 'How models inside the model-router group are ordered in the model picker.',\n sortModeCustom: 'Custom',\n sortModeName: 'By name',\n sortModeRecent: 'Recently used',\n sortModeDescCustom: 'Manual order via drag below',\n sortModeDescName: 'Sort by model name (numeric-aware)',\n sortModeDescRecent: 'Most recently used models first',\n sortCustomHint: 'Drag to reorder models in the model picker',\n sortFailed: 'Sort setting failed: {message}',\n}\n","/** Client transport for the model-router settings API. */\nexport interface RouterProviderView {\n id: string\n name: string\n credentialConfigured: boolean\n}\n\nexport type ModelSortMode = 'custom' | 'name' | 'recent'\n\nexport interface RouterModelView {\n id: string\n name: string\n active: string | null\n order: string[]\n providers: RouterProviderView[]\n}\n\nexport interface ModelRouterState {\n /** Whether provider switching is shown inside the composer model picker menu. */\n showQuickSwitch: boolean\n /** Whether model ids are matched with their leading vendor/ prefix ignored. */\n ignoreModelIdPrefix: boolean\n /** The model-list display order mode (custom | name | recent). */\n modelSort: ModelSortMode\n /** Explicit model id order for custom mode (display order). */\n modelOrder: string[]\n providers: RouterProviderView[]\n models: RouterModelView[]\n}\n\nexport class ModelRouterApiError extends Error {\n constructor(readonly code: string, message: string) {\n super(message)\n }\n}\n\nasync function call<T>(method: string, payload: Record<string, unknown> = {}): Promise<T> {\n let response: Response\n try {\n response = await fetch(`/plugins/@fonlan/dsh-model-router/api/${method}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n } catch (error) {\n throw new ModelRouterApiError('network', error instanceof Error ? error.message : String(error))\n }\n const parsed: { ok?: boolean; value?: unknown; error?: { code?: string; message?: string } } | null\n = await response.json().catch(() => null)\n if (!response.ok || parsed === null || parsed.ok !== true || parsed.value === undefined) {\n throw new ModelRouterApiError(\n parsed?.error?.code ?? 'http',\n parsed?.error?.message ?? `HTTP ${response.status}`,\n )\n }\n return parsed.value as T\n}\n\nexport const api = {\n state: () => call<ModelRouterState>('state'),\n switchActive: (modelId: string, providerId: string) =>\n call<ModelRouterState>('switch-active', { modelId, providerId }),\n reorder: (modelId: string, order: string[]) =>\n call<ModelRouterState>('reorder', { modelId, order }),\n refresh: () => call<ModelRouterState>('refresh'),\n setShowQuickSwitch: (value: boolean) =>\n call<ModelRouterState>('set-show-quick-switch', { value }),\n setIgnoreModelIdPrefix: (value: boolean) =>\n call<ModelRouterState>('set-ignore-model-id-prefix', { value }),\n setModelSort: (mode: ModelSortMode) =>\n call<ModelRouterState>('set-model-sort', { mode }),\n setModelOrder: (order: string[]) =>\n call<ModelRouterState>('set-model-order', { order }),\n}\n","/**\n * The Model Router Settings Card (设置 → 插件 → 插件配置 → 模型路由).\n *\n * Renders its own expandable chrome aligned with the built-in plugin cards\n * (external plugins cannot import PluginCard): a header naming the plugin and\n * what its settings govern, disclosing the router controls in place. All\n * reads/mutations go through the plugin's fenced API; the server persists\n * through the `model-router` settings namespace, so a switch here is live for\n * the next request globally.\n *\n * The bound settings scope (the same `model-router` namespace the host half\n * registers) supplies the card's dispatch state: while the namespace is merely\n * loading the card stays mounted, and when it is unavailable (deployment\n * without the host half) nothing renders — matching the built-in cards. A\n * read-only deployment shows the built-in card's banner and disables the\n * mutation controls.\n */\nimport { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from 'react'\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport { LOCALE_NS } from './locales'\nimport { api, type ModelRouterState, type ModelSortMode, type RouterModelView } from './api'\nimport './settings-card.css'\n\n/** Client settings scope face (subset of @deepseek-ai/dsh-client-runtime). */\nexport interface SettingsScopeFace {\n getSnapshot(): {\n status: 'loading' | 'ready' | 'unavailable'\n writable: boolean\n }\n subscribe(listener: () => void): () => void\n}\n\nexport interface SettingsCardProps {\n /** The bound `model-router` settings scope (from the slot entry's inject face). */\n scope: SettingsScopeFace\n}\n\nfunction arrayMove<T>(list: readonly T[], from: number, to: number): T[] {\n const next = [...list]\n const [item] = next.splice(from, 1)\n next.splice(to, 0, item)\n return next\n}\n\nfunction useLocaleRevision(ctx: ClientContext): number {\n const subscribe = useCallback(\n (onChange: () => void) => {\n try {\n return ctx.locale.subscribe(onChange)\n } catch {\n return () => {}\n }\n },\n [ctx],\n )\n const getSnapshot = useCallback(() => {\n try {\n return ctx.locale.getLocale().revision\n } catch {\n return 0\n }\n }, [ctx])\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n\nexport function makeSettingsCard(ctx: ClientContext): (props: SettingsCardProps) => JSX.Element | null {\n // Bound translation is namespace-typed; the card's props use the plain\n // Translate face (string keys), which the dict satisfies structurally.\n const t: Translate = (() => {\n try {\n return ctx.locale.bind(LOCALE_NS) as unknown as Translate\n } catch {\n return (key: string) => key\n }\n })()\n\n return function ModelRouterSettingsCard(props: SettingsCardProps): JSX.Element | null {\n const { scope } = props\n // Bind the methods: React invokes getSnapshot/subscribe as bare functions,\n // and SettingsScopeController's methods depend on `this`.\n const snapshot = useSyncExternalStore(\n (listener) => scope.subscribe(listener),\n () => scope.getSnapshot(),\n )\n useLocaleRevision(ctx)\n // Card-local disclosure: collapsed by default, like the built-in plugin cards.\n const [open, setOpen] = useState(false)\n const [state, setState] = useState<ModelRouterState | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loading, setLoading] = useState(true)\n const [busyModel, setBusyModel] = useState<string | null>(null)\n const [drag, setDrag] = useState<{ modelId: string; index: number } | null>(null)\n const [quickSwitchBusy, setQuickSwitchBusy] = useState(false)\n const [ignorePrefixBusy, setIgnorePrefixBusy] = useState(false)\n const [sortBusy, setSortBusy] = useState(false)\n const [modelDrag, setModelDrag] = useState<{ index: number } | null>(null)\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n setState(await api.state())\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const switchActive = useCallback(async (model: RouterModelView, providerId: string) => {\n if (model.active === providerId) return\n setBusyModel(model.id)\n try {\n setState(await api.switchActive(model.id, providerId))\n setError(null)\n } catch (cause) {\n setError(t('switchFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setBusyModel(null)\n }\n }, [t])\n\n const reorder = useCallback(async (model: RouterModelView, from: number, to: number) => {\n if (from === to) return\n const order = arrayMove(model.order, from, to)\n setState(prev => prev === null ? prev : {\n ...prev,\n models: prev.models.map(m => (m.id === model.id ? { ...m, order } : m)),\n })\n setBusyModel(model.id)\n try {\n setState(await api.reorder(model.id, order))\n setError(null)\n } catch (cause) {\n setError(t('reorderFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n setState(prev => prev === null ? prev : {\n ...prev,\n models: prev.models.map(m => (m.id === model.id ? { ...m, order: model.order } : m)),\n })\n } finally {\n setBusyModel(null)\n }\n }, [t])\n\n const toggleQuickSwitch = useCallback(async (value: boolean) => {\n if (state === null) return\n const previous = state.showQuickSwitch\n setState(prev => prev === null ? prev : { ...prev, showQuickSwitch: value })\n setQuickSwitchBusy(true)\n try {\n setState(await api.setShowQuickSwitch(value))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, showQuickSwitch: previous })\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setQuickSwitchBusy(false)\n }\n }, [state])\n\n const toggleIgnorePrefix = useCallback(async (value: boolean) => {\n if (state === null) return\n const previous = state.ignoreModelIdPrefix\n setState(prev => prev === null ? prev : { ...prev, ignoreModelIdPrefix: value })\n setIgnorePrefixBusy(true)\n try {\n setState(await api.setIgnoreModelIdPrefix(value))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, ignoreModelIdPrefix: previous })\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setIgnorePrefixBusy(false)\n }\n }, [state])\n\n const changeModelSort = useCallback(async (mode: ModelSortMode) => {\n if (state === null || state.modelSort === mode) return\n const previous = state.modelSort\n setState(prev => prev === null ? prev : { ...prev, modelSort: mode })\n setSortBusy(true)\n try {\n setState(await api.setModelSort(mode))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, modelSort: previous })\n setError(t('sortFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setSortBusy(false)\n }\n }, [state, t])\n\n const moveModel = useCallback(async (from: number, to: number) => {\n if (state === null || from === to) return\n // The drag list shows the full display order (modelOrder + catalog\n // tail); persist the whole reordered id list as the new custom order.\n const ids = state.models.map(model => model.id)\n const order = arrayMove(ids, from, to)\n setState(prev => prev === null ? prev : { ...prev, modelOrder: order })\n setSortBusy(true)\n try {\n setState(await api.setModelOrder(order))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, modelOrder: state.modelOrder })\n setError(t('sortFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setSortBusy(false)\n }\n }, [state, t])\n\n // The namespace is served by the host once the scope is ready. While it is\n // merely loading, keep the card mounted (the tab already dispatched it);\n // if it is unavailable (deployment without the host half), render nothing.\n if (snapshot.status === 'unavailable') return null\n const writable = snapshot.writable\n\n const models = useMemo(() => state?.models ?? [], [state])\n\n return (\n <li className=\"mr-settings-card\" data-open={open ? '' : undefined}>\n <button\n type=\"button\"\n className=\"mr-settings-head\"\n aria-expanded={open}\n aria-label={(open ? t('collapse') : t('expand')) + ':' + t('settingsTitle')}\n onClick={() => setOpen(!open)}\n >\n <span className=\"mr-settings-head-text\">\n <span className=\"mr-settings-title\">{t('settingsTitle')}</span>\n <span className=\"mr-settings-sub\">{t('settingsCardDescription')}</span>\n </span>\n <span className=\"mr-settings-chevron\" data-open={open ? '' : undefined} aria-hidden=\"true\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path d=\"M3.5 5.25L7 8.75L10.5 5.25\" stroke=\"currentColor\" strokeWidth=\"1.5\"\n strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n </button>\n {open && (\n <div className=\"mr-settings-body\">\n {!writable && (\n <p className=\"mr-settings-readonly\" role=\"status\">{t('readOnly')}</p>\n )}\n <div className=\"mr-root\">\n <label className=\"mr-quick-switch\">\n <input\n type=\"checkbox\"\n checked={state?.showQuickSwitch ?? true}\n disabled={loading || quickSwitchBusy || !writable}\n onChange={(event) => void toggleQuickSwitch(event.target.checked)}\n />\n <span className=\"mr-quick-switch-copy\">\n <span className=\"mr-quick-switch-label\">{t('showQuickSwitchLabel')}</span>\n <span className=\"mr-quick-switch-desc\">{t('showQuickSwitchDescription')}</span>\n </span>\n </label>\n <label className=\"mr-quick-switch\">\n <input\n type=\"checkbox\"\n checked={state?.ignoreModelIdPrefix ?? true}\n disabled={loading || ignorePrefixBusy || !writable}\n onChange={(event) => void toggleIgnorePrefix(event.target.checked)}\n />\n <span className=\"mr-quick-switch-copy\">\n <span className=\"mr-quick-switch-label\">{t('ignorePrefixLabel')}</span>\n <span className=\"mr-quick-switch-desc\">{t('ignorePrefixDescription')}</span>\n </span>\n </label>\n <div className=\"mr-sort\">\n <div className=\"mr-sort-head\">\n <span className=\"mr-sort-title\">{t('sortTitle')}</span>\n <span className=\"mr-sort-desc\">{t('sortDescription')}</span>\n </div>\n <div className=\"mr-sort-modes\" role=\"radiogroup\" aria-label={t('sortTitle')}>\n {(['custom', 'name', 'recent'] as const).map(mode => (\n <label key={mode} className=\"mr-sort-mode\">\n <input\n type=\"radio\"\n name=\"mr-model-sort\"\n checked={state?.modelSort === mode}\n disabled={loading || sortBusy || !writable}\n onChange={() => void changeModelSort(mode)}\n />\n <span className=\"mr-sort-mode-copy\">\n <span className=\"mr-sort-mode-label\">{t(`sortMode${mode[0].toUpperCase()}${mode.slice(1)}`)}</span>\n <span className=\"mr-sort-mode-desc\">{t(`sortModeDesc${mode[0].toUpperCase()}${mode.slice(1)}`)}</span>\n </span>\n </label>\n ))}\n </div>\n {state?.modelSort === 'custom' && (\n <div className=\"mr-sort-custom\">\n <p className=\"mr-sort-hint\">{t('sortCustomHint')}</p>\n <ol className=\"mr-sort-list\">\n {models.map((model, index) => {\n const dropTarget = modelDrag !== null && modelDrag.index !== index\n return (\n <li\n key={model.id}\n className={[\n 'mr-sort-item',\n dropTarget ? 'mr-sort-item-drop' : '',\n sortBusy ? 'mr-sort-item-busy' : '',\n ].filter(Boolean).join(' ')}\n draggable={!sortBusy && writable}\n onDragStart={(event) => {\n setModelDrag({ index })\n event.dataTransfer.effectAllowed = 'move'\n try {\n event.dataTransfer.setData('text/plain', model.id)\n } catch {\n // drag data is cosmetic for our own handler\n }\n }}\n onDragOver={(event) => {\n if (modelDrag !== null && modelDrag.index !== index) {\n event.preventDefault()\n event.dataTransfer.dropEffect = 'move'\n }\n }}\n onDrop={(event) => {\n if (modelDrag !== null && modelDrag.index !== index) {\n event.preventDefault()\n moveModel(modelDrag.index, index)\n }\n setModelDrag(null)\n }}\n onDragEnd={() => setModelDrag(null)}\n >\n <span className=\"mr-grip\" aria-hidden=\"true\">⠿</span>\n <span className=\"mr-sort-model-name\">{model.name}</span>\n <span className=\"mr-sort-model-id\">{model.id}</span>\n </li>\n )\n })}\n </ol>\n </div>\n )}\n </div>\n <div className=\"mr-toolbar\">\n <span className=\"mr-count\">{t('modelsCount', { count: models.length })}</span>\n <button type=\"button\" className=\"mr-button\" onClick={() => void load()} disabled={loading}>\n {t('refresh')}\n </button>\n </div>\n {error !== null && (\n <div className=\"mr-error\" role=\"alert\">{error}</div>\n )}\n {loading && models.length === 0 && (\n <div className=\"mr-empty\">{t('loading')}</div>\n )}\n {!loading && models.length === 0 && (\n <div className=\"mr-empty\">{t('empty')}</div>\n )}\n <div className=\"mr-models\">\n {models.map(model => (\n <ModelCard\n key={model.id}\n model={model}\n t={t}\n readOnly={!writable}\n busy={busyModel === model.id}\n dragging={drag}\n onDragStart={index => setDrag({ modelId: model.id, index })}\n onDragEnd={() => setDrag(null)}\n onDrop={index => {\n if (drag !== null && drag.modelId === model.id) {\n void reorder(model, drag.index, index)\n }\n setDrag(null)\n }}\n onSwitch={providerId => void switchActive(model, providerId)}\n />\n ))}\n </div>\n </div>\n </div>\n )}\n </li>\n )\n }\n}\n\ninterface ModelCardProps {\n model: RouterModelView\n t: Translate\n readOnly: boolean\n busy: boolean\n dragging: { modelId: string; index: number } | null\n onDragStart: (index: number) => void\n onDragEnd: () => void\n onDrop: (index: number) => void\n onSwitch: (providerId: string) => void\n}\n\nfunction ModelCard(props: ModelCardProps): JSX.Element {\n const { model, t, readOnly, busy, dragging } = props\n return (\n <section className={`mr-card${busy ? ' mr-card-busy' : ''}`}>\n <header className=\"mr-card-header\">\n <span className=\"mr-model-name\">{model.name}</span>\n <span className=\"mr-model-id\">{model.id}</span>\n <span className=\"mr-provider-count\">{t('providerCount', { count: model.providers.length })}</span>\n </header>\n <p className=\"mr-drag-hint\">{t('dragHint')}</p>\n <ul className=\"mr-providers\">\n {model.providers.map((provider, index) => {\n const active = provider.id === model.active\n const selectable = provider.credentialConfigured\n const dropTarget = dragging !== null && dragging.modelId === model.id && dragging.index !== index\n return (\n <li\n key={provider.id}\n className={[\n 'mr-provider',\n active ? 'mr-provider-active' : '',\n !selectable ? 'mr-provider-nocred' : '',\n dropTarget ? 'mr-provider-drop' : '',\n ].filter(Boolean).join(' ')}\n draggable={!busy && !readOnly && model.providers.length > 1}\n title={selectable ? undefined : t('noCredential')}\n onDragStart={(event) => {\n props.onDragStart(index)\n event.dataTransfer.effectAllowed = 'move'\n try {\n event.dataTransfer.setData('text/plain', model.id)\n } catch {\n // drag data is cosmetic for our own handler\n }\n }}\n onDragOver={(event) => {\n if (dragging !== null && dragging.modelId === model.id && dragging.index !== index) {\n event.preventDefault()\n event.dataTransfer.dropEffect = 'move'\n }\n }}\n onDrop={(event) => {\n if (dragging !== null && dragging.modelId === model.id) {\n event.preventDefault()\n props.onDrop(index)\n }\n }}\n onDragEnd={() => props.onDragEnd()}\n >\n <span className=\"mr-grip\" aria-hidden=\"true\">⠿</span>\n <button\n type=\"button\"\n className=\"mr-provider-button\"\n disabled={!selectable || busy || active || readOnly}\n onClick={() => props.onSwitch(provider.id)}\n >\n <span className=\"mr-provider-name\">{provider.name}</span>\n {!selectable && <span className=\"mr-provider-nocred-label\">· {t('noCredential')}</span>}\n </button>\n {active && <span className=\"mr-active-badge\">{t('activeBadge')}</span>}\n </li>\n )\n })}\n </ul>\n </section>\n )\n}\n","import {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type FocusEvent as ReactFocusEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n} from 'react'\nimport type { ClientContext, SessionId, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport {\n IconCheckOutline16,\n IconChevronDownOutline14,\n IconChevronRightOutline14,\n IconWarningOutline16,\n Toast,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport { api, type ModelRouterState, type RouterModelView } from './api'\nimport { LOCALE_NS } from './locales'\nimport './model-seat.css'\n\nconst ROUTER_PROVIDER_ID = 'model-router'\n\n/**\n * Minimal structural ModelSelection (wire shape: provider / model /\n * reasoningEffort). Declared locally to avoid pulling a new peer dependency\n * for a type-only surface; structurally identical to the host wire type.\n */\ninterface ModelSelection {\n provider: string\n model: string\n reasoningEffort?: string\n}\n\n/** The injected business face of the composer model seat (same share the host ModelSelect receives). */\ninterface ModelSeatInjected {\n available: boolean\n directory: SnapshotStore<ModelDirectoryState>\n load: () => void\n select: (selection: ModelSelection) => Promise<boolean>\n}\n\ntype ModelSeatProps = PropsRuntime<'conversation.input.model'>\n & ModelSeatInjected\n & PropsLocale<typeof LOCALE_NS>\n\ntype RouteProvider = RouterModelView['providers'][number]\n\n/**\n * The composer model seat, shadowing the host ModelSelect at a lower slot\n * priority. It renders the same two-level Model / Effort menu as the host\n * (model list grouped by provider, reasoning effort levels), plus a third\n * Provider row that opens the model-router provider list — the former quick\n * route-switcher button moved into the model picker, on par with the model\n * and effort menus.\n *\n * Shadowing contract: the host ui-model-selection registers the\n * `conversation.input.model` occupant at priority 0; this entry registers at\n * priority -1, so the renderer projects this component as the single-slot\n * winner while the host entry stays as the abdication fallback. Both entries\n * share the same per-session ModelDirectory, so selections stay consistent\n * with the /model popup and the host picker.\n */\nexport function ModelRouterSeat({\n locked,\n available,\n directory,\n load,\n select,\n t,\n}: ModelSeatProps): JSX.Element | null {\n const directoryState = useSyncExternalStore(\n onChange => directory.subscribe(onChange),\n () => directory.getSnapshot(),\n () => directory.getSnapshot(),\n )\n const current = directoryState.current\n\n const [open, setOpen] = useState(false)\n const [pane, setPane] = useState<'root' | 'model' | 'provider' | 'effort'>('root')\n const lastActionRef = useRef<'load' | 'select'>('load')\n const [toast, setToast] = useState<{ seq: number; text: string } | null>(null)\n const toastSeq = useRef(0)\n const rootRef = useRef<HTMLDivElement | null>(null)\n const triggerRef = useRef<HTMLButtonElement | null>(null)\n const itemRefs = useRef<(HTMLButtonElement | null)[]>([])\n const id = useId()\n\n // ---- model-router state (moved from the quick route switcher) ----\n const [routerState, setRouterState] = useState<ModelRouterState | null>(null)\n const [routerLoading, setRouterLoading] = useState(false)\n const [routerError, setRouterError] = useState<string | null>(null)\n const [busyProvider, setBusyProvider] = useState<string | null>(null)\n\n const isRouterModel = available && current?.provider === ROUTER_PROVIDER_ID\n const modelId = isRouterModel ? current.model : null\n\n const loadRouterState = useCallback(async (silent = false) => {\n if (!silent) setRouterLoading(true)\n try {\n setRouterState(await api.state())\n setRouterError(null)\n } catch (cause) {\n setRouterError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n if (!silent) setRouterLoading(false)\n }\n }, [])\n\n // Load the advisory directory on mount (host behavior).\n useEffect(() => {\n if (!available) return\n load()\n }, [available, load])\n\n // Fetch the router state (and thus the global toggle) on mount too, so the\n // \"hide provider switching\" setting applies as soon as it resolves.\n useEffect(() => {\n if (!available) return\n void loadRouterState()\n }, [available, loadRouterState])\n\n // Reset the open pane when the selected model changes (a different model may\n // no longer be a model-router route).\n useEffect(() => {\n setPane('root')\n setBusyProvider(null)\n setRouterError(null)\n }, [modelId])\n\n // Silent debounced refresh of the router state after directory refreshes\n // (settings edits, adapter updates), so the provider row never shows a stale\n // active provider.\n const refreshTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(() => {\n if (!isRouterModel || modelId === null || directoryState.status !== 'ready') return\n if (refreshTimer.current !== null) clearTimeout(refreshTimer.current)\n refreshTimer.current = setTimeout(() => {\n refreshTimer.current = null\n void loadRouterState(true)\n }, 300)\n return () => {\n if (refreshTimer.current !== null) clearTimeout(refreshTimer.current)\n refreshTimer.current = null\n }\n }, [directoryState.status, isRouterModel, loadRouterState, modelId])\n\n const routeModel = useMemo(\n () => modelId === null\n ? undefined\n : routerState?.models.find(model => model.id === modelId),\n [modelId, routerState],\n )\n\n const providers = useMemo(() => {\n if (routeModel === undefined) return []\n const byId = new Map(routeModel.providers.map(provider => [provider.id, provider]))\n const ordered = routeModel.order\n .map(id => byId.get(id))\n .filter((provider): provider is RouteProvider => provider !== undefined)\n const seen = new Set(ordered.map(provider => provider.id))\n return [...ordered, ...routeModel.providers.filter(provider => !seen.has(provider.id))]\n }, [routeModel])\n\n const switchProvider = useCallback(async (providerId: string) => {\n if (modelId === null || routeModel === undefined || routeModel.active === providerId) {\n setOpen(false)\n return\n }\n setBusyProvider(providerId)\n try {\n const next = await api.switchActive(modelId, providerId)\n setRouterState(next)\n setRouterError(null)\n setOpen(false)\n // Keep the host model picker description in sync immediately.\n load()\n } catch (cause) {\n setRouterError(t('switchFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setBusyProvider(null)\n }\n }, [load, modelId, routeModel, t])\n\n // ---- host ModelSelect logic (faithful copy) ----\n const choices = useMemo(() => directoryState.groups.flatMap(group => group.models.map(model => ({\n group,\n model,\n selection: {\n provider: group.id,\n model: model.id,\n ...model.reasoning?.defaultEffort === undefined ? {} : { reasoningEffort: model.reasoning.defaultEffort },\n },\n }))), [directoryState.groups])\n const currentChoice = choices[current === null ? -1 : choices.findIndex(c =>\n c.selection.provider === current?.provider && c.selection.model === current.model)]\n const reasoning = currentChoice?.model.reasoning\n const effectiveEffort = current?.reasoningEffort ?? reasoning?.defaultEffort\n const effortLabel = reasoning === undefined ? undefined\n : effectiveEffort === undefined ? t('effortProviderDefault')\n : reasoning.efforts.find(level => level.id === effectiveEffort)?.name ?? effectiveEffort\n const effortChoices = useMemo<Array<{ key: string; effort: string | undefined; label: string; description?: string }>>(() => reasoning === undefined ? [] : [\n ...(reasoning.defaultEffort === undefined ? [{\n key: 'provider-default',\n effort: undefined as string | undefined,\n label: t('effortProviderDefault'),\n }] : []),\n ...reasoning.efforts.map(effort => ({\n key: `effort:${effort.id}`,\n effort: effort.id,\n label: effort.name,\n ...effort.description === undefined ? {} : { description: effort.description },\n })),\n ], [reasoning, t])\n\n const busy = directoryState.status === 'selecting'\n const reload = () => {\n lastActionRef.current = 'load'\n load()\n }\n\n // Close on outside mousedown (host behavior).\n useEffect(() => {\n if (!open) return\n const closeOutside = (event: MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', closeOutside)\n return () => {\n document.removeEventListener('mousedown', closeOutside)\n }\n }, [open])\n\n if (!available) return null\n\n const show = () => {\n setPane('root')\n setOpen(true)\n reload()\n void loadRouterState()\n }\n const close = (restoreFocus = false) => {\n setOpen(false)\n setPane('root')\n if (restoreFocus) queueMicrotask(() => {\n triggerRef.current?.focus()\n })\n }\n const moveFocus = (offset: number) => {\n const items = itemRefs.current.filter((item): item is HTMLButtonElement => item !== null)\n if (items.length === 0) return\n const active = items.findIndex(item => item === document.activeElement)\n items[(Math.max(active, 0) + offset + items.length) % items.length]?.focus()\n }\n const onRootKeyDown = (event: ReactKeyboardEvent) => {\n if (event.key === 'Escape' && open) {\n event.preventDefault()\n if (pane !== 'root') setPane('root')\n else close(true)\n return\n }\n if (!open) return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n moveFocus(event.key === 'ArrowDown' ? 1 : -1)\n }\n }\n const onBlur = (event: ReactFocusEvent) => {\n if (event.relatedTarget instanceof Node && rootRef.current?.contains(event.relatedTarget)) return\n close()\n }\n const settleSelection = (accepted: boolean) => {\n if (accepted) {\n if (rootRef.current !== null) close(true)\n return\n }\n const message = directory.getSnapshot().error\n if (message !== null) {\n toastSeq.current += 1\n setToast({ seq: toastSeq.current, text: t('errorAction', { message }) })\n }\n }\n const choose = (selection: ModelSelection) => {\n if (current !== null && current.provider === selection.provider && current.model === selection.model) {\n close(true)\n return\n }\n lastActionRef.current = 'select'\n select(selection).then(settleSelection)\n }\n const chooseEffort = (effort: string | undefined) => {\n if (current === null) return\n if (effectiveEffort === effort) {\n close(true)\n return\n }\n const selection: ModelSelection = {\n provider: current.provider,\n model: current.model,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n }\n lastActionRef.current = 'select'\n select(selection).then(settleSelection)\n }\n\n const modelLabel = currentChoice?.model.name ?? t('triggerFallback')\n const triggerLabel = effortLabel === undefined ? modelLabel : `${modelLabel} · ${effortLabel}`\n const triggerAria = currentChoice === undefined ? t('triggerSelectAria')\n : effortLabel === undefined ? t('triggerAria', { model: modelLabel })\n : t('triggerAriaEffort', { model: modelLabel, effort: effortLabel })\n\n // ---- provider row visibility (the former quick-switch button conditions) ----\n const activeProvider = providers.find(provider => provider.id === routeModel?.active)\n const activeProviderName = activeProvider?.name ?? routeModel?.active ?? t('routeLoading')\n const providerRowVisible = isRouterModel\n && routerState !== null\n && routerState.showQuickSwitch !== false\n && routerState.providers.length >= 2\n && routeModel !== undefined\n && providers.length >= 2\n\n itemRefs.current = []\n let itemIndex = 0\n const itemRef = () => {\n const at = itemIndex++\n return (node: HTMLButtonElement | null) => {\n itemRefs.current[at] = node\n }\n }\n\n return (\n <div\n ref={rootRef}\n className=\"mr-seat-root\"\n onKeyDown={onRootKeyDown}\n onBlur={onBlur}\n >\n <button\n ref={triggerRef}\n type=\"button\"\n className=\"mr-seat-trigger\"\n aria-label={triggerAria}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? `${id}-menu` : undefined}\n title={triggerLabel}\n disabled={locked}\n onClick={() => {\n if (open) close()\n else show()\n }}\n >\n <span className=\"mr-seat-triggerLabel\">{modelLabel}</span>\n {effortLabel !== undefined && (\n <span className=\"mr-seat-triggerEffort\">{effortLabel}</span>\n )}\n <span className={`mr-seat-chevron${open ? ' mr-seat-chevronOpen' : ''}`} aria-hidden>\n <IconChevronDownOutline14 />\n </span>\n </button>\n {open && (\n <div\n id={`${id}-menu`}\n className=\"mr-seat-menu\"\n role=\"menu\"\n aria-label={t('menuAria')}\n aria-busy={directoryState.status === 'loading' || busy}\n >\n {pane === 'root' && (\n <>\n <button\n ref={itemRef()}\n type=\"button\"\n role=\"menuitem\"\n className=\"mr-seat-cell\"\n onClick={() => setPane('model')}\n >\n <span className=\"mr-seat-cellLabel\">{t('menuModel')}</span>\n <span className=\"mr-seat-cellValue\">{modelLabel}</span>\n <span className=\"mr-seat-cellChevron\" aria-hidden>\n <IconChevronRightOutline14 />\n </span>\n </button>\n {providerRowVisible && (\n <button\n ref={itemRef()}\n type=\"button\"\n role=\"menuitem\"\n className=\"mr-seat-cell\"\n onClick={() => setPane('provider')}\n >\n <span className=\"mr-seat-cellLabel\">{t('menuProvider')}</span>\n <span className=\"mr-seat-cellValue\">{activeProviderName}</span>\n <span className=\"mr-seat-cellChevron\" aria-hidden>\n <IconChevronRightOutline14 />\n </span>\n </button>\n )}\n {reasoning !== undefined && (\n <button\n ref={itemRef()}\n type=\"button\"\n role=\"menuitem\"\n className=\"mr-seat-cell\"\n onClick={() => setPane('effort')}\n >\n <span className=\"mr-seat-cellLabel\">{t('menuEffort')}</span>\n <span className=\"mr-seat-cellValue\">{effortLabel}</span>\n <span className=\"mr-seat-cellChevron\" aria-hidden>\n <IconChevronRightOutline14 />\n </span>\n </button>\n )}\n </>\n )}\n {pane === 'model' && (\n <>\n {directoryState.status === 'loading' && (\n <div className=\"mr-seat-status\">{t('statusLoading')}</div>\n )}\n {directoryState.error !== null && lastActionRef.current === 'load' && (\n <div className=\"mr-seat-error\">\n <span>{t('errorAction', { message: directoryState.error })}</span>\n <button type=\"button\" className=\"mr-seat-retry\" onClick={reload}>\n {t('retry')}\n </button>\n </div>\n )}\n {directoryState.failures.map(failure => (\n <div key={failure.id} className=\"mr-seat-warning\">\n <span>{t('warningGroupLoad', { name: failure.name, message: failure.message })}</span>\n <button type=\"button\" className=\"mr-seat-retry\" onClick={reload}>\n {t('retry')}\n </button>\n </div>\n ))}\n <div className=\"mr-seat-groups\">\n {directoryState.groups.map(group => {\n const headingId = `${id}-${group.id}`\n return (\n <section\n key={group.id}\n role=\"group\"\n aria-labelledby={headingId}\n className=\"mr-seat-group\"\n >\n <div className=\"mr-seat-groupTitle\" id={headingId}>\n {group.name}\n </div>\n {group.models.map(model => {\n const selected = current?.provider === group.id && current.model === model.id\n return (\n <button\n key={model.id}\n ref={itemRef()}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={selected}\n className={`mr-seat-option${selected ? ' mr-seat-selected' : ''}`}\n title={model.name}\n disabled={busy}\n onClick={() => choose({ provider: group.id, model: model.id })}\n >\n <span className=\"mr-seat-optionCopy\">\n <span className=\"mr-seat-modelName\">{model.name}</span>\n {model.description !== undefined && (\n <span className=\"mr-seat-description\">{model.description}</span>\n )}\n </span>\n <span className=\"mr-seat-check\" aria-hidden>\n {selected ? <IconCheckOutline16 /> : null}\n </span>\n </button>\n )\n })}\n </section>\n )\n })}\n </div>\n {directoryState.status === 'ready' && choices.length === 0 && (\n <div className=\"mr-seat-empty\">{t('emptyModels')}</div>\n )}\n </>\n )}\n {pane === 'provider' && (\n <>\n {routerError !== null && (\n <div className=\"mr-seat-error\">\n <span>{routerError}</span>\n <button\n type=\"button\"\n className=\"mr-seat-retry\"\n onClick={() => {\n void loadRouterState()\n load()\n }}\n >\n {t('retry')}\n </button>\n </div>\n )}\n {routeModel === undefined ? (\n <div className=\"mr-seat-status\">{t('routeLoading')}</div>\n ) : (\n <>\n <div className=\"mr-seat-title\">{t('routeMenuTitle', { model: modelId ?? '' })}</div>\n <div className=\"mr-seat-groups\">\n {providers.map(provider => {\n const selected = routeModel.active === provider.id\n return (\n <button\n key={provider.id}\n ref={itemRef()}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={selected}\n className={`mr-seat-option${selected ? ' mr-seat-selected' : ''}`}\n disabled={!provider.credentialConfigured || busyProvider !== null}\n onClick={() => void switchProvider(provider.id)}\n >\n <span className=\"mr-seat-optionCopy\">\n <span className=\"mr-seat-modelName\">{provider.name}</span>\n {!provider.credentialConfigured && (\n <span className=\"mr-seat-description\">{t('noCredentialShort')}</span>\n )}\n </span>\n <span className=\"mr-seat-check\" aria-hidden>\n {selected ? <IconCheckOutline16 /> : null}\n </span>\n </button>\n )\n })}\n </div>\n <div className=\"mr-seat-hint\">{t('globalRouteHint')}</div>\n </>\n )}\n </>\n )}\n {pane === 'effort' && (\n <>\n {directoryState.error !== null && lastActionRef.current === 'load' && (\n <div className=\"mr-seat-error\">\n <span>{t('errorAction', { message: directoryState.error })}</span>\n <button type=\"button\" className=\"mr-seat-retry\" onClick={reload}>\n {t('actionReload')}\n </button>\n </div>\n )}\n {effortChoices.length === 0 ? (\n <div className=\"mr-seat-empty\">{t('emptyEfforts')}</div>\n ) : effortChoices.map(level => (\n <button\n key={level.key}\n ref={itemRef()}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={effectiveEffort === level.effort}\n className={`mr-seat-option${effectiveEffort === level.effort ? ' mr-seat-selected' : ''}`}\n disabled={busy}\n onClick={() => chooseEffort(level.effort)}\n >\n <span className=\"mr-seat-optionCopy\">\n <span className=\"mr-seat-modelName\">{level.label}</span>\n {level.description !== undefined && (\n <span className=\"mr-seat-description\">{level.description}</span>\n )}\n </span>\n <span className=\"mr-seat-check\" aria-hidden>\n {effectiveEffort === level.effort ? <IconCheckOutline16 /> : null}\n </span>\n </button>\n ))}\n </>\n )}\n </div>\n )}\n {toast !== null && (\n <Toast\n key={toast.seq}\n text={toast.text}\n icon={<IconWarningOutline16 />}\n anchor={rootRef.current?.closest('[data-composer-card]') ?? null}\n onDone={() => setToast(null)}\n />\n )}\n </div>\n )\n}\n\n/** Register the model seat onto the composer's named model slot (priority -1 shadows the host seat). */\nexport function registerModelRouterSeat(ctx: ClientContext): void {\n const t = ctx.locale.bind(LOCALE_NS)\n ctx.inject(['slots', 'modelDirectories'], scope => {\n const models = scope.modelDirectories\n const sessions = scope.sessions\n scope.slots.inject('conversation.input.model', () => scope.slots.register({\n name: 'conversation.input.model',\n id: 'model-router-model-seat',\n priority: -1,\n label: () => t('seatLabel'),\n locale: LOCALE_NS,\n inject: (sessionId: SessionId) => {\n const directory = models.directoryFor(sessionId)\n const available = sessions.subagentAddress(sessionId) === undefined\n return {\n available,\n directory: directory.store,\n load: () => {\n if (available) directory.load().catch(() => {})\n },\n select: (selection: ModelSelection) =>\n available ? directory.select(selection).then(() => true, () => false) : Promise.resolve(false),\n }\n },\n } as never, ModelRouterSeat as never))\n })\n}\n","/**\n * @fonlan/dsh-model-router client half: the plugin's own Settings Card\n * (设置 → 插件 → 插件配置 → 模型路由) plus the model seat that merges the\n * provider switcher into DSH's composer model picker menu.\n */\nimport type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport { LOCALE_NS, zh, en } from './locales'\nimport { makeSettingsCard, type SettingsScopeFace } from './settings-card'\nimport { registerModelRouterSeat } from './model-seat'\n\n/** The settings namespace this card edits (must match the host half). */\nconst ROUTER_NS = 'model-router'\n\n/** Slots face: the keyed `settings.plugin.item` declaration ships with the web\n * app's ui-settings-plugins package, which external plugins do not depend on;\n * the register call below is typed through this local face (erased at build). */\ninterface Slots {\n inject(name: string, callback: () => unknown): unknown\n register(def: { name: string; key: string; inject?: () => unknown }, component: unknown): unknown\n}\n\n/** Services required before mounting (provided by the client runtime). */\nexport const inject = ['slots', 'locale', 'modelDirectories', 'sessions', 'settingsScope', 'connection', 'remote']\n\n/** Client plugin body. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n const off = ctx.locale.register(LOCALE_NS, { zh, en })\n return () => off()\n }, 'model-router: dictionaries')\n\n const SettingsCard = makeSettingsCard(ctx)\n\n // The card registers on the `settings.plugin.item` slot keyed by the\n // `model-router` settings namespace (the same string the host half\n // registers), so it appears inside 设置 → 插件 → 插件配置, paired with the\n // namespace by the tab.\n const services = ctx as unknown as {\n slots: Slots\n settingsScope: { bind(spec: { namespace: string }): SettingsScopeFace }\n }\n const scope = services.settingsScope.bind({ namespace: ROUTER_NS })\n\n services.slots.inject('settings.plugin.item', () =>\n services.slots.register(\n {\n name: 'settings.plugin.item',\n key: ROUTER_NS,\n inject: () => ({ scope }),\n },\n SettingsCard,\n ),\n )\n\n registerModelRouterSeat(ctx)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useCallback","useSyncExternalStore","useState","useMemo","useSyncExternalStore","useState","useRef","useId","useCallback","useMemo","IconChevronDownOutline14","IconChevronRightOutline14","IconCheckOutline16","Toast","IconWarningOutline16"],"sources":["../../../src/client/locales.ts","../../../src/client/api.ts","../../../src/client/settings-card.tsx","../../../src/client/model-seat.tsx","../../../src/client/index.tsx"],"sourcesContent":["// Locale namespace = the plugin's cordis id (kebab). DSH flat namespace keys\n// (settings + locale) use the internal id `model-router`; the scoped npm\n// package name is reserved for package-bound identifiers (exported `name`,\n// module-loader id, the /plugins/<pkg>/… route base).\nexport const LOCALE_NS = 'model-router'\n\nexport const zh = {\n settingsTitle: '模型路由',\n settingsCardDescription: '模型聚合、提供商切换与优先级顺序',\n expand: '展开',\n collapse: '收起',\n readOnly: '本部署的设置为只读。',\n loading: '加载中…',\n loadFailed: '加载失败:{message}',\n retry: '重试',\n refresh: '刷新',\n empty: '没有可路由的提供商或模型,请先在设置中添加提供商。',\n modelsCount: '共 {count} 个模型',\n activeBadge: '当前',\n noCredential: '未配置 API 密钥,不可选',\n dragHint: '拖拽调整优先级顺序',\n switchFailed: '切换失败:{message}',\n reorderFailed: '排序失败:{message}',\n providerCount: '{count} 个提供商',\n seatLabel: '模型选择(含提供商切换)',\n menuAria: '模型、提供商与推理等级',\n menuModel: '模型',\n menuProvider: '提供商',\n menuEffort: '推理等级',\n triggerFallback: '选择模型',\n triggerSelectAria: '选择模型',\n triggerAria: '选择模型,当前 {model}',\n triggerAriaEffort: '选择模型,当前 {model},推理等级 {effort}',\n effortProviderDefault: 'Default',\n statusLoading: '正在刷新模型列表…',\n errorAction: '模型操作失败:{message}',\n actionReload: '重新加载',\n warningGroupLoad: '{name} 加载失败:{message}',\n emptyModels: '没有可用的模型。',\n emptyEfforts: '当前模型未提供推理等级。',\n routeMenuTitle: '{model} · 选择提供商',\n routeLoading: '加载路由…',\n noCredentialShort: '未配置凭据',\n globalRouteHint: '切换后对所有会话的后续请求生效',\n showQuickSwitchLabel: '在模型选择菜单中显示提供商切换',\n showQuickSwitchDescription: '开启后,当当前模型是 model-router 路由时,模型选择弹出菜单会显示提供商列表入口,可直接切换该模型的激活提供商。',\n ignorePrefixLabel: '匹配时忽略模型 ID 前缀',\n ignorePrefixDescription: '开启后,deepseek/deepseek-v4-flash 与 deepseek-v4-flash 视为同一模型,统一显示不带前缀的模型 id(默认开启)。',\n sortTitle: '模型显示顺序',\n sortDescription: '模型选择列表中 model-router 分组内模型的排列方式。',\n sortModeCustom: '自定义',\n sortModeName: '按名称',\n sortModeRecent: '最近使用',\n sortModeDescCustom: '按下方拖拽的手动顺序排列',\n sortModeDescName: '按模型名称排序(数字感知)',\n sortModeDescRecent: '最近用过的模型排在最前',\n sortCustomHint: '拖拽调整模型在模型选择列表中的显示顺序',\n sortFailed: '排序设置失败:{message}',\n}\n\nexport const en = {\n settingsTitle: 'Model Router',\n settingsCardDescription: 'Model aggregation, provider switching and preference order',\n expand: 'Expand',\n collapse: 'Collapse',\n readOnly: 'This deployment stores settings read-only.',\n loading: 'Loading…',\n loadFailed: 'Load failed: {message}',\n retry: 'Retry',\n refresh: 'Refresh',\n empty: 'No routable providers or models yet — add providers in settings first.',\n modelsCount: '{count} models',\n activeBadge: 'active',\n noCredential: 'No API key configured — not selectable',\n dragHint: 'Drag to adjust preference order',\n switchFailed: 'Switch failed: {message}',\n reorderFailed: 'Reorder failed: {message}',\n providerCount: '{count} providers',\n seatLabel: 'Model selection (with provider switching)',\n menuAria: 'Model, provider and reasoning effort',\n menuModel: 'Model',\n menuProvider: 'Provider',\n menuEffort: 'Effort',\n triggerFallback: 'Select model',\n triggerSelectAria: 'Select model',\n triggerAria: 'Select model, current {model}',\n triggerAriaEffort: 'Select model, current {model}, reasoning effort {effort}',\n effortProviderDefault: 'Default',\n statusLoading: 'Refreshing model list…',\n errorAction: 'Model operation failed: {message}',\n actionReload: 'Reload',\n warningGroupLoad: '{name} failed to load: {message}',\n emptyModels: 'No models available.',\n emptyEfforts: 'This model provides no reasoning effort levels.',\n routeMenuTitle: '{model} · Choose provider',\n routeLoading: 'Loading routes…',\n noCredentialShort: 'No credentials',\n globalRouteHint: 'Changes apply to subsequent requests in all sessions',\n showQuickSwitchLabel: 'Show provider switching in the model picker',\n showQuickSwitchDescription: 'When enabled, the model picker menu shows a provider list entry that switches the active provider, for model-router routes.',\n ignorePrefixLabel: 'Ignore model ID prefix when matching',\n ignorePrefixDescription: 'When enabled, deepseek/deepseek-v4-flash and deepseek-v4-flash are treated as the same model and shown without the prefix (on by default).',\n sortTitle: 'Model display order',\n sortDescription: 'How models inside the model-router group are ordered in the model picker.',\n sortModeCustom: 'Custom',\n sortModeName: 'By name',\n sortModeRecent: 'Recently used',\n sortModeDescCustom: 'Manual order via drag below',\n sortModeDescName: 'Sort by model name (numeric-aware)',\n sortModeDescRecent: 'Most recently used models first',\n sortCustomHint: 'Drag to reorder models in the model picker',\n sortFailed: 'Sort setting failed: {message}',\n}\n","/** Client transport for the model-router settings API. */\nexport interface RouterProviderView {\n id: string\n name: string\n credentialConfigured: boolean\n}\n\nexport type ModelSortMode = 'custom' | 'name' | 'recent'\n\nexport interface RouterModelView {\n id: string\n name: string\n active: string | null\n order: string[]\n providers: RouterProviderView[]\n}\n\nexport interface ModelRouterState {\n /** Whether provider switching is shown inside the composer model picker menu. */\n showQuickSwitch: boolean\n /** Whether model ids are matched with their leading vendor/ prefix ignored. */\n ignoreModelIdPrefix: boolean\n /** The model-list display order mode (custom | name | recent). */\n modelSort: ModelSortMode\n /** Explicit model id order for custom mode (display order). */\n modelOrder: string[]\n providers: RouterProviderView[]\n models: RouterModelView[]\n}\n\nexport class ModelRouterApiError extends Error {\n constructor(readonly code: string, message: string) {\n super(message)\n }\n}\n\nasync function call<T>(method: string, payload: Record<string, unknown> = {}): Promise<T> {\n let response: Response\n try {\n response = await fetch(`/plugins/@fonlan/dsh-model-router/api/${method}`, {\n method: 'POST',\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify(payload),\n })\n } catch (error) {\n throw new ModelRouterApiError('network', error instanceof Error ? error.message : String(error))\n }\n const parsed: { ok?: boolean; value?: unknown; error?: { code?: string; message?: string } } | null\n = await response.json().catch(() => null)\n if (!response.ok || parsed === null || parsed.ok !== true || parsed.value === undefined) {\n throw new ModelRouterApiError(\n parsed?.error?.code ?? 'http',\n parsed?.error?.message ?? `HTTP ${response.status}`,\n )\n }\n return parsed.value as T\n}\n\nexport const api = {\n state: () => call<ModelRouterState>('state'),\n switchActive: (modelId: string, providerId: string) =>\n call<ModelRouterState>('switch-active', { modelId, providerId }),\n reorder: (modelId: string, order: string[]) =>\n call<ModelRouterState>('reorder', { modelId, order }),\n refresh: () => call<ModelRouterState>('refresh'),\n setShowQuickSwitch: (value: boolean) =>\n call<ModelRouterState>('set-show-quick-switch', { value }),\n setIgnoreModelIdPrefix: (value: boolean) =>\n call<ModelRouterState>('set-ignore-model-id-prefix', { value }),\n setModelSort: (mode: ModelSortMode) =>\n call<ModelRouterState>('set-model-sort', { mode }),\n setModelOrder: (order: string[]) =>\n call<ModelRouterState>('set-model-order', { order }),\n}\n","/**\n * The Model Router Settings Card (设置 → 插件 → 插件配置 → 模型路由).\n *\n * Renders its own expandable chrome aligned with the built-in plugin cards\n * (external plugins cannot import PluginCard): a header naming the plugin and\n * what its settings govern, disclosing the router controls in place. All\n * reads/mutations go through the plugin's fenced API; the server persists\n * through the `model-router` settings namespace, so a switch here is live for\n * the next request globally.\n *\n * The bound settings scope (the same `model-router` namespace the host half\n * registers) supplies the card's dispatch state: while the namespace is merely\n * loading the card stays mounted, and when it is unavailable (deployment\n * without the host half) nothing renders — matching the built-in cards. A\n * read-only deployment shows the built-in card's banner and disables the\n * mutation controls.\n */\nimport { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from 'react'\nimport type { Context } from '@deepseek-ai/cordis'\ntype ClientContext = Context\nimport type { Translate } from '@deepseek-ai/dsh-client-ui-slots'\nimport { LOCALE_NS } from './locales'\nimport { api, type ModelRouterState, type ModelSortMode, type RouterModelView } from './api'\nimport './settings-card.css'\n\n/** Client settings scope face (subset of the app client modules). */\nexport interface SettingsScopeFace {\n getSnapshot(): {\n status: 'loading' | 'ready' | 'unavailable'\n writable: boolean\n }\n subscribe(listener: () => void): () => void\n}\n\nexport interface SettingsCardProps {\n /** The bound `model-router` settings scope (from the slot entry's inject face). */\n scope: SettingsScopeFace\n}\n\nfunction arrayMove<T>(list: readonly T[], from: number, to: number): T[] {\n const next = [...list]\n const [item] = next.splice(from, 1)\n next.splice(to, 0, item)\n return next\n}\n\nfunction useLocaleRevision(ctx: ClientContext): number {\n const subscribe = useCallback(\n (onChange: () => void) => {\n try {\n return ctx.locale.subscribe(onChange)\n } catch {\n return () => {}\n }\n },\n [ctx],\n )\n const getSnapshot = useCallback(() => {\n try {\n return ctx.locale.getLocale().revision\n } catch {\n return 0\n }\n }, [ctx])\n return useSyncExternalStore(subscribe, getSnapshot)\n}\n\nexport function makeSettingsCard(ctx: ClientContext): (props: SettingsCardProps) => JSX.Element | null {\n // Bound translation is namespace-typed; the card's props use the plain\n // Translate face (string keys), which the dict satisfies structurally.\n const t: Translate = (() => {\n try {\n return ctx.locale.bind(LOCALE_NS) as unknown as Translate\n } catch {\n return (key: string) => key\n }\n })()\n\n return function ModelRouterSettingsCard(props: SettingsCardProps): JSX.Element | null {\n const { scope } = props\n // Bind the methods: React invokes getSnapshot/subscribe as bare functions,\n // and SettingsScopeController's methods depend on `this`.\n const snapshot = useSyncExternalStore(\n (listener) => scope.subscribe(listener),\n () => scope.getSnapshot(),\n )\n useLocaleRevision(ctx)\n // Card-local disclosure: collapsed by default, like the built-in plugin cards.\n const [open, setOpen] = useState(false)\n const [state, setState] = useState<ModelRouterState | null>(null)\n const [error, setError] = useState<string | null>(null)\n const [loading, setLoading] = useState(true)\n const [busyModel, setBusyModel] = useState<string | null>(null)\n const [drag, setDrag] = useState<{ modelId: string; index: number } | null>(null)\n const [quickSwitchBusy, setQuickSwitchBusy] = useState(false)\n const [ignorePrefixBusy, setIgnorePrefixBusy] = useState(false)\n const [sortBusy, setSortBusy] = useState(false)\n const [modelDrag, setModelDrag] = useState<{ index: number } | null>(null)\n\n const load = useCallback(async () => {\n setLoading(true)\n try {\n setState(await api.state())\n setError(null)\n } catch (cause) {\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setLoading(false)\n }\n }, [])\n\n useEffect(() => {\n void load()\n }, [load])\n\n const switchActive = useCallback(async (model: RouterModelView, providerId: string) => {\n if (model.active === providerId) return\n setBusyModel(model.id)\n try {\n setState(await api.switchActive(model.id, providerId))\n setError(null)\n } catch (cause) {\n setError(t('switchFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setBusyModel(null)\n }\n }, [t])\n\n const reorder = useCallback(async (model: RouterModelView, from: number, to: number) => {\n if (from === to) return\n const order = arrayMove(model.order, from, to)\n setState(prev => prev === null ? prev : {\n ...prev,\n models: prev.models.map(m => (m.id === model.id ? { ...m, order } : m)),\n })\n setBusyModel(model.id)\n try {\n setState(await api.reorder(model.id, order))\n setError(null)\n } catch (cause) {\n setError(t('reorderFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n setState(prev => prev === null ? prev : {\n ...prev,\n models: prev.models.map(m => (m.id === model.id ? { ...m, order: model.order } : m)),\n })\n } finally {\n setBusyModel(null)\n }\n }, [t])\n\n const toggleQuickSwitch = useCallback(async (value: boolean) => {\n if (state === null) return\n const previous = state.showQuickSwitch\n setState(prev => prev === null ? prev : { ...prev, showQuickSwitch: value })\n setQuickSwitchBusy(true)\n try {\n setState(await api.setShowQuickSwitch(value))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, showQuickSwitch: previous })\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setQuickSwitchBusy(false)\n }\n }, [state])\n\n const toggleIgnorePrefix = useCallback(async (value: boolean) => {\n if (state === null) return\n const previous = state.ignoreModelIdPrefix\n setState(prev => prev === null ? prev : { ...prev, ignoreModelIdPrefix: value })\n setIgnorePrefixBusy(true)\n try {\n setState(await api.setIgnoreModelIdPrefix(value))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, ignoreModelIdPrefix: previous })\n setError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n setIgnorePrefixBusy(false)\n }\n }, [state])\n\n const changeModelSort = useCallback(async (mode: ModelSortMode) => {\n if (state === null || state.modelSort === mode) return\n const previous = state.modelSort\n setState(prev => prev === null ? prev : { ...prev, modelSort: mode })\n setSortBusy(true)\n try {\n setState(await api.setModelSort(mode))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, modelSort: previous })\n setError(t('sortFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setSortBusy(false)\n }\n }, [state, t])\n\n const moveModel = useCallback(async (from: number, to: number) => {\n if (state === null || from === to) return\n // The drag list shows the full display order (modelOrder + catalog\n // tail); persist the whole reordered id list as the new custom order.\n const ids = state.models.map(model => model.id)\n const order = arrayMove(ids, from, to)\n setState(prev => prev === null ? prev : { ...prev, modelOrder: order })\n setSortBusy(true)\n try {\n setState(await api.setModelOrder(order))\n setError(null)\n } catch (cause) {\n setState(prev => prev === null ? prev : { ...prev, modelOrder: state.modelOrder })\n setError(t('sortFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setSortBusy(false)\n }\n }, [state, t])\n\n // The namespace is served by the host once the scope is ready. While it is\n // merely loading, keep the card mounted (the tab already dispatched it);\n // if it is unavailable (deployment without the host half), render nothing.\n if (snapshot.status === 'unavailable') return null\n const writable = snapshot.writable\n\n const models = useMemo(() => state?.models ?? [], [state])\n\n return (\n <li className=\"mr-settings-card\" data-open={open ? '' : undefined}>\n <button\n type=\"button\"\n className=\"mr-settings-head\"\n aria-expanded={open}\n aria-label={(open ? t('collapse') : t('expand')) + ':' + t('settingsTitle')}\n onClick={() => setOpen(!open)}\n >\n <span className=\"mr-settings-head-text\">\n <span className=\"mr-settings-title\">{t('settingsTitle')}</span>\n <span className=\"mr-settings-sub\">{t('settingsCardDescription')}</span>\n </span>\n <span className=\"mr-settings-chevron\" data-open={open ? '' : undefined} aria-hidden=\"true\">\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 14 14\" fill=\"none\">\n <path d=\"M3.5 5.25L7 8.75L10.5 5.25\" stroke=\"currentColor\" strokeWidth=\"1.5\"\n strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </span>\n </button>\n {open && (\n <div className=\"mr-settings-body\">\n {!writable && (\n <p className=\"mr-settings-readonly\" role=\"status\">{t('readOnly')}</p>\n )}\n <div className=\"mr-root\">\n <label className=\"mr-quick-switch\">\n <input\n type=\"checkbox\"\n checked={state?.showQuickSwitch ?? true}\n disabled={loading || quickSwitchBusy || !writable}\n onChange={(event) => void toggleQuickSwitch(event.target.checked)}\n />\n <span className=\"mr-quick-switch-copy\">\n <span className=\"mr-quick-switch-label\">{t('showQuickSwitchLabel')}</span>\n <span className=\"mr-quick-switch-desc\">{t('showQuickSwitchDescription')}</span>\n </span>\n </label>\n <label className=\"mr-quick-switch\">\n <input\n type=\"checkbox\"\n checked={state?.ignoreModelIdPrefix ?? true}\n disabled={loading || ignorePrefixBusy || !writable}\n onChange={(event) => void toggleIgnorePrefix(event.target.checked)}\n />\n <span className=\"mr-quick-switch-copy\">\n <span className=\"mr-quick-switch-label\">{t('ignorePrefixLabel')}</span>\n <span className=\"mr-quick-switch-desc\">{t('ignorePrefixDescription')}</span>\n </span>\n </label>\n <div className=\"mr-sort\">\n <div className=\"mr-sort-head\">\n <span className=\"mr-sort-title\">{t('sortTitle')}</span>\n <span className=\"mr-sort-desc\">{t('sortDescription')}</span>\n </div>\n <div className=\"mr-sort-modes\" role=\"radiogroup\" aria-label={t('sortTitle')}>\n {(['custom', 'name', 'recent'] as const).map(mode => (\n <label key={mode} className=\"mr-sort-mode\">\n <input\n type=\"radio\"\n name=\"mr-model-sort\"\n checked={state?.modelSort === mode}\n disabled={loading || sortBusy || !writable}\n onChange={() => void changeModelSort(mode)}\n />\n <span className=\"mr-sort-mode-copy\">\n <span className=\"mr-sort-mode-label\">{t(`sortMode${mode[0].toUpperCase()}${mode.slice(1)}`)}</span>\n <span className=\"mr-sort-mode-desc\">{t(`sortModeDesc${mode[0].toUpperCase()}${mode.slice(1)}`)}</span>\n </span>\n </label>\n ))}\n </div>\n {state?.modelSort === 'custom' && (\n <div className=\"mr-sort-custom\">\n <p className=\"mr-sort-hint\">{t('sortCustomHint')}</p>\n <ol className=\"mr-sort-list\">\n {models.map((model, index) => {\n const dropTarget = modelDrag !== null && modelDrag.index !== index\n return (\n <li\n key={model.id}\n className={[\n 'mr-sort-item',\n dropTarget ? 'mr-sort-item-drop' : '',\n sortBusy ? 'mr-sort-item-busy' : '',\n ].filter(Boolean).join(' ')}\n draggable={!sortBusy && writable}\n onDragStart={(event) => {\n setModelDrag({ index })\n event.dataTransfer.effectAllowed = 'move'\n try {\n event.dataTransfer.setData('text/plain', model.id)\n } catch {\n // drag data is cosmetic for our own handler\n }\n }}\n onDragOver={(event) => {\n if (modelDrag !== null && modelDrag.index !== index) {\n event.preventDefault()\n event.dataTransfer.dropEffect = 'move'\n }\n }}\n onDrop={(event) => {\n if (modelDrag !== null && modelDrag.index !== index) {\n event.preventDefault()\n moveModel(modelDrag.index, index)\n }\n setModelDrag(null)\n }}\n onDragEnd={() => setModelDrag(null)}\n >\n <span className=\"mr-grip\" aria-hidden=\"true\">⠿</span>\n <span className=\"mr-sort-model-name\">{model.name}</span>\n <span className=\"mr-sort-model-id\">{model.id}</span>\n </li>\n )\n })}\n </ol>\n </div>\n )}\n </div>\n <div className=\"mr-toolbar\">\n <span className=\"mr-count\">{t('modelsCount', { count: models.length })}</span>\n <button type=\"button\" className=\"mr-button\" onClick={() => void load()} disabled={loading}>\n {t('refresh')}\n </button>\n </div>\n {error !== null && (\n <div className=\"mr-error\" role=\"alert\">{error}</div>\n )}\n {loading && models.length === 0 && (\n <div className=\"mr-empty\">{t('loading')}</div>\n )}\n {!loading && models.length === 0 && (\n <div className=\"mr-empty\">{t('empty')}</div>\n )}\n <div className=\"mr-models\">\n {models.map(model => (\n <ModelCard\n key={model.id}\n model={model}\n t={t}\n readOnly={!writable}\n busy={busyModel === model.id}\n dragging={drag}\n onDragStart={index => setDrag({ modelId: model.id, index })}\n onDragEnd={() => setDrag(null)}\n onDrop={index => {\n if (drag !== null && drag.modelId === model.id) {\n void reorder(model, drag.index, index)\n }\n setDrag(null)\n }}\n onSwitch={providerId => void switchActive(model, providerId)}\n />\n ))}\n </div>\n </div>\n </div>\n )}\n </li>\n )\n }\n}\n\ninterface ModelCardProps {\n model: RouterModelView\n t: Translate\n readOnly: boolean\n busy: boolean\n dragging: { modelId: string; index: number } | null\n onDragStart: (index: number) => void\n onDragEnd: () => void\n onDrop: (index: number) => void\n onSwitch: (providerId: string) => void\n}\n\nfunction ModelCard(props: ModelCardProps): JSX.Element {\n const { model, t, readOnly, busy, dragging } = props\n return (\n <section className={`mr-card${busy ? ' mr-card-busy' : ''}`}>\n <header className=\"mr-card-header\">\n <span className=\"mr-model-name\">{model.name}</span>\n <span className=\"mr-model-id\">{model.id}</span>\n <span className=\"mr-provider-count\">{t('providerCount', { count: model.providers.length })}</span>\n </header>\n <p className=\"mr-drag-hint\">{t('dragHint')}</p>\n <ul className=\"mr-providers\">\n {model.providers.map((provider, index) => {\n const active = provider.id === model.active\n const selectable = provider.credentialConfigured\n const dropTarget = dragging !== null && dragging.modelId === model.id && dragging.index !== index\n return (\n <li\n key={provider.id}\n className={[\n 'mr-provider',\n active ? 'mr-provider-active' : '',\n !selectable ? 'mr-provider-nocred' : '',\n dropTarget ? 'mr-provider-drop' : '',\n ].filter(Boolean).join(' ')}\n draggable={!busy && !readOnly && model.providers.length > 1}\n title={selectable ? undefined : t('noCredential')}\n onDragStart={(event) => {\n props.onDragStart(index)\n event.dataTransfer.effectAllowed = 'move'\n try {\n event.dataTransfer.setData('text/plain', model.id)\n } catch {\n // drag data is cosmetic for our own handler\n }\n }}\n onDragOver={(event) => {\n if (dragging !== null && dragging.modelId === model.id && dragging.index !== index) {\n event.preventDefault()\n event.dataTransfer.dropEffect = 'move'\n }\n }}\n onDrop={(event) => {\n if (dragging !== null && dragging.modelId === model.id) {\n event.preventDefault()\n props.onDrop(index)\n }\n }}\n onDragEnd={() => props.onDragEnd()}\n >\n <span className=\"mr-grip\" aria-hidden=\"true\">⠿</span>\n <button\n type=\"button\"\n className=\"mr-provider-button\"\n disabled={!selectable || busy || active || readOnly}\n onClick={() => props.onSwitch(provider.id)}\n >\n <span className=\"mr-provider-name\">{provider.name}</span>\n {!selectable && <span className=\"mr-provider-nocred-label\">· {t('noCredential')}</span>}\n </button>\n {active && <span className=\"mr-active-badge\">{t('activeBadge')}</span>}\n </li>\n )\n })}\n </ul>\n </section>\n )\n}\n","import {\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n useSyncExternalStore,\n type FocusEvent as ReactFocusEvent,\n type KeyboardEvent as ReactKeyboardEvent,\n} from 'react'\nimport type { Context } from '@deepseek-ai/cordis'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SessionId } from '@deepseek-ai/dsh-session/types'\ntype ClientContext = Context\nimport type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\nimport {\n IconCheckOutline16,\n IconChevronDownOutline14,\n IconChevronRightOutline14,\n IconWarningOutline16,\n Toast,\n} from '@deepseek-ai/dsh-client-ui-primitives'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport { api, type ModelRouterState, type RouterModelView } from './api'\nimport { LOCALE_NS } from './locales'\nimport './model-seat.css'\n\nconst ROUTER_PROVIDER_ID = 'model-router'\n\n/**\n * Minimal structural ModelSelection (wire shape: provider / model /\n * reasoningEffort). Declared locally to avoid pulling a new peer dependency\n * for a type-only surface; structurally identical to the host wire type.\n */\ninterface ModelSelection {\n provider: string\n model: string\n reasoningEffort?: string\n}\n\n/** The injected business face of the composer model seat (same share the host ModelSelect receives). */\ninterface ModelSeatInjected {\n available: boolean\n directory: SnapshotStore<ModelDirectoryState>\n load: () => void\n select: (selection: ModelSelection) => Promise<boolean>\n}\n\ntype ModelSeatProps = PropsRuntime<'conversation.input.model'>\n & ModelSeatInjected\n & PropsLocale<typeof LOCALE_NS>\n\ntype RouteProvider = RouterModelView['providers'][number]\n\n/**\n * The composer model seat, shadowing the host ModelSelect at a lower slot\n * priority. It renders the same two-level Model / Effort menu as the host\n * (model list grouped by provider, reasoning effort levels), plus a third\n * Provider row that opens the model-router provider list — the former quick\n * route-switcher button moved into the model picker, on par with the model\n * and effort menus.\n *\n * Shadowing contract: the host ui-model-selection registers the\n * `conversation.input.model` occupant at priority 0; this entry registers at\n * priority -1, so the renderer projects this component as the single-slot\n * winner while the host entry stays as the abdication fallback. Both entries\n * share the same per-session ModelDirectory, so selections stay consistent\n * with the /model popup and the host picker.\n */\nexport function ModelRouterSeat({\n locked,\n available,\n directory,\n load,\n select,\n t,\n}: ModelSeatProps): JSX.Element | null {\n const directoryState = useSyncExternalStore(\n onChange => directory.subscribe(onChange),\n () => directory.getSnapshot(),\n () => directory.getSnapshot(),\n )\n const current = directoryState.current\n\n const [open, setOpen] = useState(false)\n const [pane, setPane] = useState<'root' | 'model' | 'provider' | 'effort'>('root')\n const lastActionRef = useRef<'load' | 'select'>('load')\n const [toast, setToast] = useState<{ seq: number; text: string } | null>(null)\n const toastSeq = useRef(0)\n const rootRef = useRef<HTMLDivElement | null>(null)\n const triggerRef = useRef<HTMLButtonElement | null>(null)\n const itemRefs = useRef<(HTMLButtonElement | null)[]>([])\n const id = useId()\n\n // ---- model-router state (moved from the quick route switcher) ----\n const [routerState, setRouterState] = useState<ModelRouterState | null>(null)\n const [routerLoading, setRouterLoading] = useState(false)\n const [routerError, setRouterError] = useState<string | null>(null)\n const [busyProvider, setBusyProvider] = useState<string | null>(null)\n\n const isRouterModel = available && current?.provider === ROUTER_PROVIDER_ID\n const modelId = isRouterModel ? current.model : null\n\n const loadRouterState = useCallback(async (silent = false) => {\n if (!silent) setRouterLoading(true)\n try {\n setRouterState(await api.state())\n setRouterError(null)\n } catch (cause) {\n setRouterError(cause instanceof Error ? cause.message : String(cause))\n } finally {\n if (!silent) setRouterLoading(false)\n }\n }, [])\n\n // Load the advisory directory on mount (host behavior).\n useEffect(() => {\n if (!available) return\n load()\n }, [available, load])\n\n // Fetch the router state (and thus the global toggle) on mount too, so the\n // \"hide provider switching\" setting applies as soon as it resolves.\n useEffect(() => {\n if (!available) return\n void loadRouterState()\n }, [available, loadRouterState])\n\n // Reset the open pane when the selected model changes (a different model may\n // no longer be a model-router route).\n useEffect(() => {\n setPane('root')\n setBusyProvider(null)\n setRouterError(null)\n }, [modelId])\n\n // Silent debounced refresh of the router state after directory refreshes\n // (settings edits, adapter updates), so the provider row never shows a stale\n // active provider.\n const refreshTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\n useEffect(() => {\n if (!isRouterModel || modelId === null || directoryState.status !== 'ready') return\n if (refreshTimer.current !== null) clearTimeout(refreshTimer.current)\n refreshTimer.current = setTimeout(() => {\n refreshTimer.current = null\n void loadRouterState(true)\n }, 300)\n return () => {\n if (refreshTimer.current !== null) clearTimeout(refreshTimer.current)\n refreshTimer.current = null\n }\n }, [directoryState.status, isRouterModel, loadRouterState, modelId])\n\n const routeModel = useMemo(\n () => modelId === null\n ? undefined\n : routerState?.models.find(model => model.id === modelId),\n [modelId, routerState],\n )\n\n const providers = useMemo(() => {\n if (routeModel === undefined) return []\n const byId = new Map(routeModel.providers.map(provider => [provider.id, provider]))\n const ordered = routeModel.order\n .map(id => byId.get(id))\n .filter((provider): provider is RouteProvider => provider !== undefined)\n const seen = new Set(ordered.map(provider => provider.id))\n return [...ordered, ...routeModel.providers.filter(provider => !seen.has(provider.id))]\n }, [routeModel])\n\n const switchProvider = useCallback(async (providerId: string) => {\n if (modelId === null || routeModel === undefined || routeModel.active === providerId) {\n setOpen(false)\n return\n }\n setBusyProvider(providerId)\n try {\n const next = await api.switchActive(modelId, providerId)\n setRouterState(next)\n setRouterError(null)\n setOpen(false)\n // Keep the host model picker description in sync immediately.\n load()\n } catch (cause) {\n setRouterError(t('switchFailed', { message: cause instanceof Error ? cause.message : String(cause) }))\n } finally {\n setBusyProvider(null)\n }\n }, [load, modelId, routeModel, t])\n\n // ---- host ModelSelect logic (faithful copy) ----\n const choices = useMemo(() => directoryState.groups.flatMap(group => group.models.map(model => ({\n group,\n model,\n selection: {\n provider: group.id,\n model: model.id,\n ...model.reasoning?.defaultEffort === undefined ? {} : { reasoningEffort: model.reasoning.defaultEffort },\n },\n }))), [directoryState.groups])\n const currentChoice = choices[current === null ? -1 : choices.findIndex(c =>\n c.selection.provider === current?.provider && c.selection.model === current.model)]\n const reasoning = currentChoice?.model.reasoning\n const effectiveEffort = current?.reasoningEffort ?? reasoning?.defaultEffort\n const effortLabel = reasoning === undefined ? undefined\n : effectiveEffort === undefined ? t('effortProviderDefault')\n : reasoning.efforts.find(level => level.id === effectiveEffort)?.name ?? effectiveEffort\n const effortChoices = useMemo<Array<{ key: string; effort: string | undefined; label: string; description?: string }>>(() => reasoning === undefined ? [] : [\n ...(reasoning.defaultEffort === undefined ? [{\n key: 'provider-default',\n effort: undefined as string | undefined,\n label: t('effortProviderDefault'),\n }] : []),\n ...reasoning.efforts.map(effort => ({\n key: `effort:${effort.id}`,\n effort: effort.id,\n label: effort.name,\n ...effort.description === undefined ? {} : { description: effort.description },\n })),\n ], [reasoning, t])\n\n const busy = directoryState.status === 'selecting'\n const reload = () => {\n lastActionRef.current = 'load'\n load()\n }\n\n // Close on outside mousedown (host behavior).\n useEffect(() => {\n if (!open) return\n const closeOutside = (event: MouseEvent) => {\n if (!rootRef.current?.contains(event.target as Node)) setOpen(false)\n }\n document.addEventListener('mousedown', closeOutside)\n return () => {\n document.removeEventListener('mousedown', closeOutside)\n }\n }, [open])\n\n if (!available) return null\n\n const show = () => {\n setPane('root')\n setOpen(true)\n reload()\n void loadRouterState()\n }\n const close = (restoreFocus = false) => {\n setOpen(false)\n setPane('root')\n if (restoreFocus) queueMicrotask(() => {\n triggerRef.current?.focus()\n })\n }\n const moveFocus = (offset: number) => {\n const items = itemRefs.current.filter((item): item is HTMLButtonElement => item !== null)\n if (items.length === 0) return\n const active = items.findIndex(item => item === document.activeElement)\n items[(Math.max(active, 0) + offset + items.length) % items.length]?.focus()\n }\n const onRootKeyDown = (event: ReactKeyboardEvent) => {\n if (event.key === 'Escape' && open) {\n event.preventDefault()\n if (pane !== 'root') setPane('root')\n else close(true)\n return\n }\n if (!open) return\n if (event.key === 'ArrowDown' || event.key === 'ArrowUp') {\n event.preventDefault()\n moveFocus(event.key === 'ArrowDown' ? 1 : -1)\n }\n }\n const onBlur = (event: ReactFocusEvent) => {\n if (event.relatedTarget instanceof Node && rootRef.current?.contains(event.relatedTarget)) return\n close()\n }\n const settleSelection = (accepted: boolean) => {\n if (accepted) {\n if (rootRef.current !== null) close(true)\n return\n }\n const message = directory.getSnapshot().error\n if (message !== null) {\n toastSeq.current += 1\n setToast({ seq: toastSeq.current, text: t('errorAction', { message }) })\n }\n }\n const choose = (selection: ModelSelection) => {\n if (current !== null && current.provider === selection.provider && current.model === selection.model) {\n close(true)\n return\n }\n lastActionRef.current = 'select'\n select(selection).then(settleSelection)\n }\n const chooseEffort = (effort: string | undefined) => {\n if (current === null) return\n if (effectiveEffort === effort) {\n close(true)\n return\n }\n const selection: ModelSelection = {\n provider: current.provider,\n model: current.model,\n ...effort === undefined ? {} : { reasoningEffort: effort },\n }\n lastActionRef.current = 'select'\n select(selection).then(settleSelection)\n }\n\n const modelLabel = currentChoice?.model.name ?? t('triggerFallback')\n const triggerLabel = effortLabel === undefined ? modelLabel : `${modelLabel} · ${effortLabel}`\n const triggerAria = currentChoice === undefined ? t('triggerSelectAria')\n : effortLabel === undefined ? t('triggerAria', { model: modelLabel })\n : t('triggerAriaEffort', { model: modelLabel, effort: effortLabel })\n\n // ---- provider row visibility (the former quick-switch button conditions) ----\n const activeProvider = providers.find(provider => provider.id === routeModel?.active)\n const activeProviderName = activeProvider?.name ?? routeModel?.active ?? t('routeLoading')\n const providerRowVisible = isRouterModel\n && routerState !== null\n && routerState.showQuickSwitch !== false\n && routerState.providers.length >= 2\n && routeModel !== undefined\n && providers.length >= 2\n\n itemRefs.current = []\n let itemIndex = 0\n const itemRef = () => {\n const at = itemIndex++\n return (node: HTMLButtonElement | null) => {\n itemRefs.current[at] = node\n }\n }\n\n return (\n <div\n ref={rootRef}\n className=\"mr-seat-root\"\n onKeyDown={onRootKeyDown}\n onBlur={onBlur}\n >\n <button\n ref={triggerRef}\n type=\"button\"\n className=\"mr-seat-trigger\"\n aria-label={triggerAria}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? `${id}-menu` : undefined}\n title={triggerLabel}\n disabled={locked}\n onClick={() => {\n if (open) close()\n else show()\n }}\n >\n <span className=\"mr-seat-triggerLabel\">{modelLabel}</span>\n {effortLabel !== undefined && (\n <span className=\"mr-seat-triggerEffort\">{effortLabel}</span>\n )}\n <span className={`mr-seat-chevron${open ? ' mr-seat-chevronOpen' : ''}`} aria-hidden>\n <IconChevronDownOutline14 />\n </span>\n </button>\n {open && (\n <div\n id={`${id}-menu`}\n className=\"mr-seat-menu\"\n role=\"menu\"\n aria-label={t('menuAria')}\n aria-busy={directoryState.status === 'loading' || busy}\n >\n {pane === 'root' && (\n <>\n <button\n ref={itemRef()}\n type=\"button\"\n role=\"menuitem\"\n className=\"mr-seat-cell\"\n onClick={() => setPane('model')}\n >\n <span className=\"mr-seat-cellLabel\">{t('menuModel')}</span>\n <span className=\"mr-seat-cellValue\">{modelLabel}</span>\n <span className=\"mr-seat-cellChevron\" aria-hidden>\n <IconChevronRightOutline14 />\n </span>\n </button>\n {providerRowVisible && (\n <button\n ref={itemRef()}\n type=\"button\"\n role=\"menuitem\"\n className=\"mr-seat-cell\"\n onClick={() => setPane('provider')}\n >\n <span className=\"mr-seat-cellLabel\">{t('menuProvider')}</span>\n <span className=\"mr-seat-cellValue\">{activeProviderName}</span>\n <span className=\"mr-seat-cellChevron\" aria-hidden>\n <IconChevronRightOutline14 />\n </span>\n </button>\n )}\n {reasoning !== undefined && (\n <button\n ref={itemRef()}\n type=\"button\"\n role=\"menuitem\"\n className=\"mr-seat-cell\"\n onClick={() => setPane('effort')}\n >\n <span className=\"mr-seat-cellLabel\">{t('menuEffort')}</span>\n <span className=\"mr-seat-cellValue\">{effortLabel}</span>\n <span className=\"mr-seat-cellChevron\" aria-hidden>\n <IconChevronRightOutline14 />\n </span>\n </button>\n )}\n </>\n )}\n {pane === 'model' && (\n <>\n {directoryState.status === 'loading' && (\n <div className=\"mr-seat-status\">{t('statusLoading')}</div>\n )}\n {directoryState.error !== null && lastActionRef.current === 'load' && (\n <div className=\"mr-seat-error\">\n <span>{t('errorAction', { message: directoryState.error })}</span>\n <button type=\"button\" className=\"mr-seat-retry\" onClick={reload}>\n {t('retry')}\n </button>\n </div>\n )}\n {directoryState.failures.map(failure => (\n <div key={failure.id} className=\"mr-seat-warning\">\n <span>{t('warningGroupLoad', { name: failure.name, message: failure.message })}</span>\n <button type=\"button\" className=\"mr-seat-retry\" onClick={reload}>\n {t('retry')}\n </button>\n </div>\n ))}\n <div className=\"mr-seat-groups\">\n {directoryState.groups.map(group => {\n const headingId = `${id}-${group.id}`\n return (\n <section\n key={group.id}\n role=\"group\"\n aria-labelledby={headingId}\n className=\"mr-seat-group\"\n >\n <div className=\"mr-seat-groupTitle\" id={headingId}>\n {group.name}\n </div>\n {group.models.map(model => {\n const selected = current?.provider === group.id && current.model === model.id\n return (\n <button\n key={model.id}\n ref={itemRef()}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={selected}\n className={`mr-seat-option${selected ? ' mr-seat-selected' : ''}`}\n title={model.name}\n disabled={busy}\n onClick={() => choose({ provider: group.id, model: model.id })}\n >\n <span className=\"mr-seat-optionCopy\">\n <span className=\"mr-seat-modelName\">{model.name}</span>\n {model.description !== undefined && (\n <span className=\"mr-seat-description\">{model.description}</span>\n )}\n </span>\n <span className=\"mr-seat-check\" aria-hidden>\n {selected ? <IconCheckOutline16 /> : null}\n </span>\n </button>\n )\n })}\n </section>\n )\n })}\n </div>\n {directoryState.status === 'ready' && choices.length === 0 && (\n <div className=\"mr-seat-empty\">{t('emptyModels')}</div>\n )}\n </>\n )}\n {pane === 'provider' && (\n <>\n {routerError !== null && (\n <div className=\"mr-seat-error\">\n <span>{routerError}</span>\n <button\n type=\"button\"\n className=\"mr-seat-retry\"\n onClick={() => {\n void loadRouterState()\n load()\n }}\n >\n {t('retry')}\n </button>\n </div>\n )}\n {routeModel === undefined ? (\n <div className=\"mr-seat-status\">{t('routeLoading')}</div>\n ) : (\n <>\n <div className=\"mr-seat-title\">{t('routeMenuTitle', { model: modelId ?? '' })}</div>\n <div className=\"mr-seat-groups\">\n {providers.map(provider => {\n const selected = routeModel.active === provider.id\n return (\n <button\n key={provider.id}\n ref={itemRef()}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={selected}\n className={`mr-seat-option${selected ? ' mr-seat-selected' : ''}`}\n disabled={!provider.credentialConfigured || busyProvider !== null}\n onClick={() => void switchProvider(provider.id)}\n >\n <span className=\"mr-seat-optionCopy\">\n <span className=\"mr-seat-modelName\">{provider.name}</span>\n {!provider.credentialConfigured && (\n <span className=\"mr-seat-description\">{t('noCredentialShort')}</span>\n )}\n </span>\n <span className=\"mr-seat-check\" aria-hidden>\n {selected ? <IconCheckOutline16 /> : null}\n </span>\n </button>\n )\n })}\n </div>\n <div className=\"mr-seat-hint\">{t('globalRouteHint')}</div>\n </>\n )}\n </>\n )}\n {pane === 'effort' && (\n <>\n {directoryState.error !== null && lastActionRef.current === 'load' && (\n <div className=\"mr-seat-error\">\n <span>{t('errorAction', { message: directoryState.error })}</span>\n <button type=\"button\" className=\"mr-seat-retry\" onClick={reload}>\n {t('actionReload')}\n </button>\n </div>\n )}\n {effortChoices.length === 0 ? (\n <div className=\"mr-seat-empty\">{t('emptyEfforts')}</div>\n ) : effortChoices.map(level => (\n <button\n key={level.key}\n ref={itemRef()}\n type=\"button\"\n role=\"menuitemradio\"\n aria-checked={effectiveEffort === level.effort}\n className={`mr-seat-option${effectiveEffort === level.effort ? ' mr-seat-selected' : ''}`}\n disabled={busy}\n onClick={() => chooseEffort(level.effort)}\n >\n <span className=\"mr-seat-optionCopy\">\n <span className=\"mr-seat-modelName\">{level.label}</span>\n {level.description !== undefined && (\n <span className=\"mr-seat-description\">{level.description}</span>\n )}\n </span>\n <span className=\"mr-seat-check\" aria-hidden>\n {effectiveEffort === level.effort ? <IconCheckOutline16 /> : null}\n </span>\n </button>\n ))}\n </>\n )}\n </div>\n )}\n {toast !== null && (\n <Toast\n key={toast.seq}\n text={toast.text}\n icon={<IconWarningOutline16 />}\n anchor={rootRef.current?.closest('[data-composer-card]') ?? null}\n onDone={() => setToast(null)}\n />\n )}\n </div>\n )\n}\n\n/** Register the model seat onto the composer's named model slot (priority -1 shadows the host seat). */\nexport function registerModelRouterSeat(ctx: ClientContext): void {\n const t = ctx.locale.bind(LOCALE_NS)\n ctx.inject(['slots', 'modelDirectories'], scope => {\n const models = scope.modelDirectories\n const sessions = scope.sessions\n scope.slots.inject('conversation.input.model', () => scope.slots.register({\n name: 'conversation.input.model',\n id: 'model-router-model-seat',\n priority: -1,\n label: () => t('seatLabel'),\n locale: LOCALE_NS,\n inject: (sessionId: SessionId) => {\n const directory = models.directoryFor(sessionId)\n const available = sessions.subagentAddress(sessionId) === undefined\n return {\n available,\n directory: directory.store,\n load: () => {\n if (available) directory.load().catch(() => {})\n },\n select: (selection: ModelSelection) =>\n available ? directory.select(selection).then(() => true, () => false) : Promise.resolve(false),\n }\n },\n } as never, ModelRouterSeat as never))\n })\n}\n","/**\n * @fonlan/dsh-model-router client half: the plugin's own Settings Card\n * (设置 → 插件 → 插件配置 → 模型路由) plus the model seat that merges the\n * provider switcher into DSH's composer model picker menu.\n */\nimport type { Context } from '@deepseek-ai/cordis'\ntype ClientContext = Context\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-slots'\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\nimport type {} from '@deepseek-ai/dsh-client-ui-model-selection/client'\nimport { LOCALE_NS, zh, en } from './locales'\nimport { makeSettingsCard, type SettingsScopeFace } from './settings-card'\nimport { registerModelRouterSeat } from './model-seat'\n\n/** The settings namespace this card edits (must match the host half). */\nconst ROUTER_NS = 'model-router'\n\n/** Slots face: the keyed `settings.plugin.item` declaration ships with the web\n * app's ui-settings-plugins package, which external plugins do not depend on;\n * the register call below is typed through this local face (erased at build). */\ninterface Slots {\n inject(name: string, callback: () => unknown): unknown\n register(def: { name: string; key: string; inject?: () => unknown }, component: unknown): unknown\n}\n\n/** Services required before mounting (provided by the client runtime). */\nexport const inject = ['slots', 'locale', 'modelDirectories', 'sessions', 'settingsScope', 'connection', 'remote']\n\n/** Client plugin body. */\nexport function apply(ctx: ClientContext): void {\n ctx.effect(() => {\n const off = ctx.locale.register(LOCALE_NS, { zh, en })\n return () => off()\n }, 'model-router: dictionaries')\n\n const SettingsCard = makeSettingsCard(ctx)\n\n // The card registers on the `settings.plugin.item` slot keyed by the\n // `model-router` settings namespace (the same string the host half\n // registers), so it appears inside 设置 → 插件 → 插件配置, paired with the\n // namespace by the tab.\n const services = ctx as unknown as {\n slots: Slots\n settingsScope: { bind(spec: { namespace: string }): SettingsScopeFace }\n }\n const scope = services.settingsScope.bind({ namespace: ROUTER_NS })\n\n services.slots.inject('settings.plugin.item', () =>\n services.slots.register(\n {\n name: 'settings.plugin.item',\n key: ROUTER_NS,\n inject: () => ({ scope }),\n },\n SettingsCard,\n ),\n )\n\n registerModelRouterSeat(ctx)\n}\n"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -1,5 +1,4 @@
1
1
  import z from "@deepseek-ai/schemastery";
2
- import { settingsNamespace } from "@deepseek-ai/dsh-settings";
3
2
  import { credentialRef } from "@deepseek-ai/dsh-credentials";
4
3
  import { LlmAdapter, LlmError } from "@deepseek-ai/dsh-llm";
5
4
  //#region src/shared/config.ts
@@ -584,7 +583,7 @@ var ModelRouterAdapter = class extends LlmAdapter {
584
583
  };
585
584
  //#endregion
586
585
  //#region src/server/service.ts
587
- const NS = settingsNamespace(ROUTER_SETTINGS_NS);
586
+ const NS = ROUTER_SETTINGS_NS;
588
587
  /** Settings document schema: one entry per model id. */
589
588
  const RouterConfigSchema = z.object({
590
589
  models: z.dict(z.object({
@@ -8,7 +8,7 @@ import z from '@deepseek-ai/schemastery';
8
8
  import { type ModelSortMode, type RouterConfigShape } from '../shared/config.js';
9
9
  import { type RouterCatalog } from './catalog.js';
10
10
  import { type RouterFacts } from './adapter.js';
11
- export declare const NS: import("@deepseek-ai/dsh-settings").SettingsNamespace;
11
+ export declare const NS = "model-router";
12
12
  /** Settings document schema: one entry per model id. */
13
13
  export declare const RouterConfigSchema: z<RouterConfigShape>;
14
14
  /** The settings-page state view served by the API. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fonlan/dsh-model-router",
3
- "version": "0.3.3",
3
+ "version": "0.3.4",
4
4
  "description": "DSH plugin: a virtual model-router provider that aggregates every configured provider and model, routes each request to the model's currently active provider, and ships a settings page for per-model provider ordering and switching.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -50,7 +50,6 @@
50
50
  "client": {
51
51
  "platform": "web",
52
52
  "inject": [
53
- "@deepseek-ai/dsh-client-runtime",
54
53
  "@deepseek-ai/dsh-client-locale",
55
54
  "@deepseek-ai/dsh-client-ui-slots",
56
55
  "@deepseek-ai/dsh-client-ui-primitives",
@@ -64,40 +63,41 @@
64
63
  },
65
64
  "peerDependencies": {
66
65
  "@deepseek-ai/cordis": "^4.0.1",
67
- "@deepseek-ai/schemastery": "^3.18.1",
68
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
69
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
70
- "@deepseek-ai/dsh-credentials": "^0.1.1-rc.2",
71
- "@deepseek-ai/dsh-client-runtime": "^0.1.1-rc.2",
72
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
73
- "@deepseek-ai/dsh-client-ui-slots": "^0.1.1-rc.2",
74
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
75
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.1-rc.2",
76
- "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.1-rc.2",
66
+ "@deepseek-ai/schemastery": "^3.18.2",
67
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
68
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
69
+ "@deepseek-ai/dsh-credentials": "^0.1.2-alpha.2",
70
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
71
+ "@deepseek-ai/dsh-client-ui-slots": "^0.1.2-alpha.2",
72
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
73
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-alpha.2",
74
+ "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.2-alpha.2",
77
75
  "react": "^18.2.0",
78
76
  "react-dom": "^18.2.0"
79
77
  },
80
78
  "devDependencies": {
79
+ "@deepseek-ai/cordis": "^4.0.1",
80
+ "@deepseek-ai/dsh-attachment": "0.1.2-alpha.2",
81
+ "@deepseek-ai/dsh-brand": "0.1.2-alpha.2",
82
+ "@deepseek-ai/dsh-client-locale": "^0.1.2-alpha.2",
83
+ "@deepseek-ai/dsh-client-store": "^0.1.2-alpha.2",
84
+ "@deepseek-ai/dsh-client-ui-conversation": "^0.1.2-alpha.2",
85
+ "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.2-alpha.2",
86
+ "@deepseek-ai/dsh-client-ui-primitives": "^0.1.2-alpha.2",
87
+ "@deepseek-ai/dsh-client-ui-settings": "^0.1.2-alpha.2",
88
+ "@deepseek-ai/dsh-credentials": "^0.1.2-alpha.2",
89
+ "@deepseek-ai/dsh-host-webserver": "^0.1.2-alpha.2",
90
+ "@deepseek-ai/dsh-invariants": "0.1.2-alpha.2",
91
+ "@deepseek-ai/dsh-llm": "^0.1.2-alpha.2",
92
+ "@deepseek-ai/dsh-session": "^0.1.2-alpha.2",
93
+ "@deepseek-ai/dsh-settings": "^0.1.2-alpha.2",
94
+ "@deepseek-ai/dsh-timeout": "0.1.2-alpha.2",
95
+ "@deepseek-ai/schemastery": "^3.18.2",
81
96
  "@types/node": "^22.0.0",
82
97
  "@types/react": "~18.3.1",
83
98
  "@types/react-dom": "~18.3.0",
84
99
  "tsdown": "^0.22.14",
85
100
  "typescript": "^5.9.0",
86
- "@deepseek-ai/cordis": "^4.0.1",
87
- "@deepseek-ai/schemastery": "^3.18.1",
88
- "@deepseek-ai/dsh-llm": "^0.1.1-rc.2",
89
- "@deepseek-ai/dsh-settings": "^0.1.1-rc.2",
90
- "@deepseek-ai/dsh-credentials": "^0.1.1-rc.2",
91
- "@deepseek-ai/dsh-host-webserver": "^0.1.1-rc.2",
92
- "@deepseek-ai/dsh-brand": "0.1.1-rc.2",
93
- "@deepseek-ai/dsh-attachment": "0.1.1-rc.2",
94
- "@deepseek-ai/dsh-invariants": "0.1.1-rc.2",
95
- "@deepseek-ai/dsh-timeout": "0.1.1-rc.2",
96
- "@deepseek-ai/dsh-client-locale": "^0.1.1-rc.2",
97
- "@deepseek-ai/dsh-client-ui-primitives": "^0.1.1-rc.2",
98
- "@deepseek-ai/dsh-client-ui-settings": "^0.1.1-rc.2",
99
- "@deepseek-ai/dsh-client-ui-conversation": "^0.1.1-rc.2",
100
- "@deepseek-ai/dsh-client-ui-model-selection": "^0.1.1-rc.2",
101
101
  "vitest": "^3.2.0"
102
102
  },
103
103
  "scripts": {
@@ -3,7 +3,8 @@
3
3
  * (设置 → 插件 → 插件配置 → 模型路由) plus the model seat that merges the
4
4
  * provider switcher into DSH's composer model picker menu.
5
5
  */
6
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
6
+ import type { Context } from '@deepseek-ai/cordis'
7
+ type ClientContext = Context
7
8
  import type {} from '@deepseek-ai/dsh-client-locale/client'
8
9
  import type {} from '@deepseek-ai/dsh-client-ui-slots'
9
10
  import type {} from '@deepseek-ai/dsh-client-ui-settings/client'
@@ -9,7 +9,10 @@ import {
9
9
  type FocusEvent as ReactFocusEvent,
10
10
  type KeyboardEvent as ReactKeyboardEvent,
11
11
  } from 'react'
12
- import type { ClientContext, SessionId, SnapshotStore } from '@deepseek-ai/dsh-client-runtime/client'
12
+ import type { Context } from '@deepseek-ai/cordis'
13
+ import type { SnapshotStore } from '@deepseek-ai/dsh-client-store'
14
+ import type { SessionId } from '@deepseek-ai/dsh-session/types'
15
+ type ClientContext = Context
13
16
  import type { ModelDirectoryState } from '@deepseek-ai/dsh-client-ui-model-selection/client'
14
17
  import type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
15
18
  import {
@@ -16,13 +16,14 @@
16
16
  * mutation controls.
17
17
  */
18
18
  import { useCallback, useEffect, useMemo, useState, useSyncExternalStore } from 'react'
19
- import type { ClientContext } from '@deepseek-ai/dsh-client-runtime/client'
19
+ import type { Context } from '@deepseek-ai/cordis'
20
+ type ClientContext = Context
20
21
  import type { Translate } from '@deepseek-ai/dsh-client-ui-slots'
21
22
  import { LOCALE_NS } from './locales'
22
23
  import { api, type ModelRouterState, type ModelSortMode, type RouterModelView } from './api'
23
24
  import './settings-card.css'
24
25
 
25
- /** Client settings scope face (subset of @deepseek-ai/dsh-client-runtime). */
26
+ /** Client settings scope face (subset of the app client modules). */
26
27
  export interface SettingsScopeFace {
27
28
  getSnapshot(): {
28
29
  status: 'loading' | 'ready' | 'unavailable'
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import type { Context } from '@deepseek-ai/cordis'
7
7
  import z from '@deepseek-ai/schemastery'
8
- import { settingsNamespace, type SettingsScope } from '@deepseek-ai/dsh-settings'
8
+ import type { SettingsScope } from '@deepseek-ai/dsh-settings'
9
9
  import type { AdapterRegistrationHandle } from '@deepseek-ai/dsh-llm'
10
10
  import {
11
11
  initialConfigFor,
@@ -23,7 +23,7 @@ import {
23
23
  import { buildCatalog, type RouterCatalog } from './catalog.js'
24
24
  import { ModelRouterAdapter, type RouterFacts } from './adapter.js'
25
25
 
26
- export const NS = settingsNamespace(ROUTER_SETTINGS_NS)
26
+ export const NS = ROUTER_SETTINGS_NS
27
27
 
28
28
  /** Settings document schema: one entry per model id. */
29
29
  export const RouterConfigSchema: z<RouterConfigShape> = z.object({