@deepseek-ai/dsh-client-ui-settings-models 0.2.1-alpha.1 → 0.2.1-alpha.3
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.i18n.yaml +12 -12
- package/README.md +15 -5
- package/README.zh.md +15 -5
- package/lib/client.js +243 -105
- package/lib/types/client/ApiKeyInput.d.ts +17 -0
- package/lib/types/client/ProviderEditor.d.ts +11 -1
- package/lib/types/client/WelcomeNotice.d.ts +1 -1
- package/lib/types/client/locales.d.ts +14 -3
- package/lib/types/client/operations.d.ts +1 -7
- package/lib/types/client/store.d.ts +17 -4
- package/lib/types/client/welcome-store.d.ts +7 -14
- package/locale/en.json +5 -0
- package/locale/zh.json +6 -0
- package/package.json +19 -18
package/README.i18n.yaml
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 09388d293f9be9cb
|
|
17
17
|
/deepseek-ai-dsh-client-ui-settings-models/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
18
|
+
en: db5aaf7f702e1f0c
|
|
19
|
+
zh: 409a78c14fb2b6e3
|
|
20
20
|
/deepseek-ai-dsh-client-ui-settings-models/use-this-package/api-keys:
|
|
21
|
-
en:
|
|
22
|
-
zh:
|
|
21
|
+
en: f4817eb2e3537ed9
|
|
22
|
+
zh: e589c193fa85473f
|
|
23
23
|
/deepseek-ai-dsh-client-ui-settings-models/use-this-package/editing-a-provider:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
24
|
+
en: eac663a25c60adf9
|
|
25
|
+
zh: 24450ef377a79e01
|
|
26
26
|
/deepseek-ai-dsh-client-ui-settings-models/use-this-package/adding-and-deleting-providers:
|
|
27
27
|
en: 9d533c65c82cd4a4
|
|
28
28
|
zh: 0a5da334e127c035
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
en: 589397a35f82244e
|
|
31
31
|
zh: 342fbceee2c173a2
|
|
32
32
|
/deepseek-ai-dsh-client-ui-settings-models/use-this-package/extension-slots:
|
|
33
|
-
en:
|
|
34
|
-
zh:
|
|
33
|
+
en: 79f8f80bdaba73cd
|
|
34
|
+
zh: f4d7496b293fbf81
|
|
35
35
|
/deepseek-ai-dsh-client-ui-settings-models/understand-the-implementation:
|
|
36
36
|
en: a87afbec5e339b36
|
|
37
37
|
zh: 6348c81af7e650e1
|
|
@@ -39,11 +39,11 @@
|
|
|
39
39
|
en: 74948a88fe1f9aac
|
|
40
40
|
zh: 8ad2200fa74c12c9
|
|
41
41
|
/deepseek-ai-dsh-client-ui-settings-models/understand-the-implementation/concurrency-and-credentials:
|
|
42
|
-
en:
|
|
43
|
-
zh:
|
|
42
|
+
en: 6e04c00818f014cd
|
|
43
|
+
zh: 2d57f8d8944e67ed
|
|
44
44
|
/deepseek-ai-dsh-client-ui-settings-models/understand-the-implementation/onboarding-coordinator:
|
|
45
|
-
en:
|
|
46
|
-
zh:
|
|
45
|
+
en: dc515a31212e477a
|
|
46
|
+
zh: 770ba77cd9a69f73
|
|
47
47
|
/deepseek-ai-dsh-client-ui-settings-models/further-exploration:
|
|
48
48
|
en: 20abd8b98b6c20e2
|
|
49
49
|
zh: 6dfda7955ce5f33f
|
package/README.md
CHANGED
|
@@ -35,17 +35,25 @@ Open the Models page from the Settings navigation to see every configured provid
|
|
|
35
35
|
|
|
36
36
|
A provider with a stored catalog error remains visible with its diagnostic and edit/delete actions. Add actions are offered only for registered settings namespaces, so an unavailable namespace cannot leave a button that opens no editor. A rejected save leaves the editor open and displays the Host diagnostic.
|
|
37
37
|
|
|
38
|
+
After Apply closes an editor, its saved status appears when the current provider, settings, and credential snapshot is ready. Opening any row's editor, adding a provider, and opening a removal confirmation wait for that refresh. A newly opened Models section, or one retrying after a page-load failure, waits for a ready snapshot before mounting editors. A background refresh preserves an open draft while its editor remains mounted; a failed page load or provider removal can close it.
|
|
39
|
+
|
|
38
40
|
Host configuration `credentialOnboarding` defaults to `true`. The Electron preload marker suppresses automatic credential onboarding and the Web welcome notice; Models settings and explicit API-key editing remain available. The [account plugin](../ui-settings-account/README.md#desktop-onboarding) owns the Desktop introduction. Other native shells can disable only the credential step with `credentialOnboarding: false`. Host publishes this public boolean through `webserver/index-inject`, and Client validates it before registering dialogs. It is page initialization data, not a durable completion marker.
|
|
39
41
|
|
|
40
42
|
### API keys
|
|
41
43
|
|
|
42
|
-
API-key inputs start empty and use `autocomplete="new-password"` to ask browsers not to autofill saved login passwords.
|
|
44
|
+
API-key inputs start empty and use `autocomplete="new-password"` to ask browsers not to autofill saved login passwords. A nonempty draft has the same eye control as masked conversation text: **Show secret** reveals the current input and **Hide secret** masks it. Changing or clearing the input masks it again. Stored credentials are never read into the input.
|
|
45
|
+
|
|
46
|
+
The primary field on an editor card is a single **API key** input — the page never asks for an environment-variable name. A typed key stores write-only through `credentials.set` under the profile's reference, deriving `<ROUTE>_API_KEY` when the profile has none, and the pi-ai profile records that derivation as `apiKeyEnv`, so `cordis.patch.yml` never carries a key value. Leaving a new pi-ai provider's key blank saves a reference-free profile and preserves provider-native authentication (for example the Bedrock credential chain or Vertex ADC). The field's placeholder and help tooltip use the profile's `apiKeyEnv` when it has one; otherwise they use the credential variables of the route's `nativeAuth`, excluding `baseURLEnv` address variables, in lookup order, as the configurable-provider directory reports them. These display hints omit references containing `oauth` (case-insensitively), and describe saved credentials followed by the displayed environment fallbacks. This presentation filter does not change the [credential resolution order](../../../docs/subsystems/credentials.md#resolution), the adapter's complete environment list, or an explicit reference. A filtered explicit reference still has a usable key input with the plain placeholder and no tooltip. A native route that has no key authentication omits the key field and authentication help entirely; an explicit reference still enables the field. A profile without a reference on a route without `nativeAuth`, such as a hand-declared route, shows the plain key placeholder and no tooltip. A row labels API-key state with a green solid dot only when a referenced credential is confirmed configured, and with a red solid dot only when a named reference is confirmed missing. A successful Apply emits a local accessible status message without echoing secret material.
|
|
43
47
|
|
|
44
|
-
The
|
|
48
|
+
The editor uses redacted `CredentialInfo` to choose the saved-credential placeholder or environment detection, without displaying a credential-source label. Refreshing the snapshot updates an open editor without a separate probe. The hint never receives a credential value or changes field writability.
|
|
45
49
|
|
|
46
50
|
### Editing a provider
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
A blank key field offers a saved credential when one is detected, with no status text below the input; otherwise it offers environment authentication. Redacted `credentials.describe` checks distinguish a detected environment reference, no detected variables, and an unconfirmed read. A missing-variable hint uses the warning color and names the first variable to configure. A detected environment reference uses green. Address configuration variables do not count as credentials. Hidden authentication references still participate in detection; a generic detected hint keeps their names hidden. Detection does not validate credentials, test a connection, or inspect provider-managed files such as AWS profiles and Google application-default credentials. A nonempty input shows no authentication status text. The page reads native variable names as well as named references, in batches of at most 64, and never reads their values into the Client.
|
|
53
|
+
|
|
54
|
+
An endpoint without a fixed catalog default shows the provider's `baseURLEnv` configuration names below the input. A profile endpoint remains the first placeholder choice.
|
|
55
|
+
|
|
56
|
+
The collapsed 自定义设置 fold carries the curated extras: `baseURL` for both families (the placeholder shows the endpoint the profile resolves to, the public endpoint for deepseek, else the `defaultBaseURL` the configurable-provider directory reports for a pi-ai catalog route), each adapter's model catalog, and the **display name** and **API protocol** of a pi-ai route the adapter does not ship. Profile `headers` remain deployment configuration in `cordis.patch.yml` or Cordis config and have no Models-page editor. The Provider ID stays fixed: it is the settings key, the name every other namespace and every logged session references, and the stem of a credential reference the page cannot read back to move. Reasoning effort is deliberately not among the editable fields: it is a per-model capability, so a provider-scoped control could only be set to a value some models reject. Each model row edits `id`, optional display `name`, optional `contextWindow`/`maxTokens`, and input types; unrelated model fields survive edits.
|
|
49
57
|
|
|
50
58
|
The DeepSeek card edits the `llm-deepseek` endpoint, credentials, and model catalog. It uses Messages, with the default endpoint placeholder `https://api.deepseek.com/anthropic`.
|
|
51
59
|
|
|
@@ -63,7 +71,7 @@ After the versioned notice step completes, the DeepSeek step projects first-run
|
|
|
63
71
|
|
|
64
72
|
The section declares two seats for plugins distributed outside this repository, typed in [`src/client/slot-contract.ts`](src/client/slot-contract.ts) and exported from `./client`. `settings.models.provider-card` (keyed) renders inside every card that shows a directory row — a saved row's card, its first-run setup posture, and the add-provider draft — dispatched with `entryKey = settingsNs` and owner props carrying the row's `ConfigurableProviderView`, its configured state, and its confirmed api-key credential state, so one registration under an adapter family's namespace receives every card of that family, hand-declared routes included; the hand-declared draft card has no directory row yet and dispatches nothing until saved. `settings.models.footer` (list) renders after the rows and the add controls. A registrant activates through `ctx.slots.inject` with a type-only import of this package's `/client` entry; without registrants both seats render nothing.
|
|
65
73
|
|
|
66
|
-
The Models page includes **DeepSeek Account** (`deepseek-account`, **DeepSeek 账号** in Chinese).
|
|
74
|
+
The Models page includes **DeepSeek Account** (`deepseek-account`, **DeepSeek 账号** in Chinese). The row shows a **Signed in** status and offers no editor: the account listing supplies its models, and [model overrides](../../llm/llm-deepseek-account/README.md#use-this-package) live in `cordis.patch.yml`. The account row is hidden when its available model catalog is empty, including before sign-in and after sign-out; it returns when account models become available.
|
|
67
75
|
|
|
68
76
|
-----
|
|
69
77
|
|
|
@@ -83,9 +91,11 @@ A typed API key is judged on its own field: after trimming, it must be non-empty
|
|
|
83
91
|
|
|
84
92
|
Each settings write carries the card's current `revision`, so a concurrent write from another tab or an external `cordis.patch.yml` edit is refused as `settings/conflict`. After settings commit, the card adopts the returned redacted user subtree and revision before storing the credential, so a failed credential stage retries only that stage. Deletion removes a configured, writable credential only when the profile names the page's derived `<ROUTE>_API_KEY` target, then unsets the profile; both operations are idempotent. Once loaded, the page subscribes to forwarded `settings/document-updated`, `credentials/reference-updated`, and `llm/adapters-updated` owner events, plus local `connection/reset`, so external edits converge without polling.
|
|
85
93
|
|
|
94
|
+
Concurrent `ModelsSettingsStore.load()` callers resolve after the current refresh publishes its ready or error snapshot, including callers whose reads were superseded. Older responses cannot publish or settle callers; a refresh started synchronously by a snapshot subscriber owns the waiting callers. Expected Remote failures remain snapshot diagnostics, while an unexpected rejection of the current read rejects its waiting callers.
|
|
95
|
+
|
|
86
96
|
### Onboarding coordinator
|
|
87
97
|
|
|
88
|
-
The notice step owns its exact copy in `src/client/locales.ts` and its acknowledgement version in `src/onboarding-copy.ts
|
|
98
|
+
The notice step owns its exact copy in `src/client/locales.ts` and its acknowledgement version in `src/onboarding-copy.ts`. Authenticated browsers compare and write `ui-settings-general.welcomeNoticeVersion` through the shared configuration form; only an explicit Continue records the current version, and an unavailable namespace or a refused write leaves the notice unacknowledged. Users who acknowledged an earlier version see the current notice again. The DeepSeek step targets `deepseek-official` in `llm-deepseek` and renders the existing `ProviderEditor` in credential-only mode inside the shared onboarding modal; `credentials.set` stays the only secret write, and no provider settings are changed.
|
|
89
99
|
|
|
90
100
|
</details>
|
|
91
101
|
|
package/README.zh.md
CHANGED
|
@@ -35,17 +35,25 @@ kind: "package-reference"
|
|
|
35
35
|
|
|
36
36
|
存在已存储目录错误的提供商仍显示诊断以及编辑、删除入口。添加操作只面向已注册的 settings 命名空间,因此不可用的命名空间不会留下无法打开编辑器的按钮。保存被拒绝时,编辑器保持打开并展示 Host 诊断。
|
|
37
37
|
|
|
38
|
+
应用设置并关闭编辑器后,当前提供商、settings 与凭据快照就绪时才显示保存状态。打开任一行的编辑器、添加提供商和打开移除确认都会等待该刷新。新打开的 Models 区域或页面加载失败后的重试会等到 ready 快照后才挂载编辑器。后台刷新期间,只要编辑器仍挂载,已打开的草稿就会保留用户的修改;页面加载失败或提供商被移除可能关闭编辑器。
|
|
39
|
+
|
|
38
40
|
Host 配置 `credentialOnboarding` 默认为 `true`。Electron preload 标记会抑制自动凭证引导和 Web 欢迎须知;模型设置页与显式 API Key 编辑仍然可用。[账号插件](../ui-settings-account/README.zh.md#desktop-onboarding)负责 Desktop 引导。其他原生壳可以通过 `credentialOnboarding: false` 仅禁用凭证步骤。Host 通过 `webserver/index-inject` 发布这个公开的布尔值,Client 在注册弹窗前校验它。它是页面初始化数据,不是持久化的完成标记。
|
|
39
41
|
|
|
40
42
|
### API 密钥
|
|
41
43
|
|
|
42
|
-
API 密钥输入框初始为空,并通过 `autocomplete="new-password"`
|
|
44
|
+
API 密钥输入框初始为空,并通过 `autocomplete="new-password"` 请求浏览器不要自动填入已保存的登录密码。输入非空时,显示与会话密钥遮罩一致的眼睛按钮:**显示密钥**展示当前输入,**隐藏密钥**重新遮住输入。修改或清空输入后会重新遮住密钥。已保存凭据从不读入输入框。
|
|
45
|
+
|
|
46
|
+
编辑卡片上的主字段是单独一个 **API 密钥**输入框——页面从不询问环境变量名。键入的密钥经 `credentials.set` 以**只写**方式存入 profile 的引用之下,profile 没有引用时便派生 `<ROUTE>_API_KEY`,pi-ai profile 会把这次派生记录为 `apiKeyEnv`,因此 `cordis.patch.yml` 从不携带密钥值。为新的 pi-ai 提供商留空密钥会保存一个不带引用的 profile,从而保留提供商原生认证(例如 Bedrock 凭据链或 Vertex ADC)。profile 有 `apiKeyEnv` 时,字段的占位文字与帮助提示采用该引用;否则按查找顺序采用可配置提供商目录为该路由报告的 `nativeAuth` 凭据变量,并排除 `baseURLEnv` 地址变量。这些显示提示会忽略包含 `oauth` 的引用(不区分大小写),并说明优先使用已保存凭据,其后为显示的环境后备。这项显示过滤不改变[凭据解析顺序](../../../docs/subsystems/credentials.zh.md#resolution)、适配器的完整环境变量列表或显式引用。被过滤的显式引用仍有可用的密钥输入框,使用普通占位文字且不显示帮助提示。没有密钥认证的原生路由不显示密钥字段及认证帮助;显式引用仍会启用该字段。路由没有 `nativeAuth`(例如手动声明的路由)且 profile 没有引用时,显示普通的密钥占位文字,且不显示帮助提示。只有确认引用的凭据已配置时,行才会以绿色实心点标示 API 密钥状态;只有确认具名引用缺失时,才会以红色实心点标示。「应用」成功后会发出本地无障碍状态消息,且绝不回显任何机密内容。
|
|
43
47
|
|
|
44
|
-
|
|
48
|
+
编辑器使用脱敏 `CredentialInfo` 选择已保存凭据的占位文字或环境检测,不显示凭据来源标签。快照刷新会更新打开的编辑器,无需单独探测。提示从不接收凭据值,也不改变字段的可写性。
|
|
45
49
|
|
|
46
50
|
### 编辑提供商
|
|
47
51
|
|
|
48
|
-
|
|
52
|
+
密钥字段留空时,已检测到已保存凭据则提示使用该凭据,输入框下方不显示状态文字;否则提示使用环境认证。脱敏的 `credentials.describe` 检查区分已检测到环境引用、未检测到变量和读取状态未确认。缺少变量时使用黄色提示,并列出应配置的首个变量名。已检测到环境引用时使用绿色。地址配置变量不计作凭据。隐藏的认证引用仍参与检测;使用不含变量名的通用检测提示。检测不验证凭据、不测试连接,也不检查 AWS profile 或 Google 应用默认凭据等提供商管理的文件。输入非空时,不显示认证状态文字。页面读取原生变量名和具名引用,每批最多 64 项,不将变量值读入 Client。
|
|
53
|
+
|
|
54
|
+
目录未提供固定默认端点时,输入框下方显示提供方的 `baseURLEnv` 配置变量名。Profile 中的端点仍是占位符的首选。
|
|
55
|
+
|
|
56
|
+
收起的「自定义设置」折叠区承载精选的额外字段:两个家族都有 `baseURL`(占位符显示 profile 解析出的端点,deepseek 即公共端点;没有时显示可配置提供商目录为 pi-ai 内置路由报告的 `defaultBaseURL`)、各适配器自己的模型目录,以及适配器未提供的 pi-ai 路由的**显示名称**与 **API 协议**。Profile `headers` 仍是 `cordis.patch.yml` 或 Cordis 配置中的部署配置,Models 页面不提供编辑器。Provider ID 保持固定:它是 settings 的键、其他每个 namespace 与每一条已记录会话引用的名字,也是页面读不回、因而搬不走的凭据引用词干。推理等级刻意不在可编辑字段之列:它是按模型的能力,提供商级的控件只可能被设成某些模型会拒绝的值。每个模型行可编辑 `id`、可选显示 `name`、可选 `contextWindow`/`maxTokens` 和输入类型;无关的模型字段在编辑后仍会保留。
|
|
49
57
|
|
|
50
58
|
`llm-deepseek` 的 DeepSeek 卡片编辑端点、凭据和模型目录。它使用 Messages,默认端点占位符为 `https://api.deepseek.com/anthropic`。
|
|
51
59
|
|
|
@@ -63,7 +71,7 @@ API 密钥输入框初始为空,并通过 `autocomplete="new-password"` 请求
|
|
|
63
71
|
|
|
64
72
|
本分区为仓库外分发的插件声明两个席位,类型定义在 [`src/client/slot-contract.ts`](src/client/slot-contract.ts) 并从 `./client` 导出。`settings.models.provider-card`(keyed)渲染在每张展示目录行的卡片内部——已保存行的卡片、其首次运行 setup 形态、以及「添加提供商」草稿卡——以 `entryKey = settingsNs` 分发,owner props 携带该行的 `ConfigurableProviderView`、其 configured 状态与已确认的 api-key 凭据状态,因此以某适配器家族的 namespace 注册一次即可收到该家族的全部卡片,含手工声明的路由;手工声明的草稿卡尚无目录行,保存之前不分发。`settings.models.footer`(list)渲染在行列表与新增控件之后。注册方通过 `ctx.slots.inject` 激活,并以 type-only import 引入本包 `/client` 入口;没有注册方时两个席位均不渲染任何内容。
|
|
65
73
|
|
|
66
|
-
Models 页面包含 **DeepSeek 账号**(`deepseek-account`,英文为 **DeepSeek Account
|
|
74
|
+
Models 页面包含 **DeepSeek 账号**(`deepseek-account`,英文为 **DeepSeek Account**)。该行显示 **已登录** 状态,不提供编辑器:模型来自账号的模型列表,[模型覆盖](../../llm/llm-deepseek-account/README.zh.md#use-this-package)写在 `cordis.patch.yml` 中。账号可用模型目录为空时隐藏账号行,包括登录前和退登后;账号模型恢复可用时重新显示。
|
|
67
75
|
|
|
68
76
|
-----
|
|
69
77
|
|
|
@@ -83,9 +91,11 @@ Models 页面包含 **DeepSeek 账号**(`deepseek-account`,英文为 **DeepS
|
|
|
83
91
|
|
|
84
92
|
每次 settings 写入都携带卡片当前的 `revision`,因此来自另一个标签页或外部 `cordis.patch.yml` 编辑的并发写入会以 `settings/conflict` 被拒绝。settings 提交后,卡片会在存储凭据前采纳返回的脱敏用户子树与 revision,因此失败的凭据阶段只重试该阶段。删除只会在 profile 指名本页派生的 `<ROUTE>_API_KEY` 目标时移除已配置且可写的凭据,然后 unset 该 profile;两个操作都幂等。加载完成后,页面订阅转发的 `settings/document-updated`、`credentials/reference-updated` 与 `llm/adapters-updated` 属主事件,以及本地 `connection/reset`,因此外部编辑无需轮询即可收敛。
|
|
85
93
|
|
|
94
|
+
并发的 `ModelsSettingsStore.load()` 调用会在当前刷新发布 ready 或 error 快照后 resolve,包括读取已被后续刷新取代的调用。旧响应不能发布快照或完成等待中的调用;快照订阅者同步发起的刷新负责等待中的调用。预期的 Remote 失败仍作为快照诊断展示,当前读取的意外拒绝则会拒绝所有等待中的调用。
|
|
95
|
+
|
|
86
96
|
### 引导协调器
|
|
87
97
|
|
|
88
|
-
预览版说明在 `src/client/locales.ts` 中持有精确文案,并在 `src/onboarding-copy.ts`
|
|
98
|
+
预览版说明在 `src/client/locales.ts` 中持有精确文案,并在 `src/onboarding-copy.ts` 中持有确认版本。认证浏览器通过共享配置表单比较并写入 `ui-settings-general.welcomeNoticeVersion`;只有显式点击「继续」才会记录当前版本;命名空间不可用或写入被拒时,声明保持未确认状态。已确认旧版的用户会再次看到当前说明。DeepSeek 步骤面向 `llm-deepseek` 中的 `deepseek-official`,在共享引导模态框内以仅凭据模式渲染既有 `ProviderEditor`;`credentials.set` 仍是唯一的机密写入,且不改变任何提供商设置。
|
|
89
99
|
|
|
90
100
|
</details>
|
|
91
101
|
|
package/lib/client.js
CHANGED
|
@@ -55,7 +55,7 @@ window.__ModuleLoader__.load({
|
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
57
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-models/src/client/ModelsSection.module.css.mjs
|
|
58
|
-
const css$3 = ".zGbnIq_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.zGbnIq_title{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.zGbnIq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.zGbnIq_notice{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}.zGbnIq_savedNotice{color:var(--dsw-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}.zGbnIq_rowCard{border:.5px solid var(--dsw-alias-settings-card-stroke);background:var(--dsw-alias-settings-card-fill);border-radius:var(--dsw-radius-xl);flex-direction:column;gap:12px;padding:12px 14px;display:flex}.zGbnIq_rowHead{align-items:center;gap:10px;display:flex}.zGbnIq_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.zGbnIq_rowName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.zGbnIq_rowTag{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-xs);color:var(--dsw-alias-label-secondary);flex:none;padding:1px 6px;font-size:11px;line-height:16px}.zGbnIq_credentialDot{box-sizing:border-box;corner-shape:round;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.zGbnIq_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.zGbnIq_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.zGbnIq_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.zGbnIq_primaryButton,.zGbnIq_secondaryButton,.zGbnIq_addButton{box-sizing:border-box;border-radius:var(--dsw-radius-md);height:36px;font:inherit;cursor:pointer;border:none;justify-content:center;align-items:center;gap:4px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.zGbnIq_primaryButton{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.zGbnIq_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.zGbnIq_secondaryButton,.zGbnIq_addButton{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary);background:0 0}.zGbnIq_secondaryButton:hover:not(:disabled),.zGbnIq_addButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_secondaryButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.zGbnIq_dangerButton{box-sizing:border-box;border-radius:var(--dsw-radius-md);height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.zGbnIq_dangerButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_rowActions .zGbnIq_secondaryButton,.zGbnIq_rowActions .zGbnIq_dangerButton{border-radius:var(--dsw-radius-sm);height:28px;padding:0 10px;font-size:12px;line-height:18px}.zGbnIq_primaryButton:disabled,.zGbnIq_secondaryButton:disabled,.zGbnIq_dangerButton:disabled,.zGbnIq_addButton:disabled,.zGbnIq_linkButton:disabled,.zGbnIq_addModelButton:disabled{opacity:.4;cursor:default}.zGbnIq_primaryButton:focus-visible,.zGbnIq_secondaryButton:focus-visible,.zGbnIq_dangerButton:focus-visible,.zGbnIq_addButton:focus-visible,.zGbnIq_linkButton:focus-visible,.zGbnIq_addModelButton:focus-visible,.zGbnIq_iconButton:focus-visible,.zGbnIq_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline:none}.zGbnIq_editor{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:14px;padding:14px 16px;display:flex}.zGbnIq_editorHeader{align-items:baseline;gap:8px;display:flex}.zGbnIq_editorTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.zGbnIq_editorRoute{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_field{flex-direction:column;gap:6px;display:flex}.zGbnIq_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.zGbnIq_linkButton{box-sizing:border-box;border-radius:var(--dsw-radius-sm);height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;align-items:center;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.zGbnIq_advancedHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_editorActions{justify-content:flex-end;gap:8px;display:flex}.zGbnIq_addBlock{flex-direction:column;gap:12px;display:flex}.zGbnIq_addActions{display:flex}.zGbnIq_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg);flex:1 1 0;gap:6px;min-width:180px;height:44px}.zGbnIq_addModes{flex-direction:column;align-items:flex-start;gap:8px;display:flex}.zGbnIq_addPanel{flex-direction:column;gap:14px;display:flex}.zGbnIq_addPanel[hidden]{display:none}.zGbnIq_addCard,.zGbnIq_setupCard{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.zGbnIq_addCard .zGbnIq_editor,.zGbnIq_setupCard .zGbnIq_editor{background:0 0;padding:0}.zGbnIq_customized{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:10px}.zGbnIq_customizedSummary{border-radius:var(--dsw-radius-sm);cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.zGbnIq_customizedSummary::-webkit-details-marker{display:none}.zGbnIq_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.zGbnIq_customized[open]>.zGbnIq_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.zGbnIq_customizedSummary:hover{color:var(--dsw-alias-label-primary)}.zGbnIq_customizedBody{flex-direction:column;gap:12px;padding-top:12px;display:flex}.zGbnIq_modelCatalog{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding-top:12px;display:flex}.zGbnIq_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.zGbnIq_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.zGbnIq_modelCatalogMeta,.zGbnIq_modelEmpty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_modelList{flex-direction:column;gap:8px;display:flex}.zGbnIq_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.zGbnIq_modelEntry{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);padding:6px}.zGbnIq_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}.zGbnIq_iconButton{box-sizing:border-box;border-radius:var(--dsw-radius-sm);width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;display:inline-flex}.zGbnIq_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.zGbnIq_iconButton:disabled{cursor:default;opacity:.4}.zGbnIq_iconButtonDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.zGbnIq_modelAdvanced{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 4px 2px;display:grid}.zGbnIq_modelField{flex-direction:column;gap:4px;min-width:0;display:flex}.zGbnIq_modelInputTypes{border:none;grid-column:1/-1;min-width:0;margin:0;padding:0}.zGbnIq_modelInputTypes legend{margin-bottom:4px;padding:0}.zGbnIq_modelInputChoices{flex-wrap:wrap;align-items:center;gap:16px;min-height:32px;display:flex}.zGbnIq_modelFieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_modelEmpty{border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg);text-align:center;padding:12px}.zGbnIq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-sm);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;align-self:flex-start;align-items:center;gap:4px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_addModelButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);padding:0 10px;font-size:14px;line-height:22px}select.zGbnIq_input{cursor:pointer;max-width:240px}.zGbnIq_input:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.zGbnIq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.zGbnIq_input:disabled{opacity:.6;cursor:default}.zGbnIq_selectInput{appearance:none;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-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.zGbnIq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_deleteDialog{width:min(480px,100%)}.zGbnIq_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.zGbnIq_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.zGbnIq_customizedSummary:before,.zGbnIq_switchThumb{transition:none}}.zGbnIq_fetchDialog{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);max-width:520px}.zGbnIq_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.zGbnIq_candidateSearch{flex:240px;min-width:0}.zGbnIq_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.zGbnIq_candidate{border-radius:var(--dsw-radius-md)}.zGbnIq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.zGbnIq_candidateId{min-width:0;font-family:var(--ds-font-family-code);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:13px;overflow:hidden}.zGbnIq_candidateEmpty{color:var(--dsw-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}";
|
|
58
|
+
const css$3 = ".zGbnIq_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.zGbnIq_title{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.zGbnIq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.zGbnIq_notice{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}.zGbnIq_savedNotice{color:var(--dsw-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}.zGbnIq_rowCard{border:.5px solid var(--dsw-alias-settings-card-stroke);background:var(--dsw-alias-settings-card-fill);border-radius:var(--dsw-radius-xl);flex-direction:column;gap:12px;padding:12px 14px;display:flex}.zGbnIq_rowHead{align-items:center;gap:10px;display:flex}.zGbnIq_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.zGbnIq_rowName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.zGbnIq_rowTag{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-xs);color:var(--dsw-alias-label-secondary);flex:none;padding:1px 6px;font-size:11px;line-height:16px}.zGbnIq_credentialDot{box-sizing:border-box;corner-shape:round;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.zGbnIq_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.zGbnIq_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.zGbnIq_accountStatus{color:var(--dsw-alias-state-success-primary);flex:none;align-items:center;gap:6px;font-size:13px;line-height:20px;display:inline-flex}.zGbnIq_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.zGbnIq_primaryButton,.zGbnIq_secondaryButton,.zGbnIq_addButton{box-sizing:border-box;border-radius:var(--dsw-radius-md);height:36px;font:inherit;cursor:pointer;border:none;justify-content:center;align-items:center;gap:4px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.zGbnIq_primaryButton{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.zGbnIq_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.zGbnIq_secondaryButton,.zGbnIq_addButton{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary);background:0 0}.zGbnIq_secondaryButton:hover:not(:disabled),.zGbnIq_addButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_secondaryButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.zGbnIq_dangerButton{box-sizing:border-box;border-radius:var(--dsw-radius-md);height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.zGbnIq_dangerButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_rowActions .zGbnIq_secondaryButton,.zGbnIq_rowActions .zGbnIq_dangerButton{border-radius:var(--dsw-radius-sm);height:28px;padding:0 10px;font-size:12px;line-height:18px}.zGbnIq_primaryButton:disabled,.zGbnIq_secondaryButton:disabled,.zGbnIq_dangerButton:disabled,.zGbnIq_addButton:disabled,.zGbnIq_linkButton:disabled,.zGbnIq_addModelButton:disabled{opacity:.4;cursor:default}.zGbnIq_primaryButton:focus-visible,.zGbnIq_secondaryButton:focus-visible,.zGbnIq_dangerButton:focus-visible,.zGbnIq_addButton:focus-visible,.zGbnIq_linkButton:focus-visible,.zGbnIq_addModelButton:focus-visible,.zGbnIq_iconButton:focus-visible,.zGbnIq_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline:none}.zGbnIq_editor{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:14px;padding:14px 16px;display:flex}.zGbnIq_editorHeader{align-items:baseline;gap:8px;display:flex}.zGbnIq_editorTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.zGbnIq_editorRoute{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_field{flex-direction:column;gap:6px;display:flex}.zGbnIq_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.zGbnIq_helpButton{border:.5px solid var(--dsw-alias-border-l3);corner-shape:round;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);font:inherit;text-align:center;cursor:help;background:0 0;border-radius:50%;padding:0;font-size:11px;line-height:15px}.zGbnIq_helpButton:hover,.zGbnIq_helpButton:focus-visible{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}.zGbnIq_linkButton{box-sizing:border-box;border-radius:var(--dsw-radius-sm);height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;align-items:center;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.zGbnIq_advancedHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_editorActions{justify-content:flex-end;gap:8px;display:flex}.zGbnIq_addBlock{flex-direction:column;gap:12px;display:flex}.zGbnIq_addActions{display:flex}.zGbnIq_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg);flex:1 1 0;gap:6px;min-width:180px;height:44px}.zGbnIq_addModes{flex-direction:column;align-items:flex-start;gap:8px;display:flex}.zGbnIq_addPanel{flex-direction:column;gap:14px;display:flex}.zGbnIq_addPanel[hidden]{display:none}.zGbnIq_addCard,.zGbnIq_setupCard{border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-bg-module-platform);flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.zGbnIq_addCard .zGbnIq_editor,.zGbnIq_setupCard .zGbnIq_editor{background:0 0;padding:0}.zGbnIq_customized{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:10px}.zGbnIq_customizedSummary{border-radius:var(--dsw-radius-sm);cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.zGbnIq_customizedSummary::-webkit-details-marker{display:none}.zGbnIq_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.zGbnIq_customized[open]>.zGbnIq_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.zGbnIq_customizedSummary:hover{color:var(--dsw-alias-label-primary)}.zGbnIq_customizedBody{flex-direction:column;gap:12px;padding-top:12px;display:flex}.zGbnIq_modelCatalog{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding-top:12px;display:flex}.zGbnIq_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.zGbnIq_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.zGbnIq_modelCatalogMeta,.zGbnIq_modelEmpty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_modelList{flex-direction:column;gap:8px;display:flex}.zGbnIq_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.zGbnIq_modelEntry{border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-lg);padding:6px}.zGbnIq_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}.zGbnIq_iconButton{box-sizing:border-box;border-radius:var(--dsw-radius-sm);width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;display:inline-flex}.zGbnIq_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.zGbnIq_iconButton:disabled{cursor:default;opacity:.4}.zGbnIq_iconButtonDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.zGbnIq_modelAdvanced{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 4px 2px;display:grid}.zGbnIq_modelField{flex-direction:column;gap:4px;min-width:0;display:flex}.zGbnIq_modelInputTypes{border:none;grid-column:1/-1;min-width:0;margin:0;padding:0}.zGbnIq_modelInputTypes legend{margin-bottom:4px;padding:0}.zGbnIq_modelInputChoices{flex-wrap:wrap;align-items:center;gap:16px;min-height:32px;display:flex}.zGbnIq_modelFieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_modelEmpty{border:1px dashed var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-lg);text-align:center;padding:12px}.zGbnIq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-sm);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;align-self:flex-start;align-items:center;gap:4px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_addModelButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);padding:0 10px;font-size:14px;line-height:22px}select.zGbnIq_input{cursor:pointer;max-width:240px}.zGbnIq_input:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}.zGbnIq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.zGbnIq_input:disabled{opacity:.6;cursor:default}.zGbnIq_keyInput{position:relative}.zGbnIq_keyInputFilled{padding-right:40px}.zGbnIq_keyToggle{border-radius:var(--dsw-radius-md);width:32px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute;inset:1px 1px 1px auto}.zGbnIq_keyToggle:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.zGbnIq_keyToggle:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}.zGbnIq_keyToggle:disabled{opacity:.6;cursor:default}.zGbnIq_selectInput{appearance:none;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-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.zGbnIq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_deleteDialog{width:min(480px,100%)}.zGbnIq_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.zGbnIq_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.zGbnIq_customizedSummary:before,.zGbnIq_switchThumb{transition:none}}.zGbnIq_fetchDialog{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);max-width:520px}.zGbnIq_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.zGbnIq_candidateSearch{flex:240px;min-width:0}.zGbnIq_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.zGbnIq_candidate{border-radius:var(--dsw-radius-md)}.zGbnIq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.zGbnIq_candidateId{min-width:0;font-family:var(--ds-font-family-code);text-overflow:ellipsis;white-space:nowrap;flex:auto;font-size:13px;overflow:hidden}.zGbnIq_candidateEmpty{color:var(--dsw-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}";
|
|
59
59
|
const tagId$3 = "@deepseek-ai/dsh-client-ui-settings-models/ModelsSection.module.css";
|
|
60
60
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
61
61
|
const tag = document.createElement("style");
|
|
@@ -65,6 +65,7 @@ window.__ModuleLoader__.load({
|
|
|
65
65
|
document.head.appendChild(tag);
|
|
66
66
|
}
|
|
67
67
|
var ModelsSection_module_css_default = {
|
|
68
|
+
"accountStatus": "zGbnIq_accountStatus",
|
|
68
69
|
"addActions": "zGbnIq_addActions",
|
|
69
70
|
"addBlock": "zGbnIq_addBlock",
|
|
70
71
|
"addButton": "zGbnIq_addButton",
|
|
@@ -98,11 +99,15 @@ window.__ModuleLoader__.load({
|
|
|
98
99
|
"fetchDialog": "zGbnIq_fetchDialog",
|
|
99
100
|
"field": "zGbnIq_field",
|
|
100
101
|
"fieldLabel": "zGbnIq_fieldLabel",
|
|
102
|
+
"helpButton": "zGbnIq_helpButton",
|
|
101
103
|
"hiddenLabel": "zGbnIq_hiddenLabel",
|
|
102
104
|
"iconButton": "zGbnIq_iconButton",
|
|
103
105
|
"iconButtonDanger": "zGbnIq_iconButtonDanger",
|
|
104
106
|
"input": "zGbnIq_input",
|
|
105
107
|
"intro": "zGbnIq_intro",
|
|
108
|
+
"keyInput": "zGbnIq_keyInput",
|
|
109
|
+
"keyInputFilled": "zGbnIq_keyInputFilled",
|
|
110
|
+
"keyToggle": "zGbnIq_keyToggle",
|
|
106
111
|
"linkButton": "zGbnIq_linkButton",
|
|
107
112
|
"modelAdvanced": "zGbnIq_modelAdvanced",
|
|
108
113
|
"modelCatalog": "zGbnIq_modelCatalog",
|
|
@@ -136,6 +141,55 @@ window.__ModuleLoader__.load({
|
|
|
136
141
|
"title": "zGbnIq_title"
|
|
137
142
|
};
|
|
138
143
|
//#endregion
|
|
144
|
+
//#region lib/types/client/ApiKeyInput.js
|
|
145
|
+
/** Write-only credential input with the same reveal behavior as masked conversation text. */
|
|
146
|
+
const EYE_CONTOUR = "M1.5 8C2.9 5.25 5.25 3.5 8 3.5C10.75 3.5 13.1 5.25 14.5 8C13.1 10.75 10.75 12.5 8 12.5C5.25 12.5 2.9 10.75 1.5 8Z";
|
|
147
|
+
const EYE_PATH = `${EYE_CONTOUR}M10 8C10 9.1 9.1 10 8 10C6.9 10 6 9.1 6 8C6 6.9 6.9 6 8 6C9.1 6 10 6.9 10 8Z`;
|
|
148
|
+
const EYE_OFF_PATH = `${EYE_CONTOUR}M2.5 2.5L13.5 13.5`;
|
|
149
|
+
/**
|
|
150
|
+
* Reveal only a nonempty draft; a different value starts masked, as in SecretText.
|
|
151
|
+
* @param props - current draft, input attributes, and translated control labels.
|
|
152
|
+
* @returns a password input with an optional reveal button.
|
|
153
|
+
*/
|
|
154
|
+
function ApiKeyInput({ value, t, ...props }) {
|
|
155
|
+
const [revealedValue, setRevealedValue] = (0, react.useState)();
|
|
156
|
+
const revealed = value.length > 0 && revealedValue === value;
|
|
157
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
158
|
+
className: ModelsSection_module_css_default["keyInput"],
|
|
159
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
160
|
+
...props,
|
|
161
|
+
className: `${ModelsSection_module_css_default["input"]} ${value.length > 0 ? ModelsSection_module_css_default["keyInputFilled"] : ""}`,
|
|
162
|
+
type: revealed ? "text" : "password",
|
|
163
|
+
autoComplete: "new-password",
|
|
164
|
+
value,
|
|
165
|
+
onChange: (event) => {
|
|
166
|
+
setRevealedValue(void 0);
|
|
167
|
+
props.onChange?.(event);
|
|
168
|
+
}
|
|
169
|
+
}), value.length === 0 ? null : (0, react_jsx_runtime.jsx)("button", {
|
|
170
|
+
type: "button",
|
|
171
|
+
className: ModelsSection_module_css_default["keyToggle"],
|
|
172
|
+
"aria-label": t(revealed ? "keyHide" : "keyReveal"),
|
|
173
|
+
"aria-pressed": revealed,
|
|
174
|
+
disabled: props.disabled,
|
|
175
|
+
onClick: () => {
|
|
176
|
+
setRevealedValue(revealed ? void 0 : value);
|
|
177
|
+
},
|
|
178
|
+
children: (0, react_jsx_runtime.jsx)("svg", {
|
|
179
|
+
width: "16",
|
|
180
|
+
height: "16",
|
|
181
|
+
viewBox: "0 0 16 16",
|
|
182
|
+
fill: "none",
|
|
183
|
+
stroke: "currentColor",
|
|
184
|
+
strokeWidth: 1.3,
|
|
185
|
+
strokeLinecap: "round",
|
|
186
|
+
"aria-hidden": "true",
|
|
187
|
+
children: (0, react_jsx_runtime.jsx)("path", { d: revealed ? EYE_OFF_PATH : EYE_PATH })
|
|
188
|
+
})
|
|
189
|
+
})]
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
//#endregion
|
|
139
193
|
//#region lib/types/client/EditorFooter.js
|
|
140
194
|
/**
|
|
141
195
|
* Render one provider card's action row.
|
|
@@ -914,6 +968,9 @@ window.__ModuleLoader__.load({
|
|
|
914
968
|
settingsPath: [...entry.settingsPath],
|
|
915
969
|
active: active.has(entry.provider),
|
|
916
970
|
...entry.declared === void 0 ? {} : { declared: entry.declared },
|
|
971
|
+
...entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: entry.defaultBaseURL },
|
|
972
|
+
...entry.baseURLEnv === void 0 ? {} : { baseURLEnv: entry.baseURLEnv },
|
|
973
|
+
...entry.nativeAuth === void 0 ? {} : { nativeAuth: entry.nativeAuth },
|
|
917
974
|
...entry.error === void 0 ? {} : { error: entry.error }
|
|
918
975
|
}));
|
|
919
976
|
for (const provider of registered) {
|
|
@@ -981,6 +1038,8 @@ window.__ModuleLoader__.load({
|
|
|
981
1038
|
});
|
|
982
1039
|
/** Latest load wins; an older response never overwrites a newer one. */
|
|
983
1040
|
generation = 0;
|
|
1041
|
+
/** Callers follow the current refresh's outcome, including callers whose read was superseded. */
|
|
1042
|
+
pendingLoads = /* @__PURE__ */ new Set();
|
|
984
1043
|
/**
|
|
985
1044
|
* @param ctx - the page plugin's context, whose `remote.llm` and
|
|
986
1045
|
* `remote.credentials` namespaces carry the directory and credential reads.
|
|
@@ -997,11 +1056,28 @@ window.__ModuleLoader__.load({
|
|
|
997
1056
|
* settings answer in parallel, then one batched credential describe over
|
|
998
1057
|
* every referenced ref. Provider failure or absence of an initial settings
|
|
999
1058
|
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
1000
|
-
* refresh reuses the mirror's held view.
|
|
1001
|
-
*
|
|
1059
|
+
* refresh reuses the mirror's held view. Concurrent callers resolve only
|
|
1060
|
+
* after the current refresh publishes its ready or error snapshot.
|
|
1061
|
+
* @returns resolution after the current snapshot is published.
|
|
1062
|
+
* @throws the current read's unexpected rejection; superseded rejections are ignored.
|
|
1002
1063
|
*/
|
|
1003
|
-
|
|
1064
|
+
load() {
|
|
1065
|
+
const pending = Promise.withResolvers();
|
|
1066
|
+
this.pendingLoads.add(pending);
|
|
1004
1067
|
const generation = ++this.generation;
|
|
1068
|
+
this.read(generation).then(() => {
|
|
1069
|
+
this.settleLoads(generation, (load) => {
|
|
1070
|
+
load.resolve();
|
|
1071
|
+
});
|
|
1072
|
+
}, (error) => {
|
|
1073
|
+
this.settleLoads(generation, (load) => {
|
|
1074
|
+
load.reject(error);
|
|
1075
|
+
});
|
|
1076
|
+
});
|
|
1077
|
+
return pending.promise;
|
|
1078
|
+
}
|
|
1079
|
+
/** Publish one joined answer; stale answers leave the current refresh in charge. */
|
|
1080
|
+
async read(generation) {
|
|
1005
1081
|
this.store.update((s) => {
|
|
1006
1082
|
s.status = "loading";
|
|
1007
1083
|
s.error = null;
|
|
@@ -1011,17 +1087,20 @@ window.__ModuleLoader__.load({
|
|
|
1011
1087
|
this.ctx.remote.llm.listConfigurableProviders(),
|
|
1012
1088
|
this.describeFace.ensure()
|
|
1013
1089
|
]);
|
|
1090
|
+
if (generation !== this.generation) return;
|
|
1014
1091
|
if (!registered.ok) {
|
|
1015
|
-
this.failLoad(
|
|
1092
|
+
this.failLoad(registered.error.message);
|
|
1016
1093
|
return;
|
|
1017
1094
|
}
|
|
1018
1095
|
if (!declared.ok) {
|
|
1019
|
-
this.failLoad(
|
|
1096
|
+
this.failLoad(declared.error.message);
|
|
1020
1097
|
return;
|
|
1021
1098
|
}
|
|
1022
1099
|
const mirrored = this.describeFace.getSnapshot();
|
|
1023
1100
|
if (mirrored.view === void 0) {
|
|
1024
|
-
|
|
1101
|
+
/* v8 ignore next -- SettingsDescribeFace.ensure settles with a view or the read's error */
|
|
1102
|
+
if (mirrored.error === null) throw new Error("settings describe settled with neither a view nor an error");
|
|
1103
|
+
this.failLoad(mirrored.error);
|
|
1025
1104
|
return;
|
|
1026
1105
|
}
|
|
1027
1106
|
const providers = joinProviderDirectory(registered.value, declared.value);
|
|
@@ -1042,13 +1121,16 @@ window.__ModuleLoader__.load({
|
|
|
1042
1121
|
const catalog = await this.ctx.remote.session.modelCatalog();
|
|
1043
1122
|
for (const row of rows) if (row.entry.provider === "deepseek-account") row.accountAvailable = catalog.ok && catalog.value.groups.some((group) => group.id === "deepseek-account" && group.models.length > 0);
|
|
1044
1123
|
}
|
|
1045
|
-
const refs = [...new Set(rows.filter((row) => row.entry.provider !== "deepseek-account").
|
|
1046
|
-
|
|
1124
|
+
const refs = [...new Set(rows.filter((row) => row.entry.provider !== "deepseek-account").flatMap((row) => row.apiKeyEnv === void 0 ? [deriveKeyRef(row.entry.provider), ...row.entry.nativeAuth?.env ?? []] : [row.apiKeyEnv]))];
|
|
1125
|
+
const credentials = {};
|
|
1047
1126
|
let credentialError = null;
|
|
1048
|
-
|
|
1049
|
-
const response = await this.ctx.remote.credentials.describe(refs);
|
|
1050
|
-
if (response.ok) credentials
|
|
1051
|
-
else
|
|
1127
|
+
for (let index = 0; index < refs.length; index += 64) {
|
|
1128
|
+
const response = await this.ctx.remote.credentials.describe(refs.slice(index, index + 64));
|
|
1129
|
+
if (response.ok) Object.assign(credentials, response.value);
|
|
1130
|
+
else {
|
|
1131
|
+
credentialError = response.error.message;
|
|
1132
|
+
break;
|
|
1133
|
+
}
|
|
1052
1134
|
}
|
|
1053
1135
|
if (generation !== this.generation) return;
|
|
1054
1136
|
this.store.update((s) => {
|
|
@@ -1063,15 +1145,25 @@ window.__ModuleLoader__.load({
|
|
|
1063
1145
|
return {
|
|
1064
1146
|
...row,
|
|
1065
1147
|
...named === void 0 ? {} : { credential: named },
|
|
1066
|
-
...derived === void 0 ? {} : { derivedCredential: derived }
|
|
1148
|
+
...derived === void 0 ? {} : { derivedCredential: derived },
|
|
1149
|
+
...credentialError === null ? { credentialChecks: Object.fromEntries((row.apiKeyEnv === void 0 ? row.entry.nativeAuth?.env ?? [] : [row.apiKeyEnv]).flatMap((ref) => {
|
|
1150
|
+
const info = credentials[ref];
|
|
1151
|
+
return info === void 0 ? [] : [[ref, info]];
|
|
1152
|
+
})) } : {}
|
|
1067
1153
|
};
|
|
1068
1154
|
});
|
|
1069
1155
|
s.namespaces = namespaces;
|
|
1070
1156
|
});
|
|
1071
1157
|
}
|
|
1072
|
-
/**
|
|
1073
|
-
|
|
1158
|
+
/** Settle callers only while this read still owns the current refresh. */
|
|
1159
|
+
settleLoads(generation, settle) {
|
|
1074
1160
|
if (generation !== this.generation) return;
|
|
1161
|
+
const pending = [...this.pendingLoads];
|
|
1162
|
+
this.pendingLoads.clear();
|
|
1163
|
+
for (const load of pending) settle(load);
|
|
1164
|
+
}
|
|
1165
|
+
/** Publish the current joined read's failure text. */
|
|
1166
|
+
failLoad(message) {
|
|
1075
1167
|
this.store.update((s) => {
|
|
1076
1168
|
s.status = "error";
|
|
1077
1169
|
s.error = message;
|
|
@@ -1375,10 +1467,8 @@ window.__ModuleLoader__.load({
|
|
|
1375
1467
|
className: ModelsSection_module_css_default["fieldLabel"],
|
|
1376
1468
|
children: t("keyInput")
|
|
1377
1469
|
}),
|
|
1378
|
-
(0, react_jsx_runtime.jsx)(
|
|
1379
|
-
|
|
1380
|
-
type: "password",
|
|
1381
|
-
autoComplete: "new-password",
|
|
1470
|
+
(0, react_jsx_runtime.jsx)(ApiKeyInput, {
|
|
1471
|
+
t,
|
|
1382
1472
|
value: keyDraft,
|
|
1383
1473
|
placeholder: t("keyPlaceholder"),
|
|
1384
1474
|
"aria-label": t("keyInput"),
|
|
@@ -1510,7 +1600,6 @@ window.__ModuleLoader__.load({
|
|
|
1510
1600
|
const { namespace, schema, settingsPath, operations, t } = props;
|
|
1511
1601
|
const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
|
|
1512
1602
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1513
|
-
const [keyState, setKeyState] = (0, react.useState)(void 0);
|
|
1514
1603
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
1515
1604
|
const [listBusy, setListBusy] = (0, react.useState)(false);
|
|
1516
1605
|
const { onBusyChange } = props;
|
|
@@ -1532,30 +1621,13 @@ window.__ModuleLoader__.load({
|
|
|
1532
1621
|
]);
|
|
1533
1622
|
const fallback = schema.getPath(namespace.value, settingsPath);
|
|
1534
1623
|
const disabled = props.readOnly || busy;
|
|
1535
|
-
const
|
|
1536
|
-
const layout = accountProvider ? "deepseek" : layoutOf(namespace.ns);
|
|
1624
|
+
const layout = layoutOf(namespace.ns);
|
|
1537
1625
|
const keyRef = refFor(schema, namespace, settingsPath, props.provider);
|
|
1538
1626
|
const protocols = (0, react.useMemo)(() => layout === "pi-ai" ? protocolChoices(namespace, schema) : [], [
|
|
1539
1627
|
layout,
|
|
1540
1628
|
namespace,
|
|
1541
1629
|
schema
|
|
1542
1630
|
]);
|
|
1543
|
-
(0, react.useEffect)(() => {
|
|
1544
|
-
if (accountProvider) return;
|
|
1545
|
-
let stale = false;
|
|
1546
|
-
setKeyState(void 0);
|
|
1547
|
-
operations.describeCredential(keyRef).then((described) => {
|
|
1548
|
-
if (stale) return;
|
|
1549
|
-
setKeyState(described);
|
|
1550
|
-
});
|
|
1551
|
-
return () => {
|
|
1552
|
-
stale = true;
|
|
1553
|
-
};
|
|
1554
|
-
}, [
|
|
1555
|
-
operations,
|
|
1556
|
-
keyRef,
|
|
1557
|
-
accountProvider
|
|
1558
|
-
]);
|
|
1559
1631
|
const stringAt = (source, key) => {
|
|
1560
1632
|
const value = schema.getPath(source, [key]);
|
|
1561
1633
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -1637,7 +1709,6 @@ window.__ModuleLoader__.load({
|
|
|
1637
1709
|
props.t("settingsPathUnresolvable")
|
|
1638
1710
|
]
|
|
1639
1711
|
});
|
|
1640
|
-
const keyLocked = keyState?.writable === false;
|
|
1641
1712
|
/**
|
|
1642
1713
|
* The catalog beneath the user layer: what the composition entry pinned, or
|
|
1643
1714
|
* else the schema default that `resolve` would supply. The effective value
|
|
@@ -1661,7 +1732,38 @@ window.__ModuleLoader__.load({
|
|
|
1661
1732
|
const defaultContextWindow = schema.getPath(fallback, ["defaultContextWindow"]);
|
|
1662
1733
|
const defaultMaxTokens = schema.getPath(fallback, ["maxTokens"]);
|
|
1663
1734
|
const defaultInput = schema.getPath(fallback, ["defaultInput"]);
|
|
1664
|
-
const
|
|
1735
|
+
const baseURL = stringAt(fallback, "baseURL") ?? props.defaultBaseURL;
|
|
1736
|
+
const endpointEnv = props.baseURLEnv ?? [];
|
|
1737
|
+
const endpointHint = family === "deepseek" ? t("deepSeekEndpointHint") : baseURL === void 0 && endpointEnv.length > 0 ? t("baseUrlEnvironment").replace("{env}", () => endpointEnv.join(", ")) : void 0;
|
|
1738
|
+
const namedRef = stringAt(fallback, "apiKeyEnv");
|
|
1739
|
+
const nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;
|
|
1740
|
+
const authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];
|
|
1741
|
+
const visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes("oauth"));
|
|
1742
|
+
const keyHint = visibleRefs[0];
|
|
1743
|
+
const checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);
|
|
1744
|
+
const detected = checkedRefs.find(([, info]) => info?.configured === true);
|
|
1745
|
+
const detectedRef = detected?.[0];
|
|
1746
|
+
const detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;
|
|
1747
|
+
const missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);
|
|
1748
|
+
const savedCredential = detected?.[1]?.source === "file";
|
|
1749
|
+
const credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true ? void 0 : t(detectedRef === void 0 ? missingRefs ? "keyFallbackMissing" : "keyFallbackUnchecked" : detectedVisibleRef === void 0 ? "keyFallbackDetectedHidden" : "keyFallbackDetected").replace("{hint}", () => detectedVisibleRef ?? keyHint);
|
|
1750
|
+
const keyHelp = visibleRefs.length === 0 ? void 0 : t("keyHelp").replace("{env}", () => visibleRefs.join(" / "));
|
|
1751
|
+
const authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
1752
|
+
label: keyHelp,
|
|
1753
|
+
side: "right",
|
|
1754
|
+
delayMs: 0,
|
|
1755
|
+
focusDelayMs: 0,
|
|
1756
|
+
portal: true,
|
|
1757
|
+
openOnClick: true,
|
|
1758
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
1759
|
+
type: "button",
|
|
1760
|
+
className: ModelsSection_module_css_default["helpButton"],
|
|
1761
|
+
"aria-label": t("authHelp"),
|
|
1762
|
+
children: "?"
|
|
1763
|
+
})
|
|
1764
|
+
});
|
|
1765
|
+
const keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;
|
|
1766
|
+
const keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t("keyPlaceholder") : t(savedCredential ? "keyPlaceholderSaved" : "keyPlaceholderFallback").replace("{hint}", () => keyHint);
|
|
1665
1767
|
/** What both family editors take: the rows, whose layer owns them, and the two writes. */
|
|
1666
1768
|
const catalogProps = {
|
|
1667
1769
|
models,
|
|
@@ -1675,33 +1777,32 @@ window.__ModuleLoader__.load({
|
|
|
1675
1777
|
setDraft((current) => schema.deletePath(current, ["models"]));
|
|
1676
1778
|
}
|
|
1677
1779
|
};
|
|
1678
|
-
|
|
1679
|
-
...catalogProps,
|
|
1680
|
-
defaultContextWindow: typeof defaultContextWindow === "number" ? defaultContextWindow : void 0,
|
|
1681
|
-
defaultMaxTokens: typeof defaultMaxTokens === "number" ? defaultMaxTokens : void 0
|
|
1682
|
-
});
|
|
1683
|
-
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1780
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
1684
1781
|
className: ModelsSection_module_css_default["field"],
|
|
1685
1782
|
children: [
|
|
1686
|
-
(0, react_jsx_runtime.
|
|
1783
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
1687
1784
|
className: ModelsSection_module_css_default["fieldLabel"],
|
|
1688
|
-
children: t("keyInput")
|
|
1785
|
+
children: [t("keyInput"), authHelp]
|
|
1689
1786
|
}),
|
|
1690
|
-
(0, react_jsx_runtime.jsx)(
|
|
1691
|
-
|
|
1692
|
-
type: "password",
|
|
1693
|
-
autoComplete: "new-password",
|
|
1787
|
+
(0, react_jsx_runtime.jsx)(ApiKeyInput, {
|
|
1788
|
+
t,
|
|
1694
1789
|
value: keyDraft,
|
|
1695
1790
|
placeholder: keyPlaceholder,
|
|
1696
1791
|
"aria-label": t("keyInput"),
|
|
1697
1792
|
"aria-invalid": shownKeyFailure !== void 0,
|
|
1793
|
+
"aria-describedby": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,
|
|
1698
1794
|
required: props.credentialRequired === true,
|
|
1699
1795
|
autoFocus: props.autoFocusCredential === true,
|
|
1700
|
-
disabled
|
|
1796
|
+
disabled,
|
|
1701
1797
|
onChange: (event) => {
|
|
1702
1798
|
setKeyDraft(event.target.value);
|
|
1703
1799
|
}
|
|
1704
1800
|
}),
|
|
1801
|
+
credentialHint === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
|
|
1802
|
+
id: `${props.provider}-credential-hint`,
|
|
1803
|
+
className: ModelsSection_module_css_default[missingRefs ? "notice" : detectedRef === void 0 ? "advancedHint" : "savedNotice"],
|
|
1804
|
+
children: credentialHint
|
|
1805
|
+
}),
|
|
1705
1806
|
shownKeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
|
|
1706
1807
|
className: ModelsSection_module_css_default["error"],
|
|
1707
1808
|
children: t(shownKeyFailure)
|
|
@@ -1743,19 +1844,19 @@ window.__ModuleLoader__.load({
|
|
|
1743
1844
|
className: ModelsSection_module_css_default["input"],
|
|
1744
1845
|
type: "text",
|
|
1745
1846
|
value: stringAt(draft, "baseURL") ?? "",
|
|
1746
|
-
placeholder: family === "deepseek" ? t("deepSeekBaseUrl") :
|
|
1747
|
-
"aria-describedby":
|
|
1847
|
+
placeholder: family === "deepseek" ? t("deepSeekBaseUrl") : baseURL === void 0 ? t(endpointEnv.length > 0 ? "baseUrlConfigured" : "baseUrlDefault") : t("baseUrlPlaceholder").replace("{url}", () => baseURL),
|
|
1848
|
+
"aria-describedby": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,
|
|
1748
1849
|
"aria-label": t("baseUrl"),
|
|
1749
1850
|
disabled,
|
|
1750
1851
|
onChange: (event) => {
|
|
1751
1852
|
setField("baseURL", event.target.value === "" ? void 0 : event.target.value);
|
|
1752
1853
|
}
|
|
1753
1854
|
}),
|
|
1754
|
-
|
|
1855
|
+
endpointHint === void 0 ? null : (0, react_jsx_runtime.jsx)("span", {
|
|
1755
1856
|
id: `${props.provider}-endpoint-hint`,
|
|
1756
1857
|
className: ModelsSection_module_css_default["advancedHint"],
|
|
1757
|
-
children:
|
|
1758
|
-
})
|
|
1858
|
+
children: endpointHint
|
|
1859
|
+
})
|
|
1759
1860
|
]
|
|
1760
1861
|
}),
|
|
1761
1862
|
ownsIdentity ? (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1865,12 +1966,17 @@ window.__ModuleLoader__.load({
|
|
|
1865
1966
|
* post-apply reload.
|
|
1866
1967
|
*/
|
|
1867
1968
|
/** Render an editor for either the setup posture or an expanded provider row. */
|
|
1868
|
-
function renderProviderEditor({ target, ...props }) {
|
|
1969
|
+
function renderProviderEditor({ target, row, ...props }) {
|
|
1869
1970
|
return (0, react_jsx_runtime.jsx)(ProviderEditor, {
|
|
1870
1971
|
provider: target.provider,
|
|
1871
1972
|
displayName: target.displayName,
|
|
1872
1973
|
settingsPath: target.settingsPath,
|
|
1873
1974
|
...target.declared === true ? { declared: true } : {},
|
|
1975
|
+
...target.defaultBaseURL === void 0 ? {} : { defaultBaseURL: target.defaultBaseURL },
|
|
1976
|
+
...target.baseURLEnv === void 0 ? {} : { baseURLEnv: target.baseURLEnv },
|
|
1977
|
+
...target.nativeAuth === void 0 ? {} : { nativeAuth: target.nativeAuth },
|
|
1978
|
+
...row.credential === void 0 ? {} : { credential: row.credential },
|
|
1979
|
+
...row.credentialChecks === void 0 ? {} : { credentialChecks: row.credentialChecks },
|
|
1874
1980
|
...props
|
|
1875
1981
|
});
|
|
1876
1982
|
}
|
|
@@ -1930,7 +2036,10 @@ window.__ModuleLoader__.load({
|
|
|
1930
2036
|
settingsNs: row.entry.settingsNs,
|
|
1931
2037
|
settingsPath: row.entry.settingsPath,
|
|
1932
2038
|
...credentialRef === void 0 ? {} : { credentialRef },
|
|
1933
|
-
...row.entry.declared === true ? { declared: true } : {}
|
|
2039
|
+
...row.entry.declared === true ? { declared: true } : {},
|
|
2040
|
+
...row.entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: row.entry.defaultBaseURL },
|
|
2041
|
+
...row.entry.baseURLEnv === void 0 ? {} : { baseURLEnv: row.entry.baseURLEnv },
|
|
2042
|
+
...row.entry.nativeAuth === void 0 ? {} : { nativeAuth: row.entry.nativeAuth }
|
|
1934
2043
|
};
|
|
1935
2044
|
}
|
|
1936
2045
|
/** Stable visible and accessible identity for one provider target. */
|
|
@@ -1973,6 +2082,10 @@ window.__ModuleLoader__.load({
|
|
|
1973
2082
|
}
|
|
1974
2083
|
} : row)
|
|
1975
2084
|
};
|
|
2085
|
+
/** A new or failed surface waits for a current snapshot; background refreshes preserve its drafts. */
|
|
2086
|
+
const [hasReadySnapshot, setHasReadySnapshot] = (0, react.useState)(state.status === "ready");
|
|
2087
|
+
if (state.status === "ready" && !hasReadySnapshot) setHasReadySnapshot(true);
|
|
2088
|
+
if (state.status === "error" && hasReadySnapshot) setHasReadySnapshot(false);
|
|
1976
2089
|
const [editing, setEditing] = (0, react.useState)(void 0);
|
|
1977
2090
|
const [addOpen, setAddOpen] = (0, react.useState)(false);
|
|
1978
2091
|
const [addMode, setAddMode] = (0, react.useState)("catalog");
|
|
@@ -2060,6 +2173,16 @@ window.__ModuleLoader__.load({
|
|
|
2060
2173
|
})]
|
|
2061
2174
|
});
|
|
2062
2175
|
}
|
|
2176
|
+
if (!hasReadySnapshot && state.status !== "ready") return (0, react_jsx_runtime.jsxs)("div", {
|
|
2177
|
+
className: ModelsSection_module_css_default["section"],
|
|
2178
|
+
children: [(0, react_jsx_runtime.jsx)("h2", {
|
|
2179
|
+
className: ModelsSection_module_css_default["title"],
|
|
2180
|
+
children: t("title")
|
|
2181
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
2182
|
+
className: ModelsSection_module_css_default["intro"],
|
|
2183
|
+
children: t("intro")
|
|
2184
|
+
})]
|
|
2185
|
+
});
|
|
2063
2186
|
const savedRow = savedTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === savedTarget.provider);
|
|
2064
2187
|
const savedIdentity = savedRow === void 0 ? savedTarget : {
|
|
2065
2188
|
provider: savedRow.entry.provider,
|
|
@@ -2138,6 +2261,7 @@ window.__ModuleLoader__.load({
|
|
|
2138
2261
|
error,
|
|
2139
2262
|
renderProviderEditor({
|
|
2140
2263
|
target,
|
|
2264
|
+
row,
|
|
2141
2265
|
namespace,
|
|
2142
2266
|
schema,
|
|
2143
2267
|
operations,
|
|
@@ -2173,6 +2297,13 @@ window.__ModuleLoader__.load({
|
|
|
2173
2297
|
className: ModelsSection_module_css_default["rowTag"],
|
|
2174
2298
|
children: t("customTag")
|
|
2175
2299
|
}) : null,
|
|
2300
|
+
row.entry.provider === "deepseek-account" ? (0, react_jsx_runtime.jsxs)("span", {
|
|
2301
|
+
className: ModelsSection_module_css_default["accountStatus"],
|
|
2302
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
2303
|
+
className: `${ModelsSection_module_css_default["credentialDot"]} ${ModelsSection_module_css_default["credentialDotConfigured"]}`,
|
|
2304
|
+
"aria-hidden": "true"
|
|
2305
|
+
}), t("accountSignedIn")]
|
|
2306
|
+
}) : null,
|
|
2176
2307
|
credentialConfigured ? (0, react_jsx_runtime.jsx)("span", {
|
|
2177
2308
|
className: `${ModelsSection_module_css_default["credentialDot"]} ${ModelsSection_module_css_default["credentialDotConfigured"]}`,
|
|
2178
2309
|
role: "img",
|
|
@@ -2187,11 +2318,13 @@ window.__ModuleLoader__.load({
|
|
|
2187
2318
|
]
|
|
2188
2319
|
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
2189
2320
|
className: ModelsSection_module_css_default["rowActions"],
|
|
2190
|
-
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
2321
|
+
children: [row.entry.provider === "deepseek-account" ? null : (0, react_jsx_runtime.jsx)("button", {
|
|
2191
2322
|
type: "button",
|
|
2192
2323
|
className: ModelsSection_module_css_default["secondaryButton"],
|
|
2193
2324
|
"aria-label": providerCopy(t("editProvider"), target),
|
|
2325
|
+
disabled: !open && state.status !== "ready",
|
|
2194
2326
|
onClick: () => {
|
|
2327
|
+
if (!open && controller.store.getSnapshot().status !== "ready") return;
|
|
2195
2328
|
setSavedTarget(void 0);
|
|
2196
2329
|
setAddOpen(false);
|
|
2197
2330
|
setEditing(open ? void 0 : target);
|
|
@@ -2201,8 +2334,9 @@ window.__ModuleLoader__.load({
|
|
|
2201
2334
|
type: "button",
|
|
2202
2335
|
className: ModelsSection_module_css_default["dangerButton"],
|
|
2203
2336
|
"aria-label": providerCopy(t("removeProvider"), target),
|
|
2204
|
-
disabled: !state.writable,
|
|
2337
|
+
disabled: !state.writable || state.status !== "ready",
|
|
2205
2338
|
onClick: () => {
|
|
2339
|
+
if (controller.store.getSnapshot().status !== "ready") return;
|
|
2206
2340
|
setSavedTarget(void 0);
|
|
2207
2341
|
setDeleteFailure(void 0);
|
|
2208
2342
|
setDeleteTarget(target);
|
|
@@ -2219,6 +2353,7 @@ window.__ModuleLoader__.load({
|
|
|
2219
2353
|
}, { entryKey: row.entry.settingsNs }),
|
|
2220
2354
|
open ? renderProviderEditor({
|
|
2221
2355
|
target,
|
|
2356
|
+
row,
|
|
2222
2357
|
namespace,
|
|
2223
2358
|
schema,
|
|
2224
2359
|
operations,
|
|
@@ -2309,6 +2444,10 @@ window.__ModuleLoader__.load({
|
|
|
2309
2444
|
schema,
|
|
2310
2445
|
settingsPath: draft.target.settingsPath,
|
|
2311
2446
|
operations,
|
|
2447
|
+
...draft.target.defaultBaseURL === void 0 ? {} : { defaultBaseURL: draft.target.defaultBaseURL },
|
|
2448
|
+
...draft.target.baseURLEnv === void 0 ? {} : { baseURLEnv: draft.target.baseURLEnv },
|
|
2449
|
+
...draft.target.nativeAuth === void 0 ? {} : { nativeAuth: draft.target.nativeAuth },
|
|
2450
|
+
...addRow?.credentialChecks === void 0 ? {} : { credentialChecks: addRow.credentialChecks },
|
|
2312
2451
|
t,
|
|
2313
2452
|
readOnly: !state.writable,
|
|
2314
2453
|
onClose: (changed) => {
|
|
@@ -2351,8 +2490,9 @@ window.__ModuleLoader__.load({
|
|
|
2351
2490
|
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
2352
2491
|
type: "button",
|
|
2353
2492
|
className: ModelsSection_module_css_default["addButton"],
|
|
2354
|
-
disabled: !state.writable || !catalogEnabled && !customEnabled,
|
|
2493
|
+
disabled: !state.writable || state.status !== "ready" || !catalogEnabled && !customEnabled,
|
|
2355
2494
|
onClick: () => {
|
|
2495
|
+
if (controller.store.getSnapshot().status !== "ready") return;
|
|
2356
2496
|
const first = addable[0];
|
|
2357
2497
|
const initial = catalogEnabled ? "catalog" : "custom";
|
|
2358
2498
|
setSavedTarget(void 0);
|
|
@@ -2651,16 +2791,14 @@ window.__ModuleLoader__.load({
|
|
|
2651
2791
|
//#endregion
|
|
2652
2792
|
//#region lib/types/client/welcome-store.js
|
|
2653
2793
|
/**
|
|
2654
|
-
* Welcome-notice state derived from the welcome settings scope
|
|
2655
|
-
* the
|
|
2656
|
-
* remote browser's memory-mode scope never answers and the acknowledgement
|
|
2657
|
-
* stays process-local here.
|
|
2794
|
+
* Welcome-notice state derived from the welcome settings scope: the notice
|
|
2795
|
+
* follows the Host section and records its acknowledgement through it.
|
|
2658
2796
|
*/
|
|
2659
2797
|
/* v8 ignore next 3 -- closed-union default only defends future source widening */
|
|
2660
2798
|
function assertNever(_value) {
|
|
2661
2799
|
throw new Error("unexpected welcome settings status");
|
|
2662
2800
|
}
|
|
2663
|
-
/** Coordinates durable Host acknowledgement
|
|
2801
|
+
/** Coordinates the durable Host acknowledgement. */
|
|
2664
2802
|
var WelcomeNoticeStore = class {
|
|
2665
2803
|
scope;
|
|
2666
2804
|
/** uSES-safe state source shared by the registered welcome step. */
|
|
@@ -2669,13 +2807,8 @@ window.__ModuleLoader__.load({
|
|
|
2669
2807
|
acknowledged: false,
|
|
2670
2808
|
error: null
|
|
2671
2809
|
});
|
|
2672
|
-
localAcknowledged = false;
|
|
2673
2810
|
saving = false;
|
|
2674
2811
|
following;
|
|
2675
|
-
/**
|
|
2676
|
-
* @param scope - the welcome settings namespace scope; its memory mode is
|
|
2677
|
-
* what keeps a remote browser process-local.
|
|
2678
|
-
*/
|
|
2679
2812
|
constructor(scope) {
|
|
2680
2813
|
this.scope = scope;
|
|
2681
2814
|
}
|
|
@@ -2691,17 +2824,12 @@ window.__ModuleLoader__.load({
|
|
|
2691
2824
|
return Promise.resolve();
|
|
2692
2825
|
}
|
|
2693
2826
|
/**
|
|
2694
|
-
* Persist this copy version
|
|
2695
|
-
*
|
|
2696
|
-
*
|
|
2697
|
-
* @returns true when the
|
|
2827
|
+
* Persist this copy version through the scope. Success is judged against the
|
|
2828
|
+
* state the write left behind, so a refused or failed write reports false
|
|
2829
|
+
* after its recovery read settles.
|
|
2830
|
+
* @returns true when the Host holds the acknowledgement.
|
|
2698
2831
|
*/
|
|
2699
2832
|
async acknowledge() {
|
|
2700
|
-
if (this.scope.getSnapshot().mode === "memory") {
|
|
2701
|
-
this.localAcknowledged = true;
|
|
2702
|
-
this.derive();
|
|
2703
|
-
return true;
|
|
2704
|
-
}
|
|
2705
2833
|
this.saving = true;
|
|
2706
2834
|
this.store.update((state) => {
|
|
2707
2835
|
state.status = "saving";
|
|
@@ -2728,14 +2856,6 @@ window.__ModuleLoader__.load({
|
|
|
2728
2856
|
derive() {
|
|
2729
2857
|
if (this.saving) return;
|
|
2730
2858
|
const scope = this.scope.getSnapshot();
|
|
2731
|
-
if (scope.mode === "memory") {
|
|
2732
|
-
this.store.update((state) => {
|
|
2733
|
-
state.status = "ready";
|
|
2734
|
-
state.acknowledged = this.localAcknowledged;
|
|
2735
|
-
state.error = null;
|
|
2736
|
-
});
|
|
2737
|
-
return;
|
|
2738
|
-
}
|
|
2739
2859
|
switch (scope.status) {
|
|
2740
2860
|
case "loading":
|
|
2741
2861
|
this.store.update((state) => {
|
|
@@ -2780,10 +2900,6 @@ window.__ModuleLoader__.load({
|
|
|
2780
2900
|
*/
|
|
2781
2901
|
function createModelsOperations(ctx) {
|
|
2782
2902
|
return {
|
|
2783
|
-
describeCredential: async (ref) => {
|
|
2784
|
-
const response = await ctx.remote.credentials.describe([ref]);
|
|
2785
|
-
return response.ok ? response.value[ref] : void 0;
|
|
2786
|
-
},
|
|
2787
2903
|
storeCredential: async (ref, value) => {
|
|
2788
2904
|
const response = await ctx.remote.credentials.set(ref, value);
|
|
2789
2905
|
return response.ok ? void 0 : response.error.message;
|
|
@@ -2871,19 +2987,30 @@ window.__ModuleLoader__.load({
|
|
|
2871
2987
|
savedProvider: "Saved {provider}.",
|
|
2872
2988
|
credentialConfigured: "API key configured",
|
|
2873
2989
|
credentialMissing: "API key missing",
|
|
2990
|
+
accountSignedIn: "Signed in",
|
|
2874
2991
|
readOnly: "The settings document is read-only in this deployment.",
|
|
2875
2992
|
loadFailed: "Loading the provider directory failed",
|
|
2876
2993
|
conflict: "Someone else changed these settings while this card was open. Close it and reopen to edit the current values.",
|
|
2877
2994
|
retry: "Retry",
|
|
2878
2995
|
keyInput: "API key",
|
|
2996
|
+
keyReveal: "Show secret",
|
|
2997
|
+
keyHide: "Hide secret",
|
|
2879
2998
|
keyPlaceholder: "Enter your API key",
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2999
|
+
keyPlaceholderFallback: "Leave blank to use env as auth ({hint})",
|
|
3000
|
+
keyPlaceholderSaved: "Leave blank to use saved credentials",
|
|
3001
|
+
keyFallbackMissing: "Env var not detected. Enter an API key, or configure {hint} in your env.",
|
|
3002
|
+
keyFallbackDetected: "Env var detected. ({hint})",
|
|
3003
|
+
keyFallbackDetectedHidden: "Env var detected.",
|
|
3004
|
+
keyFallbackUnchecked: "Environment credential status has not been confirmed.",
|
|
3005
|
+
keyHelp: "Saved credentials are used first. Environment fallbacks shown here, in order: {env}. Sources are launch environment, $cwd/.env, then $DSH_HOME/.env.",
|
|
3006
|
+
authHelp: "Authentication details",
|
|
2883
3007
|
customized: "Customized settings",
|
|
2884
3008
|
baseUrl: "Base URL",
|
|
2885
|
-
baseUrlDefault: "
|
|
2886
|
-
|
|
3009
|
+
baseUrlDefault: "No default endpoint",
|
|
3010
|
+
baseUrlEnvironment: "Provider endpoint configuration: {env}",
|
|
3011
|
+
baseUrlConfigured: "Provider-configured endpoint",
|
|
3012
|
+
baseUrlPlaceholder: "{url}",
|
|
3013
|
+
deepSeekBaseUrl: "https://api.deepseek.com/anthropic (Default to use DEEPSEEK_BASE_URL)",
|
|
2887
3014
|
deepSeekEndpointHint: "Use an API endpoint compatible with Anthropic Messages.",
|
|
2888
3015
|
models: "Models",
|
|
2889
3016
|
modelsInherited: "Using the adapter defaults",
|
|
@@ -2987,19 +3114,30 @@ window.__ModuleLoader__.load({
|
|
|
2987
3114
|
savedProvider: "已保存 {provider}。",
|
|
2988
3115
|
credentialConfigured: "API 密钥已配置",
|
|
2989
3116
|
credentialMissing: "API 密钥缺失",
|
|
3117
|
+
accountSignedIn: "已登录",
|
|
2990
3118
|
readOnly: "当前部署的设置文档为只读。",
|
|
2991
3119
|
loadFailed: "加载提供商目录失败",
|
|
2992
3120
|
conflict: "这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。",
|
|
2993
3121
|
retry: "重试",
|
|
2994
3122
|
keyInput: "API 密钥",
|
|
3123
|
+
keyReveal: "显示密钥",
|
|
3124
|
+
keyHide: "隐藏密钥",
|
|
2995
3125
|
keyPlaceholder: "输入 API 密钥",
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
|
|
3126
|
+
keyPlaceholderFallback: "留空使用环境认证({hint})",
|
|
3127
|
+
keyPlaceholderSaved: "留空使用已保存凭据",
|
|
3128
|
+
keyFallbackMissing: "未检测到环境变量。请填写 API 密钥,或设置环境变量 {hint}。",
|
|
3129
|
+
keyFallbackDetected: "已检测到环境变量({hint})",
|
|
3130
|
+
keyFallbackDetectedHidden: "已检测到环境变量",
|
|
3131
|
+
keyFallbackUnchecked: "环境凭据状态尚未确认",
|
|
3132
|
+
keyHelp: "优先使用已保存的凭据。此处显示的环境后备按以下顺序排列:{env}。来源依次为启动环境、$cwd/.env、$DSH_HOME/.env。",
|
|
3133
|
+
authHelp: "认证说明",
|
|
2999
3134
|
customized: "自定义设置",
|
|
3000
3135
|
baseUrl: "API 地址",
|
|
3001
|
-
baseUrlDefault: "
|
|
3002
|
-
|
|
3136
|
+
baseUrlDefault: "没有默认地址",
|
|
3137
|
+
baseUrlEnvironment: "提供方地址配置:{env}",
|
|
3138
|
+
baseUrlConfigured: "由提供方配置地址",
|
|
3139
|
+
baseUrlPlaceholder: "{url}",
|
|
3140
|
+
deepSeekBaseUrl: "https://api.deepseek.com/anthropic(默认使用环境 DEEPSEEK_BASE_URL)",
|
|
3003
3141
|
deepSeekEndpointHint: "请填写兼容 Anthropic Messages 协议的 API 地址。",
|
|
3004
3142
|
models: "模型目录",
|
|
3005
3143
|
modelsInherited: "正在使用适配器默认模型",
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { InputHTMLAttributes, ReactNode } from 'react';
|
|
2
|
+
import type { en } from './locales.ts';
|
|
3
|
+
/** Input attributes and section copy for the current credential draft. */
|
|
4
|
+
interface ApiKeyInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, 'value' | 'type' | 'className' | 'autoComplete'> {
|
|
5
|
+
/** Unsaved input; stored credentials are never read into this field. */
|
|
6
|
+
readonly value: string;
|
|
7
|
+
/** Section copy, including the same reveal labels as SecretText. */
|
|
8
|
+
readonly t: (key: keyof typeof en) => string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Reveal only a nonempty draft; a different value starts masked, as in SecretText.
|
|
12
|
+
* @param props - current draft, input attributes, and translated control labels.
|
|
13
|
+
* @returns a password input with an optional reveal button.
|
|
14
|
+
*/
|
|
15
|
+
export declare function ApiKeyInput({ value, t, ...props }: ApiKeyInputProps): ReactNode;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=ApiKeyInput.d.ts.map
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* see instead of rebuilding the whole subtree from a partial descriptor.
|
|
22
22
|
*/
|
|
23
23
|
import type { ReactNode } from 'react';
|
|
24
|
-
import type { SettingsNamespaceView, SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client';
|
|
24
|
+
import type { CredentialInfo, LlmNativeAuth, SettingsNamespaceView, SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client';
|
|
25
25
|
import type { ModelsOperations } from './operations.ts';
|
|
26
26
|
import type { SettingsSchemaOperations } from './schema-operations.ts';
|
|
27
27
|
import type { en } from './locales.ts';
|
|
@@ -49,6 +49,16 @@ export interface ProviderEditorProps {
|
|
|
49
49
|
settingsPath: readonly string[];
|
|
50
50
|
/** The Host operations this card writes and interrogates through. */
|
|
51
51
|
operations: ModelsOperations;
|
|
52
|
+
/** Endpoint the route uses when its profile sets no `baseURL`; absent when the adapter reports none. */
|
|
53
|
+
defaultBaseURL?: string;
|
|
54
|
+
/** Environment variables used by the provider to construct its endpoint. */
|
|
55
|
+
baseURLEnv?: readonly string[];
|
|
56
|
+
/** Authentication the route performs when its profile names no credential reference; absent when the adapter reports none. */
|
|
57
|
+
nativeAuth?: LlmNativeAuth;
|
|
58
|
+
/** Redacted state of the profile's named credential reference, from the page snapshot. */
|
|
59
|
+
credential?: CredentialInfo;
|
|
60
|
+
/** Redacted checks for the profile's named reference or the provider's native variables. */
|
|
61
|
+
credentialChecks?: Readonly<Record<string, CredentialInfo>>;
|
|
52
62
|
/** Section copy. */
|
|
53
63
|
t: (key: keyof typeof en) => string;
|
|
54
64
|
/** Disable writes (read-only settings provider). */
|
|
@@ -7,7 +7,7 @@ import type { en } from './locales.ts';
|
|
|
7
7
|
/** Registration-side dependencies of {@link WelcomeNotice}. */
|
|
8
8
|
export interface WelcomeNoticeInjected {
|
|
9
9
|
hooks: {
|
|
10
|
-
/** Durable
|
|
10
|
+
/** Durable acknowledgement state. */
|
|
11
11
|
welcome: SnapshotStore<WelcomeNoticeState>;
|
|
12
12
|
};
|
|
13
13
|
/** Welcome acknowledgement controller. */
|
|
@@ -30,18 +30,29 @@ export declare const en: {
|
|
|
30
30
|
savedProvider: string;
|
|
31
31
|
credentialConfigured: string;
|
|
32
32
|
credentialMissing: string;
|
|
33
|
+
accountSignedIn: string;
|
|
33
34
|
readOnly: string;
|
|
34
35
|
loadFailed: string;
|
|
35
36
|
conflict: string;
|
|
36
37
|
retry: string;
|
|
37
38
|
keyInput: string;
|
|
39
|
+
keyReveal: string;
|
|
40
|
+
keyHide: string;
|
|
38
41
|
keyPlaceholder: string;
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
keyPlaceholderFallback: string;
|
|
43
|
+
keyPlaceholderSaved: string;
|
|
44
|
+
keyFallbackMissing: string;
|
|
45
|
+
keyFallbackDetected: string;
|
|
46
|
+
keyFallbackDetectedHidden: string;
|
|
47
|
+
keyFallbackUnchecked: string;
|
|
48
|
+
keyHelp: string;
|
|
49
|
+
authHelp: string;
|
|
42
50
|
customized: string;
|
|
43
51
|
baseUrl: string;
|
|
44
52
|
baseUrlDefault: string;
|
|
53
|
+
baseUrlEnvironment: string;
|
|
54
|
+
baseUrlConfigured: string;
|
|
55
|
+
baseUrlPlaceholder: string;
|
|
45
56
|
deepSeekBaseUrl: string;
|
|
46
57
|
deepSeekEndpointHint: string;
|
|
47
58
|
models: string;
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* failure codes and Remote namespaces stay in the apply world.
|
|
6
6
|
*/
|
|
7
7
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
8
|
-
import type {
|
|
8
|
+
import type { LlmDiscoveredModel, LlmModelDiscoveryRequest, SettingsNamespaceView, SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client';
|
|
9
9
|
/** What one namespace write answered. */
|
|
10
10
|
export type SettingsWriteOutcome =
|
|
11
11
|
/** Committed; the view carries the stored user subtree and the new revision. */
|
|
@@ -40,12 +40,6 @@ export type ModelDiscoveryOutcome =
|
|
|
40
40
|
};
|
|
41
41
|
/** The Host operations the Models page and its cards invoke. */
|
|
42
42
|
export interface ModelsOperations {
|
|
43
|
-
/**
|
|
44
|
-
* Read one credential reference's state.
|
|
45
|
-
* @param ref - credential reference name.
|
|
46
|
-
* @returns the state, or undefined when the reference is unknown or the read was refused.
|
|
47
|
-
*/
|
|
48
|
-
describeCredential(ref: string): Promise<CredentialInfo | undefined>;
|
|
49
43
|
/**
|
|
50
44
|
* Store one credential literal under its reference.
|
|
51
45
|
* @param ref - credential reference name.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* re-renders from the next describe, pushed or refetched.
|
|
8
8
|
*/
|
|
9
9
|
import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
10
|
-
import type { CredentialInfo, LlmConfigurableProvider, LlmProviderInfo, SettingsNamespaceView } from '@deepseek-ai/dsh-api-remotes/client';
|
|
10
|
+
import type { CredentialInfo, LlmConfigurableProvider, LlmNativeAuth, LlmProviderInfo, SettingsNamespaceView } from '@deepseek-ai/dsh-api-remotes/client';
|
|
11
11
|
import type { SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
12
12
|
import type { SettingsDescribeFace } from '@deepseek-ai/dsh-client-ui-settings/client';
|
|
13
13
|
import type { SettingsSchemaOperations } from './schema-operations.ts';
|
|
@@ -19,6 +19,9 @@ export interface ProviderDirectoryEntry {
|
|
|
19
19
|
readonly settingsPath: readonly string[];
|
|
20
20
|
readonly active: boolean;
|
|
21
21
|
readonly declared?: boolean;
|
|
22
|
+
readonly defaultBaseURL?: string;
|
|
23
|
+
readonly baseURLEnv?: readonly string[];
|
|
24
|
+
readonly nativeAuth?: LlmNativeAuth;
|
|
22
25
|
readonly error?: string;
|
|
23
26
|
}
|
|
24
27
|
/**
|
|
@@ -49,6 +52,8 @@ export interface ProviderRow {
|
|
|
49
52
|
* own derivation rule.
|
|
50
53
|
*/
|
|
51
54
|
derivedCredential?: CredentialInfo;
|
|
55
|
+
/** Redacted checks for named or native references; absent when their read failed. */
|
|
56
|
+
credentialChecks?: Readonly<Record<string, CredentialInfo>>;
|
|
52
57
|
}
|
|
53
58
|
/** Page snapshot. */
|
|
54
59
|
export interface ModelsSettingsState {
|
|
@@ -91,6 +96,8 @@ export declare class ModelsSettingsStore {
|
|
|
91
96
|
readonly store: SnapshotStore<ModelsSettingsState>;
|
|
92
97
|
/** Latest load wins; an older response never overwrites a newer one. */
|
|
93
98
|
private generation;
|
|
99
|
+
/** Callers follow the current refresh's outcome, including callers whose read was superseded. */
|
|
100
|
+
private readonly pendingLoads;
|
|
94
101
|
/**
|
|
95
102
|
* @param ctx - the page plugin's context, whose `remote.llm` and
|
|
96
103
|
* `remote.credentials` namespaces carry the directory and credential reads.
|
|
@@ -103,11 +110,17 @@ export declare class ModelsSettingsStore {
|
|
|
103
110
|
* settings answer in parallel, then one batched credential describe over
|
|
104
111
|
* every referenced ref. Provider failure or absence of an initial settings
|
|
105
112
|
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
106
|
-
* refresh reuses the mirror's held view.
|
|
107
|
-
*
|
|
113
|
+
* refresh reuses the mirror's held view. Concurrent callers resolve only
|
|
114
|
+
* after the current refresh publishes its ready or error snapshot.
|
|
115
|
+
* @returns resolution after the current snapshot is published.
|
|
116
|
+
* @throws the current read's unexpected rejection; superseded rejections are ignored.
|
|
108
117
|
*/
|
|
109
118
|
load(): Promise<void>;
|
|
110
|
-
/** Publish one
|
|
119
|
+
/** Publish one joined answer; stale answers leave the current refresh in charge. */
|
|
120
|
+
private read;
|
|
121
|
+
/** Settle callers only while this read still owns the current refresh. */
|
|
122
|
+
private settleLoads;
|
|
123
|
+
/** Publish the current joined read's failure text. */
|
|
111
124
|
private failLoad;
|
|
112
125
|
}
|
|
113
126
|
/**
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Welcome-notice state derived from the welcome settings scope
|
|
3
|
-
* the
|
|
4
|
-
* remote browser's memory-mode scope never answers and the acknowledgement
|
|
5
|
-
* stays process-local here.
|
|
2
|
+
* Welcome-notice state derived from the welcome settings scope: the notice
|
|
3
|
+
* follows the Host section and records its acknowledgement through it.
|
|
6
4
|
*/
|
|
7
5
|
import { type SnapshotStore } from '@deepseek-ai/dsh-client-store';
|
|
8
6
|
import type { ConfigForm } from '@deepseek-ai/dsh-client-ui-settings/client';
|
|
@@ -22,18 +20,13 @@ export type WelcomeSection = Record<string, unknown>;
|
|
|
22
20
|
* @returns the section object, or an empty one for non-object values.
|
|
23
21
|
*/
|
|
24
22
|
export declare function decodeWelcomeSection(section: unknown): WelcomeSection;
|
|
25
|
-
/** Coordinates durable Host acknowledgement
|
|
23
|
+
/** Coordinates the durable Host acknowledgement. */
|
|
26
24
|
export declare class WelcomeNoticeStore {
|
|
27
25
|
private readonly scope;
|
|
28
26
|
/** uSES-safe state source shared by the registered welcome step. */
|
|
29
27
|
readonly store: SnapshotStore<WelcomeNoticeState>;
|
|
30
|
-
private localAcknowledged;
|
|
31
28
|
private saving;
|
|
32
29
|
private following;
|
|
33
|
-
/**
|
|
34
|
-
* @param scope - the welcome settings namespace scope; its memory mode is
|
|
35
|
-
* what keeps a remote browser process-local.
|
|
36
|
-
*/
|
|
37
30
|
constructor(scope: ConfigForm<WelcomeSection>);
|
|
38
31
|
/**
|
|
39
32
|
* Begin following the bound scope (idempotent) and publish its current answer.
|
|
@@ -41,10 +34,10 @@ export declare class WelcomeNoticeStore {
|
|
|
41
34
|
*/
|
|
42
35
|
load(): Promise<void>;
|
|
43
36
|
/**
|
|
44
|
-
* Persist this copy version
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* @returns true when the
|
|
37
|
+
* Persist this copy version through the scope. Success is judged against the
|
|
38
|
+
* state the write left behind, so a refused or failed write reports false
|
|
39
|
+
* after its recovery read settles.
|
|
40
|
+
* @returns true when the Host holds the acknowledgement.
|
|
48
41
|
*/
|
|
49
42
|
acknowledge(): Promise<boolean>;
|
|
50
43
|
/** Stop following the scope. */
|
package/locale/en.json
ADDED
package/locale/zh.json
ADDED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-settings-models",
|
|
3
3
|
"description": "Models settings and shared product-onboarding dialogs over existing settings and credential joins",
|
|
4
|
-
"version": "0.2.1-alpha.
|
|
4
|
+
"version": "0.2.1-alpha.3",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"default": "./lib/client.js"
|
|
24
24
|
},
|
|
25
25
|
"./src/*": "./src/*",
|
|
26
|
-
"./package.json": "./package.json"
|
|
26
|
+
"./package.json": "./package.json",
|
|
27
|
+
"./locale/*.json": "./locale/*.json"
|
|
27
28
|
},
|
|
28
29
|
"dsh": {
|
|
29
30
|
"client": {
|
|
@@ -37,29 +38,29 @@
|
|
|
37
38
|
},
|
|
38
39
|
"license": "MIT",
|
|
39
40
|
"peerDependencies": {
|
|
40
|
-
"@deepseek-ai/cordis": "~4.0.5-alpha.
|
|
41
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.2"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
|
-
"@
|
|
44
|
+
"@deepseek-ai/dsh-host-webserver": "0.2.1-alpha.3",
|
|
45
|
+
"@deepseek-ai/dsh-api-remotes": "0.2.1-alpha.3",
|
|
46
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-alpha.3",
|
|
47
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-alpha.3",
|
|
48
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.3",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.3",
|
|
50
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-alpha.3",
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.3",
|
|
52
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.2",
|
|
44
53
|
"react": "^18.2.0",
|
|
45
|
-
"@deepseek-ai/dsh-
|
|
46
|
-
"@deepseek-ai/dsh-
|
|
47
|
-
"@deepseek-ai/dsh-
|
|
48
|
-
"@deepseek-ai/dsh-
|
|
49
|
-
"@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.1",
|
|
50
|
-
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.1",
|
|
51
|
-
"@deepseek-ai/cordis": "~4.0.5-alpha.1",
|
|
52
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.1",
|
|
53
|
-
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.1",
|
|
54
|
-
"@deepseek-ai/dsh-util-values": "0.2.1-alpha.1",
|
|
55
|
-
"@deepseek-ai/dsh-remote-mock": "0.2.1-alpha.1",
|
|
56
|
-
"@deepseek-ai/dsh-client-ui-settings": "0.2.1-alpha.1",
|
|
57
|
-
"@deepseek-ai/dsh-client-product-analytics": "0.2.1-alpha.1"
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.3",
|
|
55
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-alpha.3",
|
|
56
|
+
"@deepseek-ai/dsh-remote-mock": "0.2.1-alpha.3",
|
|
57
|
+
"@deepseek-ai/dsh-client-product-analytics": "0.2.1-alpha.3"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@deepseek-ai/schemastery": "~3.18.5-alpha.
|
|
60
|
+
"@deepseek-ai/schemastery": "~3.18.5-alpha.2"
|
|
61
61
|
},
|
|
62
62
|
"files": [
|
|
63
|
+
"locale/*.json",
|
|
63
64
|
"lib/index.js",
|
|
64
65
|
"lib/client.js",
|
|
65
66
|
"lib/types/**/*.d.ts"
|