dsh-model-extension 1.1.0-alpha.1 → 1.1.0

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/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # dsh-model-extension
2
2
  > 基于 deepseek-harness 的模型扩展插件
3
3
 
4
- [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![npm](https://img.shields.io/npm/v/dsh-model-extension.svg?label=npm&labelColor=000000&color=ff4b01)](https://www.npmjs.com/package/dsh-model-extension) [![DeepSeek Harness:0.1.5-alpha.2](https://img.shields.io/badge/DeepSeek%20Harness-0.1.5--alpha.2-success.svg?labelColor=4D6BFE)](https://github.com/deepseek-ai/deepseek-harness)
4
+ [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![npm](https://img.shields.io/npm/v/dsh-model-extension.svg?label=npm&labelColor=000000&color=ff4b01)](https://www.npmjs.com/package/dsh-model-extension) [![DeepSeek Harness:0.1.5-rc.1](https://img.shields.io/badge/DeepSeek%20Harness-0.1.5--rc.1-success.svg?labelColor=4D6BFE)](https://github.com/deepseek-ai/deepseek-harness)
5
5
 
6
6
  | 供应商 | 模型 |
7
7
  | --- | --- |
@@ -49,6 +49,7 @@ npm run build
49
49
  ## 版本历史
50
50
 
51
51
  - **1.1.0**
52
+ - npm publish
52
53
  - **1.1.0-alpha.1**
53
54
  - 💪适配deepseek harness 0.1.5-alpha.2
54
55
  - **1.0.0**
package/lib/client.js CHANGED
@@ -2699,7 +2699,7 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2699
2699
  //#region src/client/index-extension.ts
2700
2700
  /** Cordis service name (distinct from the npm package name). */
2701
2701
  const name = "model-extension-client";
2702
- /** Required services — mirrors the upstream Models section registration @ 0.1.5-alpha.2. */
2702
+ /** Required services — mirrors the upstream Models section registration @ 0.1.5-rc.1. */
2703
2703
  const inject = [
2704
2704
  "slots",
2705
2705
  "locale",
package/lib/client.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":["createSnapshotStore","useState","styles","useState","styles","useState","styles","Modal","useState","useMemo","styles","useState","styles","useState","styles","Modal","extensionZh","extensionEn"],"sources":["official/src/client/vendor/store.ts","official/src/client/models-plus/models-index.ts","official/src/client/models-plus/compat.ts","official/src/client/models-plus/presets.ts","official/src/client/extension-meta.ts","official/src/client/models-plus/models-plus.module.css","official/src/client/models-plus/QuickLoad.tsx","official/src/client/models-plus/ModelEntryPanel.tsx","official/src/client/models-plus/ModelCatalog.tsx","official/src/client/models-plus/ProviderEditor.tsx","official/src/client/models-plus/CreateProviderCard.tsx","official/src/client/models-plus/ModelsPlusSection.tsx","official/src/client/vendor/operations.ts","official/src/client/vendor/schema-operations.ts","official/src/client/index-extension.ts"],"sourcesContent":["/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.5-alpha.2\n * (host tree packages/client/ui-settings-models/src/client/store.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\n/**\n * Models settings page store: one snapshot joining the configurable-provider\n * directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),\n * the settings namespaces (shared settings mirror),\n * and the referenced credentials (`credentials/describe`). The host stays the\n * single fact source — every mutation writes through the wire and the page\n * re-renders from the next describe, pushed or refetched.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView,\n} from '@deepseek-ai/dsh-api-remotes/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SettingsDescribeFace } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\n\n/**\n * Any route key walks a dict schema to the same profile node, so the lookup\n * names one that cannot collide with a configured route.\n */\nconst PROBE_ROUTE = '\\u0000probe'\n\n/** One provider row after joining the configurable directory with live routes. */\nexport interface ProviderDirectoryEntry {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n readonly active: boolean\n readonly declared?: boolean\n /** Configuration diagnostic reported by the owning adapter; absent means none. */\n readonly error?: string\n}\n\n/**\n * Join declared configurable providers with the currently registered routes.\n * @param registered - live provider routes in registration order.\n * @param directory - declared configurable providers in declaration order.\n * @returns declared rows followed by live routes with no declaration.\n */\nexport function joinProviderDirectory(\n registered: readonly LlmProviderInfo[],\n directory: readonly LlmConfigurableProvider[],\n): ProviderDirectoryEntry[] {\n const active = new Set(registered.map(provider => provider.id))\n const declared = new Set(directory.map(entry => entry.provider))\n const rows: ProviderDirectoryEntry[] = directory.map(entry => ({\n provider: entry.provider,\n displayName: entry.displayName,\n settingsNs: entry.settingsNs,\n settingsPath: [...entry.settingsPath],\n active: active.has(entry.provider),\n ...entry.declared === undefined ? {} : { declared: entry.declared },\n ...entry.error === undefined ? {} : { error: entry.error },\n }))\n for (const provider of registered) {\n if (declared.has(provider.id)) continue\n rows.push({\n provider: provider.id,\n displayName: provider.name,\n settingsNs: '',\n settingsPath: [],\n active: true,\n })\n }\n return rows\n}\n\n/** One provider row the page renders. */\nexport interface ProviderRow {\n /** The directory entry (route id, display name, settings address, live state). */\n entry: ProviderDirectoryEntry\n /** Whether any layer configures this provider (its profile resolves). */\n configured: boolean\n /** Whether the user layer alone carries the profile (removal restores the base). */\n removable: boolean\n /** The credential reference the resolved profile names, when one does. */\n apiKeyEnv: string | undefined\n /** Credential state for {@link apiKeyEnv}, once described. */\n credential: CredentialInfo | undefined\n /**\n * Credential state for the page's derived `<ROUTE>_API_KEY`, described only\n * while the profile names no reference — the provider-card seat's\n * `keyConfigured` fact for dormant and keyless rows, matching the editor's\n * own derivation rule.\n */\n derivedCredential?: CredentialInfo\n}\n\n/** Page snapshot. */\nexport interface ModelsSettingsState {\n status: 'idle' | 'loading' | 'ready' | 'error'\n /** Whole-load failure text; row-level write failures stay in the editor. */\n error: string | null\n /** Credential enrichment failure; provider/settings rows remain usable. */\n credentialError: string | null\n /** Whether the settings provider accepts writes. */\n writable: boolean\n /** Every configurable provider joined with its configured/credential state. */\n rows: readonly ProviderRow[]\n /** Namespace views by ns, for the editor's schema/layers/secrets. */\n namespaces: ReadonlyMap<string, SettingsNamespaceView>\n}\n\n/**\n * Derive the conventional credential reference for a provider route: the v1\n * page never asks for an environment-variable name, so a typed key stores\n * under this derived reference and the profile records it as `apiKeyEnv`.\n * @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).\n * @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).\n */\nexport function deriveKeyRef(provider: string): string {\n return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`\n}\n\n/**\n * The wire protocols a hand-declared route may name, read out of the owning\n * namespace's own schema. This stays a schema read rather than a wire field so\n * the choices the page offers cannot drift from the ones the adapter accepts:\n * both come from the same `Config`.\n * @param namespace - the namespace view whose schema declares the profile shape.\n * @param schema - settings schema operations.\n * @returns the protocol identifiers, or an empty list when the schema has none.\n */\nexport function protocolChoices(\n namespace: SettingsNamespaceView | undefined,\n schema: SettingsSchemaOperations,\n): string[] {\n if (namespace === undefined) return []\n const node = schema.nodeAtPath(schema.rehydrate(namespace.schema), ['providers', PROBE_ROUTE, 'api'])\n const list = (node as { type?: string; list?: readonly { value?: unknown }[] } | undefined)\n if (list?.type !== 'union' || list.list === undefined) return []\n return list.list.map(entry => entry.value).filter((value): value is string => typeof value === 'string')\n}\n\n/** The credential reference a resolved profile names (its `apiKeyEnv` field). */\nfunction apiKeyEnvOf(\n namespace: SettingsNamespaceView | undefined,\n path: readonly string[],\n schema: SettingsSchemaOperations,\n): string | undefined {\n if (namespace === undefined) return undefined\n const profile = schema.getPath(namespace.value, path)\n if (typeof profile !== 'object' || profile === null) return undefined\n const ref = (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n return typeof ref === 'string' && ref.length > 0 ? ref : undefined\n}\n\n/** The models settings page controller (one per settings surface). */\nexport class ModelsSettingsStore {\n /** The snapshot the section renders from (uSES-safe store). */\n readonly store: SnapshotStore<ModelsSettingsState> = createSnapshotStore<ModelsSettingsState>({\n status: 'idle', error: null, credentialError: null, writable: false, rows: [], namespaces: new Map(),\n })\n\n /** Latest load wins; an older response never overwrites a newer one. */\n private generation = 0\n\n /**\n * @param ctx - the page plugin's context, whose `remote.llm` and\n * `remote.credentials` namespaces carry the directory and credential reads.\n * @param schema - settings-owned schema and immutable path operations.\n * @param describeFace - the shared mirror's describe face (namespace views and writability).\n */\n constructor(\n private readonly ctx: ClientContext,\n private readonly schema: SettingsSchemaOperations,\n private readonly describeFace: SettingsDescribeFace,\n ) {}\n\n /**\n * Refresh the whole page snapshot: the provider directory and the mirror's\n * settings answer in parallel, then one batched credential describe over\n * every referenced ref. Provider failure or absence of an initial settings\n * answer keeps the last good rows and surfaces an error; a failed settings\n * refresh reuses the mirror's held view.\n * @returns nothing; the snapshot carries the outcome.\n */\n async load(): Promise<void> {\n const generation = ++this.generation\n this.store.update((s) => { s.status = 'loading'; s.error = null })\n const [registered, declared] = await Promise.all([\n this.ctx.remote.llm.listProviders(),\n this.ctx.remote.llm.listConfigurableProviders(),\n this.describeFace.ensure(),\n ])\n if (!registered.ok) { this.failLoad(generation, registered.error.message); return }\n if (!declared.ok) { this.failLoad(generation, declared.error.message); return }\n const mirrored = this.describeFace.getSnapshot()\n if (mirrored.view === undefined) {\n this.failLoad(generation, mirrored.error ?? 'settings are unavailable in this browser')\n return\n }\n const providers = joinProviderDirectory(registered.value, declared.value)\n const writable = mirrored.view.writable\n const views: readonly SettingsNamespaceView[] = mirrored.view.namespaces\n const namespaces = new Map(views.map(view => [view.ns, view]))\n const rows: ProviderRow[] = providers.map((entry) => {\n const namespace = namespaces.get(entry.settingsNs)\n const configured = namespace !== undefined\n && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== undefined)\n const removable = namespace !== undefined\n && entry.settingsPath.length > 0\n && this.schema.hasPath(namespace.user, entry.settingsPath)\n && !this.schema.hasPath(namespace.base, entry.settingsPath)\n return {\n entry,\n configured,\n removable,\n apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),\n credential: undefined,\n }\n })\n const refs = [...new Set(rows.map(row => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))]\n let credentials: Record<string, CredentialInfo> = {}\n let credentialError: string | null = null\n if (refs.length > 0) {\n const response = await this.ctx.remote.credentials.describe(refs)\n // Credential state is an enrichment for the Models page: a failure\n // degrades the badge instead of failing the load. The onboarding\n // projection below retains the failure distinction.\n if (response.ok) credentials = response.value\n else credentialError = response.error.message\n }\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'ready'\n s.error = null\n s.credentialError = credentialError\n s.writable = writable\n s.rows = rows.map((row) => {\n const named = row.apiKeyEnv === undefined ? undefined : credentials[row.apiKeyEnv]\n const derived = row.apiKeyEnv !== undefined ? undefined : credentials[deriveKeyRef(row.entry.provider)]\n return {\n ...row,\n ...named === undefined ? {} : { credential: named },\n ...derived === undefined ? {} : { derivedCredential: derived },\n }\n })\n s.namespaces = namespaces\n })\n }\n\n /** Publish one load's failure text, unless a newer load already took over. */\n private failLoad(generation: number, message: string): void {\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'error'\n s.error = message\n })\n }\n}\n\n/**\n * Whether a joined row can serve model requests as it stands: the route is\n * registered with the adapter registry, and whatever credential its resolved\n * profile names is stored. A profile naming no reference authenticates through\n * the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs\n * nothing), as does a live route with no settings address at all, so neither\n * owes this page a key.\n * @param row - one joined provider row.\n * @returns whether the user already has this provider to talk to.\n */\nexport function providerUsable(row: ProviderRow): boolean {\n if (!row.entry.active) return false\n if (row.apiKeyEnv === undefined) return true\n return row.credential?.configured === true\n}\n\n/** First-run onboarding readiness derived only from the shared Models join. */\nexport type OnboardingReadiness =\n | { kind: 'loading' }\n | { kind: 'adapter-absent' }\n | { kind: 'provider-ready' }\n | { kind: 'credential-missing' }\n | {\n kind: 'unavailable'\n reason:\n | 'load-failed'\n | 'provider-inactive'\n | 'credentials-unavailable'\n | 'settings-read-only'\n | 'credential-read-only'\n }\n\n/**\n * Project first-run readiness from the provider/settings/credential join used\n * by the Models page. The step exists to leave the user with a model to talk\n * to, so ANY usable provider ends it; only when none exists does the official\n * DeepSeek route — the one route the prompt can offer a key field for — decide\n * whether prompting can help. A missing official configurable-provider\n * declaration means the adapter is not repairable by navigating to Models.\n * @param state - current shared Models join snapshot.\n * @returns the onboarding state without reading a parallel fact source.\n */\nexport function onboardingReadiness(state: ModelsSettingsState): OnboardingReadiness {\n if ((state.status === 'idle' || state.status === 'loading') && state.rows.length === 0) {\n return { kind: 'loading' }\n }\n if (state.status === 'error') {\n return {\n kind: 'unavailable',\n reason: 'load-failed',\n }\n }\n if (state.rows.some(providerUsable)) return { kind: 'provider-ready' }\n const row = state.rows.find(candidate =>\n candidate.entry.provider === 'deepseek-official'\n && candidate.entry.settingsNs === 'llm-deepseek'\n && candidate.entry.settingsPath.length === 0)\n if (row === undefined) return { kind: 'adapter-absent' }\n if (!row.entry.active) {\n return {\n kind: 'unavailable',\n reason: 'provider-inactive',\n }\n }\n // Past the usable gate an active route names a reference it has no stored\n // credential for, so the remaining questions are all about that credential.\n if (state.credentialError !== null || row.credential === undefined) {\n return {\n kind: 'unavailable',\n reason: 'credentials-unavailable',\n }\n }\n if (!state.writable) {\n return {\n kind: 'unavailable',\n reason: 'settings-read-only',\n }\n }\n if (!row.credential.writable) {\n return {\n kind: 'unavailable',\n reason: 'credential-read-only',\n }\n }\n return { kind: 'credential-missing' }\n}\n","/**\n * Client access to the models.dev metadata index. The index is served by this\n * plugin's own server route (same origin); the raw models.json lives next to\n * settings.yaml under DSH home and is fetched from models.dev ONLY when the\n * user clicks the title-row button — nothing downloads automatically.\n *\n * The search surface is deliberately minimal (per plan): match model ids with\n * a case-insensitive substring test and show ids only, at most 10 candidates.\n * The full index is never handed to a static <datalist>.\n */\n\n/** Precise entry the metadata search returns (a subset of the raw models.dev record). */\nexport interface MetadataEntry {\n readonly id: string\n readonly context: number | undefined\n readonly output: number | undefined\n readonly input: readonly string[]\n readonly reasoning: boolean\n}\n\n/** Same-origin routes served by the server half. */\nconst INDEX_URL = '/plugins/dsh-model-extension/models-index'\nconst DOWNLOAD_URL = '/plugins/dsh-model-extension/models-download'\n\n/** Module-level cache: one page load fetches the index at most once. */\nlet cached: readonly MetadataEntry[] | undefined\n\nfunction normalize(raw: unknown): readonly MetadataEntry[] {\n if (!Array.isArray(raw)) return []\n const entries: MetadataEntry[] = []\n for (const item of raw) {\n if (typeof item !== 'object' || item === null) continue\n const row = item as Record<string, unknown>\n if (typeof row['id'] !== 'string' || row['id'].length === 0) continue\n const modalities = Array.isArray(row['input'])\n ? row['input'].filter((m): m is string => typeof m === 'string')\n : []\n entries.push({\n id: row['id'],\n context: typeof row['context'] === 'number' ? row['context'] : undefined,\n output: typeof row['output'] === 'number' ? row['output'] : undefined,\n input: modalities,\n reasoning: row['reasoning'] === true,\n })\n }\n return entries\n}\n\n/**\n * The metadata index, fetched once per page load; `undefined` while the\n * server has no metadata file (the caller shows the not-ready hint).\n */\nexport async function getMetadataIndex(): Promise<readonly MetadataEntry[] | undefined> {\n if (cached !== undefined) return cached\n try {\n const response = await fetch(INDEX_URL)\n if (!response.ok) return undefined\n cached = normalize(await response.json())\n return cached\n } catch {\n return undefined\n }\n}\n\n/** The outcome of an explicit user-triggered download. */\nexport type MetadataDownload = { readonly ok: true } | { readonly ok: false; readonly message: string }\n\n/**\n * Download/refresh the metadata file through the server half (user-triggered\n * from the title-row button). A success also refreshes the local cache.\n */\nexport async function downloadMetadata(): Promise<MetadataDownload> {\n try {\n const response = await fetch(DOWNLOAD_URL, { method: 'POST' })\n const body = await response.json().catch(() => undefined) as\n | { ok?: boolean; message?: string }\n | undefined\n if (!response.ok || body?.ok !== true) {\n return { ok: false, message: body?.message ?? `HTTP ${String(response.status)}` }\n }\n cached = normalize(body['index'])\n return { ok: true }\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) }\n }\n}\n\n/**\n * Case-insensitive substring match over model ids, at most {@link limit}\n * candidates (plan: show ids only, never the whole list).\n * @param index - the metadata index, or undefined while unavailable.\n * @param query - the user's typed text.\n * @param limit - maximum candidates to return.\n * @returns the matching ids; empty when the index is unavailable.\n */\nexport function searchModelIds(\n index: readonly MetadataEntry[] | undefined,\n query: string,\n limit = 10,\n): readonly string[] {\n if (index === undefined) return []\n const needle = query.trim().toLowerCase()\n if (needle.length === 0) return []\n const hits: string[] = []\n for (const entry of index) {\n if (!entry.id.toLowerCase().includes(needle)) continue\n hits.push(entry.id)\n if (hits.length >= limit) break\n }\n return hits\n}\n","/**\n * Pure helpers copied from the host's ui-settings-models UI component files\n * (they live inside components there, so they cannot be inlined as standalone\n * modules like operations/store/schema-operations are).\n *\n * ⚠️ Fork-copy risk: these must be re-checked against the pinned host sources\n * (packages/client/ui-settings-models/src/client/{ProviderEditor,DeepSeekModelsEditor}.tsx\n * @ 0.1.5-alpha.2) on every adapter-anchor bump.\n */\n\n/** One model entry kept structurally open so hidden or future fields survive an edit. */\nexport type ModelDraft = Record<string, unknown>\n\n// ---------------------------------------------------------------------------\n// pathOps — copied from ProviderEditor.tsx @ 0.1.5-alpha.2\n// ---------------------------------------------------------------------------\n\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\n\n/**\n * The minimal path ops carrying `after` over `before`, both as the card sees\n * them. Only keys the card observed are named; fields absent from both sides\n * produce no op, which is why edits are path-addressed rather than a rebuilt\n * section.\n * @param base - path of the edited subtree inside the user section.\n * @param before - the subtree as loaded, or undefined when it is new.\n * @param after - the subtree as edited.\n * @returns ordered set/unset ops; empty when nothing changed.\n */\nexport function pathOps(\n base: readonly string[],\n before: unknown,\n after: Record<string, unknown>,\n): SettingsPathOpView[] {\n const previous = typeof before === 'object' && before !== null && !Array.isArray(before)\n ? before as Record<string, unknown>\n : {}\n const ops: SettingsPathOpView[] = []\n for (const [key, value] of Object.entries(after)) {\n if (JSON.stringify(previous[key]) === JSON.stringify(value)) continue\n ops.push({ op: 'set', path: [...base, key], value: value as JsonValue })\n }\n for (const key of Object.keys(previous)) {\n if (!(key in after)) ops.push({ op: 'unset', path: [...base, key] })\n }\n return ops\n}\n\n// ---------------------------------------------------------------------------\n// capacity parsing/formatting — copied from DeepSeekModelsEditor.tsx @ 0.1.5-alpha.2\n// ---------------------------------------------------------------------------\n\n/** Accepted capacity spellings: a decimal count with an optional K/M suffix. */\nconst CAPACITY_PATTERN = /^(\\d+(?:\\.\\d+)?)([km])?$/i\n\n/** Decimal suffix scales — `1M` is 1000K, matching how model capacities are quoted. */\nconst CAPACITY_SCALE = { k: 1_000, m: 1_000_000 } as const\n\n/**\n * Read a typed capacity, so a user can write `256K` or `1M` instead of counting\n * zeroes. The stored value stays a plain token count.\n * @param text - raw field text.\n * @returns the count; `undefined` when blank (inherit), `NaN` when unreadable\n * (rejected by {@link validateModelRows} before any write).\n */\nexport function parseCapacity(text: string): number | undefined {\n const trimmed = text.trim()\n if (trimmed.length === 0) return undefined\n const match = CAPACITY_PATTERN.exec(trimmed)\n if (match === null) return Number.NaN\n const suffix = match[2]?.toLowerCase()\n const scale = suffix === 'k' || suffix === 'm' ? CAPACITY_SCALE[suffix] : 1\n const scaled = Number(match[1]) * scale\n // A decimal multiple is exact in intent but not in binary floating point\n // (2.3 * 1e6 lands a few ULPs high), so an integral intent snaps back.\n const rounded = Math.round(scaled)\n return Math.abs(scaled - rounded) < 1e-6 ? rounded : scaled\n}\n\n/**\n * Spell a stored count back in the shortest form that survives a round trip\n * through {@link parseCapacity}; a count that is not a whole number of\n * thousands stays written out.\n * @param value - stored capacity.\n * @returns the field text.\n */\nexport function formatCapacity(value: number): string {\n if (!Number.isInteger(value) || value <= 0) return String(value)\n if (value % CAPACITY_SCALE.m === 0) return `${String(value / CAPACITY_SCALE.m)}M`\n if (value % CAPACITY_SCALE.k === 0) return `${String(value / CAPACITY_SCALE.k)}K`\n return String(value)\n}\n\n// ---------------------------------------------------------------------------\n// model-row validation — copied from DeepSeekModelsEditor.tsx @ 0.1.5-alpha.2\n// ---------------------------------------------------------------------------\n\n/** A localized validation failure for one user-owned model array. */\nexport interface ModelRowsValidationFailure {\n /** Zero-based model position. */\n index: number\n /** Message key owned by the Models+ dictionary. */\n key: 'modelIdRequired' | 'modelIdDuplicate' | 'modelNameInvalid' | 'modelContextInvalid'\n | 'modelMaxTokensInvalid'\n}\n\n/** Convert a schema-validated catalog value into records without dropping hidden fields. */\nexport function modelDrafts(value: unknown): ModelDraft[] {\n if (!Array.isArray(value)) return []\n return value.map(entry =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n ? entry as ModelDraft\n : {})\n}\n\n// ---------------------------------------------------------------------------\n// row key-order normalization (plugin addition, v1.0.0: stable YAML key order)\n// ---------------------------------------------------------------------------\n\n/** Canonical key order for one models[] row (plugin-known fields first). */\nconst ROW_KEY_ORDER = ['id', 'name', 'contextWindow', 'maxTokens', 'input', 'reasoningEfforts', 'compat']\n\n/** Canonical key order for the row's compat sub-object. */\nconst COMPAT_KEY_ORDER = ['supportsDeveloperRole', 'supportsReasoningEffort', 'thinkingFormat']\n\n/**\n * Re-key one model row into the canonical order (plugin-known fields in\n * order, unknown/future fields kept at the tail so nothing is dropped).\n * YAML emits keys in object insertion order, and interactive edits append\n * keys at the tail — without this, rows saved after quick-load or gated-key\n * removals come out with scrambled key orders (purely cosmetic, but noisy\n * in settings.yaml diffs).\n * @param row - the drafted row.\n * @returns the re-keyed row (shallow copy).\n */\nexport function normalizeModelRow(row: ModelDraft): ModelDraft {\n const next: ModelDraft = {}\n for (const key of ROW_KEY_ORDER) {\n if (key in row) next[key] = row[key]\n }\n for (const key of Object.keys(row)) {\n if (!ROW_KEY_ORDER.includes(key)) next[key] = row[key]\n }\n const compat = next['compat']\n if (typeof compat === 'object' && compat !== null && !Array.isArray(compat)) {\n const source = compat as Record<string, unknown>\n const normalized: Record<string, unknown> = {}\n for (const key of COMPAT_KEY_ORDER) {\n if (key in source) normalized[key] = source[key]\n }\n for (const key of Object.keys(source)) {\n if (!COMPAT_KEY_ORDER.includes(key)) normalized[key] = source[key]\n }\n next['compat'] = normalized\n }\n return next\n}\n\n/**\n * Validate adapter constraints that the serialized schema cannot express.\n * @param value - user-owned `models` value, or undefined while inherited.\n * @returns the first invalid row, or undefined when the adapter will accept it.\n */\nexport function validateModelRows(value: unknown): ModelRowsValidationFailure | undefined {\n if (value === undefined) return undefined\n const models = modelDrafts(value)\n const seen = new Set<string>()\n for (const [index, model] of models.entries()) {\n // Compared trimmed: surrounding whitespace is a paste artifact the adapter\n // would never match, and an untrimmed compare lets `model ` slip past the\n // duplicate check against its own twin.\n const id = model['id']\n const trimmed = typeof id === 'string' ? id.trim() : undefined\n if (trimmed === undefined || trimmed.length === 0) return { index, key: 'modelIdRequired' }\n if (seen.has(trimmed)) return { index, key: 'modelIdDuplicate' }\n seen.add(trimmed)\n const name = model['name']\n if (name !== undefined && (typeof name !== 'string' || name.length === 0)) {\n return { index, key: 'modelNameInvalid' }\n }\n const contextWindow = model['contextWindow']\n if (contextWindow !== undefined\n && (typeof contextWindow !== 'number' || !Number.isInteger(contextWindow) || contextWindow <= 0)) {\n return { index, key: 'modelContextInvalid' }\n }\n const maxTokens = model['maxTokens']\n if (maxTokens !== undefined\n && (typeof maxTokens !== 'number' || !Number.isInteger(maxTokens) || maxTokens <= 0)) {\n return { index, key: 'modelMaxTokensInvalid' }\n }\n }\n return undefined\n}\n","/**\n * Draft defaults for a NEW model row (added by hand or adopted from a fetch),\n * per the v1.0.0 plan: reasoning effort ON with every level declared, thinking\n * format `openai`, both input modalities checked. These are draft seeds that\n * land in settings.yaml when the row is saved — they are not inherited-state\n * sentinels, except `supportsDeveloperRole`, which stays UNWRITTEN (its\n * tri-state reads an absent key as checked, so only an explicit user uncheck\n * ever writes `false`).\n */\n\nimport type { ModelDraft } from './compat.ts'\n\n/** The tri-state `compat.supportsDeveloperRole` seed: absent (reads checked). */\nconst DEVELOPER_ROLE_SEED: Record<string, unknown> = {}\n\n/** Draft seed for one new model row. */\nexport function newModelDraft(): ModelDraft {\n return {\n id: '',\n input: ['text', 'image'],\n reasoningEfforts: {\n off: null,\n minimal: 'minimal',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'xhigh',\n max: 'max',\n },\n compat: {\n ...DEVELOPER_ROLE_SEED,\n supportsReasoningEffort: true,\n thinkingFormat: 'openai',\n },\n }\n}\n","/**\n * Shared extension metadata: enums pinned to the adapter anchor version, and\n * the extra locale keys the extension adds on top of the official Models page\n * dictionaries. The anchor constant itself is injected at build time.\n */\n\n/** Adapter anchor (build-time define from package.json dsh.adapter). */\ndeclare const __DSH_ADAPTER_VERSION__: string\nexport const ADAPTER_VERSION: string =\n typeof __DSH_ADAPTER_VERSION__ === 'string' ? __DSH_ADAPTER_VERSION__ : '0.0.0-unknown'\n\n/** Thinking levels offered by llm-pi-ai (THINKING_LEVEL_GATE @ 0.1.2-alpha.4). Only `off` may carry an empty wire value. */\nexport const THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number]\n\n/** Input modalities accepted by llm-pi-ai (MODALITY_GATE @ 0.1.2-alpha.4). */\nexport const MODALITIES = ['text', 'image'] as const\nexport type Modality = (typeof MODALITIES)[number]\n\n/** Reasoning wire formats understood by llm-pi-ai (SUPPORTED_THINKING_FORMATS @ 0.1.2-alpha.4). */\nexport const THINKING_FORMATS = [\n 'openai',\n 'deepseek',\n 'openrouter',\n 'together',\n 'baseten',\n 'zai',\n 'qwen',\n 'chat-template',\n 'qwen-chat-template',\n 'string-thinking',\n 'ant-ling',\n] as const\nexport type ThinkingFormat = (typeof THINKING_FORMATS)[number]\n\n/** Extra copy for the extension, keyed like the official dictionaries (en is authoritative). */\nexport const en = {\n // --- official Models-page keys the forked components still render -------\n nav: 'Models+',\n title: 'Models+',\n intro: 'Enter your API keys to use models from the following providers.',\n edit: 'Edit',\n editProvider: 'Edit {provider}',\n remove: 'Delete',\n removeProvider: 'Delete {provider}',\n deleteTitle: 'Delete {provider}?',\n deleteDescription: 'Deleting {provider} removes its configuration. Any credential it uses is managed elsewhere and will be kept.',\n deleteDescriptionWithCredential: 'Deleting {provider} removes its configuration and stored API key.',\n deleteConfirm: 'Delete {provider}',\n deleting: 'Deleting {provider}…',\n add: 'Add provider',\n provider: 'Provider',\n close: 'Close',\n cancel: 'Cancel',\n apply: 'Apply',\n applying: 'Applying…',\n savedProvider: 'Saved {provider}.',\n credentialConfigured: 'API key configured',\n credentialMissing: 'API key missing',\n readOnly: 'The settings document is read-only in this deployment.',\n loadFailed: 'Loading the provider directory failed',\n conflict: 'Someone else changed these settings while this card was open. Close it and reopen to edit the current values.',\n retry: 'Retry',\n keyInput: 'API key',\n keyPlaceholder: 'Enter your API key',\n keyPlaceholderNative: 'Enter an API key, or leave blank to use environment authentication',\n keyStored: 'Configured — enter a new value to replace',\n keyEnvLocked: 'Provided by the launch environment (read-only)',\n customized: 'Customized settings',\n baseUrl: 'Base URL',\n baseUrlDefault: 'Provider default',\n models: 'Models',\n modelsInherited: 'Using the adapter defaults',\n modelsCustomized: 'Customized model catalog',\n resetModels: 'Restore defaults',\n model: 'Model',\n modelId: 'Model ID',\n modelName: 'Display name',\n modelNamePlaceholder: 'Uses the model ID when empty',\n contextWindow: 'Context window',\n contextWindowPlaceholder: 'Uses the provider default',\n maxTokens: 'Max output tokens',\n maxTokensPlaceholder: 'Uses the provider default',\n modelAdvanced: 'Capacities',\n addModel: 'Add model',\n removeModel: 'Delete model',\n modelsEmpty: 'No models will be shown in the selector. Unlisted IDs can still be sent directly.',\n keyBlank: 'Enter the API key, or leave the field empty to keep the stored one.',\n keyBlankNew: 'Enter the API key, or leave the field empty if this provider authenticates another way.',\n keyIllegalCharacters: 'This API key is not in a valid format. Please check it.',\n modelIdRequired: 'Model ID is required.',\n modelIdDuplicate: 'Model ID must be unique.',\n modelNameInvalid: 'Display name cannot be empty.',\n modelContextInvalid: 'Context window must be a positive count, like 131072, 256K, or 1M.',\n modelMaxTokensInvalid: 'Max output tokens must be a positive count, like 8192, 64K, or 1M.',\n advancedHint: 'Other fields live in settings.yaml; edit that section directly.',\n modelCapacityInvalid: 'A capacity must be a number, optionally suffixed K or M.',\n modelDuplicate: 'Each model ID may appear once.',\n modelContextWindow: 'Context window',\n modelMaxTokens: 'Max output tokens',\n fetchModels: 'Fetch available models',\n fetching: 'Asking the provider…',\n fetchNeedsBaseUrl: 'Enter the base URL first, then fetch.',\n fetchEmpty: 'The provider listed no models. Add them by hand.',\n fetchTitle: 'Choose models to add',\n fetchDescription: 'These are the models this provider has available. Choose the ones to add.',\n fetchSelectAll: 'Select all',\n fetchDeselectAll: 'Deselect all',\n fetchAdopt: 'Add selected',\n customAdd: 'Add a custom provider',\n customTitle: 'Custom provider',\n customTag: 'Custom',\n customRoute: 'Provider ID',\n customRouteHint: 'Lowercase identifier, starting with a letter, that uniquely names this provider in requests and as its credential name.',\n customRouteInvalid: 'Start with a lowercase letter; then lowercase letters, digits, and dashes.',\n customRouteTaken: 'A provider already uses this ID.',\n customDisplayName: 'Display name',\n customApi: 'API protocol',\n customApiUnset: 'Not selected',\n customNeedsBaseUrl: 'A custom provider needs a base URL.',\n customBaseUrlInvalid: 'Enter a valid HTTP or HTTPS URL.',\n customNeedsModels: 'A custom provider needs at least one model.',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: 'unresolvable settings path',\n create: 'Create provider',\n creating: 'Creating…',\n onboardingTitle: 'Add an API key to get started',\n onboardingDescription: 'Configure the official DeepSeek provider to start building.',\n onboardingLater: 'Configure later',\n onboardingSave: 'Save and continue',\n onboardingSaving: 'Saving…',\n keyRequired: 'Enter an API key to continue.',\n\n // --- extension-only keys ------------------------------------------------\n extDeclare: 'Declared',\n extSection: 'Model extensions',\n extSectionHint: 'Extra per-model fields that live in settings.yaml.',\n supportsReasoningEffort: 'Endpoint accepts reasoning effort',\n supportsDeveloperRole: 'System prompt may use the developer role',\n supportsDeveloperRoleHint: 'Reasoning-model system prompts go out as \"developer\"; uncheck to keep \"system\" for gateways that reject it.',\n reasoningEfforts: 'Reasoning efforts',\n reasoningEffortLevel: 'Level',\n reasoningEffortWire: 'Wire value',\n reasoningEffortOffHint: '\"off\" takes no wire value.',\n reasoningEffortEmptyWire: 'A checked level other than \"off\" needs a wire value.',\n reasoningEffortsNeedNonOff: 'Declare at least one level beyond \"off\".',\n inputModalities: 'Input modalities',\n inputNeedOne: 'Keep at least one modality checked.',\n thinkingFormat: 'Thinking format',\n} as const\n\nexport type ExtensionKey = keyof typeof en\n\n/** Chinese strings — same key set as {@link en}. */\nexport const zh: { [K in ExtensionKey]: string } = {\n // --- official Models-page keys (upstream zh values) ----------------------\n nav: '模型+',\n title: '模型+',\n intro: '填入各提供方的 API 密钥即可使用其模型。',\n edit: '编辑',\n editProvider: '编辑 {provider}',\n remove: '删除',\n removeProvider: '删除 {provider}',\n deleteTitle: '删除 {provider}?',\n deleteDescription: '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。',\n deleteDescriptionWithCredential: '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteConfirm: '删除 {provider}',\n deleting: '正在删除 {provider}…',\n add: '添加提供方',\n provider: '提供方',\n close: '关闭',\n cancel: '取消',\n apply: '保存',\n applying: '保存中…',\n savedProvider: '已保存 {provider}。',\n credentialConfigured: 'API 密钥已配置',\n credentialMissing: 'API 密钥缺失',\n readOnly: '当前部署的设置文档为只读。',\n loadFailed: '加载提供方目录失败',\n conflict: '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。',\n retry: '重试',\n keyInput: 'API 密钥',\n keyPlaceholder: '输入 API 密钥',\n keyPlaceholderNative: '输入 API 密钥,或留空使用环境认证',\n keyStored: '已配置——输入新值可替换',\n keyEnvLocked: '由启动环境提供(只读)',\n customized: '自定义设置',\n baseUrl: 'API 地址',\n baseUrlDefault: '提供方默认',\n models: '模型目录',\n modelsInherited: '正在使用适配器默认模型',\n modelsCustomized: '已自定义模型目录',\n resetModels: '恢复默认模型',\n model: '模型',\n modelId: '模型 ID',\n modelName: '显示名称',\n modelNamePlaceholder: '留空时使用模型 ID',\n contextWindow: '上下文窗口',\n contextWindowPlaceholder: '使用提供方默认值',\n maxTokens: '最大输出 token 数',\n maxTokensPlaceholder: '使用提供方默认值',\n modelAdvanced: '容量',\n addModel: '添加模型',\n removeModel: '删除模型',\n modelsEmpty: '模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。',\n keyBlank: '请输入 API 密钥;留空则保持已存储的密钥。',\n keyBlankNew: '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。',\n keyIllegalCharacters: '此 API 密钥格式无效,请检查。',\n modelIdRequired: '模型 ID 必填。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n advancedHint: '其余字段存于 settings.yaml;请直接编辑该节。',\n modelCapacityInvalid: '容量须为数字,可带 K 或 M 后缀。',\n modelDuplicate: '每个模型 ID 只能出现一次。',\n modelContextWindow: '上下文窗口',\n modelMaxTokens: '最大输出 token 数',\n fetchModels: '获取可用模型',\n fetching: '正在询问提供方…',\n fetchNeedsBaseUrl: '请先填写 API 地址再获取。',\n fetchEmpty: '该提供方未列出任何模型,请手动添加。',\n fetchTitle: '选择要添加的模型',\n fetchDescription: '这些是该提供方可用的模型,选择要添加的项。',\n fetchSelectAll: '全选',\n fetchDeselectAll: '取消全选',\n fetchAdopt: '添加所选',\n customAdd: '添加自定义提供方',\n customTitle: '自定义提供方',\n customTag: '自定义',\n customRoute: '提供方 ID',\n customRouteHint: '小写字母开头的唯一标识符,用于请求与凭证命名。',\n customRouteInvalid: '以小写字母开头;其后为小写字母、数字和短横线。',\n customRouteTaken: '已有提供方使用此 ID。',\n customDisplayName: '显示名称',\n customApi: 'API 协议',\n customApiUnset: '未选择',\n customNeedsBaseUrl: '自定义提供方需要 API 地址。',\n customBaseUrlInvalid: '请输入有效的 HTTP 或 HTTPS 地址。',\n customNeedsModels: '自定义提供方至少需要一个模型。',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: '无法解析设置路径',\n create: '创建提供方',\n creating: '创建中…',\n onboardingTitle: '先添加一个 API 密钥即可开始',\n onboardingDescription: '配置官方 DeepSeek 提供方以开始构建。',\n onboardingLater: '稍后配置',\n onboardingSave: '保存并继续',\n onboardingSaving: '保存中…',\n keyRequired: '请输入 API 密钥以继续。',\n\n // --- extension-only keys ------------------------------------------------\n extDeclare: '声明',\n extSection: '模型扩展',\n extSectionHint: 'settings.yaml 中按模型生效的扩展字段。',\n supportsReasoningEffort: '端点接受推理挡位参数(reasoning_effort)',\n supportsDeveloperRole: '允许以 developer 角色发送系统提示',\n supportsDeveloperRoleHint: '推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。',\n reasoningEfforts: '推理挡位',\n reasoningEffortLevel: '挡位',\n reasoningEffortWire: '线上取值',\n reasoningEffortOffHint: '“off”不需要线上取值。',\n reasoningEffortEmptyWire: '除 off 外勾选的挡位必须填写线上取值。',\n reasoningEffortsNeedNonOff: '至少声明一个 off 以外的挡位。',\n inputModalities: '输入模态',\n inputNeedOne: '至少保留一个模态。',\n thinkingFormat: '思考格式',\n}\n","/* models-plus styles — the official ModelsSection.module.css classes (as\n * transcribed and verified in docs/models-settings-demo.html) plus the\n * extension-block styles, all on --dsw-alias tokens. */\n\n.section { display: flex; flex-direction: column; gap: 12px; max-width: 720px; color: var(--dsw-alias-label-primary); }\n.titleRow { display: flex; align-items: center; gap: 10px; }\n.title { margin: 0; font-size: 16px; line-height: 24px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n.intro { margin: 0; font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-tertiary); }\n.savedNotice { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n.error { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-error-primary); }\n\n.rows { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }\n.rowCard { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 16px; padding: 12px 14px; display: flex; flex-direction: column; gap: 12px; }\n.rowHead { display: flex; align-items: center; gap: 10px; }\n.rowIdentity { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }\n.rowName { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n.rowTag { flex: none; padding: 1px 6px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 4px; font-size: 11px; line-height: 16px; color: var(--dsw-alias-label-secondary); }\n.credentialDot { box-sizing: border-box; display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; }\n.credentialDotConfigured { background: var(--dsw-alias-state-success-primary); }\n.credentialDotMissing { background: var(--dsw-alias-state-error-primary); }\n.rowActions { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }\n\n.primaryButton, .secondaryButton, .addButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 36px; padding: 0 14px; border: none; border-radius: 18px; font: inherit; font-size: 14px; line-height: 22px; cursor: pointer; }\n.primaryButton { background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }\n.primaryButton:hover:not(:disabled) { background: var(--dsw-alias-button-primary-hover); }\n.secondaryButton, .addButton { border: 0.5px solid var(--dsw-alias-border-l3); background: transparent; color: var(--dsw-alias-label-primary); }\n.secondaryButton:hover:not(:disabled), .addButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n.secondaryButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dangerButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; height: 36px; padding: 0 14px; border: none; border-radius: 18px; background: transparent; color: var(--dsw-alias-state-error-primary); font: inherit; font-size: 14px; line-height: 22px; cursor: pointer; }\n.dangerButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n.rowActions .secondaryButton, .rowActions .dangerButton { height: 28px; padding: 0 10px; border-radius: 14px; font-size: 12px; line-height: 18px; }\n.primaryButton:disabled, .secondaryButton:disabled, .dangerButton:disabled, .addButton:disabled, .linkButton:disabled, .addModelButton:disabled { opacity: 0.4; cursor: default; }\n.primaryButton:focus-visible, .secondaryButton:focus-visible, .dangerButton:focus-visible, .addButton:focus-visible, .linkButton:focus-visible, .addModelButton:focus-visible, .iconButton:focus-visible, .customizedSummary:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dsw-alias-border-l3); }\n\n.editor { border-radius: 12px; background: var(--dsw-alias-bg-module-platform); padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; }\n.field { display: flex; flex-direction: column; gap: 6px; }\n.fieldLabel { display: inline-flex; align-items: center; gap: 10px; font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.linkButton { box-sizing: border-box; display: inline-flex; align-items: center; height: 28px; padding: 0 10px; border: none; border-radius: 14px; background: transparent; color: var(--dsw-alias-label-tertiary); font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }\n.linkButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-secondary); }\n.advancedHint { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.editorActions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.addBlock { display: flex; flex-direction: column; gap: 12px; }\n.addActions { display: flex; flex-wrap: wrap; gap: 10px; }\n.addButton { flex: 1 1 0; min-width: 180px; gap: 6px; height: 44px; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 16px; }\n.addCard { border-radius: 12px; background: var(--dsw-alias-bg-module-platform); padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; list-style: none; }\n.addCard .editor, .setupCard .editor { background: none; padding: 0; }\n\n\n.tabs { display: flex; flex-direction: column; gap: 12px; }\n.tabBar { display: flex; gap: 4px; border-bottom: 0.5px solid var(--dsw-alias-border-l2); }\n.tabButton { appearance: none; border: none; background: transparent; padding: 6px 12px 8px; font: inherit; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-tertiary); cursor: pointer; position: relative; }\n.tabButton:hover { color: var(--dsw-alias-label-primary); }\n.tabButton:disabled { opacity: 0.4; cursor: default; }\n.tabButtonActive { color: var(--dsw-alias-label-primary); font-weight: 500; }\n.tabButtonActive::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--dsw-alias-brand-primary); }\n.tabPanel { display: flex; flex-direction: column; gap: 12px; }\n.modelCatalog { display: flex; flex-direction: column; gap: 10px; }\n.modelCatalogHeading { display: flex; flex-direction: column; gap: 2px; }\n.modelCatalogTitle { font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.modelCatalogMeta, .modelEmpty { margin: 0; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }\n.modelList { display: flex; flex-direction: column; gap: 8px; }\n.modelListHead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }\n.modelEntry { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 10px; padding: 6px; }\n.modelRow { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto; align-items: center; gap: 6px; }\n.iconButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-tertiary); cursor: pointer; }\n.iconButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n.iconButton:disabled { cursor: default; opacity: 0.4; }\n.iconButtonDanger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); color: var(--dsw-alias-state-error-primary); }\n.modelAdvanced { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; padding: 8px 4px 2px; }\n.modelField { display: flex; flex-direction: column; gap: 4px; }\n.modelFieldLabel { color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }\n.modelEmpty { padding: 12px; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 8px; text-align: center; }\n.addModelButton { box-sizing: border-box; align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 14px; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }\n.addModelButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n\n.input { box-sizing: border-box; width: 100%; height: 32px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; font: inherit; font-size: 14px; line-height: 22px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\nselect.input { max-width: 240px; cursor: pointer; }\n.input:focus { outline: none; border-color: var(--dsw-alias-brand-primary); }\n.input::placeholder { color: var(--dsw-alias-label-dimmed); }\n.input:disabled { opacity: 0.6; cursor: default; }\n.selectInput { appearance: none; padding-right: 32px; background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\"); background-repeat: no-repeat; background-position: right 12px center; background-size: 12px 12px; }\n\n.deleteDialog { width: min(480px, 100%); }\n.deleteConfirm:not(:disabled) { border-color: var(--dsw-alias-state-error-primary); color: var(--dsw-alias-state-error-primary); }\n.deleteConfirm:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n\n.fetchDialog { max-width: 520px; }\n.candidateToolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.candidateSearch { min-width: 0; flex: 1 1 240px; }\n.candidateList { display: flex; flex-direction: column; gap: 2px; max-height: 320px; margin: 0; overflow-y: auto; padding: 0; list-style: none; }\n.candidate { border-radius: 6px; }\n.candidateLabel { display: flex; align-items: center; gap: 8px; padding: 6px 8px; cursor: pointer; }\n.candidateId { flex: 1 1 auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; overflow-wrap: anywhere; }\n.candidateEmpty { margin: 24px 0; color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 20px; text-align: center; }\n\n/* ---- extension block (plugin-owned; official token palette) ---- */\n[hidden] { display: none !important; }\n.extBlock { border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 10px; padding: 10px; margin: 8px 4px 2px; background: var(--dsw-alias-bg-layer-1); display: flex; flex-direction: column; gap: 10px; }\n.extGroup { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }\n.extGroupFirst { border-top: none; padding-top: 0; }\n.extCheck { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; }\n.extCheckLabel { font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-primary); }\n.extHint { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.extGated { display: flex; flex-direction: column; gap: 12px; padding-left: 2px; }\n.extField { display: flex; flex-direction: column; gap: 6px; }\n.extLabel { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.extTable { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; overflow: hidden; }\n.extTHead { display: grid; grid-template-columns: 64px minmax(0,1fr) minmax(0,1.2fr); font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); background: var(--dsw-alias-bg-module-platform); }\n.extTHead > div { padding: 6px 10px; }\n.extTHead > div + div { border-left: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow { display: grid; grid-template-columns: 64px minmax(0,1fr) minmax(0,1.2fr); align-items: center; border-top: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow > div { padding: 6px 10px; font-size: 14px; }\n.extTRow > div + div { border-left: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow input[type=\"text\"] { box-sizing: border-box; width: 100%; height: 32px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; font: inherit; font-size: 14px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\n.extTRow input[type=\"text\"]:disabled { opacity: 0.6; cursor: default; }\n.extCheckbox { accent-color: var(--dsw-alias-brand-primary); width: 15px; height: 15px; flex: none; }\n.switchRow { display: flex; align-items: center; gap: 8px; font-size: 14px; line-height: 22px; cursor: pointer; }\n.extTag { flex: none; padding: 1px 6px; border: 0.5px solid rgba(65,118,230,0.35); border-radius: 4px; background: var(--dsw-static-deepseek-100); color: var(--dsw-static-deepseek-600); font-size: 11px; line-height: 16px; font-weight: 500; }\n\n/* ---- modal (matches the ui-primitives look closely enough for these two dialogs) ---- */\n.modalMask { position: fixed; inset: 0; background: var(--dsw-alias-bg-mask-1); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 24px; }\n.modal { background: var(--dsw-specific-menu); border-radius: 16px; padding: 20px; width: 100%; box-shadow: 0 12px 40px rgba(0,0,0,0.18); }\n.modalTitle { font-size: 16px; line-height: 24px; font-weight: 500; margin-bottom: 8px; color: var(--dsw-alias-label-primary); }\n.modalDesc { font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-secondary); margin-bottom: 16px; }\n.modalFoot { display: flex; justify-content: flex-end; gap: 8px; }\n\n/* ---- quick-load dropdown (filtered, max 10 candidates, never a static datalist) ---- */\n.quickWrap { position: relative; display: flex; flex-direction: column; gap: 6px; }\n.quickList { position: absolute; top: 100%; left: 0; right: 0; z-index: 20; margin-top: 2px; padding: 4px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 8px; background: var(--dsw-specific-menu); box-shadow: 0 8px 24px rgba(0,0,0,0.12); max-height: 264px; overflow-y: auto; }\n.quickItem { display: block; width: 100%; padding: 6px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; text-align: left; cursor: pointer; overflow-wrap: anywhere; }\n.quickItem:hover { background: var(--dsw-alias-interactive-bg-hover); }\n.quickEmpty { padding: 6px 8px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n@media (prefers-reduced-motion: reduce) {\n .customizedSummary::before { transition: none; }\n}\n","/**\n * Quick-load: a searchable dropdown over the models.dev metadata index.\n * Plan constraints: ids only, case-insensitive substring match, at most 10\n * candidates rendered — the index is filtered on every keystroke and the\n * candidate list is only mounted while open, so a 370-row index never lands\n * in the DOM wholesale.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { getMetadataIndex, searchModelIds } from './models-index.ts'\nimport type { MetadataEntry } from './models-index.ts'\nimport styles from './models-plus.module.css'\n\n/** Props of {@link QuickLoad}. */\nexport interface QuickLoadProps {\n /** Apply one metadata entry to the current model draft. */\n onPick: (entry: MetadataEntry) => void\n /** Disable while a write is in flight. */\n disabled: boolean\n}\n\n/**\n * Render the quick-load input with its filtered candidate dropdown.\n * @param props - the pick handler and disabled flag.\n * @returns the quick-load field.\n */\nexport function QuickLoad(props: QuickLoadProps): ReactNode {\n const [query, setQuery] = useState('')\n const [open, setOpen] = useState(false)\n const [index, setIndex] = useState<readonly MetadataEntry[] | undefined>(undefined)\n\n const ensureIndex = (): void => {\n if (index !== undefined) return\n void getMetadataIndex().then((loaded) => { setIndex(loaded) })\n }\n\n const hits = searchModelIds(index, query, 10)\n\n const pick = (id: string): void => {\n const entry = index?.find(candidate => candidate.id === id)\n setOpen(false)\n setQuery('')\n if (entry !== undefined) props.onPick(entry)\n }\n\n return (\n <div className={styles['quickWrap']}>\n <span className={styles['extLabel']}>快速装入</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={query}\n placeholder=\"搜索模型 id(如 aper)…\"\n aria-label=\"快速装入\"\n disabled={props.disabled}\n onFocus={() => { ensureIndex(); setOpen(true) }}\n onBlur={() => { setOpen(false) }}\n onChange={(event) => { setQuery(event.target.value); setOpen(true) }}\n />\n {open\n ? (\n <div className={styles['quickList']}>\n {index === undefined\n ? <span className={styles['quickEmpty']}>元数据预填不可用——点击页首「下载/更新元数据」</span>\n : hits.length === 0\n ? <span className={styles['quickEmpty']}>{query.trim().length === 0 ? '输入关键字搜索模型 id' : '没有匹配的模型'}</span>\n : hits.map(id => (\n <button\n type=\"button\"\n key={id}\n className={styles['quickItem']}\n onMouseDown={(event) => {\n // mousedown beats the input's blur handler.\n event.preventDefault()\n pick(id)\n }}\n >\n {id}\n </button>\n ))}\n </div>\n )\n : null}\n </div>\n )\n}\n","/**\n * One model entry's expanded panel: quick-load, capacities (the official\n * modelAdvanced fields, merged into this block per the v1.0.0 design), input\n * modalities, the developer-role tri-state, the reasoning-effort gate and its\n * gated area (thinking format, then the seven-level effort table).\n *\n * Every edit patches the row's draft object through `onChange` — persistence\n * rides the card's existing path-ops save with no extra wire calls. Clearing\n * the effort gate drops `reasoningEfforts` AND `compat.thinkingFormat` in ONE\n * commit so partial updates never overwrite each other (no orphan settings).\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { THINKING_FORMATS, THINKING_LEVELS } from '../extension-meta.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { formatCapacity, parseCapacity } from './compat.ts'\nimport { QuickLoad } from './QuickLoad.tsx'\nimport type { MetadataEntry } from './models-index.ts'\nimport styles from './models-plus.module.css'\n\n/** The row's compat sub-object as a plain record (absent → empty). */\nfunction compatOf(model: ModelDraft): Record<string, unknown> {\n const value = model['compat']\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {}\n}\n\n/** The row's reasoningEfforts dict (absent/invalid → undefined = not declared). */\nfunction effortsOf(model: ModelDraft): Record<string, string | null> | undefined {\n const value = model['reasoningEfforts']\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n return value as Record<string, string | null>\n}\n\n/** The row's input modality list (absent → empty, matching the host reader). */\nfunction inputsOf(model: ModelDraft): readonly string[] {\n const value = model['input']\n return Array.isArray(value) ? value.filter((m): m is string => typeof m === 'string') : []\n}\n\n/** Props of {@link ModelEntryPanel}. */\nexport interface ModelEntryPanelProps {\n /** The row's current draft (read). */\n model: ModelDraft\n /** Replace the row with this next draft; `undefined`-valued keys clear them. */\n onChange: (next: ModelDraft) => void\n /** Disable every control (read-only deployment or a pending write). */\n disabled: boolean\n}\n\n/**\n * Render one model entry's expanded panel.\n * @param props - the row draft, its writer, and the disabled flag.\n * @returns the expanded panel.\n */\nexport function ModelEntryPanel(props: ModelEntryPanelProps): ReactNode {\n const { model, onChange, disabled } = props\n\n // Capacities are text-edited, so keystrokes live in this buffer rather than\n // being re-derived from the parsed count (which would rewrite `1000` to\n // `1K` mid-word). Unreadable text stays on screen for the save-time check.\n const [capacityText, setCapacityText] = useState<ReadonlyMap<string, string>>(() => new Map())\n\n /** Patch one key onto the row; `undefined` clears it. */\n const setKey = (key: string, value: unknown): void => {\n const next = { ...model }\n if (value === undefined) Reflect.deleteProperty(next, key)\n else next[key] = value\n onChange(next)\n }\n\n /** Patch one key inside `compat`; an emptied compat leaves no trace. */\n const setCompatKey = (key: string, value: unknown): void => {\n const compat = { ...compatOf(model) }\n if (value === undefined) Reflect.deleteProperty(compat, key)\n else compat[key] = value\n setKey('compat', Object.keys(compat).length === 0 ? undefined : compat)\n }\n\n const setEfforts = (efforts: Record<string, string | null> | undefined): void => {\n setKey('reasoningEfforts', efforts)\n }\n\n const setInput = (modalities: readonly string[]): void => {\n setKey('input', modalities.length === 0 ? undefined : [...modalities])\n }\n\n // --- quick load ----------------------------------------------------------\n const applyMetadata = (entry: MetadataEntry): void => {\n // Only the four metadata fields are overwritten; everything else keeps\n // its draft value (a fresh row already carries the v1.0.0 defaults).\n const next = { ...model }\n if (entry.context === undefined) Reflect.deleteProperty(next, 'contextWindow')\n else next['contextWindow'] = entry.context\n if (entry.output === undefined) Reflect.deleteProperty(next, 'maxTokens')\n else next['maxTokens'] = entry.output\n const compat = { ...compatOf(model) }\n compat['supportsReasoningEffort'] = entry.reasoning\n if (!entry.reasoning) {\n // A non-reasoning model: keep the draft free of orphan gated values.\n Reflect.deleteProperty(compat, 'thinkingFormat')\n Reflect.deleteProperty(next, 'reasoningEfforts')\n }\n setKey('compat', Object.keys(compat).length === 0 ? undefined : compat)\n const supported = entry.input.filter(m => m === 'text' || m === 'image')\n if (supported.length > 0) next['input'] = supported\n onChange(next)\n setCapacityText(new Map())\n }\n\n // --- capacities ----------------------------------------------------------\n const capacityField = (field: 'contextWindow' | 'maxTokens', label: string): ReactNode => {\n const stored = model[field]\n const typed = capacityText.get(field)\n const text = typed ?? (typeof stored === 'number' ? formatCapacity(stored) : '')\n return (\n <label className={styles['modelField']}>\n <span className={styles['modelFieldLabel']}>{label}</span>\n <input\n className={styles['input']}\n type=\"text\"\n inputMode=\"numeric\"\n value={text}\n placeholder=\"使用提供方默认值\"\n aria-label={label}\n disabled={disabled}\n onChange={(event) => {\n setCapacityText(current => new Map(current).set(field, event.target.value))\n setKey(field, parseCapacity(event.target.value))\n }}\n onBlur={() => {\n const raw = capacityText.get(field)\n if (raw === undefined) return\n const parsed = parseCapacity(raw)\n // Unreadable text stays on screen; the save-time check names it.\n if (parsed !== undefined && Number.isNaN(parsed)) return\n setCapacityText(current => {\n const next = new Map(current)\n next.delete(field)\n return next\n })\n }}\n />\n </label>\n )\n }\n\n // --- developer role (tri-state, NOT gated) -------------------------------\n const compat = compatOf(model)\n const developerRole = compat['supportsDeveloperRole'] !== false\n\n // --- effort gate ----------------------------------------------------------\n const supportsReasoningEffort = compat['supportsReasoningEffort'] === true\n const efforts = effortsOf(model)\n\n const toggleGate = (checked: boolean): void => {\n if (checked) {\n setCompatKey('supportsReasoningEffort', true)\n return\n }\n // One commit clears the flag AND every gated node — no orphan settings.\n const nextCompat = { ...compat }\n Reflect.deleteProperty(nextCompat, 'supportsReasoningEffort')\n Reflect.deleteProperty(nextCompat, 'thinkingFormat')\n const next = { ...model, compat: Object.keys(nextCompat).length === 0 ? undefined : nextCompat }\n Reflect.deleteProperty(next, 'reasoningEfforts')\n onChange(next)\n }\n\n const toggleLevel = (level: string, checked: boolean): void => {\n const current = { ...(efforts ?? {}) }\n if (checked) current[level] = level === 'off' ? null : level\n else Reflect.deleteProperty(current, level)\n setEfforts(Object.keys(current).length === 0 ? undefined : current)\n }\n\n const setWireValue = (level: string, text: string): void => {\n if (efforts === undefined || !(level in efforts)) return\n const current = { ...efforts }\n current[level] = text.trim().length === 0 ? null : text.trim()\n setEfforts(current)\n }\n\n // --- validation (mirrors the host checks) --------------------------------\n const declaredLevels = efforts === undefined ? [] : THINKING_LEVELS.filter(level => level in efforts)\n const hasEmptyWire = declaredLevels.some(level =>\n level !== 'off' && String(efforts?.[level] ?? '').trim().length === 0)\n const onlyOffDeclared = efforts !== undefined\n && declaredLevels.length > 0\n && !declaredLevels.some(level => level !== 'off')\n\n // --- input modalities ------------------------------------------------------\n const inputList = inputsOf(model)\n const toggleModality = (modality: string, checked: boolean): void => {\n // Reading defaults to text-bearing rows; an explicit list wins.\n const base = inputList.length === 0 && model['input'] === undefined ? ['text'] : [...inputList]\n setInput(checked ? [...new Set([...base, modality])] : base.filter(m => m !== modality))\n }\n\n return (\n <div className={styles['extBlock']}>\n <div className={`${styles['extGroup']} ${styles['extGroupFirst']}`}>\n <QuickLoad onPick={applyMetadata} disabled={disabled} />\n </div>\n\n <div className={styles['extGroup']}>\n <div className={styles['modelField']} style={{ padding: '0 4px' }}>\n {capacityField('contextWindow', '上下文窗口')}\n {capacityField('maxTokens', '最大输出 token')}\n </div>\n </div>\n\n <div className={styles['extGroup']}>\n <span className={styles['extLabel']} style={{ marginBottom: 6 }}>输入模态</span>\n <div style={{ display: 'flex', gap: 18 }}>\n {['text', 'image'].map(modality => (\n <label key={modality} className={styles['switchRow']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={inputList.includes(modality)}\n disabled={disabled}\n onChange={(event) => { toggleModality(modality, event.target.checked) }}\n />\n {modality === 'text' ? '文本' : '图像'}\n </label>\n ))}\n </div>\n </div>\n\n <div className={styles['extGroup']}>\n <label className={styles['extCheck']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n style={{ marginTop: 3 }}\n checked={developerRole}\n disabled={disabled}\n onChange={(event) => {\n // Checked is the natural default, so a check REMOVES the key;\n // only an explicit uncheck writes `false`.\n setCompatKey('supportsDeveloperRole', event.target.checked ? undefined : false)\n }}\n />\n <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <span className={styles['extCheckLabel']}>允许以 developer 角色发送系统提示</span>\n <span className={styles['extHint']}>\n 推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。\n </span>\n </span>\n </label>\n </div>\n\n <div className={styles['extGroup']}>\n <label className={styles['switchRow']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={supportsReasoningEffort}\n disabled={disabled}\n onChange={(event) => { toggleGate(event.target.checked) }}\n />\n 端点接受推理挡位参数(reasoning_effort)\n </label>\n </div>\n\n {/* Gated area: HIDDEN (not dimmed) while the gate is off. */}\n <div className={styles['extGated']} hidden={!supportsReasoningEffort}>\n <div className={styles['extField']}>\n <span className={styles['extLabel']}>思考格式</span>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={typeof compat['thinkingFormat'] === 'string' ? compat['thinkingFormat'] : ''}\n disabled={disabled}\n onChange={(event) => { setCompatKey('thinkingFormat', event.target.value === '' ? undefined : event.target.value) }}\n >\n <option value=\"\">—</option>\n {THINKING_FORMATS.map(format => <option key={format} value={format}>{format}</option>)}\n </select>\n </div>\n\n <div className={styles['extField']}>\n <span className={styles['extLabel']}>推理挡位</span>\n <div className={styles['extTable']}>\n <div className={styles['extTHead']}>\n <div>声明</div><div>挡位</div><div>线上取值</div>\n </div>\n {THINKING_LEVELS.map((level) => {\n const declared = efforts !== undefined && level in efforts\n const isOff = level === 'off'\n const wire = declared ? String(efforts?.[level] ?? '') : ''\n return (\n <div key={level} className={styles['extTRow']}>\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={declared}\n disabled={disabled}\n aria-label={`声明 ${level}`}\n onChange={(event) => { toggleLevel(level, event.target.checked) }}\n />\n </div>\n <div style={{ opacity: declared ? 1 : 0.5 }}>{level}</div>\n <div style={{ opacity: declared ? 1 : 0.4 }}>\n {declared && !isOff\n ? (\n <input\n type=\"text\"\n value={wire}\n placeholder={level}\n aria-label={`${level} 线上取值`}\n disabled={disabled}\n onChange={(event) => { setWireValue(level, event.target.value) }}\n />\n )\n : <span style={{ fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' }}>—</span>}\n </div>\n </div>\n )\n })}\n </div>\n {hasEmptyWire || onlyOffDeclared\n ? (\n <p className={styles['error']} style={{ marginTop: 6 }}>\n {hasEmptyWire ? '除 off 外勾选的挡位必须填写线上取值。' : '至少声明一个 off 以外的挡位。'}\n </p>\n )\n : null}\n </div>\n </div>\n </div>\n )\n}\n\n","/**\n * One provider profile's model catalog: rows joined from the draft's `models`\n * array, the fetch action (interrogating the endpoint the form currently\n * shows), and the candidate-picker modal. Each row's expanded panel is the\n * plugin's ModelEntryPanel — capacities and extension fields in one block.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { LlmDiscoveredModel } from '@deepseek-ai/dsh-api-remotes/client'\nimport { Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ModelDraft } from './compat.ts'\nimport { newModelDraft } from './presets.ts'\nimport { ModelEntryPanel } from './ModelEntryPanel.tsx'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport styles from './models-plus.module.css'\n\n/** Endpoint facts for the fetch action, taken from the live form. */\nexport interface ProbeTarget {\n readonly settingsNs: string\n readonly provider?: string\n readonly baseURL?: string\n readonly api?: string\n readonly apiKey?: string\n}\n\n/** Props of {@link ModelCatalog}. */\nexport interface ModelCatalogProps {\n /** The drafted rows (inherited rows until the first edit materializes an override). */\n models: readonly ModelDraft[]\n /** Whether the user layer owns the whole array. */\n overridden: boolean\n /** DeepSeek-family route-level fallbacks (undefined on the pi-ai family). */\n defaultContextWindow: number | undefined\n defaultMaxTokens: number | undefined\n /** Endpoint facts for the fetch action. */\n probe: ProbeTarget\n /** Why the fetch action is unavailable, or undefined when it is. */\n probeBlocked?: string\n /** The Host operations whose interrogation answers the fetch action. */\n operations: ModelsOperations\n /** Disable every control (read-only deployment or a pending write). */\n disabled: boolean\n /** Replace the drafted rows. */\n onChange: (models: ModelDraft[]) => void\n /** Remove the user-owned array and return to inheritance. */\n onReset?: () => void\n}\n\n/** A row's text field, or the empty string when unset or not a string. */\nfunction textOf(model: ModelDraft, key: string): string {\n const value = model[key]\n return typeof value === 'string' ? value : ''\n}\n\n/** Adopt one candidate, v1.0.0 defaults + the endpoint's disclosed capacities. */\nfunction adopt(candidate: LlmDiscoveredModel): ModelDraft {\n const row = newModelDraft()\n row['id'] = candidate.id\n row['name'] = candidate.name ?? candidate.id\n if (candidate.contextWindow !== undefined) row['contextWindow'] = candidate.contextWindow\n if (candidate.maxTokens !== undefined) row['maxTokens'] = candidate.maxTokens\n return row\n}\n\n/**\n * Render the model catalog with its fetch action.\n * @param props - the drafted rows, probe target, wire face, and mutators.\n * @returns the catalog editor.\n */\nexport function ModelCatalog(props: ModelCatalogProps): ReactNode {\n const { models, onChange, probe, operations, disabled } = props\n\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n const [candidates, setCandidates] = useState<readonly LlmDiscoveredModel[] | undefined>(undefined)\n const [picked, setPicked] = useState<ReadonlySet<string>>(() => new Set())\n const [query, setQuery] = useState('')\n const [expanded, setExpanded] = useState<ReadonlySet<number>>(() => new Set())\n\n const patch = (index: number, next: Record<string, string | number | undefined>): void => {\n onChange(models.map((model, at) => {\n if (at !== index) return model\n const cleared = new Set(\n Object.entries(next).filter(([, value]) => value === undefined || value === '').map(([key]) => key),\n )\n return Object.fromEntries(\n Object.entries({ ...model, ...next }).filter(([key]) => !cleared.has(key)),\n )\n }))\n }\n\n const toggleExpanded = (index: number): void => {\n setExpanded((current) => {\n const next = new Set(current)\n if (!next.delete(index)) next.add(index)\n return next\n })\n }\n\n const removeRow = (index: number): void => {\n onChange(models.filter((_model, at) => at !== index))\n // Both stores are keyed by position; shift the rows after this one down.\n setExpanded((current) => {\n const next = new Set<number>()\n for (const at of current) {\n if (at < index) next.add(at)\n else if (at > index) next.add(at - 1)\n }\n return next\n })\n }\n\n const fetchModels = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const answer = await operations.discoverModels(probe.settingsNs, {\n ...probe.provider === undefined ? {} : { provider: probe.provider },\n ...probe.baseURL === undefined || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },\n ...probe.api === undefined ? {} : { api: probe.api },\n ...probe.apiKey === undefined ? {} : { apiKey: probe.apiKey },\n })\n if (answer.kind === 'refused') {\n setFailure(answer.message)\n return\n }\n const found = answer.models\n if (found.length === 0) {\n setFailure('该提供方没有列出任何模型,请手动添加。')\n return\n }\n const known = new Set(models.map(model => textOf(model, 'id')))\n setQuery('')\n setCandidates(found)\n setPicked(new Set(found.filter(model => !known.has(model.id)).map(model => model.id)))\n } finally {\n setBusy(false)\n }\n }\n\n const closePicker = (): void => {\n setCandidates(undefined)\n setPicked(new Set())\n setQuery('')\n }\n\n const adoptPicked = (): void => {\n if (candidates === undefined) return\n const byId = new Map(models.map(model => [textOf(model, 'id'), model]))\n for (const candidate of candidates) {\n if (!picked.has(candidate.id)) continue\n // A row the user already tuned wins over the provider's own numbers.\n byId.set(candidate.id, byId.get(candidate.id) ?? adopt(candidate))\n }\n onChange([...byId.values()])\n closePicker()\n }\n\n const toggle = (id: string): void => {\n setPicked((current) => {\n const next = new Set(current)\n if (!next.delete(id)) next.add(id)\n return next\n })\n }\n\n const activeCandidates = candidates ?? []\n const needle = query.trim().toLowerCase()\n const visible = needle.length === 0\n ? activeCandidates\n : activeCandidates.filter(candidate => candidate.id.toLowerCase().includes(needle))\n const allPicked = visible.length > 0 && visible.every(candidate => picked.has(candidate.id))\n\n // A route the adapter already describes answers without an endpoint.\n const askable = probe.provider !== undefined || (probe.baseURL !== undefined && probe.baseURL.length > 0)\n\n return (\n <section className={styles['modelCatalog']} aria-label=\"模型目录\">\n <div className={styles['modelListHead']}>\n <div className={styles['modelCatalogHeading']}>\n <span className={styles['modelCatalogTitle']}>模型目录</span>\n <span className={styles['modelCatalogMeta']}>\n {props.overridden ? '已自定义模型目录' : '正在使用适配器默认模型'}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {props.overridden && props.onReset !== undefined\n ? (\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={disabled}\n onClick={props.onReset}\n >\n 恢复默认模型\n </button>\n )\n : null}\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={disabled || busy || !askable || props.probeBlocked !== undefined}\n title={props.probeBlocked !== undefined\n ? props.probeBlocked\n : askable ? undefined : '请先填写 API 地址,再获取。'}\n onClick={() => { void fetchModels() }}\n >\n {busy ? '正在询问提供方…' : '获取可用模型'}\n </button>\n </div>\n </div>\n\n {models.length === 0\n ? <p className={styles['modelEmpty']}>模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。</p>\n : (\n <div className={styles['modelList']}>\n {models.map((model, index) => (\n <div\n key={`${String(index)}:${textOf(model, 'id')}`}\n className={styles['modelEntry']}\n >\n <div className={styles['modelRow']}>\n <input\n className={styles['input']}\n type=\"text\"\n value={textOf(model, 'id')}\n placeholder=\"模型 ID\"\n aria-label={`模型 ID ${String(index + 1)}`}\n disabled={disabled}\n onChange={(event) => { patch(index, { id: event.target.value }) }}\n />\n <input\n className={styles['input']}\n type=\"text\"\n value={textOf(model, 'name')}\n placeholder=\"显示名称\"\n aria-label={`显示名称 ${String(index + 1)}`}\n disabled={disabled}\n onChange={(event) => { patch(index, { name: event.target.value === '' ? undefined : event.target.value }) }}\n />\n <button\n type=\"button\"\n className={styles['iconButton']}\n aria-label={`容量 ${String(index + 1)}`}\n aria-expanded={expanded.has(index)}\n title=\"容量\"\n onClick={() => { toggleExpanded(index) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\" style={{ transform: expanded.has(index) ? 'rotate(90deg)' : undefined, transition: 'transform 120ms ease' }}>\n <path d=\"M6 3.5L10.5 8L6 12.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n className={`${styles['iconButton']} ${styles['iconButtonDanger']}`}\n aria-label={`删除模型 ${String(index + 1)}`}\n title=\"删除模型\"\n disabled={disabled}\n onClick={() => { removeRow(index) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2.5 4h11M6.5 4V2.5h3V4M4 4l.7 9a1 1 0 001 .9h4.6a1 1 0 001-.9L12 4M6.5 6.8v4.4M9.5 6.8v4.4\" stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n {expanded.has(index)\n ? (\n <ModelEntryPanel\n model={model}\n disabled={disabled}\n onChange={(next) => {\n onChange(models.map((row, at) => (at === index ? next : row)))\n }}\n />\n )\n : null}\n </div>\n ))}\n </div>\n )}\n\n <button\n type=\"button\"\n className={styles['addModelButton']}\n disabled={disabled}\n onClick={() => { onChange([...models, newModelDraft()]) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加模型\n </button>\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n\n <Modal\n open={candidates !== undefined}\n onClose={closePicker}\n title=\"选择要添加的模型\"\n closeLabel=\"关闭\"\n description=\"以下是模型提供方的可用模型,勾选要添加的模型。\"\n className={styles['fetchDialog'] as string}\n footer={(\n <>\n <button type=\"button\" className={styles['secondaryButton']} onClick={closePicker}>取消</button>\n <button type=\"button\" className={styles['primaryButton']} onClick={adoptPicked}>添加所选</button>\n </>\n )}\n >\n <div className={styles['candidateToolbar']}>\n <input\n className={`${styles['input']} ${styles['candidateSearch']}`}\n type=\"search\"\n value={query}\n placeholder=\"搜索模型\"\n aria-label=\"搜索模型\"\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={visible.length === 0}\n onClick={() => {\n setPicked(current => {\n if (visible.every(candidate => current.has(candidate.id))) {\n return new Set([...current].filter(id => !visible.some(candidate => candidate.id === id)))\n }\n return new Set([...current, ...visible.map(candidate => candidate.id)])\n })\n }}\n >\n {allPicked ? '取消全选' : '全选'}\n </button>\n </div>\n {visible.length === 0\n ? <p className={styles['candidateEmpty']} role=\"status\">没有匹配的模型。</p>\n : (\n <ul className={styles['candidateList']}>\n {visible.map(candidate => (\n <li key={candidate.id} className={styles['candidate']}>\n <label className={styles['candidateLabel']}>\n <input\n type=\"checkbox\"\n checked={picked.has(candidate.id)}\n onChange={() => { toggle(candidate.id) }}\n />\n <span className={styles['candidateId']}>{candidate.id}</span>\n </label>\n </li>\n ))}\n </ul>\n )}\n </Modal>\n </section>\n )\n}\n\n","/**\n * One existing provider's editor card, fully plugin-owned (v1.0.0 rewrite).\n * Primary field: a single write-only API key input; the collapsed\n * 「供应商」 section carries baseURL (plus displayName/protocol for a\n * hand-declared route), the 「模型」 section the model catalog with the\n * extension panel. Save semantics mirror the host card: minimal path ops\n * against the stored section with a revision fence, then the credential\n * write — the draft comes from the user layer, so a wholesale replace can\n * never delete fields outside the card.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CredentialInfo, SettingsNamespaceView } from '@deepseek-ai/dsh-api-remotes/client'\nimport { deriveKeyRef, protocolChoices } from '../vendor/store.ts'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport type { SettingsSchemaOperations } from '../vendor/schema-operations.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { modelDrafts, normalizeModelRow, pathOps, validateModelRows } from './compat.ts'\nimport { ModelCatalog } from './ModelCatalog.tsx'\nimport styles from './models-plus.module.css'\n\n/** The public DeepSeek endpoint shown as the deepseek base-URL placeholder. */\nconst DEEPSEEK_PUBLIC_BASE_URL = 'https://api.deepseek.com'\n\n/** Per-adapter-family curated field sets (unknown namespaces get the hint alone). */\nexport type EditorLayout = 'deepseek' | 'pi-ai' | 'unknown'\n\n/** The editor layout the owning namespace selects. */\nexport function layoutOf(ns: string): EditorLayout {\n if (ns === 'llm-deepseek') return 'deepseek'\n if (ns === 'llm-pi-ai') return 'pi-ai'\n return 'unknown'\n}\n\n/** A user-section subtree as a plain draft object (absent → empty). */\nexport function draftAt(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n): Record<string, unknown> {\n const subtree = schema.getPath(namespace.user, path)\n if (typeof subtree !== 'object' || subtree === null || Array.isArray(subtree)) return {}\n return structuredClone(subtree) as Record<string, unknown>\n}\n\n/** The credential reference this profile resolves keys through. */\nfunction refFor(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n provider: string,\n): string {\n const profile = schema.getPath(namespace.value, path)\n const named = typeof profile === 'object' && profile !== null\n ? (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n : undefined\n return typeof named === 'string' && named.length > 0 ? named : deriveKeyRef(provider)\n}\n\n/** Props of {@link ProviderEditor}. */\nexport interface ProviderEditorProps {\n /** Provider route id. */\n provider: string\n /** Display name for the card title. */\n displayName: string\n /** Whether the adapter reports this route as hand-declared. */\n declared?: boolean\n /** The owning namespace view (schema, layers, secrets). */\n namespace: SettingsNamespaceView\n /** Settings-owned synchronous schema and immutable path operations. */\n schema: SettingsSchemaOperations\n /** Path from the section root to this provider's profile. */\n settingsPath: readonly string[]\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the editor; `changed` reports whether an Apply committed. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render one existing provider's editing card.\n * @param props - the addressed profile plus wire faces.\n * @returns the editor card.\n */\nexport function ProviderEditor(props: ProviderEditorProps): ReactNode {\n const { namespace, schema, settingsPath, operations } = props\n const [draft, setDraft] = useState<Record<string, unknown>>(() => draftAt(schema, namespace, settingsPath))\n const [tab, setTab] = useState<'provider' | 'models'>('provider')\n const [keyDraft, setKeyDraft] = useState('')\n const [keyState, setKeyState] = useState<CredentialInfo | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n const [committedOriginal, setCommittedOriginal] = useState<unknown>(\n () => schema.getPath(namespace.user, settingsPath),\n )\n const [expectedRevision, setExpectedRevision] = useState(() => namespace.revision)\n const root = useMemo(() => schema.rehydrate(namespace.schema), [namespace.schema, schema])\n const node = useMemo(() => schema.nodeAtPath(root, settingsPath), [root, schema, settingsPath])\n const fallback = schema.getPath(namespace.value, settingsPath)\n const disabled = props.readOnly || busy\n const layout = layoutOf(namespace.ns)\n const keyRef = refFor(schema, namespace, settingsPath, props.provider)\n const protocols = useMemo(\n () => layout === 'pi-ai' ? protocolChoices(namespace, schema) : [],\n [layout, namespace, schema],\n )\n\n useEffect(() => {\n let stale = false\n setKeyState(undefined)\n void operations.describeCredential(keyRef).then((described) => {\n if (stale) return\n setKeyState(described)\n })\n return () => { stale = true }\n }, [operations, keyRef])\n\n const stringAt = (source: unknown, key: string): string | undefined => {\n const value = schema.getPath(source, [key])\n return typeof value === 'string' && value.trim().length > 0 ? value : undefined\n }\n const setField = (key: string, next: string | undefined): void => {\n const value = next === undefined || next.trim().length === 0 ? undefined : next\n setDraft((current) => value === undefined\n ? schema.deletePath(current, [key])\n : schema.setPath(current, [key], value))\n }\n\n const modelFailure = validateModelRows(schema.getPath(draft, ['models']))\n const keyFailure = ((): 'keyBlank' | 'keyIllegalCharacters' | undefined => {\n if (keyDraft.length === 0) return undefined\n const value = keyDraft.trim()\n if (value.length === 0) return 'keyBlank'\n // Mirrors the host's apiKeyFailure heuristics (env line / quoted / charset).\n if (/^[A-Z][A-Z0-9_]*=[^=]/.test(value)) return 'keyIllegalCharacters'\n const first = value[0]\n if ((first === '\"' || first === '\\'' || first === '`') && value.length > 1 && value.endsWith(first)) {\n return 'keyIllegalCharacters'\n }\n return /^[\\x21-\\x7E]+$/.test(value) ? undefined : 'keyIllegalCharacters'\n })()\n const keyValue = keyDraft.trim()\n\n const probe = {\n settingsNs: namespace.ns,\n provider: props.provider,\n ...(() => {\n const baseURL = stringAt(draft, 'baseURL') ?? stringAt(fallback, 'baseURL')\n return baseURL === undefined ? {} : { baseURL }\n })(),\n ...(() => {\n const api = layout === 'pi-ai' && props.declared === true\n ? stringAt(draft, 'api') ?? stringAt(fallback, 'api')\n : undefined\n return api === undefined ? {} : { api }\n })(),\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }\n\n /** The write for this card, or a failure message. */\n const applyOnce = async (): Promise<string | undefined> => {\n const ns = namespace.ns\n let next = layout === 'pi-ai' && stringAt(draft, 'apiKeyEnv') === undefined\n && stringAt(fallback, 'apiKeyEnv') === undefined && keyValue.length > 0\n ? schema.setPath(draft, ['apiKeyEnv'], keyRef)\n : draft\n const rowFailure = validateModelRows(schema.getPath(next, ['models']))\n if (rowFailure !== undefined) {\n return `模型 ${String(rowFailure.index + 1)}:${{\n modelIdRequired: '模型 ID 不能为空。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n }[rowFailure.key]}`\n }\n if (node !== undefined && settingsPath.length === 0) {\n const sectionError = schema.validate(node, next)\n if (sectionError !== undefined) return sectionError\n }\n // Stable YAML key order: normalize every drafted row before diffing.\n if (schema.hasPath(next, ['models'])) {\n next = schema.setPath(\n next,\n ['models'],\n modelDrafts(schema.getPath(next, ['models'])).map(normalizeModelRow),\n )\n }\n // Official semantic: a pi-ai route whose only act is activating the route\n // (no fields the card can see, no key yet) still writes an empty profile\n // so the route exists in the directory at all.\n const materializesNativeProfile = layout === 'pi-ai'\n && fallback === undefined\n && committedOriginal === undefined\n && Object.keys(next).length === 0\n const ops = materializesNativeProfile\n ? [{ op: 'set', path: [...settingsPath], value: {} }]\n : pathOps(settingsPath, committedOriginal, next)\n if (ops.length > 0) {\n const written = await operations.writeSettings(ns, ops, expectedRevision)\n if (written.kind !== 'written') return written.kind === 'conflict'\n ? '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。'\n : written.message\n setCommittedOriginal(schema.getPath(written.view.user, settingsPath))\n setExpectedRevision(written.view.revision)\n setDraft(next)\n }\n if (keyValue.length > 0) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n setKeyDraft('')\n return undefined\n }\n\n const apply = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const applyFailure = await applyOnce()\n if (applyFailure !== undefined) {\n setFailure(applyFailure)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n if (node === undefined) {\n return <p className={styles['error']}>{props.provider}: 无法解析设置路径</p>\n }\n\n /**\n * The catalog beneath the user layer: the composition entry's pin, or the\n * schema default — reading the effective value would echo the stored\n * override back the moment reset drops it.\n */\n const inheritedModels = (): unknown => {\n const pinned = schema.getPath(namespace.base, [...settingsPath, 'models'])\n return pinned ?? schema.nodeAtPath(root, [...settingsPath, 'models'])?.meta.default\n }\n const customModels = schema.getPath(draft, ['models'])\n const modelsOverridden = schema.hasPath(draft, ['models'])\n const models = modelDrafts(modelsOverridden ? customModels : inheritedModels())\n const defaultContextWindow = schema.getPath(fallback, ['defaultContextWindow'])\n const defaultMaxTokens = schema.getPath(fallback, ['maxTokens'])\n\n const keyPlaceholder = keyState?.writable === false\n ? '由启动环境提供(只读)'\n : keyState?.configured === true\n ? '已配置——输入新值可替换'\n : layout === 'pi-ai' && props.declared === true\n ? '输入 API 密钥,或留空使用环境认证'\n : '输入 API 密钥'\n const keyLocked = keyState?.writable === false\n\n return (\n <div className={styles['editor']}>\n {layout === 'unknown'\n ? <p className={styles['advancedHint']}>其余字段存于 settings.yaml;请直接编辑对应段。({namespace.ns})</p>\n : (\n <>\n <div className={styles['tabs']}>\n <div className={styles['tabBar']} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'provider'} className={tab === 'provider' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('provider') }}>供应商</button>\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'models'} className={tab === 'models' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('models') }}>模型</button>\n </div> <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'provider'}>\n {layout === 'pi-ai' && props.declared === true\n ? (\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>显示名称</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'displayName') ?? ''}\n placeholder={stringAt(schema.getPath(namespace.base, settingsPath), 'displayName')\n ?? props.provider}\n aria-label=\"显示名称\"\n disabled={disabled}\n onChange={(event) => { setField('displayName', event.target.value) }}\n />\n </div>\n )\n : null}\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 密钥</label>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder={keyPlaceholder}\n aria-label=\"API 密钥\"\n disabled={disabled || keyLocked}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{keyFailure === 'keyBlank' ? '请输入 API 密钥;留空则保持已存储的密钥。' : '此 API 密钥格式无效,请检查。'}</p>}\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 地址</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'baseURL') ?? ''}\n placeholder={layout === 'deepseek'\n ? DEEPSEEK_PUBLIC_BASE_URL\n : stringAt(fallback, 'baseURL') ?? '提供方默认'}\n aria-label=\"API 地址\"\n disabled={disabled}\n onChange={(event) => { setField('baseURL', event.target.value === '' ? undefined : event.target.value) }}\n />\n </div>\n {layout === 'pi-ai' && props.declared === true\n ? (\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 协议</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={stringAt(draft, 'api') ?? stringAt(fallback, 'api') ?? ''}\n aria-label=\"API 协议\"\n disabled={disabled}\n onChange={(event) => { setField('api', event.target.value) }}\n >\n {(stringAt(draft, 'api') ?? stringAt(fallback, 'api')) === undefined\n ? <option value=\"\">未选择</option>\n : null}\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n )\n : null}\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'models'}>\n <ModelCatalog\n models={models}\n overridden={modelsOverridden}\n defaultContextWindow={typeof defaultContextWindow === 'number' ? defaultContextWindow : undefined}\n defaultMaxTokens={typeof defaultMaxTokens === 'number' ? defaultMaxTokens : undefined}\n probe={probe}\n probeBlocked={keyFailure}\n operations={operations}\n disabled={disabled}\n onChange={(rows: ModelDraft[]) => {\n setDraft(current => schema.setPath(current, ['models'], rows))\n }}\n onReset={() => { setDraft(current => schema.deletePath(current, ['models'])) }}\n />\n </div>\n </div>\n </>\n )}\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {modelFailure === undefined\n ? null\n : (\n <p className={styles['advancedHint']}>\n {`模型 ${String(modelFailure.index + 1)}:${modelFailure.key}`}\n </p>\n )}\n\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={busy}\n onClick={() => { props.onClose(false) }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={disabled || layout === 'unknown' || modelFailure !== undefined\n || keyFailure !== undefined}\n onClick={() => { void apply() }}\n >\n {busy ? '保存中…' : '保存'}\n </button>\n </div>\n </div>\n )\n}\n","/**\n * The card that declares a provider pi-ai does not ship — an OpenAI-compatible\n * gateway, a self-hosted server, or a provider newer than the installed\n * catalog. One `settings.mutate` sets the whole profile at `providers.<route>`;\n * the key travels separately through `credentials/set` under the reference\n * the profile records. The three fields a hand-declared route cannot default\n * (endpoint, protocol, at least one model) are required here.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport { deriveKeyRef } from '../vendor/store.ts'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { normalizeModelRow, validateModelRows } from './compat.ts'\nimport { ModelCatalog } from './ModelCatalog.tsx'\nimport styles from './models-plus.module.css'\n\n/** The settings namespace a hand-declared provider is written into. */\nconst NS = 'llm-pi-ai'\n\n/**\n * A route id usable as a settings key AND as the stem of a credential name.\n */\nconst ROUTE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\n\n/** Props of {@link CreateProviderCard}. */\nexport interface CreateProviderCardProps {\n /** Route ids already declared, so the card refuses to shadow one. */\n taken: readonly string[]\n /** Wire protocols the adapter can serve, in the order it reports them. */\n protocols: readonly string[]\n /** Revision of the `llm-pi-ai` user section this card opened at. */\n revision: number\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the card; `changed` reports whether a provider was created. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render the custom-provider creation card.\n * @param props - existing routes, protocol choices, wire faces.\n * @returns the creation card.\n */\nexport function CreateProviderCard(props: CreateProviderCardProps): ReactNode {\n const { taken, protocols, operations } = props\n const [openedAt] = useState(() => props.revision)\n const [route, setRoute] = useState('')\n const [displayName, setDisplayName] = useState('')\n const [baseURL, setBaseURL] = useState('')\n const [protocol, setProtocol] = useState(protocols[0] ?? '')\n const [tab, setTab] = useState<'provider' | 'models'>('provider')\n const [keyDraft, setKeyDraft] = useState('')\n const [models, setModels] = useState<readonly ModelDraft[]>([])\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n /** The profile write landed; only the key write can still be outstanding. */\n const [committed, setCommitted] = useState(false)\n const disabled = props.readOnly || busy\n const profileDisabled = disabled || committed\n\n const routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route)\n const routeTaken = taken.includes(route)\n const modelFailure = validateModelRows(models)\n const keyFailure = ((): 'keyBlank' | 'keyIllegalCharacters' | undefined => {\n if (keyDraft.length === 0) return undefined\n const value = keyDraft.trim()\n if (value.length === 0) return 'keyBlank'\n if (/^[A-Z][A-Z0-9_]*=[^=]/.test(value)) return 'keyIllegalCharacters'\n const first = value[0]\n if ((first === '\"' || first === '\\'' || first === '`') && value.length > 1 && value.endsWith(first)) {\n return 'keyIllegalCharacters'\n }\n return /^[\\x21-\\x7E]+$/.test(value) ? undefined : 'keyIllegalCharacters'\n })()\n const keyValue = keyDraft.trim()\n const ready = route.length > 0 && !routeInvalid && !routeTaken\n && baseURL.length > 0 && models.length > 0 && modelFailure === undefined\n && keyFailure === undefined\n const hint = failure !== undefined || ready || keyFailure !== undefined\n || route.length === 0 || routeInvalid || routeTaken\n ? undefined\n : baseURL.length === 0\n ? '自定义提供方需要填写 API 地址。'\n : modelFailure !== undefined\n ? `模型 ${String(modelFailure.index + 1)}:${modelFailure.key}`\n : '自定义提供方至少需要一个模型。'\n\n /** Perform the create, returning a failure message or undefined. */\n const createOnce = async (): Promise<string | undefined> => {\n const keyRef = deriveKeyRef(route)\n const storesKey = keyValue.length > 0\n if (!committed) {\n const profile = {\n ...displayName.length === 0 ? {} : { displayName },\n ...storesKey ? { apiKeyEnv: keyRef } : {},\n api: protocol,\n baseURL,\n models: models.map(normalizeModelRow),\n }\n const written = await operations.writeSettings(\n NS,\n [{ op: 'set', path: ['providers', route], value: profile as JsonValue }],\n openedAt,\n )\n if (written.kind !== 'written') {\n return written.kind === 'conflict'\n ? '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。'\n : written.message\n }\n // A retry after a failed key write must not re-run this mutate.\n setCommitted(true)\n }\n if (storesKey) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n return undefined\n }\n\n const create = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const outcome = await createOnce()\n if (outcome !== undefined) {\n setFailure(outcome)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <div className={styles['editor']}>\n <div className={styles['field']} style={{ paddingTop: 12, borderTop: '0.5px solid var(--dsw-alias-border-l2)' }}>\n <label className={styles['fieldLabel']}>Provider ID</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={route}\n placeholder=\"acme-gateway\"\n aria-label=\"Provider ID\"\n disabled={profileDisabled}\n onChange={(event) => { setRoute(event.target.value) }}\n />\n {routeInvalid || routeTaken\n ? <p className={styles['error']}>{routeInvalid ? '需以小写字母开头,之后可用小写字母、数字和短横线。' : '已有提供方使用了这个 ID。'}</p>\n : <p className={styles['advancedHint']}>以小写字母开头的标识,在请求中唯一标识该提供方,并用于派生凭据名。</p>}\n </div>\n\n <div className={styles['tabs']}>\n <div className={styles['tabBar']} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'provider'} className={tab === 'provider' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('provider') }}>供应商</button>\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'models'} className={tab === 'models' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('models') }}>模型</button>\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'provider'}>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>显示名称</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={displayName}\n placeholder={route.length === 0 ? '显示名称' : route}\n aria-label=\"显示名称\"\n disabled={profileDisabled}\n onChange={(event) => { setDisplayName(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 地址</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={baseURL}\n placeholder=\"https://gateway.example/v1\"\n aria-label=\"API 地址\"\n disabled={profileDisabled}\n onChange={(event) => { setBaseURL(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 协议</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={protocol}\n aria-label=\"API 协议\"\n disabled={profileDisabled}\n onChange={(event) => { setProtocol(event.target.value) }}\n >\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 密钥</label>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder=\"输入 API 密钥,或留空使用环境认证\"\n aria-label=\"API 密钥\"\n disabled={disabled}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{keyFailure === 'keyBlank' ? '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。' : '此 API 密钥格式无效,请检查。'}</p>}\n </div>\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'models'}>\n <ModelCatalog\n models={models}\n overridden={true}\n defaultContextWindow={undefined}\n defaultMaxTokens={undefined}\n probe={{\n settingsNs: NS,\n baseURL,\n api: protocol,\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }}\n probeBlocked={keyFailure === 'keyBlank' ? '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。' : keyFailure}\n operations={operations}\n disabled={profileDisabled}\n onChange={setModels}\n />\n </div>\n </div>\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {hint === undefined ? null : <p className={styles['advancedHint']}>{hint}</p>}\n\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={busy}\n onClick={() => { props.onClose(committed) }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={disabled || !ready}\n onClick={() => { void create() }}\n >\n {busy ? '创建中…' : '创建提供方'}\n </button>\n </div>\n </div>\n )\n}\n\n","/**\n * The Models+ settings section (v1.0.0, fully plugin-owned UI): provider rows\n * joined from the configurable directory, settings namespaces, and credential\n * states, one editor card at a time. The title row carries the adapter badge\n * and the metadata download button — the only place models.dev data is ever\n * fetched, on an explicit user click.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ModelsSettingsStore, ProviderRow } from '../vendor/store.ts'\nimport { deriveKeyRef, protocolChoices, providerUsable } from '../vendor/store.ts'\nimport type { ModelsOperations } from './operations.ts'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\nimport { downloadMetadata } from './models-index.ts'\nimport { ProviderEditor } from './ProviderEditor.tsx'\nimport { CreateProviderCard } from './CreateProviderCard.tsx'\nimport styles from './models-plus.module.css'\n\n/** One existing row or dormant directory entry addressed by an editor action. */\nexport interface EditorTarget {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n /** Writable credential identified under this page's conventional reference. */\n credentialRef?: string\n readonly declared?: boolean\n}\n\n/** Injected dependencies of {@link ModelsPlusSection} (slot `inject`). */\nexport interface ModelsPlusInjected {\n controller: ModelsSettingsStore\n hooks: {\n snapshot: ModelsSettingsStore['store']\n }\n operations: ModelsOperations\n schema: SettingsSchemaOperations\n t: (key: string) => string\n}\n\n/** One fact decides the first-run posture: whether any provider is usable. */\nfunction needsSetup(row: ProviderRow, anyUsable: boolean): boolean {\n if (anyUsable) return false\n if (row.entry.settingsPath.length > 0) return false\n return row.credential?.configured !== true\n}\n\n/** The credential reference a row resolves keys through, confirmed configured. */\nfunction keyConfiguredOf(row: ProviderRow): boolean {\n return row.apiKeyEnv !== undefined\n ? row.credential?.configured === true\n : row.derivedCredential?.configured === true\n}\n\nfunction targetOf(row: ProviderRow): EditorTarget {\n const managedRef = deriveKeyRef(row.entry.provider)\n const credentialRef = row.apiKeyEnv === managedRef\n && row.credential?.configured === true\n && row.credential.writable\n ? managedRef\n : undefined\n return {\n provider: row.entry.provider,\n displayName: row.entry.displayName,\n settingsNs: row.entry.settingsNs,\n settingsPath: row.entry.settingsPath,\n ...credentialRef === undefined ? {} : { credentialRef },\n ...row.entry.declared === true ? { declared: true } : {},\n }\n}\n\n/**\n * Remove one user-added provider and its page-managed credential. Credential\n * removal comes first so a second-step failure leaves the row retryable.\n */\nasync function removeProviderProfile(\n operations: ModelsOperations,\n controller: ModelsSettingsStore,\n target: { settingsNs: string; settingsPath: readonly string[]; credentialRef?: string },\n): Promise<string | undefined> {\n if (target.credentialRef !== undefined) {\n const credential = await operations.removeCredential(target.credentialRef)\n if (credential !== undefined) return credential\n }\n const written = await operations.writeSettings(\n target.settingsNs,\n [{ op: 'unset', path: [...target.settingsPath] }],\n undefined,\n )\n if (written.kind !== 'written') return written.message\n await controller.load()\n return undefined\n}\n\n/** Replace the one provider placeholder in localized destructive copy. */\nfunction providerCopy(template: string, target: { displayName: string; provider: string }): string {\n const label = target.provider === target.displayName\n ? target.provider\n : `${target.displayName} (${target.provider})`\n return template.replace('{provider}', () => label)\n}\n\n/**\n * Render the Models+ section content column.\n * @param props - slot-delivered injected dependencies.\n * @returns the section, or null while the shell has not injected yet.\n */\nexport function ModelsPlusSection(props: {\n controller?: ModelsPlusInjected['controller']\n useSnapshot?: ModelsPlusInjected['hooks']['snapshot']\n operations?: ModelsPlusInjected['operations']\n schema?: ModelsPlusInjected['schema']\n t?: ModelsPlusInjected['t']\n}): ReactNode {\n const { controller, useSnapshot, operations, schema, t } = props\n if (\n controller === undefined || useSnapshot === undefined || operations === undefined\n || schema === undefined || t === undefined\n ) return null\n // Hooks live in the Loaded child (mirrors the host section): the null check\n // above must not change this component's hook count between renders.\n return <Loaded injected={{ controller, useSnapshot, operations, schema, t }} />\n}\n\nfunction Loaded({ injected }: { injected: ModelsPlusInjected }): ReactNode {\n const { controller, operations, schema, t } = injected\n const useSnapshot = injected.useSnapshot\n\n const state = useSnapshot(snapshot => snapshot)\n const [editing, setEditing] = useState<EditorTarget | undefined>(undefined)\n const [adding, setAdding] = useState(false)\n const [declaring, setDeclaring] = useState(false)\n const [deleteTarget, setDeleteTarget] = useState<EditorTarget | undefined>(undefined)\n const [deleting, setDeleting] = useState(false)\n const [deleteFailure, setDeleteFailure] = useState<string | undefined>(undefined)\n const [savedTarget, setSavedTarget] = useState<{ displayName: string; provider: string } | undefined>(undefined)\n const [dismissedSetup, setDismissedSetup] = useState<ReadonlySet<string>>(() => new Set())\n const [metaBusy, setMetaBusy] = useState(false)\n const [metaMessage, setMetaMessage] = useState<{ ok: boolean; text: string } | undefined>(undefined)\n\n const announceSaved = (target: { displayName: string; provider: string }): void => {\n void controller.load().then(() => { setSavedTarget(target) })\n }\n\n const closeEditor = (changed: boolean, target: { displayName: string; provider: string }): void => {\n setEditing(undefined)\n setAdding(false)\n setDeclaring(false)\n if (changed) announceSaved(target)\n }\n\n const closeSetup = (changed: boolean, target: { displayName: string; provider: string }): void => {\n setDismissedSetup(previous => new Set([...previous, target.provider]))\n if (changed) announceSaved(target)\n }\n\n const downloadMeta = async (): Promise<void> => {\n setMetaBusy(true)\n setMetaMessage(undefined)\n try {\n const outcome = await downloadMetadata()\n setMetaMessage(outcome.ok\n ? { ok: true, text: 'models.dev 元数据已下载并就绪。' }\n : { ok: false, text: `元数据下载失败:${outcome.message}` })\n } finally {\n setMetaBusy(false)\n }\n }\n\n if (state.status === 'idle') void controller.load()\n if (state.status === 'error') {\n const errorText = state.error ?? ''\n return (\n <div className={styles['section']}>\n <p className={styles['error']}>{`加载提供方目录失败: ${errorText}`}</p>\n <button type=\"button\" className={styles['secondaryButton']} onClick={() => { void controller.load() }}>\n 重试\n </button>\n </div>\n )\n }\n\n const savedRow = savedTarget === undefined\n ? undefined\n : state.rows.find(row => row.entry.provider === savedTarget.provider)\n const savedIdentity = savedRow === undefined\n ? savedTarget\n : { displayName: savedRow.entry.displayName, provider: savedRow.entry.provider }\n\n const anyUsable = state.rows.some(providerUsable)\n const configured = state.rows.filter(row => row.configured)\n // Mirrors the host page @ 0.1.5-alpha.2: a row is addable only when its\n // settings namespace actually resolved — a namespace name the settings\n // document does not carry would open a card that can never save.\n const configurable = state.rows.filter(row => state.namespaces.has(row.entry.settingsNs))\n const addable = configurable.filter(row => !row.configured)\n const addTarget = adding ? editing : undefined\n const addNamespace = addTarget === undefined ? undefined : state.namespaces.get(addTarget.settingsNs)\n const protocols = (() => {\n // The protocol choices a hand-declared route may name (schema read).\n return protocolChoices(state.namespaces.get('llm-pi-ai'), schema)\n })()\n\n const renderEditor = (\n target: EditorTarget,\n namespace: Parameters<typeof ProviderEditor>[0]['namespace'] | undefined,\n onClose: (changed: boolean) => void,\n ): ReactNode => {\n if (namespace === undefined) return null\n return (\n <ProviderEditor\n provider={target.provider}\n displayName={target.displayName}\n settingsPath={target.settingsPath}\n {...target.declared === true ? { declared: true } : {}}\n namespace={namespace}\n schema={schema}\n operations={operations}\n readOnly={!state.writable}\n onClose={onClose}\n />\n )\n }\n\n return (\n <div className={styles['section']}>\n {/* Title row: heading + metadata download button */}\n <div className={styles['titleRow']}>\n <h2 className={styles['title']}>{t('nav')}</h2>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={metaBusy}\n title=\"下载/更新 models.dev 元数据(供快速装入预填)\"\n onClick={() => { void downloadMeta() }}\n >\n {metaBusy ? '正在下载元数据…' : '下载/更新元数据'}\n </button>\n </span>\n </div>\n {metaMessage === undefined\n ? null\n : <p className={metaMessage.ok ? styles['savedNotice'] : styles['error']}>{metaMessage.text}</p>}\n\n <p className={styles['intro']}>{t('intro')}</p>\n\n {savedIdentity === undefined\n ? null\n : (\n <p className={styles['savedNotice']} role=\"status\" aria-live=\"polite\">\n {providerCopy('已保存 {provider}。', savedIdentity)}\n </p>\n )}\n\n <ul className={styles['rows']}>\n {configured.map((row) => {\n const target = targetOf(row)\n const namespace = state.namespaces.get(target.settingsNs)\n if (namespace === undefined) return null\n // Adapter-reported configuration diagnostic (@ 0.1.5-alpha.2): shown\n // above the card so a route that cannot be served still explains why.\n const error = row.entry.error === undefined\n ? null\n : <p role=\"alert\" className={styles['error']}>{row.entry.error}</p>\n if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) {\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n {error}\n {renderEditor(target, namespace, (changed) => { closeSetup(changed, target) })}\n </li>\n )\n }\n const open = !adding && !declaring && editing?.provider === row.entry.provider\n const credentialConfigured = row.credential?.configured === true\n const credentialMissing = !credentialConfigured\n && row.apiKeyEnv !== undefined\n && row.credential?.configured === false\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n {error}\n <div className={styles['rowHead']}>\n <span className={styles['rowIdentity']}>\n <span className={styles['rowName']}>{row.entry.displayName}</span>\n {row.entry.declared === true\n ? <span className={styles['rowTag']}>自定义</span>\n : null}\n {credentialConfigured\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotConfigured']}`}\n role=\"img\"\n aria-label=\"API 密钥已配置\"\n title=\"API 密钥已配置\"\n />\n )\n : credentialMissing\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotMissing']}`}\n role=\"img\"\n aria-label=\"API 密钥缺失\"\n title=\"API 密钥缺失\"\n />\n )\n : null}\n </span>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n aria-label={providerCopy('编辑 {provider}', target)}\n onClick={() => {\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(false)\n setEditing(open ? undefined : target)\n }}\n >\n 编辑\n </button>\n {row.removable\n ? (\n <button\n type=\"button\"\n className={styles['dangerButton']}\n aria-label={providerCopy('删除 {provider}', target)}\n disabled={!state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setDeleteFailure(undefined)\n setDeleteTarget(target)\n }}\n >\n 删除\n </button>\n )\n : null}\n </span>\n </div>\n {open\n ? renderEditor(target, namespace, (changed) => { closeEditor(changed, target) })\n : null}\n </li>\n )\n })}\n </ul>\n\n <div className={styles['addBlock']}>\n {addTarget !== undefined && addNamespace !== undefined\n ? (\n <div className={styles['addCard']}>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>提供方</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={addTarget.provider}\n aria-label=\"提供方\"\n onChange={(event) => {\n const row = addable.find(candidate => candidate.entry.provider === event.target.value)\n if (row === undefined) return\n setEditing(targetOf(row))\n }}\n >\n {addable.map(row => (\n <option key={row.entry.provider} value={row.entry.provider}>\n {row.entry.displayName}\n </option>\n ))}\n </select>\n </div>\n <ProviderEditor\n key={addTarget.provider}\n provider={addTarget.provider}\n displayName={addTarget.displayName}\n namespace={addNamespace}\n schema={schema}\n settingsPath={addTarget.settingsPath}\n operations={operations}\n readOnly={!state.writable}\n onClose={(changed) => { closeEditor(changed, addTarget) }}\n />\n </div>\n )\n : declaring\n ? (\n <div className={styles['addCard']}>\n <CreateProviderCard\n taken={state.rows.map(row => row.entry.provider)}\n protocols={protocols}\n revision={state.namespaces.get('llm-pi-ai')?.revision ?? 0}\n operations={operations}\n readOnly={!state.writable}\n onClose={(changed) => {\n setDeclaring(false)\n if (changed) void controller.load()\n }}\n />\n </div>\n )\n : (\n <div className={styles['addActions']}>\n {configurable.length > 0 && (\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={addable.length === 0 || !state.writable}\n onClick={() => {\n const first = addable[0]\n if (first === undefined) return\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(true)\n setEditing(targetOf(first))\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加提供方\n </button>\n )}\n {state.namespaces.has('llm-pi-ai') && (\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={protocols.length === 0 || !state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setAdding(false)\n setEditing(undefined)\n setDeclaring(true)\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加自定义提供方\n </button>\n )}\n </div>\n )}\n </div>\n\n <Modal\n open={deleteTarget !== undefined}\n onClose={() => {\n if (deleting) return\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }}\n title={deleteTarget === undefined ? '' : providerCopy('删除 {provider}?', deleteTarget)}\n closeLabel=\"关闭\"\n description={deleteTarget === undefined\n ? ''\n : providerCopy(\n deleteTarget.credentialRef === undefined\n ? '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。'\n : '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteTarget,\n )}\n className={styles['deleteDialog'] as string}\n footer={(\n <>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={deleting}\n onClick={() => {\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={`${styles['secondaryButton']} ${styles['deleteConfirm']}`}\n disabled={deleting}\n onClick={() => {\n if (deleteTarget === undefined || deleting) return\n setDeleting(true)\n setDeleteFailure(undefined)\n void removeProviderProfile(operations, controller, deleteTarget)\n .then((removeFailure) => {\n if (removeFailure !== undefined) {\n setDeleteFailure(removeFailure)\n return\n }\n setDeleteTarget(undefined)\n })\n .finally(() => { setDeleting(false) })\n }}\n >\n {deleteTarget === undefined ? '' : providerCopy(deleting ? '正在删除 {provider}…' : '删除 {provider}', deleteTarget)}\n </button>\n </>\n )}\n >\n {deleteFailure === undefined ? null : <p className={styles['error']}>{deleteFailure}</p>}\n </Modal>\n </div>\n )\n}\n\n","/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.5-alpha.2\n * (host tree packages/client/ui-settings-models/src/client/operations.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\n/**\n * The Host reads and writes the Models cards perform, as callbacks built in the\n * plugin body. Cards receive these instead of a context: the outcomes name what\n * a card renders — a stored view, a stale revision, a refusal message — so the\n * failure codes and Remote namespaces stay in the apply world.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmDiscoveredModel, LlmModelDiscoveryRequest,\n SettingsNamespaceView, SettingsPathOpView,\n} from '@deepseek-ai/dsh-api-remotes/client'\n\n/** What one namespace write answered. */\nexport type SettingsWriteOutcome =\n /** Committed; the view carries the stored user subtree and the new revision. */\n | { readonly kind: 'written'; readonly view: SettingsNamespaceView }\n /**\n * The stored revision moved after the card read it, so the draft is stale.\n * The message stays for callers that report the Host diagnostic as it is.\n */\n | { readonly kind: 'conflict'; readonly message: string }\n /** Any other refusal, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** What one endpoint interrogation answered. */\nexport type ModelDiscoveryOutcome =\n /** The candidates the provider disclosed, in its own order. */\n | { readonly kind: 'found'; readonly models: readonly LlmDiscoveredModel[] }\n /** The interrogation was refused, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** The Host operations the Models page and its cards invoke. */\nexport interface ModelsOperations {\n /**\n * Read one credential reference's state.\n * @param ref - credential reference name.\n * @returns the state, or undefined when the reference is unknown or the read was refused.\n */\n describeCredential(ref: string): Promise<CredentialInfo | undefined>\n /**\n * Store one credential literal under its reference.\n * @param ref - credential reference name.\n * @param value - the literal to store.\n * @returns the refusal message, or undefined once stored.\n */\n storeCredential(ref: string, value: string): Promise<string | undefined>\n /**\n * Remove one credential reference (idempotent).\n * @param ref - credential reference name.\n * @returns the refusal message, or undefined once removed.\n */\n removeCredential(ref: string): Promise<string | undefined>\n /**\n * Apply path operations to one settings namespace.\n * @param ns - settings namespace identity.\n * @param ops - ordered path operations against the stored section, as the\n * wire takes them (the Remote signature owns the array).\n * @param expectedRevision - revision the draft was opened at, or undefined to write unfenced.\n * @returns the write outcome the card renders from.\n */\n writeSettings(\n ns: string,\n ops: SettingsPathOpView[],\n expectedRevision: number | undefined,\n ): Promise<SettingsWriteOutcome>\n /**\n * Ask a provider endpoint what models it serves.\n * @param settingsNs - namespace whose adapter family answers.\n * @param request - endpoint facts as the form currently shows them.\n * @returns the candidates, or the refusal.\n */\n discoverModels(settingsNs: string, request: LlmModelDiscoveryRequest): Promise<ModelDiscoveryOutcome>\n}\n\n/**\n * Bind the page's Host operations to the plugin's own Remote namespaces.\n * @param ctx - the page plugin's context, which declares `remote.credentials`,\n * `remote.llm`, and `remote.settings` in its own `inject`.\n * @returns the callbacks the section and its cards are injected with.\n */\nexport function createModelsOperations(ctx: ClientContext): ModelsOperations {\n return {\n describeCredential: async (ref) => {\n const response = await ctx.remote.credentials.describe([ref])\n return response.ok ? response.value[ref] : undefined\n },\n storeCredential: async (ref, value) => {\n const response = await ctx.remote.credentials.set(ref, value)\n return response.ok ? undefined : response.error.message\n },\n removeCredential: async (ref) => {\n const response = await ctx.remote.credentials.unset(ref)\n return response.ok ? undefined : response.error.message\n },\n writeSettings: async (ns, ops, expectedRevision) => {\n const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision)\n if (response.ok) return { kind: 'written', view: response.value }\n const { code, message } = response.error\n return code === 'settings/conflict' ? { kind: 'conflict', message } : { kind: 'refused', message }\n },\n discoverModels: async (settingsNs, request) => {\n const response = await ctx.remote.llm.discoverModels(settingsNs, request)\n return response.ok\n ? { kind: 'found', models: response.value }\n : { kind: 'refused', message: response.error.message }\n },\n }\n}\n","/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.5-alpha.2\n * (host tree packages/client/ui-settings-models/src/client/schema-operations.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\nimport type {\n SettingsSchemaService,\n} from '@deepseek-ai/dsh-client-ui-settings/client'\n\n/** Plain schema callbacks exposed to Models stores and presentation components. */\nexport type SettingsSchemaOperations = Pick<\n SettingsSchemaService,\n 'rehydrate' | 'validate' | 'nodeAtPath' | 'getPath' | 'hasPath' | 'setPath' | 'deletePath'\n>\n\n/**\n * Hide the Cordis service identity behind bound schema callbacks.\n * @param service - settings-owned schema service available in the apply context.\n * @returns callbacks that cannot expose the service context to React components.\n */\nexport function createSettingsSchemaOperations(service: SettingsSchemaService): SettingsSchemaOperations {\n return {\n rehydrate: serialized => service.rehydrate(serialized),\n validate: (schema, draft) => service.validate(schema, draft),\n nodeAtPath: (root, path) => service.nodeAtPath(root, path),\n getPath: (value, path) => service.getPath(value, path),\n hasPath: (value, path) => service.hasPath(value, path),\n setPath: (root, path, value) => service.setPath(root, path, value),\n deletePath: (root, path) => service.deletePath(root, path),\n }\n}\n","/**\n * dsh-model-extension — client entry (v1.0.0).\n *\n * Registers the Models+ settings section rendering the fully plugin-owned\n * models-plus component tree (no host component code is bundled). The store,\n * schema operations, Host operations, dictionaries, and invalidation wiring\n * keep the upstream ui-settings-models contracts @ 0.1.5-alpha.2 — the logic\n * modules (store/operations/schema-operations) are still inlined from the\n * host tree at build time, only the presentation is ours.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: pulls the shell's SlotMap merge ('settings.section') into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the ui renderer's Context merge (useSnapshot and friends on inject faces).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\n// Type-only: pulls the ctx.remote merge and forwarded-event key face.\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport { ModelsPlusSection } from './models-plus/ModelsPlusSection.tsx'\nimport type { ModelsPlusInjected } from './models-plus/ModelsPlusSection.tsx'\nimport { ModelsSettingsStore } from './vendor/store.ts'\nimport { createModelsOperations } from './vendor/operations.ts'\nimport { createSettingsSchemaOperations } from './vendor/schema-operations.ts'\nimport { en as extensionEn, zh as extensionZh } from './extension-meta.ts'\n\n/** Cordis service name (distinct from the npm package name). */\nexport const name = 'model-extension-client'\n\n/** Required services — mirrors the upstream Models section registration @ 0.1.5-alpha.2. */\nexport const inject = [\n 'slots', 'locale', 'remote', 'remote.credentials', 'remote.llm', 'remote.settings',\n 'settingsScope', 'settingsSchema',\n]\n\n/** Refetch the page snapshot only after its first load (upstream helper, inlined). */\nfunction refreshIfLoaded(controller: ModelsSettingsStore): void {\n if (controller.store.getSnapshot().status === 'idle') return\n void controller.load()\n}\n\n/**\n * Apply: register the Models+ section once slot/locale services are up.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n const NS = 'settings.models-extension'\n ctx.effect(() => ctx.locale.register(NS, {\n zh: { ...extensionZh },\n en: { ...extensionEn },\n }), 'dsh-model-extension: copy dictionaries')\n\n const schema = createSettingsSchemaOperations(ctx.settingsSchema)\n const operations = createModelsOperations(ctx)\n const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe())\n const t = ctx.locale.bind(NS) as ModelsPlusInjected['t']\n const injected = (): ModelsPlusInjected => ({\n controller,\n hooks: { snapshot: controller.store },\n operations,\n schema,\n t,\n })\n\n // Pushed invalidations converge every open surface without polling.\n ctx.effect(() => {\n const refreshModels = (): void => { refreshIfLoaded(controller) }\n return () => [\n ctx.remote.$on('settings/document-updated', () => { refreshModels() }),\n ctx.remote.$on('credentials/reference-updated', refreshModels),\n ctx.remote.$on('llm/adapters-updated', refreshModels),\n ctx.on('connection/reset', refreshModels),\n ]\n }, 'dsh-model-extension: pushed invalidations')\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'models-extension',\n order: 11,\n label: () => t('nav'),\n inject: injected,\n }, ModelsPlusSection))\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.js","names":["createSnapshotStore","useState","styles","useState","styles","useState","styles","Modal","useState","useMemo","styles","useState","styles","useState","styles","Modal","extensionZh","extensionEn"],"sources":["official/src/client/vendor/store.ts","official/src/client/models-plus/models-index.ts","official/src/client/models-plus/compat.ts","official/src/client/models-plus/presets.ts","official/src/client/extension-meta.ts","official/src/client/models-plus/models-plus.module.css","official/src/client/models-plus/QuickLoad.tsx","official/src/client/models-plus/ModelEntryPanel.tsx","official/src/client/models-plus/ModelCatalog.tsx","official/src/client/models-plus/ProviderEditor.tsx","official/src/client/models-plus/CreateProviderCard.tsx","official/src/client/models-plus/ModelsPlusSection.tsx","official/src/client/vendor/operations.ts","official/src/client/vendor/schema-operations.ts","official/src/client/index-extension.ts"],"sourcesContent":["/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.5-rc.1\n * (host tree packages/client/ui-settings-models/src/client/store.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\n/**\n * Models settings page store: one snapshot joining the configurable-provider\n * directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),\n * the settings namespaces (shared settings mirror),\n * and the referenced credentials (`credentials/describe`). The host stays the\n * single fact source — every mutation writes through the wire and the page\n * re-renders from the next describe, pushed or refetched.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView,\n} from '@deepseek-ai/dsh-api-remotes/client'\nimport type { SnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport { createSnapshotStore } from '@deepseek-ai/dsh-client-store'\nimport type { SettingsDescribeFace } from '@deepseek-ai/dsh-client-ui-settings/client'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\n\n/**\n * Any route key walks a dict schema to the same profile node, so the lookup\n * names one that cannot collide with a configured route.\n */\nconst PROBE_ROUTE = '\\u0000probe'\n\n/** One provider row after joining the configurable directory with live routes. */\nexport interface ProviderDirectoryEntry {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n readonly active: boolean\n readonly declared?: boolean\n readonly error?: string\n}\n\n/**\n * Join declared configurable providers with the currently registered routes.\n * @param registered - live provider routes in registration order.\n * @param directory - declared configurable providers in declaration order.\n * @returns declared rows followed by live routes with no declaration.\n */\nexport function joinProviderDirectory(\n registered: readonly LlmProviderInfo[],\n directory: readonly LlmConfigurableProvider[],\n): ProviderDirectoryEntry[] {\n const active = new Set(registered.map(provider => provider.id))\n const declared = new Set(directory.map(entry => entry.provider))\n const rows: ProviderDirectoryEntry[] = directory.map(entry => ({\n provider: entry.provider,\n displayName: entry.displayName,\n settingsNs: entry.settingsNs,\n settingsPath: [...entry.settingsPath],\n active: active.has(entry.provider),\n ...entry.declared === undefined ? {} : { declared: entry.declared },\n ...entry.error === undefined ? {} : { error: entry.error },\n }))\n for (const provider of registered) {\n if (declared.has(provider.id)) continue\n rows.push({\n provider: provider.id,\n displayName: provider.name,\n settingsNs: '',\n settingsPath: [],\n active: true,\n })\n }\n return rows\n}\n\n/** One provider row the page renders. */\nexport interface ProviderRow {\n /** The directory entry (route id, display name, settings address, live state). */\n entry: ProviderDirectoryEntry\n /** Whether any layer configures this provider (its profile resolves). */\n configured: boolean\n /** Whether the user layer alone carries the profile (removal restores the base). */\n removable: boolean\n /** The credential reference the resolved profile names, when one does. */\n apiKeyEnv: string | undefined\n /** Credential state for {@link apiKeyEnv}, once described. */\n credential: CredentialInfo | undefined\n /**\n * Credential state for the page's derived `<ROUTE>_API_KEY`, described only\n * while the profile names no reference — the provider-card seat's\n * `keyConfigured` fact for dormant and keyless rows, matching the editor's\n * own derivation rule.\n */\n derivedCredential?: CredentialInfo\n}\n\n/** Page snapshot. */\nexport interface ModelsSettingsState {\n status: 'idle' | 'loading' | 'ready' | 'error'\n /** Whole-load failure text; row-level write failures stay in the editor. */\n error: string | null\n /** Credential enrichment failure; provider/settings rows remain usable. */\n credentialError: string | null\n /** Whether the settings provider accepts writes. */\n writable: boolean\n /** Every configurable provider joined with its configured/credential state. */\n rows: readonly ProviderRow[]\n /** Namespace views by ns, for the editor's schema/layers/secrets. */\n namespaces: ReadonlyMap<string, SettingsNamespaceView>\n}\n\n/**\n * Derive the conventional credential reference for a provider route: the v1\n * page never asks for an environment-variable name, so a typed key stores\n * under this derived reference and the profile records it as `apiKeyEnv`.\n * @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).\n * @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).\n */\nexport function deriveKeyRef(provider: string): string {\n return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, '_')}_API_KEY`\n}\n\n/**\n * The wire protocols a hand-declared route may name, read out of the owning\n * namespace's own schema. This stays a schema read rather than a wire field so\n * the choices the page offers cannot drift from the ones the adapter accepts:\n * both come from the same `Config`.\n * @param namespace - the namespace view whose schema declares the profile shape.\n * @param schema - settings schema operations.\n * @returns the protocol identifiers, or an empty list when the schema has none.\n */\nexport function protocolChoices(\n namespace: SettingsNamespaceView | undefined,\n schema: SettingsSchemaOperations,\n): string[] {\n if (namespace === undefined) return []\n const node = schema.nodeAtPath(schema.rehydrate(namespace.schema), ['providers', PROBE_ROUTE, 'api'])\n const list = (node as { type?: string; list?: readonly { value?: unknown }[] } | undefined)\n if (list?.type !== 'union' || list.list === undefined) return []\n return list.list.map(entry => entry.value).filter((value): value is string => typeof value === 'string')\n}\n\n/** The credential reference a resolved profile names (its `apiKeyEnv` field). */\nfunction apiKeyEnvOf(\n namespace: SettingsNamespaceView | undefined,\n path: readonly string[],\n schema: SettingsSchemaOperations,\n): string | undefined {\n if (namespace === undefined) return undefined\n const profile = schema.getPath(namespace.value, path)\n if (typeof profile !== 'object' || profile === null) return undefined\n const ref = (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n return typeof ref === 'string' && ref.length > 0 ? ref : undefined\n}\n\n/** The models settings page controller (one per settings surface). */\nexport class ModelsSettingsStore {\n /** The snapshot the section renders from (uSES-safe store). */\n readonly store: SnapshotStore<ModelsSettingsState> = createSnapshotStore<ModelsSettingsState>({\n status: 'idle', error: null, credentialError: null, writable: false, rows: [], namespaces: new Map(),\n })\n\n /** Latest load wins; an older response never overwrites a newer one. */\n private generation = 0\n\n /**\n * @param ctx - the page plugin's context, whose `remote.llm` and\n * `remote.credentials` namespaces carry the directory and credential reads.\n * @param schema - settings-owned schema and immutable path operations.\n * @param describeFace - the shared mirror's describe face (namespace views and writability).\n */\n constructor(\n private readonly ctx: ClientContext,\n private readonly schema: SettingsSchemaOperations,\n private readonly describeFace: SettingsDescribeFace,\n ) {}\n\n /**\n * Refresh the whole page snapshot: the provider directory and the mirror's\n * settings answer in parallel, then one batched credential describe over\n * every referenced ref. Provider failure or absence of an initial settings\n * answer keeps the last good rows and surfaces an error; a failed settings\n * refresh reuses the mirror's held view.\n * @returns nothing; the snapshot carries the outcome.\n */\n async load(): Promise<void> {\n const generation = ++this.generation\n this.store.update((s) => { s.status = 'loading'; s.error = null })\n const [registered, declared] = await Promise.all([\n this.ctx.remote.llm.listProviders(),\n this.ctx.remote.llm.listConfigurableProviders(),\n this.describeFace.ensure(),\n ])\n if (!registered.ok) { this.failLoad(generation, registered.error.message); return }\n if (!declared.ok) { this.failLoad(generation, declared.error.message); return }\n const mirrored = this.describeFace.getSnapshot()\n if (mirrored.view === undefined) {\n this.failLoad(generation, mirrored.error ?? 'settings are unavailable in this browser')\n return\n }\n const providers = joinProviderDirectory(registered.value, declared.value)\n const writable = mirrored.view.writable\n const views: readonly SettingsNamespaceView[] = mirrored.view.namespaces\n const namespaces = new Map(views.map(view => [view.ns, view]))\n const rows: ProviderRow[] = providers.map((entry) => {\n const namespace = namespaces.get(entry.settingsNs)\n const configured = namespace !== undefined\n && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== undefined)\n const removable = namespace !== undefined\n && entry.settingsPath.length > 0\n && this.schema.hasPath(namespace.user, entry.settingsPath)\n && !this.schema.hasPath(namespace.base, entry.settingsPath)\n return {\n entry,\n configured,\n removable,\n apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),\n credential: undefined,\n }\n })\n const refs = [...new Set(rows.map(row => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))]\n let credentials: Record<string, CredentialInfo> = {}\n let credentialError: string | null = null\n if (refs.length > 0) {\n const response = await this.ctx.remote.credentials.describe(refs)\n // Credential state is an enrichment for the Models page: a failure\n // degrades the badge instead of failing the load. The onboarding\n // projection below retains the failure distinction.\n if (response.ok) credentials = response.value\n else credentialError = response.error.message\n }\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'ready'\n s.error = null\n s.credentialError = credentialError\n s.writable = writable\n s.rows = rows.map((row) => {\n const named = row.apiKeyEnv === undefined ? undefined : credentials[row.apiKeyEnv]\n const derived = row.apiKeyEnv !== undefined ? undefined : credentials[deriveKeyRef(row.entry.provider)]\n return {\n ...row,\n ...named === undefined ? {} : { credential: named },\n ...derived === undefined ? {} : { derivedCredential: derived },\n }\n })\n s.namespaces = namespaces\n })\n }\n\n /** Publish one load's failure text, unless a newer load already took over. */\n private failLoad(generation: number, message: string): void {\n if (generation !== this.generation) return\n this.store.update((s) => {\n s.status = 'error'\n s.error = message\n })\n }\n}\n\n/**\n * Whether a joined row can serve model requests as it stands: the route is\n * registered with the adapter registry, and whatever credential its resolved\n * profile names is stored. A profile naming no reference authenticates through\n * the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs\n * nothing), as does a live route with no settings address at all, so neither\n * owes this page a key.\n * @param row - one joined provider row.\n * @returns whether the user already has this provider to talk to.\n */\nexport function providerUsable(row: ProviderRow): boolean {\n if (!row.entry.active) return false\n if (row.apiKeyEnv === undefined) return true\n return row.credential?.configured === true\n}\n\n/** First-run onboarding readiness derived only from the shared Models join. */\nexport type OnboardingReadiness =\n | { kind: 'loading' }\n | { kind: 'adapter-absent' }\n | { kind: 'provider-ready' }\n | { kind: 'credential-missing' }\n | {\n kind: 'unavailable'\n reason:\n | 'load-failed'\n | 'provider-inactive'\n | 'credentials-unavailable'\n | 'settings-read-only'\n | 'credential-read-only'\n }\n\n/**\n * Project first-run readiness from the provider/settings/credential join used\n * by the Models page. The step exists to leave the user with a model to talk\n * to, so ANY usable provider ends it; only when none exists does the official\n * DeepSeek route — the one route the prompt can offer a key field for — decide\n * whether prompting can help. A missing official configurable-provider\n * declaration means the adapter is not repairable by navigating to Models.\n * @param state - current shared Models join snapshot.\n * @returns the onboarding state without reading a parallel fact source.\n */\nexport function onboardingReadiness(state: ModelsSettingsState): OnboardingReadiness {\n if ((state.status === 'idle' || state.status === 'loading') && state.rows.length === 0) {\n return { kind: 'loading' }\n }\n if (state.status === 'error') {\n return {\n kind: 'unavailable',\n reason: 'load-failed',\n }\n }\n if (state.rows.some(providerUsable)) return { kind: 'provider-ready' }\n const row = state.rows.find(candidate =>\n candidate.entry.provider === 'deepseek-official'\n && candidate.entry.settingsNs === 'llm-deepseek'\n && candidate.entry.settingsPath.length === 0)\n if (row === undefined) return { kind: 'adapter-absent' }\n if (!row.entry.active) {\n return {\n kind: 'unavailable',\n reason: 'provider-inactive',\n }\n }\n // Past the usable gate an active route names a reference it has no stored\n // credential for, so the remaining questions are all about that credential.\n if (state.credentialError !== null || row.credential === undefined) {\n return {\n kind: 'unavailable',\n reason: 'credentials-unavailable',\n }\n }\n if (!state.writable) {\n return {\n kind: 'unavailable',\n reason: 'settings-read-only',\n }\n }\n if (!row.credential.writable) {\n return {\n kind: 'unavailable',\n reason: 'credential-read-only',\n }\n }\n return { kind: 'credential-missing' }\n}\n","/**\n * Client access to the models.dev metadata index. The index is served by this\n * plugin's own server route (same origin); the raw models.json lives next to\n * settings.yaml under DSH home and is fetched from models.dev ONLY when the\n * user clicks the title-row button — nothing downloads automatically.\n *\n * The search surface is deliberately minimal (per plan): match model ids with\n * a case-insensitive substring test and show ids only, at most 10 candidates.\n * The full index is never handed to a static <datalist>.\n */\n\n/** Precise entry the metadata search returns (a subset of the raw models.dev record). */\nexport interface MetadataEntry {\n readonly id: string\n readonly context: number | undefined\n readonly output: number | undefined\n readonly input: readonly string[]\n readonly reasoning: boolean\n}\n\n/** Same-origin routes served by the server half. */\nconst INDEX_URL = '/plugins/dsh-model-extension/models-index'\nconst DOWNLOAD_URL = '/plugins/dsh-model-extension/models-download'\n\n/** Module-level cache: one page load fetches the index at most once. */\nlet cached: readonly MetadataEntry[] | undefined\n\nfunction normalize(raw: unknown): readonly MetadataEntry[] {\n if (!Array.isArray(raw)) return []\n const entries: MetadataEntry[] = []\n for (const item of raw) {\n if (typeof item !== 'object' || item === null) continue\n const row = item as Record<string, unknown>\n if (typeof row['id'] !== 'string' || row['id'].length === 0) continue\n const modalities = Array.isArray(row['input'])\n ? row['input'].filter((m): m is string => typeof m === 'string')\n : []\n entries.push({\n id: row['id'],\n context: typeof row['context'] === 'number' ? row['context'] : undefined,\n output: typeof row['output'] === 'number' ? row['output'] : undefined,\n input: modalities,\n reasoning: row['reasoning'] === true,\n })\n }\n return entries\n}\n\n/**\n * The metadata index, fetched once per page load; `undefined` while the\n * server has no metadata file (the caller shows the not-ready hint).\n */\nexport async function getMetadataIndex(): Promise<readonly MetadataEntry[] | undefined> {\n if (cached !== undefined) return cached\n try {\n const response = await fetch(INDEX_URL)\n if (!response.ok) return undefined\n cached = normalize(await response.json())\n return cached\n } catch {\n return undefined\n }\n}\n\n/** The outcome of an explicit user-triggered download. */\nexport type MetadataDownload = { readonly ok: true } | { readonly ok: false; readonly message: string }\n\n/**\n * Download/refresh the metadata file through the server half (user-triggered\n * from the title-row button). A success also refreshes the local cache.\n */\nexport async function downloadMetadata(): Promise<MetadataDownload> {\n try {\n const response = await fetch(DOWNLOAD_URL, { method: 'POST' })\n const body = await response.json().catch(() => undefined) as\n | { ok?: boolean; message?: string }\n | undefined\n if (!response.ok || body?.ok !== true) {\n return { ok: false, message: body?.message ?? `HTTP ${String(response.status)}` }\n }\n cached = normalize(body['index'])\n return { ok: true }\n } catch (error) {\n return { ok: false, message: error instanceof Error ? error.message : String(error) }\n }\n}\n\n/**\n * Case-insensitive substring match over model ids, at most {@link limit}\n * candidates (plan: show ids only, never the whole list).\n * @param index - the metadata index, or undefined while unavailable.\n * @param query - the user's typed text.\n * @param limit - maximum candidates to return.\n * @returns the matching ids; empty when the index is unavailable.\n */\nexport function searchModelIds(\n index: readonly MetadataEntry[] | undefined,\n query: string,\n limit = 10,\n): readonly string[] {\n if (index === undefined) return []\n const needle = query.trim().toLowerCase()\n if (needle.length === 0) return []\n const hits: string[] = []\n for (const entry of index) {\n if (!entry.id.toLowerCase().includes(needle)) continue\n hits.push(entry.id)\n if (hits.length >= limit) break\n }\n return hits\n}\n","/**\n * Pure helpers copied from the host's ui-settings-models UI component files\n * (they live inside components there, so they cannot be inlined as standalone\n * modules like operations/store/schema-operations are).\n *\n * ⚠️ Fork-copy risk: these must be re-checked against the pinned host sources\n * (packages/client/ui-settings-models/src/client/{ProviderEditor,DeepSeekModelsEditor}.tsx\n * @ 0.1.5-rc.1) on every adapter-anchor bump.\n */\n\n/** One model entry kept structurally open so hidden or future fields survive an edit. */\nexport type ModelDraft = Record<string, unknown>\n\n// ---------------------------------------------------------------------------\n// pathOps — copied from ProviderEditor.tsx @ 0.1.5-rc.1\n// ---------------------------------------------------------------------------\n\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'\n\n/**\n * The minimal path ops carrying `after` over `before`, both as the card sees\n * them. Only keys the card observed are named; fields absent from both sides\n * produce no op, which is why edits are path-addressed rather than a rebuilt\n * section.\n * @param base - path of the edited subtree inside the user section.\n * @param before - the subtree as loaded, or undefined when it is new.\n * @param after - the subtree as edited.\n * @returns ordered set/unset ops; empty when nothing changed.\n */\nexport function pathOps(\n base: readonly string[],\n before: unknown,\n after: Record<string, unknown>,\n): SettingsPathOpView[] {\n const previous = typeof before === 'object' && before !== null && !Array.isArray(before)\n ? before as Record<string, unknown>\n : {}\n const ops: SettingsPathOpView[] = []\n for (const [key, value] of Object.entries(after)) {\n if (JSON.stringify(previous[key]) === JSON.stringify(value)) continue\n ops.push({ op: 'set', path: [...base, key], value: value as JsonValue })\n }\n for (const key of Object.keys(previous)) {\n if (!(key in after)) ops.push({ op: 'unset', path: [...base, key] })\n }\n return ops\n}\n\n// ---------------------------------------------------------------------------\n// capacity parsing/formatting — copied from DeepSeekModelsEditor.tsx @ 0.1.5-rc.1\n// ---------------------------------------------------------------------------\n\n/** Accepted capacity spellings: a decimal count with an optional K/M suffix. */\nconst CAPACITY_PATTERN = /^(\\d+(?:\\.\\d+)?)([km])?$/i\n\n/** Decimal suffix scales — `1M` is 1000K, matching how model capacities are quoted. */\nconst CAPACITY_SCALE = { k: 1_000, m: 1_000_000 } as const\n\n/**\n * Read a typed capacity, so a user can write `256K` or `1M` instead of counting\n * zeroes. The stored value stays a plain token count.\n * @param text - raw field text.\n * @returns the count; `undefined` when blank (inherit), `NaN` when unreadable\n * (rejected by {@link validateModelRows} before any write).\n */\nexport function parseCapacity(text: string): number | undefined {\n const trimmed = text.trim()\n if (trimmed.length === 0) return undefined\n const match = CAPACITY_PATTERN.exec(trimmed)\n if (match === null) return Number.NaN\n const suffix = match[2]?.toLowerCase()\n const scale = suffix === 'k' || suffix === 'm' ? CAPACITY_SCALE[suffix] : 1\n const scaled = Number(match[1]) * scale\n // A decimal multiple is exact in intent but not in binary floating point\n // (2.3 * 1e6 lands a few ULPs high), so an integral intent snaps back.\n const rounded = Math.round(scaled)\n return Math.abs(scaled - rounded) < 1e-6 ? rounded : scaled\n}\n\n/**\n * Spell a stored count back in the shortest form that survives a round trip\n * through {@link parseCapacity}; a count that is not a whole number of\n * thousands stays written out.\n * @param value - stored capacity.\n * @returns the field text.\n */\nexport function formatCapacity(value: number): string {\n if (!Number.isInteger(value) || value <= 0) return String(value)\n if (value % CAPACITY_SCALE.m === 0) return `${String(value / CAPACITY_SCALE.m)}M`\n if (value % CAPACITY_SCALE.k === 0) return `${String(value / CAPACITY_SCALE.k)}K`\n return String(value)\n}\n\n// ---------------------------------------------------------------------------\n// model-row validation — copied from DeepSeekModelsEditor.tsx @ 0.1.5-rc.1\n// ---------------------------------------------------------------------------\n\n/** A localized validation failure for one user-owned model array. */\nexport interface ModelRowsValidationFailure {\n /** Zero-based model position. */\n index: number\n /** Message key owned by the Models+ dictionary. */\n key: 'modelIdRequired' | 'modelIdDuplicate' | 'modelNameInvalid' | 'modelContextInvalid'\n | 'modelMaxTokensInvalid'\n}\n\n/** Convert a schema-validated catalog value into records without dropping hidden fields. */\nexport function modelDrafts(value: unknown): ModelDraft[] {\n if (!Array.isArray(value)) return []\n return value.map(entry =>\n typeof entry === 'object' && entry !== null && !Array.isArray(entry)\n ? entry as ModelDraft\n : {})\n}\n\n// ---------------------------------------------------------------------------\n// row key-order normalization (plugin addition, v1.0.0: stable YAML key order)\n// ---------------------------------------------------------------------------\n\n/** Canonical key order for one models[] row (plugin-known fields first). */\nconst ROW_KEY_ORDER = ['id', 'name', 'contextWindow', 'maxTokens', 'input', 'reasoningEfforts', 'compat']\n\n/** Canonical key order for the row's compat sub-object. */\nconst COMPAT_KEY_ORDER = ['supportsDeveloperRole', 'supportsReasoningEffort', 'thinkingFormat']\n\n/**\n * Re-key one model row into the canonical order (plugin-known fields in\n * order, unknown/future fields kept at the tail so nothing is dropped).\n * YAML emits keys in object insertion order, and interactive edits append\n * keys at the tail — without this, rows saved after quick-load or gated-key\n * removals come out with scrambled key orders (purely cosmetic, but noisy\n * in settings.yaml diffs).\n * @param row - the drafted row.\n * @returns the re-keyed row (shallow copy).\n */\nexport function normalizeModelRow(row: ModelDraft): ModelDraft {\n const next: ModelDraft = {}\n for (const key of ROW_KEY_ORDER) {\n if (key in row) next[key] = row[key]\n }\n for (const key of Object.keys(row)) {\n if (!ROW_KEY_ORDER.includes(key)) next[key] = row[key]\n }\n const compat = next['compat']\n if (typeof compat === 'object' && compat !== null && !Array.isArray(compat)) {\n const source = compat as Record<string, unknown>\n const normalized: Record<string, unknown> = {}\n for (const key of COMPAT_KEY_ORDER) {\n if (key in source) normalized[key] = source[key]\n }\n for (const key of Object.keys(source)) {\n if (!COMPAT_KEY_ORDER.includes(key)) normalized[key] = source[key]\n }\n next['compat'] = normalized\n }\n return next\n}\n\n/**\n * Validate adapter constraints that the serialized schema cannot express.\n * @param value - user-owned `models` value, or undefined while inherited.\n * @returns the first invalid row, or undefined when the adapter will accept it.\n */\nexport function validateModelRows(value: unknown): ModelRowsValidationFailure | undefined {\n if (value === undefined) return undefined\n const models = modelDrafts(value)\n const seen = new Set<string>()\n for (const [index, model] of models.entries()) {\n // Compared trimmed: surrounding whitespace is a paste artifact the adapter\n // would never match, and an untrimmed compare lets `model ` slip past the\n // duplicate check against its own twin.\n const id = model['id']\n const trimmed = typeof id === 'string' ? id.trim() : undefined\n if (trimmed === undefined || trimmed.length === 0) return { index, key: 'modelIdRequired' }\n if (seen.has(trimmed)) return { index, key: 'modelIdDuplicate' }\n seen.add(trimmed)\n const name = model['name']\n if (name !== undefined && (typeof name !== 'string' || name.length === 0)) {\n return { index, key: 'modelNameInvalid' }\n }\n const contextWindow = model['contextWindow']\n if (contextWindow !== undefined\n && (typeof contextWindow !== 'number' || !Number.isInteger(contextWindow) || contextWindow <= 0)) {\n return { index, key: 'modelContextInvalid' }\n }\n const maxTokens = model['maxTokens']\n if (maxTokens !== undefined\n && (typeof maxTokens !== 'number' || !Number.isInteger(maxTokens) || maxTokens <= 0)) {\n return { index, key: 'modelMaxTokensInvalid' }\n }\n }\n return undefined\n}\n","/**\n * Draft defaults for a NEW model row (added by hand or adopted from a fetch),\n * per the v1.0.0 plan: reasoning effort ON with every level declared, thinking\n * format `openai`, both input modalities checked. These are draft seeds that\n * land in settings.yaml when the row is saved — they are not inherited-state\n * sentinels, except `supportsDeveloperRole`, which stays UNWRITTEN (its\n * tri-state reads an absent key as checked, so only an explicit user uncheck\n * ever writes `false`).\n */\n\nimport type { ModelDraft } from './compat.ts'\n\n/** The tri-state `compat.supportsDeveloperRole` seed: absent (reads checked). */\nconst DEVELOPER_ROLE_SEED: Record<string, unknown> = {}\n\n/** Draft seed for one new model row. */\nexport function newModelDraft(): ModelDraft {\n return {\n id: '',\n input: ['text', 'image'],\n reasoningEfforts: {\n off: null,\n minimal: 'minimal',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'xhigh',\n max: 'max',\n },\n compat: {\n ...DEVELOPER_ROLE_SEED,\n supportsReasoningEffort: true,\n thinkingFormat: 'openai',\n },\n }\n}\n","/**\n * Shared extension metadata: enums pinned to the adapter anchor version, and\n * the extra locale keys the extension adds on top of the official Models page\n * dictionaries. The anchor constant itself is injected at build time.\n */\n\n/** Adapter anchor (build-time define from package.json dsh.adapter). */\ndeclare const __DSH_ADAPTER_VERSION__: string\nexport const ADAPTER_VERSION: string =\n typeof __DSH_ADAPTER_VERSION__ === 'string' ? __DSH_ADAPTER_VERSION__ : '0.0.0-unknown'\n\n/** Thinking levels offered by llm-pi-ai (THINKING_LEVEL_GATE @ 0.1.2-alpha.4). Only `off` may carry an empty wire value. */\nexport const THINKING_LEVELS = ['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'] as const\nexport type ThinkingLevel = (typeof THINKING_LEVELS)[number]\n\n/** Input modalities accepted by llm-pi-ai (MODALITY_GATE @ 0.1.2-alpha.4). */\nexport const MODALITIES = ['text', 'image'] as const\nexport type Modality = (typeof MODALITIES)[number]\n\n/** Reasoning wire formats understood by llm-pi-ai (SUPPORTED_THINKING_FORMATS @ 0.1.2-alpha.4). */\nexport const THINKING_FORMATS = [\n 'openai',\n 'deepseek',\n 'openrouter',\n 'together',\n 'baseten',\n 'zai',\n 'qwen',\n 'chat-template',\n 'qwen-chat-template',\n 'string-thinking',\n 'ant-ling',\n] as const\nexport type ThinkingFormat = (typeof THINKING_FORMATS)[number]\n\n/** Extra copy for the extension, keyed like the official dictionaries (en is authoritative). */\nexport const en = {\n // --- official Models-page keys the forked components still render -------\n nav: 'Models+',\n title: 'Models+',\n intro: 'Enter your API keys to use models from the following providers.',\n edit: 'Edit',\n editProvider: 'Edit {provider}',\n remove: 'Delete',\n removeProvider: 'Delete {provider}',\n deleteTitle: 'Delete {provider}?',\n deleteDescription: 'Deleting {provider} removes its configuration. Any credential it uses is managed elsewhere and will be kept.',\n deleteDescriptionWithCredential: 'Deleting {provider} removes its configuration and stored API key.',\n deleteConfirm: 'Delete {provider}',\n deleting: 'Deleting {provider}…',\n add: 'Add provider',\n provider: 'Provider',\n close: 'Close',\n cancel: 'Cancel',\n apply: 'Apply',\n applying: 'Applying…',\n savedProvider: 'Saved {provider}.',\n credentialConfigured: 'API key configured',\n credentialMissing: 'API key missing',\n readOnly: 'The settings document is read-only in this deployment.',\n loadFailed: 'Loading the provider directory failed',\n conflict: 'Someone else changed these settings while this card was open. Close it and reopen to edit the current values.',\n retry: 'Retry',\n keyInput: 'API key',\n keyPlaceholder: 'Enter your API key',\n keyPlaceholderNative: 'Enter an API key, or leave blank to use environment authentication',\n keyStored: 'Configured — enter a new value to replace',\n keyEnvLocked: 'Provided by the launch environment (read-only)',\n customized: 'Customized settings',\n baseUrl: 'Base URL',\n baseUrlDefault: 'Provider default',\n models: 'Models',\n modelsInherited: 'Using the adapter defaults',\n modelsCustomized: 'Customized model catalog',\n resetModels: 'Restore defaults',\n model: 'Model',\n modelId: 'Model ID',\n modelName: 'Display name',\n modelNamePlaceholder: 'Uses the model ID when empty',\n contextWindow: 'Context window',\n contextWindowPlaceholder: 'Uses the provider default',\n maxTokens: 'Max output tokens',\n maxTokensPlaceholder: 'Uses the provider default',\n modelAdvanced: 'Capacities',\n addModel: 'Add model',\n removeModel: 'Delete model',\n modelsEmpty: 'No models will be shown in the selector. Unlisted IDs can still be sent directly.',\n keyBlank: 'Enter the API key, or leave the field empty to keep the stored one.',\n keyBlankNew: 'Enter the API key, or leave the field empty if this provider authenticates another way.',\n keyIllegalCharacters: 'This API key is not in a valid format. Please check it.',\n modelIdRequired: 'Model ID is required.',\n modelIdDuplicate: 'Model ID must be unique.',\n modelNameInvalid: 'Display name cannot be empty.',\n modelContextInvalid: 'Context window must be a positive count, like 131072, 256K, or 1M.',\n modelMaxTokensInvalid: 'Max output tokens must be a positive count, like 8192, 64K, or 1M.',\n advancedHint: 'Other fields live in settings.yaml; edit that section directly.',\n modelCapacityInvalid: 'A capacity must be a number, optionally suffixed K or M.',\n modelDuplicate: 'Each model ID may appear once.',\n modelContextWindow: 'Context window',\n modelMaxTokens: 'Max output tokens',\n fetchModels: 'Fetch available models',\n fetching: 'Asking the provider…',\n fetchNeedsBaseUrl: 'Enter the base URL first, then fetch.',\n fetchEmpty: 'The provider listed no models. Add them by hand.',\n fetchTitle: 'Choose models to add',\n fetchDescription: 'These are the models this provider has available. Choose the ones to add.',\n fetchSelectAll: 'Select all',\n fetchDeselectAll: 'Deselect all',\n fetchAdopt: 'Add selected',\n customAdd: 'Add a custom provider',\n customTitle: 'Custom provider',\n customTag: 'Custom',\n customRoute: 'Provider ID',\n customRouteHint: 'Lowercase identifier, starting with a letter, that uniquely names this provider in requests and as its credential name.',\n customRouteInvalid: 'Start with a lowercase letter; then lowercase letters, digits, and dashes.',\n customRouteTaken: 'A provider already uses this ID.',\n customDisplayName: 'Display name',\n customApi: 'API protocol',\n customApiUnset: 'Not selected',\n customNeedsBaseUrl: 'A custom provider needs a base URL.',\n customBaseUrlInvalid: 'Enter a valid HTTP or HTTPS URL.',\n customNeedsModels: 'A custom provider needs at least one model.',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: 'unresolvable settings path',\n create: 'Create provider',\n creating: 'Creating…',\n onboardingTitle: 'Add an API key to get started',\n onboardingDescription: 'Configure the official DeepSeek provider to start building.',\n onboardingLater: 'Configure later',\n onboardingSave: 'Save and continue',\n onboardingSaving: 'Saving…',\n keyRequired: 'Enter an API key to continue.',\n\n // --- extension-only keys ------------------------------------------------\n extDeclare: 'Declared',\n extSection: 'Model extensions',\n extSectionHint: 'Extra per-model fields that live in settings.yaml.',\n supportsReasoningEffort: 'Endpoint accepts reasoning effort',\n supportsDeveloperRole: 'System prompt may use the developer role',\n supportsDeveloperRoleHint: 'Reasoning-model system prompts go out as \"developer\"; uncheck to keep \"system\" for gateways that reject it.',\n reasoningEfforts: 'Reasoning efforts',\n reasoningEffortLevel: 'Level',\n reasoningEffortWire: 'Wire value',\n reasoningEffortOffHint: '\"off\" takes no wire value.',\n reasoningEffortEmptyWire: 'A checked level other than \"off\" needs a wire value.',\n reasoningEffortsNeedNonOff: 'Declare at least one level beyond \"off\".',\n inputModalities: 'Input modalities',\n inputNeedOne: 'Keep at least one modality checked.',\n thinkingFormat: 'Thinking format',\n} as const\n\nexport type ExtensionKey = keyof typeof en\n\n/** Chinese strings — same key set as {@link en}. */\nexport const zh: { [K in ExtensionKey]: string } = {\n // --- official Models-page keys (upstream zh values) ----------------------\n nav: '模型+',\n title: '模型+',\n intro: '填入各提供方的 API 密钥即可使用其模型。',\n edit: '编辑',\n editProvider: '编辑 {provider}',\n remove: '删除',\n removeProvider: '删除 {provider}',\n deleteTitle: '删除 {provider}?',\n deleteDescription: '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。',\n deleteDescriptionWithCredential: '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteConfirm: '删除 {provider}',\n deleting: '正在删除 {provider}…',\n add: '添加提供方',\n provider: '提供方',\n close: '关闭',\n cancel: '取消',\n apply: '保存',\n applying: '保存中…',\n savedProvider: '已保存 {provider}。',\n credentialConfigured: 'API 密钥已配置',\n credentialMissing: 'API 密钥缺失',\n readOnly: '当前部署的设置文档为只读。',\n loadFailed: '加载提供方目录失败',\n conflict: '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。',\n retry: '重试',\n keyInput: 'API 密钥',\n keyPlaceholder: '输入 API 密钥',\n keyPlaceholderNative: '输入 API 密钥,或留空使用环境认证',\n keyStored: '已配置——输入新值可替换',\n keyEnvLocked: '由启动环境提供(只读)',\n customized: '自定义设置',\n baseUrl: 'API 地址',\n baseUrlDefault: '提供方默认',\n models: '模型目录',\n modelsInherited: '正在使用适配器默认模型',\n modelsCustomized: '已自定义模型目录',\n resetModels: '恢复默认模型',\n model: '模型',\n modelId: '模型 ID',\n modelName: '显示名称',\n modelNamePlaceholder: '留空时使用模型 ID',\n contextWindow: '上下文窗口',\n contextWindowPlaceholder: '使用提供方默认值',\n maxTokens: '最大输出 token 数',\n maxTokensPlaceholder: '使用提供方默认值',\n modelAdvanced: '容量',\n addModel: '添加模型',\n removeModel: '删除模型',\n modelsEmpty: '模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。',\n keyBlank: '请输入 API 密钥;留空则保持已存储的密钥。',\n keyBlankNew: '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。',\n keyIllegalCharacters: '此 API 密钥格式无效,请检查。',\n modelIdRequired: '模型 ID 必填。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n advancedHint: '其余字段存于 settings.yaml;请直接编辑该节。',\n modelCapacityInvalid: '容量须为数字,可带 K 或 M 后缀。',\n modelDuplicate: '每个模型 ID 只能出现一次。',\n modelContextWindow: '上下文窗口',\n modelMaxTokens: '最大输出 token 数',\n fetchModels: '获取可用模型',\n fetching: '正在询问提供方…',\n fetchNeedsBaseUrl: '请先填写 API 地址再获取。',\n fetchEmpty: '该提供方未列出任何模型,请手动添加。',\n fetchTitle: '选择要添加的模型',\n fetchDescription: '这些是该提供方可用的模型,选择要添加的项。',\n fetchSelectAll: '全选',\n fetchDeselectAll: '取消全选',\n fetchAdopt: '添加所选',\n customAdd: '添加自定义提供方',\n customTitle: '自定义提供方',\n customTag: '自定义',\n customRoute: '提供方 ID',\n customRouteHint: '小写字母开头的唯一标识符,用于请求与凭证命名。',\n customRouteInvalid: '以小写字母开头;其后为小写字母、数字和短横线。',\n customRouteTaken: '已有提供方使用此 ID。',\n customDisplayName: '显示名称',\n customApi: 'API 协议',\n customApiUnset: '未选择',\n customNeedsBaseUrl: '自定义提供方需要 API 地址。',\n customBaseUrlInvalid: '请输入有效的 HTTP 或 HTTPS 地址。',\n customNeedsModels: '自定义提供方至少需要一个模型。',\n customBaseUrlPlaceholder: 'https://gateway.example/v1',\n settingsPathUnresolvable: '无法解析设置路径',\n create: '创建提供方',\n creating: '创建中…',\n onboardingTitle: '先添加一个 API 密钥即可开始',\n onboardingDescription: '配置官方 DeepSeek 提供方以开始构建。',\n onboardingLater: '稍后配置',\n onboardingSave: '保存并继续',\n onboardingSaving: '保存中…',\n keyRequired: '请输入 API 密钥以继续。',\n\n // --- extension-only keys ------------------------------------------------\n extDeclare: '声明',\n extSection: '模型扩展',\n extSectionHint: 'settings.yaml 中按模型生效的扩展字段。',\n supportsReasoningEffort: '端点接受推理挡位参数(reasoning_effort)',\n supportsDeveloperRole: '允许以 developer 角色发送系统提示',\n supportsDeveloperRoleHint: '推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。',\n reasoningEfforts: '推理挡位',\n reasoningEffortLevel: '挡位',\n reasoningEffortWire: '线上取值',\n reasoningEffortOffHint: '“off”不需要线上取值。',\n reasoningEffortEmptyWire: '除 off 外勾选的挡位必须填写线上取值。',\n reasoningEffortsNeedNonOff: '至少声明一个 off 以外的挡位。',\n inputModalities: '输入模态',\n inputNeedOne: '至少保留一个模态。',\n thinkingFormat: '思考格式',\n}\n","/* models-plus styles — the official ModelsSection.module.css classes (as\n * transcribed and verified in docs/models-settings-demo.html) plus the\n * extension-block styles, all on --dsw-alias tokens. */\n\n.section { display: flex; flex-direction: column; gap: 12px; max-width: 720px; color: var(--dsw-alias-label-primary); }\n.titleRow { display: flex; align-items: center; gap: 10px; }\n.title { margin: 0; font-size: 16px; line-height: 24px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n.intro { margin: 0; font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-tertiary); }\n.savedNotice { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-success-primary); }\n.error { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-state-error-primary); }\n\n.rows { list-style: none; margin: 12px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }\n.rowCard { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 16px; padding: 12px 14px; display: flex; flex-direction: column; gap: 12px; }\n.rowHead { display: flex; align-items: center; gap: 10px; }\n.rowIdentity { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }\n.rowName { font-size: 14px; line-height: 22px; font-weight: 500; color: var(--dsw-alias-label-primary); }\n.rowTag { flex: none; padding: 1px 6px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 4px; font-size: 11px; line-height: 16px; color: var(--dsw-alias-label-secondary); }\n.credentialDot { box-sizing: border-box; display: inline-block; flex: none; width: 8px; height: 8px; border-radius: 50%; }\n.credentialDotConfigured { background: var(--dsw-alias-state-success-primary); }\n.credentialDotMissing { background: var(--dsw-alias-state-error-primary); }\n.rowActions { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; }\n\n.primaryButton, .secondaryButton, .addButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; gap: 4px; height: 36px; padding: 0 14px; border: none; border-radius: 18px; font: inherit; font-size: 14px; line-height: 22px; cursor: pointer; }\n.primaryButton { background: var(--dsw-alias-button-primary-fill); color: var(--dsw-alias-label-primary-foreground); }\n.primaryButton:hover:not(:disabled) { background: var(--dsw-alias-button-primary-hover); }\n.secondaryButton, .addButton { border: 0.5px solid var(--dsw-alias-border-l3); background: transparent; color: var(--dsw-alias-label-primary); }\n.secondaryButton:hover:not(:disabled), .addButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n.secondaryButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-solid); }\n.dangerButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; height: 36px; padding: 0 14px; border: none; border-radius: 18px; background: transparent; color: var(--dsw-alias-state-error-primary); font: inherit; font-size: 14px; line-height: 22px; cursor: pointer; }\n.dangerButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n.rowActions .secondaryButton, .rowActions .dangerButton { height: 28px; padding: 0 10px; border-radius: 14px; font-size: 12px; line-height: 18px; }\n.primaryButton:disabled, .secondaryButton:disabled, .dangerButton:disabled, .addButton:disabled, .linkButton:disabled, .addModelButton:disabled { opacity: 0.4; cursor: default; }\n.primaryButton:focus-visible, .secondaryButton:focus-visible, .dangerButton:focus-visible, .addButton:focus-visible, .linkButton:focus-visible, .addModelButton:focus-visible, .iconButton:focus-visible, .customizedSummary:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dsw-alias-border-l3); }\n\n.editor { border-radius: 12px; background: var(--dsw-alias-bg-module-platform); padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; }\n.field { display: flex; flex-direction: column; gap: 6px; }\n.fieldLabel { display: inline-flex; align-items: center; gap: 10px; font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.linkButton { box-sizing: border-box; display: inline-flex; align-items: center; height: 28px; padding: 0 10px; border: none; border-radius: 14px; background: transparent; color: var(--dsw-alias-label-tertiary); font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }\n.linkButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-secondary); }\n.advancedHint { margin: 0; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.editorActions { display: flex; justify-content: flex-end; gap: 8px; }\n\n.addBlock { display: flex; flex-direction: column; gap: 12px; }\n.addActions { display: flex; flex-wrap: wrap; gap: 10px; }\n.addButton { flex: 1 1 0; min-width: 180px; gap: 6px; height: 44px; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 16px; }\n.addCard { border-radius: 12px; background: var(--dsw-alias-bg-module-platform); padding: 14px 16px; display: flex; flex-direction: column; gap: 14px; list-style: none; }\n.addCard .editor, .setupCard .editor { background: none; padding: 0; }\n\n\n.tabs { display: flex; flex-direction: column; gap: 12px; }\n.tabBar { display: flex; gap: 4px; border-bottom: 0.5px solid var(--dsw-alias-border-l2); }\n.tabButton { appearance: none; border: none; background: transparent; padding: 6px 12px 8px; font: inherit; font-size: 13px; line-height: 20px; color: var(--dsw-alias-label-tertiary); cursor: pointer; position: relative; }\n.tabButton:hover { color: var(--dsw-alias-label-primary); }\n.tabButton:disabled { opacity: 0.4; cursor: default; }\n.tabButtonActive { color: var(--dsw-alias-label-primary); font-weight: 500; }\n.tabButtonActive::after { content: ''; position: absolute; left: 10px; right: 10px; bottom: -1px; height: 2px; border-radius: 2px; background: var(--dsw-alias-brand-primary); }\n.tabPanel { display: flex; flex-direction: column; gap: 12px; }\n.modelCatalog { display: flex; flex-direction: column; gap: 10px; }\n.modelCatalogHeading { display: flex; flex-direction: column; gap: 2px; }\n.modelCatalogTitle { font-size: 12px; line-height: 18px; font-weight: 500; color: var(--dsw-alias-label-secondary); }\n.modelCatalogMeta, .modelEmpty { margin: 0; color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }\n.modelList { display: flex; flex-direction: column; gap: 8px; }\n.modelListHead { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }\n.modelEntry { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 10px; padding: 6px; }\n.modelRow { display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr) auto auto; align-items: center; gap: 6px; }\n.iconButton { box-sizing: border-box; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-tertiary); cursor: pointer; }\n.iconButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n.iconButton:disabled { cursor: default; opacity: 0.4; }\n.iconButtonDanger:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); color: var(--dsw-alias-state-error-primary); }\n.modelAdvanced { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: 8px; padding: 8px 4px 2px; }\n.modelField { display: flex; flex-direction: column; gap: 4px; }\n.modelFieldLabel { color: var(--dsw-alias-label-tertiary); font-size: 12px; line-height: 18px; }\n.modelEmpty { padding: 12px; border: 1px dashed var(--dsw-alias-border-l3); border-radius: 8px; text-align: center; }\n.addModelButton { box-sizing: border-box; align-self: flex-start; display: inline-flex; align-items: center; gap: 4px; height: 28px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 14px; background: transparent; color: var(--dsw-alias-label-primary); font: inherit; font-size: 12px; line-height: 18px; cursor: pointer; }\n.addModelButton:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n\n.input { box-sizing: border-box; width: 100%; height: 32px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; font: inherit; font-size: 14px; line-height: 22px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\nselect.input { max-width: 240px; cursor: pointer; }\n.input:focus { outline: none; border-color: var(--dsw-alias-brand-primary); }\n.input::placeholder { color: var(--dsw-alias-label-dimmed); }\n.input:disabled { opacity: 0.6; cursor: default; }\n.selectInput { appearance: none; padding-right: 32px; background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\"); background-repeat: no-repeat; background-position: right 12px center; background-size: 12px 12px; }\n\n.deleteDialog { width: min(480px, 100%); }\n.deleteConfirm:not(:disabled) { border-color: var(--dsw-alias-state-error-primary); color: var(--dsw-alias-state-error-primary); }\n.deleteConfirm:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover-danger); }\n\n.fetchDialog { max-width: 520px; }\n.candidateToolbar { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; }\n.candidateSearch { min-width: 0; flex: 1 1 240px; }\n.candidateList { display: flex; flex-direction: column; gap: 2px; max-height: 320px; margin: 0; overflow-y: auto; padding: 0; list-style: none; }\n.candidate { border-radius: 6px; }\n.candidateLabel { display: flex; align-items: center; gap: 8px; padding: 6px 8px; cursor: pointer; }\n.candidateId { flex: 1 1 auto; font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; overflow-wrap: anywhere; }\n.candidateEmpty { margin: 24px 0; color: var(--dsw-alias-label-secondary); font-size: 13px; line-height: 20px; text-align: center; }\n\n/* ---- extension block (plugin-owned; official token palette) ---- */\n[hidden] { display: none !important; }\n.extBlock { border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 10px; padding: 10px; margin: 8px 4px 2px; background: var(--dsw-alias-bg-layer-1); display: flex; flex-direction: column; gap: 10px; }\n.extGroup { border-top: 0.5px solid var(--dsw-alias-border-l2); padding-top: 12px; }\n.extGroupFirst { border-top: none; padding-top: 0; }\n.extCheck { display: flex; align-items: flex-start; gap: 8px; cursor: pointer; }\n.extCheckLabel { font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-primary); }\n.extHint { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.extGated { display: flex; flex-direction: column; gap: 12px; padding-left: 2px; }\n.extField { display: flex; flex-direction: column; gap: 6px; }\n.extLabel { font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n.extTable { border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; overflow: hidden; }\n.extTHead { display: grid; grid-template-columns: 64px minmax(0,1fr) minmax(0,1.2fr); font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); background: var(--dsw-alias-bg-module-platform); }\n.extTHead > div { padding: 6px 10px; }\n.extTHead > div + div { border-left: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow { display: grid; grid-template-columns: 64px minmax(0,1fr) minmax(0,1.2fr); align-items: center; border-top: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow > div { padding: 6px 10px; font-size: 14px; }\n.extTRow > div + div { border-left: 0.5px solid var(--dsw-alias-border-l2); }\n.extTRow input[type=\"text\"] { box-sizing: border-box; width: 100%; height: 32px; padding: 0 10px; border: 0.5px solid var(--dsw-alias-border-l4); border-radius: 8px; font: inherit; font-size: 14px; background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); }\n.extTRow input[type=\"text\"]:disabled { opacity: 0.6; cursor: default; }\n.extCheckbox { accent-color: var(--dsw-alias-brand-primary); width: 15px; height: 15px; flex: none; }\n.switchRow { display: flex; align-items: center; gap: 8px; font-size: 14px; line-height: 22px; cursor: pointer; }\n.extTag { flex: none; padding: 1px 6px; border: 0.5px solid rgba(65,118,230,0.35); border-radius: 4px; background: var(--dsw-static-deepseek-100); color: var(--dsw-static-deepseek-600); font-size: 11px; line-height: 16px; font-weight: 500; }\n\n/* ---- modal (matches the ui-primitives look closely enough for these two dialogs) ---- */\n.modalMask { position: fixed; inset: 0; background: var(--dsw-alias-bg-mask-1); display: flex; align-items: center; justify-content: center; z-index: 100; padding: 24px; }\n.modal { background: var(--dsw-specific-menu); border-radius: 16px; padding: 20px; width: 100%; box-shadow: 0 12px 40px rgba(0,0,0,0.18); }\n.modalTitle { font-size: 16px; line-height: 24px; font-weight: 500; margin-bottom: 8px; color: var(--dsw-alias-label-primary); }\n.modalDesc { font-size: 14px; line-height: 22px; color: var(--dsw-alias-label-secondary); margin-bottom: 16px; }\n.modalFoot { display: flex; justify-content: flex-end; gap: 8px; }\n\n/* ---- quick-load dropdown (filtered, max 10 candidates, never a static datalist) ---- */\n.quickWrap { position: relative; display: flex; flex-direction: column; gap: 6px; }\n.quickList { position: absolute; top: 100%; left: 0; right: 0; z-index: 20; margin-top: 2px; padding: 4px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: 8px; background: var(--dsw-specific-menu); box-shadow: 0 8px 24px rgba(0,0,0,0.12); max-height: 264px; overflow-y: auto; }\n.quickItem { display: block; width: 100%; padding: 6px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 13px; text-align: left; cursor: pointer; overflow-wrap: anywhere; }\n.quickItem:hover { background: var(--dsw-alias-interactive-bg-hover); }\n.quickEmpty { padding: 6px 8px; font-size: 12px; line-height: 18px; color: var(--dsw-alias-label-tertiary); }\n\n@media (prefers-reduced-motion: reduce) {\n .customizedSummary::before { transition: none; }\n}\n","/**\n * Quick-load: a searchable dropdown over the models.dev metadata index.\n * Plan constraints: ids only, case-insensitive substring match, at most 10\n * candidates rendered — the index is filtered on every keystroke and the\n * candidate list is only mounted while open, so a 370-row index never lands\n * in the DOM wholesale.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { getMetadataIndex, searchModelIds } from './models-index.ts'\nimport type { MetadataEntry } from './models-index.ts'\nimport styles from './models-plus.module.css'\n\n/** Props of {@link QuickLoad}. */\nexport interface QuickLoadProps {\n /** Apply one metadata entry to the current model draft. */\n onPick: (entry: MetadataEntry) => void\n /** Disable while a write is in flight. */\n disabled: boolean\n}\n\n/**\n * Render the quick-load input with its filtered candidate dropdown.\n * @param props - the pick handler and disabled flag.\n * @returns the quick-load field.\n */\nexport function QuickLoad(props: QuickLoadProps): ReactNode {\n const [query, setQuery] = useState('')\n const [open, setOpen] = useState(false)\n const [index, setIndex] = useState<readonly MetadataEntry[] | undefined>(undefined)\n\n const ensureIndex = (): void => {\n if (index !== undefined) return\n void getMetadataIndex().then((loaded) => { setIndex(loaded) })\n }\n\n const hits = searchModelIds(index, query, 10)\n\n const pick = (id: string): void => {\n const entry = index?.find(candidate => candidate.id === id)\n setOpen(false)\n setQuery('')\n if (entry !== undefined) props.onPick(entry)\n }\n\n return (\n <div className={styles['quickWrap']}>\n <span className={styles['extLabel']}>快速装入</span>\n <input\n className={styles['input']}\n type=\"text\"\n value={query}\n placeholder=\"搜索模型 id(如 aper)…\"\n aria-label=\"快速装入\"\n disabled={props.disabled}\n onFocus={() => { ensureIndex(); setOpen(true) }}\n onBlur={() => { setOpen(false) }}\n onChange={(event) => { setQuery(event.target.value); setOpen(true) }}\n />\n {open\n ? (\n <div className={styles['quickList']}>\n {index === undefined\n ? <span className={styles['quickEmpty']}>元数据预填不可用——点击页首「下载/更新元数据」</span>\n : hits.length === 0\n ? <span className={styles['quickEmpty']}>{query.trim().length === 0 ? '输入关键字搜索模型 id' : '没有匹配的模型'}</span>\n : hits.map(id => (\n <button\n type=\"button\"\n key={id}\n className={styles['quickItem']}\n onMouseDown={(event) => {\n // mousedown beats the input's blur handler.\n event.preventDefault()\n pick(id)\n }}\n >\n {id}\n </button>\n ))}\n </div>\n )\n : null}\n </div>\n )\n}\n","/**\n * One model entry's expanded panel: quick-load, capacities (the official\n * modelAdvanced fields, merged into this block per the v1.0.0 design), input\n * modalities, the developer-role tri-state, the reasoning-effort gate and its\n * gated area (thinking format, then the seven-level effort table).\n *\n * Every edit patches the row's draft object through `onChange` — persistence\n * rides the card's existing path-ops save with no extra wire calls. Clearing\n * the effort gate drops `reasoningEfforts` AND `compat.thinkingFormat` in ONE\n * commit so partial updates never overwrite each other (no orphan settings).\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { THINKING_FORMATS, THINKING_LEVELS } from '../extension-meta.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { formatCapacity, parseCapacity } from './compat.ts'\nimport { QuickLoad } from './QuickLoad.tsx'\nimport type { MetadataEntry } from './models-index.ts'\nimport styles from './models-plus.module.css'\n\n/** The row's compat sub-object as a plain record (absent → empty). */\nfunction compatOf(model: ModelDraft): Record<string, unknown> {\n const value = model['compat']\n return typeof value === 'object' && value !== null && !Array.isArray(value)\n ? value as Record<string, unknown>\n : {}\n}\n\n/** The row's reasoningEfforts dict (absent/invalid → undefined = not declared). */\nfunction effortsOf(model: ModelDraft): Record<string, string | null> | undefined {\n const value = model['reasoningEfforts']\n if (typeof value !== 'object' || value === null || Array.isArray(value)) return undefined\n return value as Record<string, string | null>\n}\n\n/** The row's input modality list (absent → empty, matching the host reader). */\nfunction inputsOf(model: ModelDraft): readonly string[] {\n const value = model['input']\n return Array.isArray(value) ? value.filter((m): m is string => typeof m === 'string') : []\n}\n\n/** Props of {@link ModelEntryPanel}. */\nexport interface ModelEntryPanelProps {\n /** The row's current draft (read). */\n model: ModelDraft\n /** Replace the row with this next draft; `undefined`-valued keys clear them. */\n onChange: (next: ModelDraft) => void\n /** Disable every control (read-only deployment or a pending write). */\n disabled: boolean\n}\n\n/**\n * Render one model entry's expanded panel.\n * @param props - the row draft, its writer, and the disabled flag.\n * @returns the expanded panel.\n */\nexport function ModelEntryPanel(props: ModelEntryPanelProps): ReactNode {\n const { model, onChange, disabled } = props\n\n // Capacities are text-edited, so keystrokes live in this buffer rather than\n // being re-derived from the parsed count (which would rewrite `1000` to\n // `1K` mid-word). Unreadable text stays on screen for the save-time check.\n const [capacityText, setCapacityText] = useState<ReadonlyMap<string, string>>(() => new Map())\n\n /** Patch one key onto the row; `undefined` clears it. */\n const setKey = (key: string, value: unknown): void => {\n const next = { ...model }\n if (value === undefined) Reflect.deleteProperty(next, key)\n else next[key] = value\n onChange(next)\n }\n\n /** Patch one key inside `compat`; an emptied compat leaves no trace. */\n const setCompatKey = (key: string, value: unknown): void => {\n const compat = { ...compatOf(model) }\n if (value === undefined) Reflect.deleteProperty(compat, key)\n else compat[key] = value\n setKey('compat', Object.keys(compat).length === 0 ? undefined : compat)\n }\n\n const setEfforts = (efforts: Record<string, string | null> | undefined): void => {\n setKey('reasoningEfforts', efforts)\n }\n\n const setInput = (modalities: readonly string[]): void => {\n setKey('input', modalities.length === 0 ? undefined : [...modalities])\n }\n\n // --- quick load ----------------------------------------------------------\n const applyMetadata = (entry: MetadataEntry): void => {\n // Only the four metadata fields are overwritten; everything else keeps\n // its draft value (a fresh row already carries the v1.0.0 defaults).\n const next = { ...model }\n if (entry.context === undefined) Reflect.deleteProperty(next, 'contextWindow')\n else next['contextWindow'] = entry.context\n if (entry.output === undefined) Reflect.deleteProperty(next, 'maxTokens')\n else next['maxTokens'] = entry.output\n const compat = { ...compatOf(model) }\n compat['supportsReasoningEffort'] = entry.reasoning\n if (!entry.reasoning) {\n // A non-reasoning model: keep the draft free of orphan gated values.\n Reflect.deleteProperty(compat, 'thinkingFormat')\n Reflect.deleteProperty(next, 'reasoningEfforts')\n }\n setKey('compat', Object.keys(compat).length === 0 ? undefined : compat)\n const supported = entry.input.filter(m => m === 'text' || m === 'image')\n if (supported.length > 0) next['input'] = supported\n onChange(next)\n setCapacityText(new Map())\n }\n\n // --- capacities ----------------------------------------------------------\n const capacityField = (field: 'contextWindow' | 'maxTokens', label: string): ReactNode => {\n const stored = model[field]\n const typed = capacityText.get(field)\n const text = typed ?? (typeof stored === 'number' ? formatCapacity(stored) : '')\n return (\n <label className={styles['modelField']}>\n <span className={styles['modelFieldLabel']}>{label}</span>\n <input\n className={styles['input']}\n type=\"text\"\n inputMode=\"numeric\"\n value={text}\n placeholder=\"使用提供方默认值\"\n aria-label={label}\n disabled={disabled}\n onChange={(event) => {\n setCapacityText(current => new Map(current).set(field, event.target.value))\n setKey(field, parseCapacity(event.target.value))\n }}\n onBlur={() => {\n const raw = capacityText.get(field)\n if (raw === undefined) return\n const parsed = parseCapacity(raw)\n // Unreadable text stays on screen; the save-time check names it.\n if (parsed !== undefined && Number.isNaN(parsed)) return\n setCapacityText(current => {\n const next = new Map(current)\n next.delete(field)\n return next\n })\n }}\n />\n </label>\n )\n }\n\n // --- developer role (tri-state, NOT gated) -------------------------------\n const compat = compatOf(model)\n const developerRole = compat['supportsDeveloperRole'] !== false\n\n // --- effort gate ----------------------------------------------------------\n const supportsReasoningEffort = compat['supportsReasoningEffort'] === true\n const efforts = effortsOf(model)\n\n const toggleGate = (checked: boolean): void => {\n if (checked) {\n setCompatKey('supportsReasoningEffort', true)\n return\n }\n // One commit clears the flag AND every gated node — no orphan settings.\n const nextCompat = { ...compat }\n Reflect.deleteProperty(nextCompat, 'supportsReasoningEffort')\n Reflect.deleteProperty(nextCompat, 'thinkingFormat')\n const next = { ...model, compat: Object.keys(nextCompat).length === 0 ? undefined : nextCompat }\n Reflect.deleteProperty(next, 'reasoningEfforts')\n onChange(next)\n }\n\n const toggleLevel = (level: string, checked: boolean): void => {\n const current = { ...(efforts ?? {}) }\n if (checked) current[level] = level === 'off' ? null : level\n else Reflect.deleteProperty(current, level)\n setEfforts(Object.keys(current).length === 0 ? undefined : current)\n }\n\n const setWireValue = (level: string, text: string): void => {\n if (efforts === undefined || !(level in efforts)) return\n const current = { ...efforts }\n current[level] = text.trim().length === 0 ? null : text.trim()\n setEfforts(current)\n }\n\n // --- validation (mirrors the host checks) --------------------------------\n const declaredLevels = efforts === undefined ? [] : THINKING_LEVELS.filter(level => level in efforts)\n const hasEmptyWire = declaredLevels.some(level =>\n level !== 'off' && String(efforts?.[level] ?? '').trim().length === 0)\n const onlyOffDeclared = efforts !== undefined\n && declaredLevels.length > 0\n && !declaredLevels.some(level => level !== 'off')\n\n // --- input modalities ------------------------------------------------------\n const inputList = inputsOf(model)\n const toggleModality = (modality: string, checked: boolean): void => {\n // Reading defaults to text-bearing rows; an explicit list wins.\n const base = inputList.length === 0 && model['input'] === undefined ? ['text'] : [...inputList]\n setInput(checked ? [...new Set([...base, modality])] : base.filter(m => m !== modality))\n }\n\n return (\n <div className={styles['extBlock']}>\n <div className={`${styles['extGroup']} ${styles['extGroupFirst']}`}>\n <QuickLoad onPick={applyMetadata} disabled={disabled} />\n </div>\n\n <div className={styles['extGroup']}>\n <div className={styles['modelField']} style={{ padding: '0 4px' }}>\n {capacityField('contextWindow', '上下文窗口')}\n {capacityField('maxTokens', '最大输出 token')}\n </div>\n </div>\n\n <div className={styles['extGroup']}>\n <span className={styles['extLabel']} style={{ marginBottom: 6 }}>输入模态</span>\n <div style={{ display: 'flex', gap: 18 }}>\n {['text', 'image'].map(modality => (\n <label key={modality} className={styles['switchRow']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={inputList.includes(modality)}\n disabled={disabled}\n onChange={(event) => { toggleModality(modality, event.target.checked) }}\n />\n {modality === 'text' ? '文本' : '图像'}\n </label>\n ))}\n </div>\n </div>\n\n <div className={styles['extGroup']}>\n <label className={styles['extCheck']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n style={{ marginTop: 3 }}\n checked={developerRole}\n disabled={disabled}\n onChange={(event) => {\n // Checked is the natural default, so a check REMOVES the key;\n // only an explicit uncheck writes `false`.\n setCompatKey('supportsDeveloperRole', event.target.checked ? undefined : false)\n }}\n />\n <span style={{ display: 'flex', flexDirection: 'column', gap: 2 }}>\n <span className={styles['extCheckLabel']}>允许以 developer 角色发送系统提示</span>\n <span className={styles['extHint']}>\n 推理模型的系统提示将以 developer 角色发出;网关拒绝该角色时取消勾选,改用 system。\n </span>\n </span>\n </label>\n </div>\n\n <div className={styles['extGroup']}>\n <label className={styles['switchRow']}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={supportsReasoningEffort}\n disabled={disabled}\n onChange={(event) => { toggleGate(event.target.checked) }}\n />\n 端点接受推理挡位参数(reasoning_effort)\n </label>\n </div>\n\n {/* Gated area: HIDDEN (not dimmed) while the gate is off. */}\n <div className={styles['extGated']} hidden={!supportsReasoningEffort}>\n <div className={styles['extField']}>\n <span className={styles['extLabel']}>思考格式</span>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={typeof compat['thinkingFormat'] === 'string' ? compat['thinkingFormat'] : ''}\n disabled={disabled}\n onChange={(event) => { setCompatKey('thinkingFormat', event.target.value === '' ? undefined : event.target.value) }}\n >\n <option value=\"\">—</option>\n {THINKING_FORMATS.map(format => <option key={format} value={format}>{format}</option>)}\n </select>\n </div>\n\n <div className={styles['extField']}>\n <span className={styles['extLabel']}>推理挡位</span>\n <div className={styles['extTable']}>\n <div className={styles['extTHead']}>\n <div>声明</div><div>挡位</div><div>线上取值</div>\n </div>\n {THINKING_LEVELS.map((level) => {\n const declared = efforts !== undefined && level in efforts\n const isOff = level === 'off'\n const wire = declared ? String(efforts?.[level] ?? '') : ''\n return (\n <div key={level} className={styles['extTRow']}>\n <div style={{ display: 'flex', justifyContent: 'center' }}>\n <input\n type=\"checkbox\"\n className={styles['extCheckbox']}\n checked={declared}\n disabled={disabled}\n aria-label={`声明 ${level}`}\n onChange={(event) => { toggleLevel(level, event.target.checked) }}\n />\n </div>\n <div style={{ opacity: declared ? 1 : 0.5 }}>{level}</div>\n <div style={{ opacity: declared ? 1 : 0.4 }}>\n {declared && !isOff\n ? (\n <input\n type=\"text\"\n value={wire}\n placeholder={level}\n aria-label={`${level} 线上取值`}\n disabled={disabled}\n onChange={(event) => { setWireValue(level, event.target.value) }}\n />\n )\n : <span style={{ fontSize: 12, color: 'var(--dsw-alias-label-tertiary)' }}>—</span>}\n </div>\n </div>\n )\n })}\n </div>\n {hasEmptyWire || onlyOffDeclared\n ? (\n <p className={styles['error']} style={{ marginTop: 6 }}>\n {hasEmptyWire ? '除 off 外勾选的挡位必须填写线上取值。' : '至少声明一个 off 以外的挡位。'}\n </p>\n )\n : null}\n </div>\n </div>\n </div>\n )\n}\n\n","/**\n * One provider profile's model catalog: rows joined from the draft's `models`\n * array, the fetch action (interrogating the endpoint the form currently\n * shows), and the candidate-picker modal. Each row's expanded panel is the\n * plugin's ModelEntryPanel — capacities and extension fields in one block.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { LlmDiscoveredModel } from '@deepseek-ai/dsh-api-remotes/client'\nimport { Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ModelDraft } from './compat.ts'\nimport { newModelDraft } from './presets.ts'\nimport { ModelEntryPanel } from './ModelEntryPanel.tsx'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport styles from './models-plus.module.css'\n\n/** Endpoint facts for the fetch action, taken from the live form. */\nexport interface ProbeTarget {\n readonly settingsNs: string\n readonly provider?: string\n readonly baseURL?: string\n readonly api?: string\n readonly apiKey?: string\n}\n\n/** Props of {@link ModelCatalog}. */\nexport interface ModelCatalogProps {\n /** The drafted rows (inherited rows until the first edit materializes an override). */\n models: readonly ModelDraft[]\n /** Whether the user layer owns the whole array. */\n overridden: boolean\n /** DeepSeek-family route-level fallbacks (undefined on the pi-ai family). */\n defaultContextWindow: number | undefined\n defaultMaxTokens: number | undefined\n /** Endpoint facts for the fetch action. */\n probe: ProbeTarget\n /** Why the fetch action is unavailable, or undefined when it is. */\n probeBlocked?: string\n /** The Host operations whose interrogation answers the fetch action. */\n operations: ModelsOperations\n /** Disable every control (read-only deployment or a pending write). */\n disabled: boolean\n /** Replace the drafted rows. */\n onChange: (models: ModelDraft[]) => void\n /** Remove the user-owned array and return to inheritance. */\n onReset?: () => void\n}\n\n/** A row's text field, or the empty string when unset or not a string. */\nfunction textOf(model: ModelDraft, key: string): string {\n const value = model[key]\n return typeof value === 'string' ? value : ''\n}\n\n/** Adopt one candidate, v1.0.0 defaults + the endpoint's disclosed capacities. */\nfunction adopt(candidate: LlmDiscoveredModel): ModelDraft {\n const row = newModelDraft()\n row['id'] = candidate.id\n row['name'] = candidate.name ?? candidate.id\n if (candidate.contextWindow !== undefined) row['contextWindow'] = candidate.contextWindow\n if (candidate.maxTokens !== undefined) row['maxTokens'] = candidate.maxTokens\n return row\n}\n\n/**\n * Render the model catalog with its fetch action.\n * @param props - the drafted rows, probe target, wire face, and mutators.\n * @returns the catalog editor.\n */\nexport function ModelCatalog(props: ModelCatalogProps): ReactNode {\n const { models, onChange, probe, operations, disabled } = props\n\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n const [candidates, setCandidates] = useState<readonly LlmDiscoveredModel[] | undefined>(undefined)\n const [picked, setPicked] = useState<ReadonlySet<string>>(() => new Set())\n const [query, setQuery] = useState('')\n const [expanded, setExpanded] = useState<ReadonlySet<number>>(() => new Set())\n\n const patch = (index: number, next: Record<string, string | number | undefined>): void => {\n onChange(models.map((model, at) => {\n if (at !== index) return model\n const cleared = new Set(\n Object.entries(next).filter(([, value]) => value === undefined || value === '').map(([key]) => key),\n )\n return Object.fromEntries(\n Object.entries({ ...model, ...next }).filter(([key]) => !cleared.has(key)),\n )\n }))\n }\n\n const toggleExpanded = (index: number): void => {\n setExpanded((current) => {\n const next = new Set(current)\n if (!next.delete(index)) next.add(index)\n return next\n })\n }\n\n const removeRow = (index: number): void => {\n onChange(models.filter((_model, at) => at !== index))\n // Both stores are keyed by position; shift the rows after this one down.\n setExpanded((current) => {\n const next = new Set<number>()\n for (const at of current) {\n if (at < index) next.add(at)\n else if (at > index) next.add(at - 1)\n }\n return next\n })\n }\n\n const fetchModels = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const answer = await operations.discoverModels(probe.settingsNs, {\n ...probe.provider === undefined ? {} : { provider: probe.provider },\n ...probe.baseURL === undefined || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },\n ...probe.api === undefined ? {} : { api: probe.api },\n ...probe.apiKey === undefined ? {} : { apiKey: probe.apiKey },\n })\n if (answer.kind === 'refused') {\n setFailure(answer.message)\n return\n }\n const found = answer.models\n if (found.length === 0) {\n setFailure('该提供方没有列出任何模型,请手动添加。')\n return\n }\n const known = new Set(models.map(model => textOf(model, 'id')))\n setQuery('')\n setCandidates(found)\n setPicked(new Set(found.filter(model => !known.has(model.id)).map(model => model.id)))\n } finally {\n setBusy(false)\n }\n }\n\n const closePicker = (): void => {\n setCandidates(undefined)\n setPicked(new Set())\n setQuery('')\n }\n\n const adoptPicked = (): void => {\n if (candidates === undefined) return\n const byId = new Map(models.map(model => [textOf(model, 'id'), model]))\n for (const candidate of candidates) {\n if (!picked.has(candidate.id)) continue\n // A row the user already tuned wins over the provider's own numbers.\n byId.set(candidate.id, byId.get(candidate.id) ?? adopt(candidate))\n }\n onChange([...byId.values()])\n closePicker()\n }\n\n const toggle = (id: string): void => {\n setPicked((current) => {\n const next = new Set(current)\n if (!next.delete(id)) next.add(id)\n return next\n })\n }\n\n const activeCandidates = candidates ?? []\n const needle = query.trim().toLowerCase()\n const visible = needle.length === 0\n ? activeCandidates\n : activeCandidates.filter(candidate => candidate.id.toLowerCase().includes(needle))\n const allPicked = visible.length > 0 && visible.every(candidate => picked.has(candidate.id))\n\n // A route the adapter already describes answers without an endpoint.\n const askable = probe.provider !== undefined || (probe.baseURL !== undefined && probe.baseURL.length > 0)\n\n return (\n <section className={styles['modelCatalog']} aria-label=\"模型目录\">\n <div className={styles['modelListHead']}>\n <div className={styles['modelCatalogHeading']}>\n <span className={styles['modelCatalogTitle']}>模型目录</span>\n <span className={styles['modelCatalogMeta']}>\n {props.overridden ? '已自定义模型目录' : '正在使用适配器默认模型'}\n </span>\n </div>\n <div style={{ display: 'flex', alignItems: 'center', gap: 4 }}>\n {props.overridden && props.onReset !== undefined\n ? (\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={disabled}\n onClick={props.onReset}\n >\n 恢复默认模型\n </button>\n )\n : null}\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={disabled || busy || !askable || props.probeBlocked !== undefined}\n title={props.probeBlocked !== undefined\n ? props.probeBlocked\n : askable ? undefined : '请先填写 API 地址,再获取。'}\n onClick={() => { void fetchModels() }}\n >\n {busy ? '正在询问提供方…' : '获取可用模型'}\n </button>\n </div>\n </div>\n\n {models.length === 0\n ? <p className={styles['modelEmpty']}>模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。</p>\n : (\n <div className={styles['modelList']}>\n {models.map((model, index) => (\n <div\n key={`${String(index)}:${textOf(model, 'id')}`}\n className={styles['modelEntry']}\n >\n <div className={styles['modelRow']}>\n <input\n className={styles['input']}\n type=\"text\"\n value={textOf(model, 'id')}\n placeholder=\"模型 ID\"\n aria-label={`模型 ID ${String(index + 1)}`}\n disabled={disabled}\n onChange={(event) => { patch(index, { id: event.target.value }) }}\n />\n <input\n className={styles['input']}\n type=\"text\"\n value={textOf(model, 'name')}\n placeholder=\"显示名称\"\n aria-label={`显示名称 ${String(index + 1)}`}\n disabled={disabled}\n onChange={(event) => { patch(index, { name: event.target.value === '' ? undefined : event.target.value }) }}\n />\n <button\n type=\"button\"\n className={styles['iconButton']}\n aria-label={`容量 ${String(index + 1)}`}\n aria-expanded={expanded.has(index)}\n title=\"容量\"\n onClick={() => { toggleExpanded(index) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\" style={{ transform: expanded.has(index) ? 'rotate(90deg)' : undefined, transition: 'transform 120ms ease' }}>\n <path d=\"M6 3.5L10.5 8L6 12.5\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n <button\n type=\"button\"\n className={`${styles['iconButton']} ${styles['iconButtonDanger']}`}\n aria-label={`删除模型 ${String(index + 1)}`}\n title=\"删除模型\"\n disabled={disabled}\n onClick={() => { removeRow(index) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M2.5 4h11M6.5 4V2.5h3V4M4 4l.7 9a1 1 0 001 .9h4.6a1 1 0 001-.9L12 4M6.5 6.8v4.4M9.5 6.8v4.4\" stroke=\"currentColor\" strokeWidth=\"1.3\" strokeLinecap=\"round\" strokeLinejoin=\"round\" />\n </svg>\n </button>\n </div>\n {expanded.has(index)\n ? (\n <ModelEntryPanel\n model={model}\n disabled={disabled}\n onChange={(next) => {\n onChange(models.map((row, at) => (at === index ? next : row)))\n }}\n />\n )\n : null}\n </div>\n ))}\n </div>\n )}\n\n <button\n type=\"button\"\n className={styles['addModelButton']}\n disabled={disabled}\n onClick={() => { onChange([...models, newModelDraft()]) }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加模型\n </button>\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n\n <Modal\n open={candidates !== undefined}\n onClose={closePicker}\n title=\"选择要添加的模型\"\n closeLabel=\"关闭\"\n description=\"以下是模型提供方的可用模型,勾选要添加的模型。\"\n className={styles['fetchDialog'] as string}\n footer={(\n <>\n <button type=\"button\" className={styles['secondaryButton']} onClick={closePicker}>取消</button>\n <button type=\"button\" className={styles['primaryButton']} onClick={adoptPicked}>添加所选</button>\n </>\n )}\n >\n <div className={styles['candidateToolbar']}>\n <input\n className={`${styles['input']} ${styles['candidateSearch']}`}\n type=\"search\"\n value={query}\n placeholder=\"搜索模型\"\n aria-label=\"搜索模型\"\n onChange={(event) => { setQuery(event.target.value) }}\n />\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={visible.length === 0}\n onClick={() => {\n setPicked(current => {\n if (visible.every(candidate => current.has(candidate.id))) {\n return new Set([...current].filter(id => !visible.some(candidate => candidate.id === id)))\n }\n return new Set([...current, ...visible.map(candidate => candidate.id)])\n })\n }}\n >\n {allPicked ? '取消全选' : '全选'}\n </button>\n </div>\n {visible.length === 0\n ? <p className={styles['candidateEmpty']} role=\"status\">没有匹配的模型。</p>\n : (\n <ul className={styles['candidateList']}>\n {visible.map(candidate => (\n <li key={candidate.id} className={styles['candidate']}>\n <label className={styles['candidateLabel']}>\n <input\n type=\"checkbox\"\n checked={picked.has(candidate.id)}\n onChange={() => { toggle(candidate.id) }}\n />\n <span className={styles['candidateId']}>{candidate.id}</span>\n </label>\n </li>\n ))}\n </ul>\n )}\n </Modal>\n </section>\n )\n}\n\n","/**\n * One existing provider's editor card, fully plugin-owned (v1.0.0 rewrite).\n * Primary field: a single write-only API key input; the collapsed\n * 「供应商」 section carries baseURL (plus displayName/protocol for a\n * hand-declared route), the 「模型」 section the model catalog with the\n * extension panel. Save semantics mirror the host card: minimal path ops\n * against the stored section with a revision fence, then the credential\n * write — the draft comes from the user layer, so a wholesale replace can\n * never delete fields outside the card.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { CredentialInfo, SettingsNamespaceView } from '@deepseek-ai/dsh-api-remotes/client'\nimport { deriveKeyRef, protocolChoices } from '../vendor/store.ts'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport type { SettingsSchemaOperations } from '../vendor/schema-operations.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { modelDrafts, normalizeModelRow, pathOps, validateModelRows } from './compat.ts'\nimport { ModelCatalog } from './ModelCatalog.tsx'\nimport styles from './models-plus.module.css'\n\n/** The public DeepSeek endpoint shown as the deepseek base-URL placeholder. */\nconst DEEPSEEK_PUBLIC_BASE_URL = 'https://api.deepseek.com'\n\n/** Per-adapter-family curated field sets (unknown namespaces get the hint alone). */\nexport type EditorLayout = 'deepseek' | 'pi-ai' | 'unknown'\n\n/** The editor layout the owning namespace selects. */\nexport function layoutOf(ns: string): EditorLayout {\n if (ns === 'llm-deepseek') return 'deepseek'\n if (ns === 'llm-pi-ai') return 'pi-ai'\n return 'unknown'\n}\n\n/** A user-section subtree as a plain draft object (absent → empty). */\nexport function draftAt(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n): Record<string, unknown> {\n const subtree = schema.getPath(namespace.user, path)\n if (typeof subtree !== 'object' || subtree === null || Array.isArray(subtree)) return {}\n return structuredClone(subtree) as Record<string, unknown>\n}\n\n/** The credential reference this profile resolves keys through. */\nfunction refFor(\n schema: SettingsSchemaOperations,\n namespace: SettingsNamespaceView,\n path: readonly string[],\n provider: string,\n): string {\n const profile = schema.getPath(namespace.value, path)\n const named = typeof profile === 'object' && profile !== null\n ? (profile as { apiKeyEnv?: unknown }).apiKeyEnv\n : undefined\n return typeof named === 'string' && named.length > 0 ? named : deriveKeyRef(provider)\n}\n\n/** Props of {@link ProviderEditor}. */\nexport interface ProviderEditorProps {\n /** Provider route id. */\n provider: string\n /** Display name for the card title. */\n displayName: string\n /** Whether the adapter reports this route as hand-declared. */\n declared?: boolean\n /** The owning namespace view (schema, layers, secrets). */\n namespace: SettingsNamespaceView\n /** Settings-owned synchronous schema and immutable path operations. */\n schema: SettingsSchemaOperations\n /** Path from the section root to this provider's profile. */\n settingsPath: readonly string[]\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the editor; `changed` reports whether an Apply committed. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render one existing provider's editing card.\n * @param props - the addressed profile plus wire faces.\n * @returns the editor card.\n */\nexport function ProviderEditor(props: ProviderEditorProps): ReactNode {\n const { namespace, schema, settingsPath, operations } = props\n const [draft, setDraft] = useState<Record<string, unknown>>(() => draftAt(schema, namespace, settingsPath))\n const [tab, setTab] = useState<'provider' | 'models'>('provider')\n const [keyDraft, setKeyDraft] = useState('')\n const [keyState, setKeyState] = useState<CredentialInfo | undefined>(undefined)\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n const [committedOriginal, setCommittedOriginal] = useState<unknown>(\n () => schema.getPath(namespace.user, settingsPath),\n )\n const [expectedRevision, setExpectedRevision] = useState(() => namespace.revision)\n const root = useMemo(() => schema.rehydrate(namespace.schema), [namespace.schema, schema])\n const node = useMemo(() => schema.nodeAtPath(root, settingsPath), [root, schema, settingsPath])\n const fallback = schema.getPath(namespace.value, settingsPath)\n const disabled = props.readOnly || busy\n const layout = layoutOf(namespace.ns)\n const keyRef = refFor(schema, namespace, settingsPath, props.provider)\n const protocols = useMemo(\n () => layout === 'pi-ai' ? protocolChoices(namespace, schema) : [],\n [layout, namespace, schema],\n )\n\n useEffect(() => {\n let stale = false\n setKeyState(undefined)\n void operations.describeCredential(keyRef).then((described) => {\n if (stale) return\n setKeyState(described)\n })\n return () => { stale = true }\n }, [operations, keyRef])\n\n const stringAt = (source: unknown, key: string): string | undefined => {\n const value = schema.getPath(source, [key])\n return typeof value === 'string' && value.trim().length > 0 ? value : undefined\n }\n const setField = (key: string, next: string | undefined): void => {\n const value = next === undefined || next.trim().length === 0 ? undefined : next\n setDraft((current) => value === undefined\n ? schema.deletePath(current, [key])\n : schema.setPath(current, [key], value))\n }\n\n const modelFailure = validateModelRows(schema.getPath(draft, ['models']))\n const keyFailure = ((): 'keyBlank' | 'keyIllegalCharacters' | undefined => {\n if (keyDraft.length === 0) return undefined\n const value = keyDraft.trim()\n if (value.length === 0) return 'keyBlank'\n // Mirrors the host's apiKeyFailure heuristics (env line / quoted / charset).\n if (/^[A-Z][A-Z0-9_]*=[^=]/.test(value)) return 'keyIllegalCharacters'\n const first = value[0]\n if ((first === '\"' || first === '\\'' || first === '`') && value.length > 1 && value.endsWith(first)) {\n return 'keyIllegalCharacters'\n }\n return /^[\\x21-\\x7E]+$/.test(value) ? undefined : 'keyIllegalCharacters'\n })()\n const keyValue = keyDraft.trim()\n\n const probe = {\n settingsNs: namespace.ns,\n provider: props.provider,\n ...(() => {\n const baseURL = stringAt(draft, 'baseURL') ?? stringAt(fallback, 'baseURL')\n return baseURL === undefined ? {} : { baseURL }\n })(),\n ...(() => {\n const api = layout === 'pi-ai' && props.declared === true\n ? stringAt(draft, 'api') ?? stringAt(fallback, 'api')\n : undefined\n return api === undefined ? {} : { api }\n })(),\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }\n\n /** The write for this card, or a failure message. */\n const applyOnce = async (): Promise<string | undefined> => {\n const ns = namespace.ns\n let next = layout === 'pi-ai' && stringAt(draft, 'apiKeyEnv') === undefined\n && stringAt(fallback, 'apiKeyEnv') === undefined && keyValue.length > 0\n ? schema.setPath(draft, ['apiKeyEnv'], keyRef)\n : draft\n const rowFailure = validateModelRows(schema.getPath(next, ['models']))\n if (rowFailure !== undefined) {\n return `模型 ${String(rowFailure.index + 1)}:${{\n modelIdRequired: '模型 ID 不能为空。',\n modelIdDuplicate: '模型 ID 不能重复。',\n modelNameInvalid: '显示名称不能为空。',\n modelContextInvalid: '上下文窗口须为正数,如 131072、256K、1M。',\n modelMaxTokensInvalid: '最大输出 token 数须为正数,如 8192、64K、1M。',\n }[rowFailure.key]}`\n }\n if (node !== undefined && settingsPath.length === 0) {\n const sectionError = schema.validate(node, next)\n if (sectionError !== undefined) return sectionError\n }\n // Stable YAML key order: normalize every drafted row before diffing.\n if (schema.hasPath(next, ['models'])) {\n next = schema.setPath(\n next,\n ['models'],\n modelDrafts(schema.getPath(next, ['models'])).map(normalizeModelRow),\n )\n }\n // Official semantic: a pi-ai route whose only act is activating the route\n // (no fields the card can see, no key yet) still writes an empty profile\n // so the route exists in the directory at all.\n const materializesNativeProfile = layout === 'pi-ai'\n && fallback === undefined\n && committedOriginal === undefined\n && Object.keys(next).length === 0\n const ops = materializesNativeProfile\n ? [{ op: 'set', path: [...settingsPath], value: {} }]\n : pathOps(settingsPath, committedOriginal, next)\n if (ops.length > 0) {\n const written = await operations.writeSettings(ns, ops, expectedRevision)\n if (written.kind !== 'written') return written.kind === 'conflict'\n ? '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。'\n : written.message\n setCommittedOriginal(schema.getPath(written.view.user, settingsPath))\n setExpectedRevision(written.view.revision)\n setDraft(next)\n }\n if (keyValue.length > 0) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n setKeyDraft('')\n return undefined\n }\n\n const apply = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const applyFailure = await applyOnce()\n if (applyFailure !== undefined) {\n setFailure(applyFailure)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n if (node === undefined) {\n return <p className={styles['error']}>{props.provider}: 无法解析设置路径</p>\n }\n\n /**\n * The catalog beneath the user layer: the composition entry's pin, or the\n * schema default — reading the effective value would echo the stored\n * override back the moment reset drops it.\n */\n const inheritedModels = (): unknown => {\n const pinned = schema.getPath(namespace.base, [...settingsPath, 'models'])\n return pinned ?? schema.nodeAtPath(root, [...settingsPath, 'models'])?.meta.default\n }\n const customModels = schema.getPath(draft, ['models'])\n const modelsOverridden = schema.hasPath(draft, ['models'])\n const models = modelDrafts(modelsOverridden ? customModels : inheritedModels())\n const defaultContextWindow = schema.getPath(fallback, ['defaultContextWindow'])\n const defaultMaxTokens = schema.getPath(fallback, ['maxTokens'])\n\n const keyPlaceholder = keyState?.writable === false\n ? '由启动环境提供(只读)'\n : keyState?.configured === true\n ? '已配置——输入新值可替换'\n : layout === 'pi-ai' && props.declared === true\n ? '输入 API 密钥,或留空使用环境认证'\n : '输入 API 密钥'\n const keyLocked = keyState?.writable === false\n\n return (\n <div className={styles['editor']}>\n {layout === 'unknown'\n ? <p className={styles['advancedHint']}>其余字段存于 settings.yaml;请直接编辑对应段。({namespace.ns})</p>\n : (\n <>\n <div className={styles['tabs']}>\n <div className={styles['tabBar']} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'provider'} className={tab === 'provider' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('provider') }}>供应商</button>\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'models'} className={tab === 'models' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('models') }}>模型</button>\n </div> <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'provider'}>\n {layout === 'pi-ai' && props.declared === true\n ? (\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>显示名称</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'displayName') ?? ''}\n placeholder={stringAt(schema.getPath(namespace.base, settingsPath), 'displayName')\n ?? props.provider}\n aria-label=\"显示名称\"\n disabled={disabled}\n onChange={(event) => { setField('displayName', event.target.value) }}\n />\n </div>\n )\n : null}\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 密钥</label>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder={keyPlaceholder}\n aria-label=\"API 密钥\"\n disabled={disabled || keyLocked}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{keyFailure === 'keyBlank' ? '请输入 API 密钥;留空则保持已存储的密钥。' : '此 API 密钥格式无效,请检查。'}</p>}\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 地址</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={stringAt(draft, 'baseURL') ?? ''}\n placeholder={layout === 'deepseek'\n ? DEEPSEEK_PUBLIC_BASE_URL\n : stringAt(fallback, 'baseURL') ?? '提供方默认'}\n aria-label=\"API 地址\"\n disabled={disabled}\n onChange={(event) => { setField('baseURL', event.target.value === '' ? undefined : event.target.value) }}\n />\n </div>\n {layout === 'pi-ai' && props.declared === true\n ? (\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 协议</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={stringAt(draft, 'api') ?? stringAt(fallback, 'api') ?? ''}\n aria-label=\"API 协议\"\n disabled={disabled}\n onChange={(event) => { setField('api', event.target.value) }}\n >\n {(stringAt(draft, 'api') ?? stringAt(fallback, 'api')) === undefined\n ? <option value=\"\">未选择</option>\n : null}\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n )\n : null}\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'models'}>\n <ModelCatalog\n models={models}\n overridden={modelsOverridden}\n defaultContextWindow={typeof defaultContextWindow === 'number' ? defaultContextWindow : undefined}\n defaultMaxTokens={typeof defaultMaxTokens === 'number' ? defaultMaxTokens : undefined}\n probe={probe}\n probeBlocked={keyFailure}\n operations={operations}\n disabled={disabled}\n onChange={(rows: ModelDraft[]) => {\n setDraft(current => schema.setPath(current, ['models'], rows))\n }}\n onReset={() => { setDraft(current => schema.deletePath(current, ['models'])) }}\n />\n </div>\n </div>\n </>\n )}\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {modelFailure === undefined\n ? null\n : (\n <p className={styles['advancedHint']}>\n {`模型 ${String(modelFailure.index + 1)}:${modelFailure.key}`}\n </p>\n )}\n\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={busy}\n onClick={() => { props.onClose(false) }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={disabled || layout === 'unknown' || modelFailure !== undefined\n || keyFailure !== undefined}\n onClick={() => { void apply() }}\n >\n {busy ? '保存中…' : '保存'}\n </button>\n </div>\n </div>\n )\n}\n","/**\n * The card that declares a provider pi-ai does not ship — an OpenAI-compatible\n * gateway, a self-hosted server, or a provider newer than the installed\n * catalog. One `settings.mutate` sets the whole profile at `providers.<route>`;\n * the key travels separately through `credentials/set` under the reference\n * the profile records. The three fields a hand-declared route cannot default\n * (endpoint, protocol, at least one model) are required here.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport type { JsonValue } from '@deepseek-ai/dsh-util-values'\nimport { deriveKeyRef } from '../vendor/store.ts'\nimport type { ModelsOperations } from '../vendor/operations.ts'\nimport type { ModelDraft } from './compat.ts'\nimport { normalizeModelRow, validateModelRows } from './compat.ts'\nimport { ModelCatalog } from './ModelCatalog.tsx'\nimport styles from './models-plus.module.css'\n\n/** The settings namespace a hand-declared provider is written into. */\nconst NS = 'llm-pi-ai'\n\n/**\n * A route id usable as a settings key AND as the stem of a credential name.\n */\nconst ROUTE_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/\n\n/** Props of {@link CreateProviderCard}. */\nexport interface CreateProviderCardProps {\n /** Route ids already declared, so the card refuses to shadow one. */\n taken: readonly string[]\n /** Wire protocols the adapter can serve, in the order it reports them. */\n protocols: readonly string[]\n /** Revision of the `llm-pi-ai` user section this card opened at. */\n revision: number\n /** The Host operations this card writes and interrogates through. */\n operations: ModelsOperations\n /** Disable writes (read-only settings provider). */\n readOnly: boolean\n /** Close the card; `changed` reports whether a provider was created. */\n onClose: (changed: boolean) => void\n}\n\n/**\n * Render the custom-provider creation card.\n * @param props - existing routes, protocol choices, wire faces.\n * @returns the creation card.\n */\nexport function CreateProviderCard(props: CreateProviderCardProps): ReactNode {\n const { taken, protocols, operations } = props\n const [openedAt] = useState(() => props.revision)\n const [route, setRoute] = useState('')\n const [displayName, setDisplayName] = useState('')\n const [baseURL, setBaseURL] = useState('')\n const [protocol, setProtocol] = useState(protocols[0] ?? '')\n const [tab, setTab] = useState<'provider' | 'models'>('provider')\n const [keyDraft, setKeyDraft] = useState('')\n const [models, setModels] = useState<readonly ModelDraft[]>([])\n const [busy, setBusy] = useState(false)\n const [failure, setFailure] = useState<string | undefined>(undefined)\n /** The profile write landed; only the key write can still be outstanding. */\n const [committed, setCommitted] = useState(false)\n const disabled = props.readOnly || busy\n const profileDisabled = disabled || committed\n\n const routeInvalid = route.length > 0 && !ROUTE_PATTERN.test(route)\n const routeTaken = taken.includes(route)\n const modelFailure = validateModelRows(models)\n const keyFailure = ((): 'keyBlank' | 'keyIllegalCharacters' | undefined => {\n if (keyDraft.length === 0) return undefined\n const value = keyDraft.trim()\n if (value.length === 0) return 'keyBlank'\n if (/^[A-Z][A-Z0-9_]*=[^=]/.test(value)) return 'keyIllegalCharacters'\n const first = value[0]\n if ((first === '\"' || first === '\\'' || first === '`') && value.length > 1 && value.endsWith(first)) {\n return 'keyIllegalCharacters'\n }\n return /^[\\x21-\\x7E]+$/.test(value) ? undefined : 'keyIllegalCharacters'\n })()\n const keyValue = keyDraft.trim()\n const ready = route.length > 0 && !routeInvalid && !routeTaken\n && baseURL.length > 0 && models.length > 0 && modelFailure === undefined\n && keyFailure === undefined\n const hint = failure !== undefined || ready || keyFailure !== undefined\n || route.length === 0 || routeInvalid || routeTaken\n ? undefined\n : baseURL.length === 0\n ? '自定义提供方需要填写 API 地址。'\n : modelFailure !== undefined\n ? `模型 ${String(modelFailure.index + 1)}:${modelFailure.key}`\n : '自定义提供方至少需要一个模型。'\n\n /** Perform the create, returning a failure message or undefined. */\n const createOnce = async (): Promise<string | undefined> => {\n const keyRef = deriveKeyRef(route)\n const storesKey = keyValue.length > 0\n if (!committed) {\n const profile = {\n ...displayName.length === 0 ? {} : { displayName },\n ...storesKey ? { apiKeyEnv: keyRef } : {},\n api: protocol,\n baseURL,\n models: models.map(normalizeModelRow),\n }\n const written = await operations.writeSettings(\n NS,\n [{ op: 'set', path: ['providers', route], value: profile as JsonValue }],\n openedAt,\n )\n if (written.kind !== 'written') {\n return written.kind === 'conflict'\n ? '这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。'\n : written.message\n }\n // A retry after a failed key write must not re-run this mutate.\n setCommitted(true)\n }\n if (storesKey) {\n const stored = await operations.storeCredential(keyRef, keyValue)\n if (stored !== undefined) return stored\n }\n return undefined\n }\n\n const create = async (): Promise<void> => {\n setBusy(true)\n setFailure(undefined)\n try {\n const outcome = await createOnce()\n if (outcome !== undefined) {\n setFailure(outcome)\n return\n }\n props.onClose(true)\n } finally {\n setBusy(false)\n }\n }\n\n return (\n <div className={styles['editor']}>\n <div className={styles['field']} style={{ paddingTop: 12, borderTop: '0.5px solid var(--dsw-alias-border-l2)' }}>\n <label className={styles['fieldLabel']}>Provider ID</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={route}\n placeholder=\"acme-gateway\"\n aria-label=\"Provider ID\"\n disabled={profileDisabled}\n onChange={(event) => { setRoute(event.target.value) }}\n />\n {routeInvalid || routeTaken\n ? <p className={styles['error']}>{routeInvalid ? '需以小写字母开头,之后可用小写字母、数字和短横线。' : '已有提供方使用了这个 ID。'}</p>\n : <p className={styles['advancedHint']}>以小写字母开头的标识,在请求中唯一标识该提供方,并用于派生凭据名。</p>}\n </div>\n\n <div className={styles['tabs']}>\n <div className={styles['tabBar']} role=\"tablist\">\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'provider'} className={tab === 'provider' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('provider') }}>供应商</button>\n <button type=\"button\" role=\"tab\" aria-selected={tab === 'models'} className={tab === 'models' ? `${styles['tabButton']} ${styles['tabButtonActive']}` : styles['tabButton']} onClick={() => { setTab('models') }}>模型</button>\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'provider'}>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>显示名称</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={displayName}\n placeholder={route.length === 0 ? '显示名称' : route}\n aria-label=\"显示名称\"\n disabled={profileDisabled}\n onChange={(event) => { setDisplayName(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 地址</label>\n <input\n className={styles['input']}\n type=\"text\"\n value={baseURL}\n placeholder=\"https://gateway.example/v1\"\n aria-label=\"API 地址\"\n disabled={profileDisabled}\n onChange={(event) => { setBaseURL(event.target.value) }}\n />\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 协议</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={protocol}\n aria-label=\"API 协议\"\n disabled={profileDisabled}\n onChange={(event) => { setProtocol(event.target.value) }}\n >\n {protocols.map(choice => <option key={choice} value={choice}>{choice}</option>)}\n </select>\n </div>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>API 密钥</label>\n <input\n className={styles['input']}\n type=\"password\"\n autoComplete=\"off\"\n value={keyDraft}\n placeholder=\"输入 API 密钥,或留空使用环境认证\"\n aria-label=\"API 密钥\"\n disabled={disabled}\n onChange={(event) => { setKeyDraft(event.target.value) }}\n />\n {keyFailure === undefined\n ? null\n : <p className={styles['error']}>{keyFailure === 'keyBlank' ? '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。' : '此 API 密钥格式无效,请检查。'}</p>}\n </div>\n </div>\n <div className={styles['tabPanel']} role=\"tabpanel\" hidden={tab !== 'models'}>\n <ModelCatalog\n models={models}\n overridden={true}\n defaultContextWindow={undefined}\n defaultMaxTokens={undefined}\n probe={{\n settingsNs: NS,\n baseURL,\n api: protocol,\n ...keyValue.length === 0 ? {} : { apiKey: keyValue },\n }}\n probeBlocked={keyFailure === 'keyBlank' ? '请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。' : keyFailure}\n operations={operations}\n disabled={profileDisabled}\n onChange={setModels}\n />\n </div>\n </div>\n\n {failure !== undefined ? <p className={styles['error']}>{failure}</p> : null}\n {hint === undefined ? null : <p className={styles['advancedHint']}>{hint}</p>}\n\n <div className={styles['editorActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={busy}\n onClick={() => { props.onClose(committed) }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={styles['primaryButton']}\n disabled={disabled || !ready}\n onClick={() => { void create() }}\n >\n {busy ? '创建中…' : '创建提供方'}\n </button>\n </div>\n </div>\n )\n}\n\n","/**\n * The Models+ settings section (v1.0.0, fully plugin-owned UI): provider rows\n * joined from the configurable directory, settings namespaces, and credential\n * states, one editor card at a time. The title row carries the adapter badge\n * and the metadata download button — the only place models.dev data is ever\n * fetched, on an explicit user click.\n */\n\nimport { useState } from 'react'\nimport type { ReactNode } from 'react'\nimport { Modal } from '@deepseek-ai/dsh-client-ui-primitives'\nimport type { ModelsSettingsStore, ProviderRow } from '../vendor/store.ts'\nimport { deriveKeyRef, protocolChoices, providerUsable } from '../vendor/store.ts'\nimport type { ModelsOperations } from './operations.ts'\nimport type { SettingsSchemaOperations } from './schema-operations.ts'\nimport { downloadMetadata } from './models-index.ts'\nimport { ProviderEditor } from './ProviderEditor.tsx'\nimport { CreateProviderCard } from './CreateProviderCard.tsx'\nimport styles from './models-plus.module.css'\n\n/** One existing row or dormant directory entry addressed by an editor action. */\nexport interface EditorTarget {\n readonly provider: string\n readonly displayName: string\n readonly settingsNs: string\n readonly settingsPath: readonly string[]\n /** Writable credential identified under this page's conventional reference. */\n credentialRef?: string\n readonly declared?: boolean\n}\n\n/** Injected dependencies of {@link ModelsPlusSection} (slot `inject`). */\nexport interface ModelsPlusInjected {\n controller: ModelsSettingsStore\n hooks: {\n snapshot: ModelsSettingsStore['store']\n }\n operations: ModelsOperations\n schema: SettingsSchemaOperations\n t: (key: string) => string\n}\n\n/** One fact decides the first-run posture: whether any provider is usable. */\nfunction needsSetup(row: ProviderRow, anyUsable: boolean): boolean {\n if (anyUsable) return false\n if (row.entry.settingsPath.length > 0) return false\n return row.credential?.configured !== true\n}\n\n/** The credential reference a row resolves keys through, confirmed configured. */\nfunction keyConfiguredOf(row: ProviderRow): boolean {\n return row.apiKeyEnv !== undefined\n ? row.credential?.configured === true\n : row.derivedCredential?.configured === true\n}\n\nfunction targetOf(row: ProviderRow): EditorTarget {\n const managedRef = deriveKeyRef(row.entry.provider)\n const credentialRef = row.apiKeyEnv === managedRef\n && row.credential?.configured === true\n && row.credential.writable\n ? managedRef\n : undefined\n return {\n provider: row.entry.provider,\n displayName: row.entry.displayName,\n settingsNs: row.entry.settingsNs,\n settingsPath: row.entry.settingsPath,\n ...credentialRef === undefined ? {} : { credentialRef },\n ...row.entry.declared === true ? { declared: true } : {},\n }\n}\n\n/**\n * Remove one user-added provider and its page-managed credential. Credential\n * removal comes first so a second-step failure leaves the row retryable.\n */\nasync function removeProviderProfile(\n operations: ModelsOperations,\n controller: ModelsSettingsStore,\n target: { settingsNs: string; settingsPath: readonly string[]; credentialRef?: string },\n): Promise<string | undefined> {\n if (target.credentialRef !== undefined) {\n const credential = await operations.removeCredential(target.credentialRef)\n if (credential !== undefined) return credential\n }\n const written = await operations.writeSettings(\n target.settingsNs,\n [{ op: 'unset', path: [...target.settingsPath] }],\n undefined,\n )\n if (written.kind !== 'written') return written.message\n await controller.load()\n return undefined\n}\n\n/** Replace the one provider placeholder in localized destructive copy. */\nfunction providerCopy(template: string, target: { displayName: string; provider: string }): string {\n const label = target.provider === target.displayName\n ? target.provider\n : `${target.displayName} (${target.provider})`\n return template.replace('{provider}', () => label)\n}\n\n/**\n * Render the Models+ section content column.\n * @param props - slot-delivered injected dependencies.\n * @returns the section, or null while the shell has not injected yet.\n */\nexport function ModelsPlusSection(props: {\n controller?: ModelsPlusInjected['controller']\n useSnapshot?: ModelsPlusInjected['hooks']['snapshot']\n operations?: ModelsPlusInjected['operations']\n schema?: ModelsPlusInjected['schema']\n t?: ModelsPlusInjected['t']\n}): ReactNode {\n const { controller, useSnapshot, operations, schema, t } = props\n if (\n controller === undefined || useSnapshot === undefined || operations === undefined\n || schema === undefined || t === undefined\n ) return null\n // Hooks live in the Loaded child (mirrors the host section): the null check\n // above must not change this component's hook count between renders.\n return <Loaded injected={{ controller, useSnapshot, operations, schema, t }} />\n}\n\nfunction Loaded({ injected }: { injected: ModelsPlusInjected }): ReactNode {\n const { controller, operations, schema, t } = injected\n const useSnapshot = injected.useSnapshot\n\n const state = useSnapshot(snapshot => snapshot)\n const [editing, setEditing] = useState<EditorTarget | undefined>(undefined)\n const [adding, setAdding] = useState(false)\n const [declaring, setDeclaring] = useState(false)\n const [deleteTarget, setDeleteTarget] = useState<EditorTarget | undefined>(undefined)\n const [deleting, setDeleting] = useState(false)\n const [deleteFailure, setDeleteFailure] = useState<string | undefined>(undefined)\n const [savedTarget, setSavedTarget] = useState<{ displayName: string; provider: string } | undefined>(undefined)\n const [dismissedSetup, setDismissedSetup] = useState<ReadonlySet<string>>(() => new Set())\n const [metaBusy, setMetaBusy] = useState(false)\n const [metaMessage, setMetaMessage] = useState<{ ok: boolean; text: string } | undefined>(undefined)\n\n const announceSaved = (target: { displayName: string; provider: string }): void => {\n void controller.load().then(() => { setSavedTarget(target) })\n }\n\n const closeEditor = (changed: boolean, target: { displayName: string; provider: string }): void => {\n setEditing(undefined)\n setAdding(false)\n setDeclaring(false)\n if (changed) announceSaved(target)\n }\n\n const closeSetup = (changed: boolean, target: { displayName: string; provider: string }): void => {\n setDismissedSetup(previous => new Set([...previous, target.provider]))\n if (changed) announceSaved(target)\n }\n\n const downloadMeta = async (): Promise<void> => {\n setMetaBusy(true)\n setMetaMessage(undefined)\n try {\n const outcome = await downloadMetadata()\n setMetaMessage(outcome.ok\n ? { ok: true, text: 'models.dev 元数据已下载并就绪。' }\n : { ok: false, text: `元数据下载失败:${outcome.message}` })\n } finally {\n setMetaBusy(false)\n }\n }\n\n if (state.status === 'idle') void controller.load()\n if (state.status === 'error') {\n const errorText = state.error ?? ''\n return (\n <div className={styles['section']}>\n <p className={styles['error']}>{`加载提供方目录失败: ${errorText}`}</p>\n <button type=\"button\" className={styles['secondaryButton']} onClick={() => { void controller.load() }}>\n 重试\n </button>\n </div>\n )\n }\n\n const savedRow = savedTarget === undefined\n ? undefined\n : state.rows.find(row => row.entry.provider === savedTarget.provider)\n const savedIdentity = savedRow === undefined\n ? savedTarget\n : { displayName: savedRow.entry.displayName, provider: savedRow.entry.provider }\n\n const anyUsable = state.rows.some(providerUsable)\n const configured = state.rows.filter(row => row.configured)\n // Mirrors the host page @ 0.1.5-rc.1: a row is addable only when its\n // settings namespace actually resolved — a namespace name the settings\n // document does not carry would open a card that can never save.\n const configurable = state.rows.filter(row => state.namespaces.has(row.entry.settingsNs))\n const addable = configurable.filter(row => !row.configured)\n const addTarget = adding ? editing : undefined\n const addNamespace = addTarget === undefined ? undefined : state.namespaces.get(addTarget.settingsNs)\n const protocols = (() => {\n // The protocol choices a hand-declared route may name (schema read).\n return protocolChoices(state.namespaces.get('llm-pi-ai'), schema)\n })()\n\n const renderEditor = (\n target: EditorTarget,\n namespace: Parameters<typeof ProviderEditor>[0]['namespace'] | undefined,\n onClose: (changed: boolean) => void,\n ): ReactNode => {\n if (namespace === undefined) return null\n return (\n <ProviderEditor\n provider={target.provider}\n displayName={target.displayName}\n settingsPath={target.settingsPath}\n {...target.declared === true ? { declared: true } : {}}\n namespace={namespace}\n schema={schema}\n operations={operations}\n readOnly={!state.writable}\n onClose={onClose}\n />\n )\n }\n\n return (\n <div className={styles['section']}>\n {/* Title row: heading + metadata download button */}\n <div className={styles['titleRow']}>\n <h2 className={styles['title']}>{t('nav')}</h2>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['linkButton']}\n disabled={metaBusy}\n title=\"下载/更新 models.dev 元数据(供快速装入预填)\"\n onClick={() => { void downloadMeta() }}\n >\n {metaBusy ? '正在下载元数据…' : '下载/更新元数据'}\n </button>\n </span>\n </div>\n {metaMessage === undefined\n ? null\n : <p className={metaMessage.ok ? styles['savedNotice'] : styles['error']}>{metaMessage.text}</p>}\n\n <p className={styles['intro']}>{t('intro')}</p>\n\n {savedIdentity === undefined\n ? null\n : (\n <p className={styles['savedNotice']} role=\"status\" aria-live=\"polite\">\n {providerCopy('已保存 {provider}。', savedIdentity)}\n </p>\n )}\n\n <ul className={styles['rows']}>\n {configured.map((row) => {\n const target = targetOf(row)\n const namespace = state.namespaces.get(target.settingsNs)\n if (namespace === undefined) return null\n // Adapter-reported configuration diagnostic (@ 0.1.5-rc.1): shown\n // above the card so a route that cannot be served still explains why.\n const error = row.entry.error === undefined\n ? null\n : <p role=\"alert\" className={styles['error']}>{row.entry.error}</p>\n if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) {\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n {error}\n {renderEditor(target, namespace, (changed) => { closeSetup(changed, target) })}\n </li>\n )\n }\n const open = !adding && !declaring && editing?.provider === row.entry.provider\n const credentialConfigured = row.credential?.configured === true\n const credentialMissing = !credentialConfigured\n && row.apiKeyEnv !== undefined\n && row.credential?.configured === false\n return (\n <li key={row.entry.provider} className={styles['rowCard']}>\n {error}\n <div className={styles['rowHead']}>\n <span className={styles['rowIdentity']}>\n <span className={styles['rowName']}>{row.entry.displayName}</span>\n {row.entry.declared === true\n ? <span className={styles['rowTag']}>自定义</span>\n : null}\n {credentialConfigured\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotConfigured']}`}\n role=\"img\"\n aria-label=\"API 密钥已配置\"\n title=\"API 密钥已配置\"\n />\n )\n : credentialMissing\n ? (\n <span\n className={`${styles['credentialDot']} ${styles['credentialDotMissing']}`}\n role=\"img\"\n aria-label=\"API 密钥缺失\"\n title=\"API 密钥缺失\"\n />\n )\n : null}\n </span>\n <span className={styles['rowActions']}>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n aria-label={providerCopy('编辑 {provider}', target)}\n onClick={() => {\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(false)\n setEditing(open ? undefined : target)\n }}\n >\n 编辑\n </button>\n {row.removable\n ? (\n <button\n type=\"button\"\n className={styles['dangerButton']}\n aria-label={providerCopy('删除 {provider}', target)}\n disabled={!state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setDeleteFailure(undefined)\n setDeleteTarget(target)\n }}\n >\n 删除\n </button>\n )\n : null}\n </span>\n </div>\n {open\n ? renderEditor(target, namespace, (changed) => { closeEditor(changed, target) })\n : null}\n </li>\n )\n })}\n </ul>\n\n <div className={styles['addBlock']}>\n {addTarget !== undefined && addNamespace !== undefined\n ? (\n <div className={styles['addCard']}>\n <div className={styles['field']}>\n <label className={styles['fieldLabel']}>提供方</label>\n <select\n className={`${styles['input']} ${styles['selectInput']}`}\n value={addTarget.provider}\n aria-label=\"提供方\"\n onChange={(event) => {\n const row = addable.find(candidate => candidate.entry.provider === event.target.value)\n if (row === undefined) return\n setEditing(targetOf(row))\n }}\n >\n {addable.map(row => (\n <option key={row.entry.provider} value={row.entry.provider}>\n {row.entry.displayName}\n </option>\n ))}\n </select>\n </div>\n <ProviderEditor\n key={addTarget.provider}\n provider={addTarget.provider}\n displayName={addTarget.displayName}\n namespace={addNamespace}\n schema={schema}\n settingsPath={addTarget.settingsPath}\n operations={operations}\n readOnly={!state.writable}\n onClose={(changed) => { closeEditor(changed, addTarget) }}\n />\n </div>\n )\n : declaring\n ? (\n <div className={styles['addCard']}>\n <CreateProviderCard\n taken={state.rows.map(row => row.entry.provider)}\n protocols={protocols}\n revision={state.namespaces.get('llm-pi-ai')?.revision ?? 0}\n operations={operations}\n readOnly={!state.writable}\n onClose={(changed) => {\n setDeclaring(false)\n if (changed) void controller.load()\n }}\n />\n </div>\n )\n : (\n <div className={styles['addActions']}>\n {configurable.length > 0 && (\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={addable.length === 0 || !state.writable}\n onClick={() => {\n const first = addable[0]\n if (first === undefined) return\n setSavedTarget(undefined)\n setDeclaring(false)\n setAdding(true)\n setEditing(targetOf(first))\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加提供方\n </button>\n )}\n {state.namespaces.has('llm-pi-ai') && (\n <button\n type=\"button\"\n className={styles['addButton']}\n disabled={protocols.length === 0 || !state.writable}\n onClick={() => {\n setSavedTarget(undefined)\n setAdding(false)\n setEditing(undefined)\n setDeclaring(true)\n }}\n >\n <svg width=\"14\" height=\"14\" viewBox=\"0 0 16 16\" fill=\"none\" aria-hidden=\"true\">\n <path d=\"M8 3.5v9M3.5 8h9\" stroke=\"currentColor\" strokeWidth=\"1.5\" strokeLinecap=\"round\" />\n </svg>\n 添加自定义提供方\n </button>\n )}\n </div>\n )}\n </div>\n\n <Modal\n open={deleteTarget !== undefined}\n onClose={() => {\n if (deleting) return\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }}\n title={deleteTarget === undefined ? '' : providerCopy('删除 {provider}?', deleteTarget)}\n closeLabel=\"关闭\"\n description={deleteTarget === undefined\n ? ''\n : providerCopy(\n deleteTarget.credentialRef === undefined\n ? '删除 {provider} 会移除其配置;其使用的凭证(如有)由其他位置管理,将会保留。'\n : '删除 {provider} 会移除其配置和存储的 API 密钥。',\n deleteTarget,\n )}\n className={styles['deleteDialog'] as string}\n footer={(\n <>\n <button\n type=\"button\"\n className={styles['secondaryButton']}\n disabled={deleting}\n onClick={() => {\n setDeleteTarget(undefined)\n setDeleteFailure(undefined)\n }}\n >\n 取消\n </button>\n <button\n type=\"button\"\n className={`${styles['secondaryButton']} ${styles['deleteConfirm']}`}\n disabled={deleting}\n onClick={() => {\n if (deleteTarget === undefined || deleting) return\n setDeleting(true)\n setDeleteFailure(undefined)\n void removeProviderProfile(operations, controller, deleteTarget)\n .then((removeFailure) => {\n if (removeFailure !== undefined) {\n setDeleteFailure(removeFailure)\n return\n }\n setDeleteTarget(undefined)\n })\n .finally(() => { setDeleting(false) })\n }}\n >\n {deleteTarget === undefined ? '' : providerCopy(deleting ? '正在删除 {provider}…' : '删除 {provider}', deleteTarget)}\n </button>\n </>\n )}\n >\n {deleteFailure === undefined ? null : <p className={styles['error']}>{deleteFailure}</p>}\n </Modal>\n </div>\n )\n}\n\n","/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.5-rc.1\n * (host tree packages/client/ui-settings-models/src/client/operations.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\n/**\n * The Host reads and writes the Models cards perform, as callbacks built in the\n * plugin body. Cards receive these instead of a context: the outcomes name what\n * a card renders — a stored view, a stale revision, a refusal message — so the\n * failure codes and Remote namespaces stay in the apply world.\n */\n\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\nimport type {\n CredentialInfo, LlmDiscoveredModel, LlmModelDiscoveryRequest,\n SettingsNamespaceView, SettingsPathOpView,\n} from '@deepseek-ai/dsh-api-remotes/client'\n\n/** What one namespace write answered. */\nexport type SettingsWriteOutcome =\n /** Committed; the view carries the stored user subtree and the new revision. */\n | { readonly kind: 'written'; readonly view: SettingsNamespaceView }\n /**\n * The stored revision moved after the card read it, so the draft is stale.\n * The message stays for callers that report the Host diagnostic as it is.\n */\n | { readonly kind: 'conflict'; readonly message: string }\n /** Any other refusal, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** What one endpoint interrogation answered. */\nexport type ModelDiscoveryOutcome =\n /** The candidates the provider disclosed, in its own order. */\n | { readonly kind: 'found'; readonly models: readonly LlmDiscoveredModel[] }\n /** The interrogation was refused, with the Host's own diagnostic. */\n | { readonly kind: 'refused'; readonly message: string }\n\n/** The Host operations the Models page and its cards invoke. */\nexport interface ModelsOperations {\n /**\n * Read one credential reference's state.\n * @param ref - credential reference name.\n * @returns the state, or undefined when the reference is unknown or the read was refused.\n */\n describeCredential(ref: string): Promise<CredentialInfo | undefined>\n /**\n * Store one credential literal under its reference.\n * @param ref - credential reference name.\n * @param value - the literal to store.\n * @returns the refusal message, or undefined once stored.\n */\n storeCredential(ref: string, value: string): Promise<string | undefined>\n /**\n * Remove one credential reference (idempotent).\n * @param ref - credential reference name.\n * @returns the refusal message, or undefined once removed.\n */\n removeCredential(ref: string): Promise<string | undefined>\n /**\n * Apply path operations to one settings namespace.\n * @param ns - settings namespace identity.\n * @param ops - ordered path operations against the stored section, as the\n * wire takes them (the Remote signature owns the array).\n * @param expectedRevision - revision the draft was opened at, or undefined to write unfenced.\n * @returns the write outcome the card renders from.\n */\n writeSettings(\n ns: string,\n ops: SettingsPathOpView[],\n expectedRevision: number | undefined,\n ): Promise<SettingsWriteOutcome>\n /**\n * Ask a provider endpoint what models it serves.\n * @param settingsNs - namespace whose adapter family answers.\n * @param request - endpoint facts as the form currently shows them.\n * @returns the candidates, or the refusal.\n */\n discoverModels(settingsNs: string, request: LlmModelDiscoveryRequest): Promise<ModelDiscoveryOutcome>\n}\n\n/**\n * Bind the page's Host operations to the plugin's own Remote namespaces.\n * @param ctx - the page plugin's context, which declares `remote.credentials`,\n * `remote.llm`, and `remote.settings` in its own `inject`.\n * @returns the callbacks the section and its cards are injected with.\n */\nexport function createModelsOperations(ctx: ClientContext): ModelsOperations {\n return {\n describeCredential: async (ref) => {\n const response = await ctx.remote.credentials.describe([ref])\n return response.ok ? response.value[ref] : undefined\n },\n storeCredential: async (ref, value) => {\n const response = await ctx.remote.credentials.set(ref, value)\n return response.ok ? undefined : response.error.message\n },\n removeCredential: async (ref) => {\n const response = await ctx.remote.credentials.unset(ref)\n return response.ok ? undefined : response.error.message\n },\n writeSettings: async (ns, ops, expectedRevision) => {\n const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision)\n if (response.ok) return { kind: 'written', view: response.value }\n const { code, message } = response.error\n return code === 'settings/conflict' ? { kind: 'conflict', message } : { kind: 'refused', message }\n },\n discoverModels: async (settingsNs, request) => {\n const response = await ctx.remote.llm.discoverModels(settingsNs, request)\n return response.ok\n ? { kind: 'found', models: response.value }\n : { kind: 'refused', message: response.error.message }\n },\n }\n}\n","/**\n * VENDORED from @deepseek-ai/dsh-client-ui-settings-models @ 0.1.5-rc.1\n * (host tree packages/client/ui-settings-models/src/client/schema-operations.ts) — copied\n * VERBATIM so the build is self-contained (no host checkout required).\n * Re-diff against the host source on every adapter-anchor bump.\n */\nimport type {\n SettingsSchemaService,\n} from '@deepseek-ai/dsh-client-ui-settings/client'\n\n/** Plain schema callbacks exposed to Models stores and presentation components. */\nexport type SettingsSchemaOperations = Pick<\n SettingsSchemaService,\n 'rehydrate' | 'validate' | 'nodeAtPath' | 'getPath' | 'hasPath' | 'setPath' | 'deletePath'\n>\n\n/**\n * Hide the Cordis service identity behind bound schema callbacks.\n * @param service - settings-owned schema service available in the apply context.\n * @returns callbacks that cannot expose the service context to React components.\n */\nexport function createSettingsSchemaOperations(service: SettingsSchemaService): SettingsSchemaOperations {\n return {\n rehydrate: serialized => service.rehydrate(serialized),\n validate: (schema, draft) => service.validate(schema, draft),\n nodeAtPath: (root, path) => service.nodeAtPath(root, path),\n getPath: (value, path) => service.getPath(value, path),\n hasPath: (value, path) => service.hasPath(value, path),\n setPath: (root, path, value) => service.setPath(root, path, value),\n deletePath: (root, path) => service.deletePath(root, path),\n }\n}\n","/**\n * dsh-model-extension — client entry (v1.0.0).\n *\n * Registers the Models+ settings section rendering the fully plugin-owned\n * models-plus component tree (no host component code is bundled). The store,\n * schema operations, Host operations, dictionaries, and invalidation wiring\n * keep the upstream ui-settings-models contracts @ 0.1.5-rc.1 — the logic\n * modules (store/operations/schema-operations) are still inlined from the\n * host tree at build time, only the presentation is ours.\n */\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\n// Type-only: pulls the shell's SlotMap merge ('settings.section') into this program.\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\n// Type-only: pulls the locale plugin's Context merge (ctx.locale).\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\n// Type-only: pulls the ui renderer's Context merge (useSnapshot and friends on inject faces).\nimport type {} from '@deepseek-ai/dsh-client-ui-renderer/client'\n// Type-only: pulls the ctx.remote merge and forwarded-event key face.\nimport type {} from '@deepseek-ai/dsh-api-remotes/client'\nimport { ModelsPlusSection } from './models-plus/ModelsPlusSection.tsx'\nimport type { ModelsPlusInjected } from './models-plus/ModelsPlusSection.tsx'\nimport { ModelsSettingsStore } from './vendor/store.ts'\nimport { createModelsOperations } from './vendor/operations.ts'\nimport { createSettingsSchemaOperations } from './vendor/schema-operations.ts'\nimport { en as extensionEn, zh as extensionZh } from './extension-meta.ts'\n\n/** Cordis service name (distinct from the npm package name). */\nexport const name = 'model-extension-client'\n\n/** Required services — mirrors the upstream Models section registration @ 0.1.5-rc.1. */\nexport const inject = [\n 'slots', 'locale', 'remote', 'remote.credentials', 'remote.llm', 'remote.settings',\n 'settingsScope', 'settingsSchema',\n]\n\n/** Refetch the page snapshot only after its first load (upstream helper, inlined). */\nfunction refreshIfLoaded(controller: ModelsSettingsStore): void {\n if (controller.store.getSnapshot().status === 'idle') return\n void controller.load()\n}\n\n/**\n * Apply: register the Models+ section once slot/locale services are up.\n * @param ctx - client root context.\n */\nexport function apply(ctx: ClientContext): void {\n const NS = 'settings.models-extension'\n ctx.effect(() => ctx.locale.register(NS, {\n zh: { ...extensionZh },\n en: { ...extensionEn },\n }), 'dsh-model-extension: copy dictionaries')\n\n const schema = createSettingsSchemaOperations(ctx.settingsSchema)\n const operations = createModelsOperations(ctx)\n const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe())\n const t = ctx.locale.bind(NS) as ModelsPlusInjected['t']\n const injected = (): ModelsPlusInjected => ({\n controller,\n hooks: { snapshot: controller.store },\n operations,\n schema,\n t,\n })\n\n // Pushed invalidations converge every open surface without polling.\n ctx.effect(() => {\n const refreshModels = (): void => { refreshIfLoaded(controller) }\n return () => [\n ctx.remote.$on('settings/document-updated', () => { refreshModels() }),\n ctx.remote.$on('credentials/reference-updated', refreshModels),\n ctx.remote.$on('llm/adapters-updated', refreshModels),\n ctx.on('connection/reset', refreshModels),\n ]\n }, 'dsh-model-extension: pushed invalidations')\n\n ctx.slots.inject('settings.section', () => ctx.slots.register({\n name: 'settings.section',\n id: 'models-extension',\n order: 11,\n label: () => t('nav'),\n inject: injected,\n }, ModelsPlusSection))\n}\n"],"mappings":"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"}
package/lib/index.js CHANGED
@@ -19,7 +19,7 @@ import { fileURLToPath } from "node:url";
19
19
  * home. Only the flat models.dev shape (top-level keys = full model ids)
20
20
  * is accepted; anything else is a refusal, per plan.
21
21
  */
22
- const ADAPTER_VERSION = "0.1.5-alpha.2";
22
+ const ADAPTER_VERSION = "0.1.5-rc.1";
23
23
  /** Cordis service name (distinct from the npm package name). */
24
24
  const name = "model-extension";
25
25
  /** Required services — the route registry lives on the host web server. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-model-extension",
3
- "version": "1.1.0-alpha.1",
3
+ "version": "1.1.0",
4
4
  "description": "DeepSeek Harness plugin: the Models+ settings page — a fully plugin-owned model/provider UI with per-model extension fields (reasoning efforts, input modalities, compat flags) and models.dev metadata prefill",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",
@@ -26,7 +26,7 @@
26
26
  "registry": "https://registry.npmjs.org/"
27
27
  },
28
28
  "dsh": {
29
- "adapter": "0.1.5-alpha.2",
29
+ "adapter": "0.1.5-rc.1",
30
30
  "bundle": {
31
31
  "patch": "./cordis.patch.yml"
32
32
  },