@fonlan/dsh-model-router 0.3.6 → 0.3.7

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-section.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 sectionSub: '模型聚合、提供商切换与优先级顺序',\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: Record<keyof typeof zh, string> = {\n settingsTitle: 'Model Router',\n sectionSub: 'Model aggregation, provider switching and preference order',\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 page (设置 → 侧栏「模型路由」).\n *\n * Registers into the settings.section slot, so the page owns one entry in the\n * settings sidebar and renders its content in the panel's content column. The\n * page draws its own static header (title plus a one-line summary) over the\n * router controls: every routed model with its providers, their order and the\n * provider the model currently routes to. All reads/mutations go through the\n * plugin's fenced API; the server persists through the `model-router` settings\n * namespace, so a switch here is live for the next request globally.\n *\n * The bound settings scope (the same `model-router` namespace the host half\n * registers) supplies the page's dispatch state: while the namespace is merely\n * loading the page stays mounted, and when it is unavailable (deployment\n * without the host half) nothing renders. A read-only deployment shows the\n * banner and disables the 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-section.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 SettingsSectionProps {\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 makeSettingsSection(ctx: ClientContext): (props: SettingsSectionProps) => JSX.Element | null {\n // Bound translation is namespace-typed; the page'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 ModelRouterSettingsSection(props: SettingsSectionProps): 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 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 page mounted (the sidebar already dispatched\n // it); if it is unavailable (deployment without the host half), render\n // 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 <div className=\"mr-page\">\n <header className=\"mr-page-head\">\n <h3 className=\"mr-page-title\">{t('settingsTitle')}</h3>\n <p className=\"mr-page-sub\">{t('sectionSub')}</p>\n </header>\n <div className=\"mr-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 </div>\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/**\n * Structural subsets of the host model-catalog wire types (declared locally to\n * avoid pulling a new peer dependency; identical to the host shapes).\n */\ninterface ModelReasoningEffort {\n id: string\n name: string\n description?: string\n}\n\ninterface ModelReasoning {\n efforts: readonly ModelReasoningEffort[]\n defaultEffort?: string\n}\n\ninterface ModelCatalogModel {\n id: string\n name: string\n description?: string\n reasoning?: ModelReasoning\n}\n\ninterface ModelProviderGroup {\n id: string\n name: string\n models: readonly ModelCatalogModel[]\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: ModelProviderGroup) => group.models.map((model: ModelCatalogModel) => ({\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: ModelReasoningEffort) => 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: ModelReasoningEffort) => ({\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: ModelCatalogModel) => {\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/** The modelDirectories service face (structural subset of the host service). */\ninterface ModelDirectoriesFace {\n directoryFor(sessionId: SessionId): SessionDirectoryFace\n}\n\n/** The sessions service face (structural subset of the host service). */\ninterface SessionsFace {\n subagentAddress(sessionId: SessionId): unknown\n}\n\n/** One session model directory (structural subset of the host ModelDirectory). */\ninterface SessionDirectoryFace {\n store: SnapshotStore<ModelDirectoryState>\n load(): Promise<unknown>\n select(selection: ModelSelection): Promise<unknown>\n}\n\n/** The slots service face (structural subset; the register call is typed `never` below). */\ninterface SlotsFace {\n inject(name: string, callback: () => unknown): unknown\n register(def: unknown, component: unknown): unknown\n}\n\n/** The scope resolved by the seat's inject block. */\ninterface SeatScopeFace {\n modelDirectories: ModelDirectoriesFace\n sessions: SessionsFace\n slots: SlotsFace\n}\n\nconst EMPTY_DIRECTORY_STATE: ModelDirectoryState = {\n current: null,\n routable: null,\n groups: [],\n failures: [],\n status: 'idle',\n error: null,\n}\n\n/**\n * Inert face for the pathological case where the session directory cannot be\n * resolved even after `remote.session` mounted. The seat renders nothing\n * (available: false), but crucially the slot entry never throws, so it is\n * never abdicated and the host seat can keep the cell alive on the next\n * registration pass.\n */\nconst INERT_DIRECTORY_STORE: SnapshotStore<ModelDirectoryState> = {\n subscribe: () => () => {},\n getSnapshot: () => EMPTY_DIRECTORY_STATE,\n update: () => {},\n set: () => {},\n}\n\n/**\n * Build the seat face without ever throwing out of the slot `inject` hook.\n *\n * The seat registration below depends on `remote.session` (the namespace is\n * mounted asynchronously at startup), so by the time this runs the host\n * `modelDirectories.directoryFor(sessionId)` resolves — the original race is\n * gone by construction. The try/catch here is belt-and-braces: a throwing\n * inject would permanently abdicate this slot entry in the renderer\n * (`reportEntryError` with `abdicate` for single slots), after which the host\n * seat takes over and the Provider row never appears again.\n */\nfunction seatFace(\n models: ModelDirectoriesFace,\n sessions: SessionsFace,\n sessionId: SessionId,\n): ModelSeatInjected {\n let directory: SessionDirectoryFace | null = null\n try {\n directory = models.directoryFor(sessionId)\n } catch {\n // unknown session / transient teardown: degrade to the inert face\n }\n if (directory === null) {\n return {\n available: false,\n directory: INERT_DIRECTORY_STORE,\n load: () => {},\n select: () => Promise.resolve(false),\n }\n }\n let available = true\n try {\n available = sessions.subagentAddress(sessionId) === undefined\n } catch {\n // sessions face not ready; treat as available\n }\n return {\n available,\n directory: directory.store,\n load: () => {\n if (available) directory?.load().catch(() => {})\n },\n select: (selection) =>\n available ? directory!.select(selection).then(() => true, () => false) : Promise.resolve(false),\n }\n}\n\n/**\n * Register the model seat onto the composer's named model slot (priority -1\n * shadows the host seat). The inject block additionally depends on\n * `remote.session` so the seat registers only after the remote session\n * namespace has mounted — `directoryFor` can throw while it is still mounting,\n * and a throwing inject permanently abdicates the entry (the host seat then\n * wins and the Provider row never appears).\n */\nexport function registerModelRouterSeat(ctx: ClientContext): void {\n const t = ctx.locale.bind(LOCALE_NS)\n ctx.inject(['slots', 'modelDirectories', 'remote.session'], scope => {\n const face = scope as unknown as SeatScopeFace\n face.slots.inject('conversation.input.model', () => face.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) => seatFace(face.modelDirectories, face.sessions, sessionId),\n } as never, ModelRouterSeat as never))\n })\n}\n","/**\n * @fonlan/dsh-model-router client half: the plugin's own Settings page\n * (设置 → 侧栏「模型路由」) plus the model seat that merges the provider\n * switcher into DSH's composer model picker menu.\n *\n * The page registers into the settings.section slot, so it owns one entry in\n * the settings sidebar and renders in the panel content column; the page\n * component itself lives in ./settings-section.\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 { makeSettingsSection, type SettingsScopeFace } from './settings-section'\nimport { registerModelRouterSeat } from './model-seat'\n\n/** The settings namespace this page edits (must match the host half). */\nconst ROUTER_NS = 'model-router'\n\n/** The settings sidebar entry this page owns (must stay stable). */\nconst SECTION_ID = 'model-router'\n\n/** Slots face: the settings.section list slot is declared at runtime by the\n * settings shell (ui-settings-general), which external plugins do not depend\n * on; the register call below is typed through this local face (erased at\n * build time). Its inject face binds the model-router settings scope, which\n * reaches the component as the scope prop. */\ninterface SectionEntry {\n name: string\n id?: string\n order?: number\n label?: () => string\n locale?: string\n inject?: () => unknown\n}\n\ninterface Slots {\n inject(name: string, callback: () => unknown): unknown\n register(def: SectionEntry, component: unknown): unknown\n}\n\n/** Services required before mounting (provided by the client runtime).\n * `remote.session` is included like the host ui-model-selection declares it:\n * the seat's `directoryFor` depends on the namespace, which mounts\n * asynchronously at startup. */\nexport const inject = ['slots', 'locale', 'modelDirectories', 'sessions', 'settingsScope', 'connection', 'remote', 'remote.session']\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 t = ctx.locale.bind(LOCALE_NS) as unknown as (key: string) => string\n const SettingsSection = makeSettingsSection(ctx)\n\n // The page registers on the settings.section list slot under a stable id, so\n // it appears in the settings sidebar's left navigation. The bound\n // model-router settings scope (the same namespace the host half registers)\n // travels through the inject face and reaches the component as scope.\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.section', () =>\n services.slots.register(\n {\n name: 'settings.section',\n id: SECTION_ID,\n order: 300,\n label: () => t('settingsTitle'),\n locale: LOCALE_NS,\n inject: () => ({ scope }),\n },\n SettingsSection,\n ),\n )\n\n registerModelRouterSeat(ctx)\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["useCallback","useSyncExternalStore","useState","useMemo","primitives","useSyncExternalStore","useState","useRef","useId","useCallback","useMemo","Toast"],"sources":["../../../src/client/locales.ts","../../../src/client/api.ts","../../../src/client/settings-section.tsx","../../../src/client/icons.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 sectionSub: '模型聚合、提供商切换与优先级顺序',\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: Record<keyof typeof zh, string> = {\n settingsTitle: 'Model Router',\n sectionSub: 'Model aggregation, provider switching and preference order',\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 /**\n * Whether this deployment can persist router configuration (the host half\n * found the settings service). False renders the page read-only.\n */\n writable: boolean\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 page (设置 → 侧栏「模型路由」).\n *\n * Registers into the settings.section slot, so the page owns one entry in the\n * settings sidebar and renders its content in the panel's content column. The\n * page draws its own static header (title plus a one-line summary) over the\n * router controls: every routed model with its providers, their order and the\n * provider the model currently routes to. All reads/mutations go through the\n * plugin's fenced API; the server persists into this plugin's loader-entry\n * config (dsh >= 0.1.7), so a switch here is live for the next request\n * globally.\n *\n * The page needs no settings service: whether the deployment can persist is\n * reported by the API itself (`state.writable`), so the page registers and\n * mounts everywhere the host half serves its API. A read-only deployment\n * shows the banner and disables the 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-section.css'\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 makeSettingsSection(ctx: ClientContext): () => JSX.Element {\n // Bound translation is namespace-typed; the page'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 ModelRouterSettingsSection(): JSX.Element {\n useLocaleRevision(ctx)\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 const next = await api.state()\n setState(next)\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 // Persistence capability is reported by the host half through the API\n // itself. A host that predates the field reads as writable: the page must\n // not block edits (with a wrong \"read-only\" banner) merely because the\n // host half and the client bundle are briefly out of step.\n const writable = state?.writable ?? true\n\n const models = useMemo(() => state?.models ?? [], [state])\n\n return (\n <div className=\"mr-page\">\n <header className=\"mr-page-head\">\n <h3 className=\"mr-page-title\">{t('settingsTitle')}</h3>\n <p className=\"mr-page-sub\">{t('sectionSub')}</p>\n </header>\n <div className=\"mr-body\">\n {!loading && state !== null && !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 </div>\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 * as primitives from '@deepseek-ai/dsh-client-ui-primitives'\n\n/** Props every shell icon accepts: square edge in px, color rides currentColor. */\nexport interface IconProps {\n size?: number\n className?: string\n}\n\n/** One shell icon component. */\nexport type IconComponent = (props: IconProps) => JSX.Element\n\n/** The runtime export table, read by capability instead of by one hard-coded name. */\nconst table = primitives as unknown as Record<string, IconComponent | undefined>\n\n/** First name the runtime actually provides (a missing export is `undefined`). */\nfunction firstDefined(...names: string[]): IconComponent | undefined {\n for (const name of names) {\n let candidate: IconComponent | undefined\n try {\n candidate = table[name]\n } catch {\n // Some module namespaces reject unknown names instead of yielding\n // `undefined`; a rename must never throw on its way to the fallback.\n continue\n }\n if (typeof candidate === 'function') return candidate\n }\n return undefined\n}\n\n/** One-path stroked glyph fallback (16×16 viewBox — the 0.1.7 artwork). */\nfunction glyph(path: string, defaultSize: number): IconComponent {\n return function Glyph({ size = defaultSize, className }: IconProps): JSX.Element {\n return (\n <svg\n width={size}\n height={size}\n className={className}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n strokeWidth={1}\n >\n <path d={path} stroke=\"currentColor\" />\n </svg>\n )\n }\n}\n\n/** Warning circle fallback (the 0.1.7 artwork: ring, stem, dot). */\nfunction WarningFallback({ size = 16, className }: IconProps): JSX.Element {\n return (\n <svg\n width={size}\n height={size}\n className={className}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n aria-hidden=\"true\"\n strokeWidth={1}\n >\n <path d=\"M8 14.5C11.5899 14.5 14.5 11.5899 14.5 8C14.5 4.41015 11.5899 1.5 8 1.5C4.41015 1.5 1.5 4.41015 1.5 8C1.5 11.5899 4.41015 14.5 8 14.5Z\" stroke=\"currentColor\" />\n <path d=\"M8 4.29199V9.79199\" stroke=\"currentColor\" />\n <path d=\"M8 10.708V11.708\" stroke=\"currentColor\" />\n </svg>\n )\n}\n\n/**\n * Shell icons used by the model seat.\n *\n * DSH 0.1.7 renamed every size-suffixed icon export (`IconCheckOutline16`,\n * `IconChevronDownOutline14`, …) into stroke-weight variants (`…OutlineRegular`\n * 1px / `…OutlineMedium` 1.3px). A stale named import resolves to `undefined`\n * and React then throws \"Element type is invalid\" while rendering the slot\n * entry — the whole seat is dropped from the conversation input instead of\n * degrading (this is exactly what the 0.1.7 upgrade did to this plugin).\n * Resolve the names at runtime, newest first, so the next rename lands on\n * another shipped variant or on the inlined artwork below.\n */\nexport const CheckIcon: IconComponent =\n firstDefined('IconCheckOutlineRegular', 'IconCheckOutlineMedium', 'IconCheckOutline16')\n ?? glyph('M2.25 8.5L5.49732 11.7473C5.90519 12.1552 6.57263 12.1344 6.95426 11.7018L13.75 4', 16)\n\nexport const ChevronDownIcon: IconComponent =\n firstDefined('IconChevronDownOutlineRegular', 'IconChevronDownOutlineMedium', 'IconChevronDownOutline14')\n ?? glyph('M4 6L7.29289 9.29289C7.68342 9.68342 8.31658 9.68342 8.70711 9.29289L12 6', 14)\n\nexport const ChevronRightIcon: IconComponent =\n firstDefined('IconChevronRightOutlineRegular', 'IconChevronRightOutlineMedium', 'IconChevronRightOutline14')\n ?? glyph('M6 12L9.29289 8.70711C9.68342 8.31658 9.68342 7.68342 9.29289 7.29289L6 4', 14)\n\nexport const WarningIcon: IconComponent =\n firstDefined('IconWarningOutlineRegular', 'IconWarningOutlineMedium', 'IconWarningOutline16')\n ?? WarningFallback\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 { Toast } 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 { CheckIcon, ChevronDownIcon, ChevronRightIcon, WarningIcon } from './icons'\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/**\n * Structural subsets of the host model-catalog wire types (declared locally to\n * avoid pulling a new peer dependency; identical to the host shapes).\n */\ninterface ModelReasoningEffort {\n id: string\n name: string\n description?: string\n}\n\ninterface ModelReasoning {\n efforts: readonly ModelReasoningEffort[]\n defaultEffort?: string\n}\n\ninterface ModelCatalogModel {\n id: string\n name: string\n description?: string\n reasoning?: ModelReasoning\n}\n\ninterface ModelProviderGroup {\n id: string\n name: string\n models: readonly ModelCatalogModel[]\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: ModelProviderGroup) => group.models.map((model: ModelCatalogModel) => ({\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: ModelReasoningEffort) => 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: ModelReasoningEffort) => ({\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 <ChevronDownIcon />\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 <ChevronRightIcon />\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 <ChevronRightIcon />\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 <ChevronRightIcon />\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: ModelCatalogModel) => {\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 ? <CheckIcon /> : 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 ? <CheckIcon /> : 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 ? <CheckIcon /> : 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={<WarningIcon />}\n anchor={rootRef.current?.closest('[data-composer-card]') ?? null}\n onDone={() => setToast(null)}\n />\n )}\n </div>\n )\n}\n\n/** The modelDirectories service face (structural subset of the host service). */\ninterface ModelDirectoriesFace {\n directoryFor(sessionId: SessionId): SessionDirectoryFace\n}\n\n/** The sessions service face (structural subset of the host service). */\ninterface SessionsFace {\n subagentAddress(sessionId: SessionId): unknown\n}\n\n/** One session model directory (structural subset of the host ModelDirectory). */\ninterface SessionDirectoryFace {\n store: SnapshotStore<ModelDirectoryState>\n load(): Promise<unknown>\n select(selection: ModelSelection): Promise<unknown>\n}\n\n/** The slots service face (structural subset; the register call is typed `never` below). */\ninterface SlotsFace {\n inject(name: string, callback: () => unknown): unknown\n register(def: unknown, component: unknown): unknown\n}\n\n/** The scope resolved by the seat's inject block. */\ninterface SeatScopeFace {\n modelDirectories: ModelDirectoriesFace\n sessions: SessionsFace\n slots: SlotsFace\n}\n\nconst EMPTY_DIRECTORY_STATE: ModelDirectoryState = {\n current: null,\n routable: null,\n groups: [],\n failures: [],\n status: 'idle',\n error: null,\n}\n\n/**\n * Inert face for the pathological case where the session directory cannot be\n * resolved even after `remote.session` mounted. The seat renders nothing\n * (available: false), but crucially the slot entry never throws, so it is\n * never abdicated and the host seat can keep the cell alive on the next\n * registration pass.\n */\nconst INERT_DIRECTORY_STORE: SnapshotStore<ModelDirectoryState> = {\n subscribe: () => () => {},\n getSnapshot: () => EMPTY_DIRECTORY_STATE,\n update: () => {},\n set: () => {},\n}\n\n/**\n * Build the seat face without ever throwing out of the slot `inject` hook.\n *\n * The seat registration below depends on `remote.session` (the namespace is\n * mounted asynchronously at startup), so by the time this runs the host\n * `modelDirectories.directoryFor(sessionId)` resolves — the original race is\n * gone by construction. The try/catch here is belt-and-braces: a throwing\n * inject would permanently abdicate this slot entry in the renderer\n * (`reportEntryError` with `abdicate` for single slots), after which the host\n * seat takes over and the Provider row never appears again.\n */\nfunction seatFace(\n models: ModelDirectoriesFace,\n sessions: SessionsFace,\n sessionId: SessionId,\n): ModelSeatInjected {\n let directory: SessionDirectoryFace | null = null\n try {\n directory = models.directoryFor(sessionId)\n } catch {\n // unknown session / transient teardown: degrade to the inert face\n }\n if (directory === null) {\n return {\n available: false,\n directory: INERT_DIRECTORY_STORE,\n load: () => {},\n select: () => Promise.resolve(false),\n }\n }\n let available = true\n try {\n available = sessions.subagentAddress(sessionId) === undefined\n } catch {\n // sessions face not ready; treat as available\n }\n return {\n available,\n directory: directory.store,\n load: () => {\n if (available) directory?.load().catch(() => {})\n },\n select: (selection) =>\n available ? directory!.select(selection).then(() => true, () => false) : Promise.resolve(false),\n }\n}\n\n/**\n * Register the model seat onto the composer's named model slot (priority -1\n * shadows the host seat). The inject block additionally depends on\n * `remote.session` so the seat registers only after the remote session\n * namespace has mounted — `directoryFor` can throw while it is still mounting,\n * and a throwing inject permanently abdicates the entry (the host seat then\n * wins and the Provider row never appears).\n */\nexport function registerModelRouterSeat(ctx: ClientContext): void {\n const t = ctx.locale.bind(LOCALE_NS)\n ctx.inject(['slots', 'modelDirectories', 'remote.session'], scope => {\n const face = scope as unknown as SeatScopeFace\n face.slots.inject('conversation.input.model', () => face.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) => seatFace(face.modelDirectories, face.sessions, sessionId),\n } as never, ModelRouterSeat as never))\n })\n}\n","/**\n * @fonlan/dsh-model-router client half: the plugin's own Settings page\n * (设置 → 侧栏「模型路由」) plus the model seat that merges the provider\n * switcher into DSH's composer model picker menu.\n *\n * The page registers into the settings.section slot, so it owns one entry in\n * the settings sidebar and renders in the panel content column; the page\n * component itself lives in ./settings-section.\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 { makeSettingsSection } from './settings-section'\nimport { registerModelRouterSeat } from './model-seat'\n\n/** The settings sidebar entry this page owns (must stay stable). */\nconst SECTION_ID = 'model-router'\n\n/** Slots face: the settings.section list slot is declared at runtime by the\n * settings shell (ui-settings-general), which external plugins do not depend\n * on; the register call below is typed through this local face (erased at\n * build time). */\ninterface SectionEntry {\n name: string\n id?: string\n order?: number\n label?: () => string\n locale?: string\n}\n\ninterface Slots {\n inject(name: string, callback: () => unknown): unknown\n register(def: SectionEntry, component: unknown): unknown\n}\n\n/** Services required before mounting (provided by the client runtime).\n * `remote.session` is included like the host ui-model-selection declares it:\n * the seat's `directoryFor` depends on the namespace, which mounts\n * asynchronously at startup. */\nexport const inject = ['slots', 'locale', 'modelDirectories', 'sessions', 'connection', 'remote', 'remote.session']\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 t = ctx.locale.bind(LOCALE_NS) as unknown as (key: string) => string\n const SettingsSection = makeSettingsSection(ctx)\n\n // The page registers on the settings.section list slot under a stable id, so\n // it appears in the settings sidebar's left navigation.\n //\n // dsh >= 0.1.7 dropped the client-side `settingsScope` service (plugin\n // configuration became loader-entry config, projected by the host), and the\n // old conditional registration therefore never fired: the section silently\n // disappeared from Settings. Register unconditionally — the page reads and\n // writes through this plugin's own fenced API (see ./settings-section), so\n // it needs no settings service at all. Never gate a slot registration on a\n // service that may not exist: the failure mode is an invisible page.\n const slots = (ctx as unknown as { slots: Slots }).slots\n slots.inject('settings.section', () =>\n slots.register(\n {\n name: 'settings.section',\n id: SECTION_ID,\n order: 300,\n label: () => t('settingsTitle'),\n locale: LOCALE_NS,\n },\n SettingsSection,\n ),\n )\n\n registerModelRouterSeat(ctx)\n}\n"],"mappings":"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"}