@deepseek-ai/dsh-client-ui-settings-models 0.1.6-alpha.1 → 0.1.6-alpha.2
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 +2 -2
- package/README.md +4 -2
- package/README.zh.md +4 -2
- package/lib/client.js +244 -227
- package/lib/types/client/DeepSeekModelsEditor.d.ts +1 -1
- package/lib/types/client/ModelInputTypes.d.ts +29 -0
- package/lib/types/client/ModelListEditor.d.ts +4 -0
- package/lib/types/client/ModelRow.d.ts +37 -0
- package/lib/types/client/locales.d.ts +3 -2
- package/package.json +11 -11
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# pnpm run verify-translation-pairing --write packages/client/ui-settings-models/README.md
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: 6feb95d987f11bcf81b9bfa2c67068567244dcec
|
|
6
|
+
README.zh.md: 9316d698bdf11f630f5815b9fffd0bbdc4546031
|
package/README.md
CHANGED
|
@@ -35,13 +35,15 @@ The primary field on an editor card is a single **API key** input — the page n
|
|
|
35
35
|
|
|
36
36
|
### Editing a provider
|
|
37
37
|
|
|
38
|
-
The collapsed 自定义设置 fold carries the curated extras: `baseURL` for both families (the deepseek placeholder shows the public endpoint), 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 `settings.yaml` 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
|
|
38
|
+
The collapsed 自定义设置 fold carries the curated extras: `baseURL` for both families (the deepseek placeholder shows the public endpoint), 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 `settings.yaml` 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.
|
|
39
39
|
|
|
40
40
|
The DeepSeek card edits the shared `llm-deepseek` endpoint, credentials, and model catalog without a protocol selector. When Cordis YAML selects Messages, the public endpoint placeholder is `https://api.deepseek.com/anthropic`. Saving the card preserves protocol configuration.
|
|
41
41
|
|
|
42
|
+
Expand **Customized settings → Model options** to edit each model. Both provider families share the same row layout, labels, and icons: context window and max output tokens occupy two columns, and **Input types** occupies a separate row with **Text** and **Image** checkboxes. A row without an input declaration displays the installed model’s input types, then the provider default, then Text. Known pi-ai providers load their installed catalog without endpoint I/O; opening a row does not write an override. Explicit input selections take precedence, including text-only overrides of vision models. Checkbox edits save the selected types, with at least one type required. DeepSeek writes `inputModalities`; pi-ai writes `input`. Unchecking Image for DeepSeek also removes `imagePixelBudget` and `imageMaxBytes`, because the adapter rejects those limits without image input. Clearing the input field in `settings.yaml` restores adapter inheritance; **Restore default models** resets the entire catalog override. Declare only input types the upstream model can actually process.
|
|
43
|
+
|
|
42
44
|
### Adding and deleting providers
|
|
43
45
|
|
|
44
|
-
The add flow is a card carrying the dormant-directory provider select — a bare-mounted `llm-pi-ai` offers its whole installed catalog before any route exists. **Add a custom provider** declares a route pi-ai does not ship; the create card asks for a unique **Provider ID**, an endpoint, a protocol, and at least one uniquely-identified model, because nothing can default those. The endpoint must be a parseable HTTP or HTTPS URL; localhost, IPv4 and IPv6 literals, and custom ports remain valid. A syntax error blocks both discovery and creation at the field, while a request failure remains a separate provider error. **Fetch available models** asks the `llm/discoverModels` Remote about the endpoint the form shows, so adding a provider is one pass instead of save-then-return; the reply opens a searchable picker rather than being written, and nothing is written until **Add selected**. Each selected candidate copies its id, display name, context window,
|
|
46
|
+
The add flow is a card carrying the dormant-directory provider select — a bare-mounted `llm-pi-ai` offers its whole installed catalog before any route exists. **Add a custom provider** declares a route pi-ai does not ship; the create card asks for a unique **Provider ID**, an endpoint, a protocol, and at least one uniquely-identified model, because nothing can default those. The endpoint must be a parseable HTTP or HTTPS URL; localhost, IPv4 and IPv6 literals, and custom ports remain valid. A syntax error blocks both discovery and creation at the field, while a request failure remains a separate provider error. **Fetch available models** asks the `llm/discoverModels` Remote about the endpoint the form shows, so adding a provider is one pass instead of save-then-return; the reply opens a searchable picker rather than being written, and nothing is written until **Add selected**. Each selected candidate copies its id, display name, context window, output-token cap, and disclosed input types into the editable row when disclosed, while an existing row retains its user-tuned values. Search matches model ids and optional display names without clearing hidden selections. **Select all** adds the visible results, while **Deselect all** clears the entire selection so hidden results cannot be adopted accidentally. A row is deletable only when the user layer alone carries it (removal restores the composition base), and its confirmation dialog names the provider.
|
|
45
47
|
|
|
46
48
|
### First-run dialogs
|
|
47
49
|
|
package/README.zh.md
CHANGED
|
@@ -35,13 +35,15 @@ kind: "package-reference"
|
|
|
35
35
|
|
|
36
36
|
### 编辑提供方
|
|
37
37
|
|
|
38
|
-
收起的「自定义设置」折叠区承载精选的额外字段:两个家族都有 `baseURL`(deepseek 的占位符显示公共端点)、各适配器自己的模型目录,以及适配器未提供的 pi-ai 路由的**显示名称**与 **API 协议**。Profile `headers` 仍是 `settings.yaml` 或 Cordis 配置中的部署配置,Models 页面不提供编辑器。Provider ID 保持固定:它是 settings 的键、其他每个 namespace
|
|
38
|
+
收起的「自定义设置」折叠区承载精选的额外字段:两个家族都有 `baseURL`(deepseek 的占位符显示公共端点)、各适配器自己的模型目录,以及适配器未提供的 pi-ai 路由的**显示名称**与 **API 协议**。Profile `headers` 仍是 `settings.yaml` 或 Cordis 配置中的部署配置,Models 页面不提供编辑器。Provider ID 保持固定:它是 settings 的键、其他每个 namespace 与每一条已记录会话引用的名字,也是页面读不回、因而搬不走的凭据引用词干。推理等级刻意不在可编辑字段之列:它是按模型的能力,提供方级的控件只可能被设成某些模型会拒绝的值。每个模型行可编辑 `id`、可选显示 `name`、可选 `contextWindow`/`maxTokens` 和输入类型;无关的模型字段在编辑后仍会保留。
|
|
39
39
|
|
|
40
40
|
`llm-deepseek` 的 DeepSeek 卡片编辑共用的端点、凭据和模型目录,不提供协议选择器。Cordis YAML 选择 Messages 时,官方端点占位符为 `https://api.deepseek.com/anthropic`;保存卡片不会改写协议配置。
|
|
41
41
|
|
|
42
|
+
展开**自定义设置 → 模型选项**编辑模型。两个提供方家族共用相同的模型行布局、标签和图标:上下文窗口与最大输出 token 数分为两列,**输入类型**独占下一行,提供**文本**和**图片**复选框。未声明输入类型的模型行优先显示已安装模型的输入类型,其次是提供方默认值,最后回退为文本。已知 pi-ai 提供方会加载已安装目录,不向端点发送请求;打开模型行不会写入覆盖值。显式输入选择具有优先权,包括为视觉模型设置的仅文本覆盖。修改复选框会保存所选类型,且至少保留一种。DeepSeek 写入 `inputModalities`,pi-ai 写入 `input`。DeepSeek 取消勾选图片时,还会移除 `imagePixelBudget` 和 `imageMaxBytes`,因为适配器在没有图片输入时拒绝这些限制。在 `settings.yaml` 中清除输入字段可恢复适配器继承;**恢复默认模型**会重置整个模型目录覆盖。仅声明上游模型实际能够处理的输入类型。
|
|
43
|
+
|
|
42
44
|
### 新增与删除提供方
|
|
43
45
|
|
|
44
|
-
「新增」流程是一张承载休眠目录提供方选择框的卡片——裸挂载的 `llm-pi-ai` 在任何路由存在之前就能提供其完整的已安装 catalog。**添加自定义提供方**声明一条 pi-ai 不提供的路由;创建卡片会索要唯一的 **Provider ID**、端点、协议与至少一个可唯一识别的模型,因为没有东西能为它们兜底。端点必须是可解析的 HTTP 或 HTTPS URL;localhost、IPv4 与 IPv6 字面地址以及自定义端口仍然有效。语法错误会在字段处阻止询问与创建,请求失败则继续作为独立的提供方错误显示。**获取可用模型**通过 `llm/discoverModels` Remote 查询表单显示的端点,因此新增提供方一次即可完成,而非先保存再返回;回复打开的是可搜索选择器而非直接写入,只有点击**添加所选**才会写入。每个选中候选会在提供方公布相应信息时,把 id
|
|
46
|
+
「新增」流程是一张承载休眠目录提供方选择框的卡片——裸挂载的 `llm-pi-ai` 在任何路由存在之前就能提供其完整的已安装 catalog。**添加自定义提供方**声明一条 pi-ai 不提供的路由;创建卡片会索要唯一的 **Provider ID**、端点、协议与至少一个可唯一识别的模型,因为没有东西能为它们兜底。端点必须是可解析的 HTTP 或 HTTPS URL;localhost、IPv4 与 IPv6 字面地址以及自定义端口仍然有效。语法错误会在字段处阻止询问与创建,请求失败则继续作为独立的提供方错误显示。**获取可用模型**通过 `llm/discoverModels` Remote 查询表单显示的端点,因此新增提供方一次即可完成,而非先保存再返回;回复打开的是可搜索选择器而非直接写入,只有点击**添加所选**才会写入。每个选中候选会在提供方公布相应信息时,把 id、显示名、上下文窗口、最大输出 token 数和已公布的输入类型复制进可编辑行;已经存在的行保留用户调整过的值。搜索会匹配模型 id 与可选显示名称,且不会清除隐藏项的勾选状态。**全选**会加入可见结果,而**取消全选**会清空全部勾选,以免意外采用隐藏结果。只有用户层单独携带某行时,该行才可删除(删除会恢复组合基线),其确认对话框会指名该提供方。
|
|
45
47
|
|
|
46
48
|
### 首次运行弹窗
|
|
47
49
|
|
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-border-l4);border-radius:16px;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);color:var(--dsw-alias-label-secondary);border-radius:4px;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;height:36px;font:inherit;cursor:pointer;border:none;border-radius:18px;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;height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:18px;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:14px;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-alias-border-l3);outline:none}.zGbnIq_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;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;height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:14px;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{flex-wrap:wrap;gap:10px;display:flex}.zGbnIq_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}.zGbnIq_addCard,.zGbnIq_setupCard{background:var(--dsw-alias-bg-module-platform);border-radius:12px;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{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);border-radius:6px;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:10px;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;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;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(auto-fit,minmax(160px,1fr));gap:8px;padding:8px 4px 2px;display:grid}.zGbnIq_modelField{flex-direction:column;gap:4px;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);text-align:center;border-radius:8px;padding:12px}.zGbnIq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;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);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;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-brand-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:6px}.zGbnIq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.zGbnIq_candidateId{font-family:var(--ds-font-family-code);overflow-wrap:anywhere;flex:auto;font-size:13px}.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-border-l4);border-radius:16px;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);color:var(--dsw-alias-label-secondary);border-radius:4px;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;height:36px;font:inherit;cursor:pointer;border:none;border-radius:18px;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;height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:18px;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:14px;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-alias-border-l3);outline:none}.zGbnIq_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;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;height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:14px;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{flex-wrap:wrap;gap:10px;display:flex}.zGbnIq_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}.zGbnIq_addCard,.zGbnIq_setupCard{background:var(--dsw-alias-bg-module-platform);border-radius:12px;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{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);border-radius:6px;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:10px;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;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;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);text-align:center;border-radius:8px;padding:12px}.zGbnIq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;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);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;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-brand-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:6px}.zGbnIq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.zGbnIq_candidateId{font-family:var(--ds-font-family-code);overflow-wrap:anywhere;flex:auto;font-size:13px}.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");
|
|
@@ -111,6 +111,8 @@ window.__ModuleLoader__.load({
|
|
|
111
111
|
"modelEntry": "zGbnIq_modelEntry",
|
|
112
112
|
"modelField": "zGbnIq_modelField",
|
|
113
113
|
"modelFieldLabel": "zGbnIq_modelFieldLabel",
|
|
114
|
+
"modelInputChoices": "zGbnIq_modelInputChoices",
|
|
115
|
+
"modelInputTypes": "zGbnIq_modelInputTypes",
|
|
114
116
|
"modelList": "zGbnIq_modelList",
|
|
115
117
|
"modelListHead": "zGbnIq_modelListHead",
|
|
116
118
|
"modelRow": "zGbnIq_modelRow",
|
|
@@ -158,6 +160,122 @@ window.__ModuleLoader__.load({
|
|
|
158
160
|
});
|
|
159
161
|
}
|
|
160
162
|
//#endregion
|
|
163
|
+
//#region lib/types/client/ModelInputTypes.js
|
|
164
|
+
/**
|
|
165
|
+
* Edit a nonempty set of input types, displaying inherited types before an override exists.
|
|
166
|
+
* @param props - model declaration and row replacement action.
|
|
167
|
+
* @returns the labeled text and image checkboxes.
|
|
168
|
+
*/
|
|
169
|
+
function ModelInputTypes({ model, field, position, disabled, fallback, t, onChange }) {
|
|
170
|
+
const modalities = model[field];
|
|
171
|
+
const selected = Array.isArray(modalities) && modalities.length > 0 ? modalities : fallback ?? ["text"];
|
|
172
|
+
return (0, react_jsx_runtime.jsxs)("fieldset", {
|
|
173
|
+
className: ModelsSection_module_css_default["modelInputTypes"],
|
|
174
|
+
"aria-label": `${t("modelInputTypes")} ${String(position)}`,
|
|
175
|
+
children: [(0, react_jsx_runtime.jsx)("legend", {
|
|
176
|
+
className: ModelsSection_module_css_default["modelFieldLabel"],
|
|
177
|
+
children: t("modelInputTypes")
|
|
178
|
+
}), (0, react_jsx_runtime.jsx)("div", {
|
|
179
|
+
className: ModelsSection_module_css_default["modelInputChoices"],
|
|
180
|
+
children: ["text", "image"].map((modality) => (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
|
|
181
|
+
label: t(modality === "text" ? "modelInputText" : "modelInputImage"),
|
|
182
|
+
checked: selected.includes(modality),
|
|
183
|
+
disabled: disabled || selected.length === 1 && selected.includes(modality),
|
|
184
|
+
onChange: (checked) => {
|
|
185
|
+
const nextSelected = ["text", "image"].filter((value) => value === modality ? checked : selected.includes(value));
|
|
186
|
+
const next = {
|
|
187
|
+
...model,
|
|
188
|
+
[field]: nextSelected
|
|
189
|
+
};
|
|
190
|
+
if (field === "inputModalities" && !nextSelected.includes("image")) {
|
|
191
|
+
Reflect.deleteProperty(next, "imagePixelBudget");
|
|
192
|
+
Reflect.deleteProperty(next, "imageMaxBytes");
|
|
193
|
+
}
|
|
194
|
+
onChange(next);
|
|
195
|
+
}
|
|
196
|
+
}, modality))
|
|
197
|
+
})]
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region lib/types/client/ModelRow.js
|
|
202
|
+
/**
|
|
203
|
+
* Render consistent model identity, capacity, and input-type controls.
|
|
204
|
+
* @param props - drafted fields and their owning editor's actions.
|
|
205
|
+
* @returns one expandable model entry.
|
|
206
|
+
*/
|
|
207
|
+
function ModelRow(props) {
|
|
208
|
+
const { model, position, t, disabled } = props;
|
|
209
|
+
return (0, react_jsx_runtime.jsxs)("div", {
|
|
210
|
+
className: ModelsSection_module_css_default["modelEntry"],
|
|
211
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
212
|
+
className: ModelsSection_module_css_default["modelRow"],
|
|
213
|
+
children: [
|
|
214
|
+
["id", "name"].map((field) => (0, react_jsx_runtime.jsx)("input", {
|
|
215
|
+
className: ModelsSection_module_css_default["input"],
|
|
216
|
+
type: "text",
|
|
217
|
+
value: typeof model[field] === "string" ? model[field] : "",
|
|
218
|
+
placeholder: t(field === "id" ? "modelId" : "modelName"),
|
|
219
|
+
"aria-label": `${t(field === "id" ? "modelId" : "modelName")} ${String(position)}`,
|
|
220
|
+
disabled,
|
|
221
|
+
onChange: (event) => {
|
|
222
|
+
const value = event.target.value;
|
|
223
|
+
props.onFieldChange(field, field === "name" && value === "" ? void 0 : value);
|
|
224
|
+
},
|
|
225
|
+
onBlur: field === "id" ? (event) => props.onIdBlur?.(event.target.value) : void 0
|
|
226
|
+
}, field)),
|
|
227
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
228
|
+
type: "button",
|
|
229
|
+
className: ModelsSection_module_css_default["iconButton"],
|
|
230
|
+
"aria-label": `${t("modelAdvanced")} ${String(position)}`,
|
|
231
|
+
"aria-expanded": props.expanded,
|
|
232
|
+
title: t("modelAdvanced"),
|
|
233
|
+
onClick: props.onToggle,
|
|
234
|
+
children: props.expanded ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {})
|
|
235
|
+
}),
|
|
236
|
+
(0, react_jsx_runtime.jsx)("button", {
|
|
237
|
+
type: "button",
|
|
238
|
+
className: `${ModelsSection_module_css_default["iconButton"]} ${ModelsSection_module_css_default["iconButtonDanger"]}`,
|
|
239
|
+
"aria-label": `${t("removeModel")} ${String(position)}`,
|
|
240
|
+
title: t("removeModel"),
|
|
241
|
+
disabled,
|
|
242
|
+
onClick: props.onRemove,
|
|
243
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
|
|
244
|
+
})
|
|
245
|
+
]
|
|
246
|
+
}), props.expanded ? (0, react_jsx_runtime.jsxs)("div", {
|
|
247
|
+
className: ModelsSection_module_css_default["modelAdvanced"],
|
|
248
|
+
children: [["contextWindow", "maxTokens"].map((field) => (0, react_jsx_runtime.jsxs)("label", {
|
|
249
|
+
className: ModelsSection_module_css_default["modelField"],
|
|
250
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
251
|
+
className: ModelsSection_module_css_default["modelFieldLabel"],
|
|
252
|
+
children: t(field)
|
|
253
|
+
}), (0, react_jsx_runtime.jsx)("input", {
|
|
254
|
+
className: ModelsSection_module_css_default["input"],
|
|
255
|
+
type: "text",
|
|
256
|
+
inputMode: "numeric",
|
|
257
|
+
value: props[field].value,
|
|
258
|
+
placeholder: props[field].placeholder,
|
|
259
|
+
"aria-label": `${t(field)} ${String(position)}`,
|
|
260
|
+
disabled,
|
|
261
|
+
onChange: (event) => {
|
|
262
|
+
props[field].onChange(event.target.value);
|
|
263
|
+
},
|
|
264
|
+
onBlur: props[field].onBlur
|
|
265
|
+
})]
|
|
266
|
+
}, field)), (0, react_jsx_runtime.jsx)(ModelInputTypes, {
|
|
267
|
+
model,
|
|
268
|
+
field: props.inputField,
|
|
269
|
+
position,
|
|
270
|
+
fallback: props.inputFallback,
|
|
271
|
+
disabled: disabled || props.inputLoading === true,
|
|
272
|
+
t,
|
|
273
|
+
onChange: props.onChange
|
|
274
|
+
})]
|
|
275
|
+
}) : null]
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
//#endregion
|
|
161
279
|
//#region lib/types/client/DeepSeekModelsEditor.js
|
|
162
280
|
/**
|
|
163
281
|
* Curated editor for the direct DeepSeek adapter's advisory model catalog.
|
|
@@ -252,7 +370,7 @@ window.__ModuleLoader__.load({
|
|
|
252
370
|
}
|
|
253
371
|
/**
|
|
254
372
|
* Render the direct DeepSeek adapter's model catalog: id and display name on
|
|
255
|
-
* each row, capacities behind the row's own disclosure.
|
|
373
|
+
* each row, capacities and input types behind the row's own disclosure.
|
|
256
374
|
* @param props - effective rows plus the array-level override actions.
|
|
257
375
|
* @returns the catalog editor.
|
|
258
376
|
*/
|
|
@@ -320,29 +438,16 @@ window.__ModuleLoader__.load({
|
|
|
320
438
|
return next;
|
|
321
439
|
});
|
|
322
440
|
};
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
value: capacityText(model, index, field),
|
|
334
|
-
placeholder: fallback === void 0 ? props.t(field === "contextWindow" ? "contextWindowPlaceholder" : "maxTokensPlaceholder") : formatCapacity(fallback),
|
|
335
|
-
"aria-label": `${props.t(field === "contextWindow" ? "contextWindow" : "maxTokens")} ${String(index + 1)}`,
|
|
336
|
-
disabled: props.disabled,
|
|
337
|
-
onChange: (event) => {
|
|
338
|
-
const text = event.target.value;
|
|
339
|
-
setEditing((current) => new Map(current).set(`${String(index)}:${field}`, text));
|
|
340
|
-
update(index, field, parseCapacity(text));
|
|
341
|
-
},
|
|
342
|
-
onBlur: () => {
|
|
343
|
-
settleCapacity(index, field);
|
|
344
|
-
}
|
|
345
|
-
})]
|
|
441
|
+
const capacityInput = (model, index, field, fallback) => ({
|
|
442
|
+
value: capacityText(model, index, field),
|
|
443
|
+
placeholder: fallback === void 0 ? props.t(field === "contextWindow" ? "contextWindowPlaceholder" : "maxTokensPlaceholder") : formatCapacity(fallback),
|
|
444
|
+
onChange: (text) => {
|
|
445
|
+
setEditing((current) => new Map(current).set(`${String(index)}:${field}`, text));
|
|
446
|
+
update(index, field, parseCapacity(text));
|
|
447
|
+
},
|
|
448
|
+
onBlur: () => {
|
|
449
|
+
settleCapacity(index, field);
|
|
450
|
+
}
|
|
346
451
|
});
|
|
347
452
|
return (0, react_jsx_runtime.jsxs)("section", {
|
|
348
453
|
className: ModelsSection_module_css_default["modelCatalog"],
|
|
@@ -372,64 +477,31 @@ window.__ModuleLoader__.load({
|
|
|
372
477
|
children: props.t("modelsEmpty")
|
|
373
478
|
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
374
479
|
className: ModelsSection_module_css_default["modelList"],
|
|
375
|
-
children: props.models.map((model, index) => (0, react_jsx_runtime.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
"aria-label": `${props.t("modelName")} ${String(index + 1)}`,
|
|
401
|
-
disabled: props.disabled,
|
|
402
|
-
onChange: (event) => {
|
|
403
|
-
update(index, "name", event.target.value === "" ? void 0 : event.target.value);
|
|
404
|
-
}
|
|
405
|
-
}),
|
|
406
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
407
|
-
type: "button",
|
|
408
|
-
className: ModelsSection_module_css_default["iconButton"],
|
|
409
|
-
"aria-label": `${props.t("modelAdvanced")} ${String(index + 1)}`,
|
|
410
|
-
"aria-expanded": expanded.has(index),
|
|
411
|
-
title: props.t("modelAdvanced"),
|
|
412
|
-
onClick: () => {
|
|
413
|
-
toggle(index);
|
|
414
|
-
},
|
|
415
|
-
children: expanded.has(index) ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutline14, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutline14, {})
|
|
416
|
-
}),
|
|
417
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
418
|
-
type: "button",
|
|
419
|
-
className: `${ModelsSection_module_css_default["iconButton"]} ${ModelsSection_module_css_default["iconButtonDanger"]}`,
|
|
420
|
-
"aria-label": `${props.t("removeModel")} ${String(index + 1)}`,
|
|
421
|
-
title: props.t("removeModel"),
|
|
422
|
-
disabled: props.disabled,
|
|
423
|
-
onClick: () => {
|
|
424
|
-
remove(index);
|
|
425
|
-
},
|
|
426
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutline16, { size: 14 })
|
|
427
|
-
})
|
|
428
|
-
]
|
|
429
|
-
}), expanded.has(index) ? (0, react_jsx_runtime.jsxs)("div", {
|
|
430
|
-
className: ModelsSection_module_css_default["modelAdvanced"],
|
|
431
|
-
children: [capacityField(model, index, "contextWindow", props.defaultContextWindow), capacityField(model, index, "maxTokens", props.defaultMaxTokens)]
|
|
432
|
-
}) : null]
|
|
480
|
+
children: props.models.map((model, index) => (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
481
|
+
model,
|
|
482
|
+
position: index + 1,
|
|
483
|
+
inputField: "inputModalities",
|
|
484
|
+
expanded: expanded.has(index),
|
|
485
|
+
disabled: props.disabled,
|
|
486
|
+
t: props.t,
|
|
487
|
+
contextWindow: capacityInput(model, index, "contextWindow", props.defaultContextWindow),
|
|
488
|
+
maxTokens: capacityInput(model, index, "maxTokens", props.defaultMaxTokens),
|
|
489
|
+
onFieldChange: (field, value) => {
|
|
490
|
+
update(index, field, value);
|
|
491
|
+
},
|
|
492
|
+
onIdBlur: (value) => {
|
|
493
|
+
const trimmed = value.trim();
|
|
494
|
+
if (trimmed !== value) update(index, "id", trimmed);
|
|
495
|
+
},
|
|
496
|
+
onChange: (next) => {
|
|
497
|
+
props.onChange(props.models.map((row, at) => at === index ? next : row));
|
|
498
|
+
},
|
|
499
|
+
onToggle: () => {
|
|
500
|
+
toggle(index);
|
|
501
|
+
},
|
|
502
|
+
onRemove: () => {
|
|
503
|
+
remove(index);
|
|
504
|
+
}
|
|
433
505
|
}, index))
|
|
434
506
|
}),
|
|
435
507
|
(0, react_jsx_runtime.jsxs)("button", {
|
|
@@ -471,44 +543,6 @@ window.__ModuleLoader__.load({
|
|
|
471
543
|
const value = model[key];
|
|
472
544
|
return typeof value === "number" ? value : void 0;
|
|
473
545
|
}
|
|
474
|
-
/** Disclosure chevron; rotates to point down while its row is open. */
|
|
475
|
-
function IconChevron({ open }) {
|
|
476
|
-
return (0, react_jsx_runtime.jsx)("svg", {
|
|
477
|
-
width: "14",
|
|
478
|
-
height: "14",
|
|
479
|
-
viewBox: "0 0 16 16",
|
|
480
|
-
fill: "none",
|
|
481
|
-
"aria-hidden": true,
|
|
482
|
-
style: {
|
|
483
|
-
transform: open ? "rotate(90deg)" : void 0,
|
|
484
|
-
transition: "transform 120ms ease"
|
|
485
|
-
},
|
|
486
|
-
children: (0, react_jsx_runtime.jsx)("path", {
|
|
487
|
-
d: "M6 3.5L10.5 8L6 12.5",
|
|
488
|
-
stroke: "currentColor",
|
|
489
|
-
strokeWidth: "1.5",
|
|
490
|
-
strokeLinecap: "round",
|
|
491
|
-
strokeLinejoin: "round"
|
|
492
|
-
})
|
|
493
|
-
});
|
|
494
|
-
}
|
|
495
|
-
/** Removal glyph for one model row. */
|
|
496
|
-
function IconTrash() {
|
|
497
|
-
return (0, react_jsx_runtime.jsx)("svg", {
|
|
498
|
-
width: "14",
|
|
499
|
-
height: "14",
|
|
500
|
-
viewBox: "0 0 16 16",
|
|
501
|
-
fill: "none",
|
|
502
|
-
"aria-hidden": true,
|
|
503
|
-
children: (0, react_jsx_runtime.jsx)("path", {
|
|
504
|
-
d: "M2.5 4h11M6.5 4V2.5h3V4M4 4l.7 9a1 1 0 001 .9h4.6a1 1 0 001-.9L12 4M6.5 6.8v4.4M9.5 6.8v4.4",
|
|
505
|
-
stroke: "currentColor",
|
|
506
|
-
strokeWidth: "1.3",
|
|
507
|
-
strokeLinecap: "round",
|
|
508
|
-
strokeLinejoin: "round"
|
|
509
|
-
})
|
|
510
|
-
});
|
|
511
|
-
}
|
|
512
546
|
/**
|
|
513
547
|
* What an empty capacity field is worth, shown as its placeholder so a row left
|
|
514
548
|
* blank does not read as a model with no capacity at all.
|
|
@@ -534,13 +568,14 @@ window.__ModuleLoader__.load({
|
|
|
534
568
|
function capacitySpelling(value) {
|
|
535
569
|
return value === void 0 ? "" : formatCapacity(value);
|
|
536
570
|
}
|
|
537
|
-
/** Adopt a candidate,
|
|
571
|
+
/** Adopt a candidate, preserving disclosed capacities and input types. */
|
|
538
572
|
function adopt(candidate) {
|
|
539
573
|
return {
|
|
540
574
|
id: candidate.id,
|
|
541
575
|
...candidate.name === void 0 ? {} : { name: candidate.name },
|
|
542
576
|
...candidate.contextWindow === void 0 ? {} : { contextWindow: candidate.contextWindow },
|
|
543
|
-
...candidate.maxTokens === void 0 ? {} : { maxTokens: candidate.maxTokens }
|
|
577
|
+
...candidate.maxTokens === void 0 ? {} : { maxTokens: candidate.maxTokens },
|
|
578
|
+
...candidate.inputModalities === void 0 ? {} : { input: [...candidate.inputModalities] }
|
|
544
579
|
};
|
|
545
580
|
}
|
|
546
581
|
/**
|
|
@@ -550,8 +585,31 @@ window.__ModuleLoader__.load({
|
|
|
550
585
|
*/
|
|
551
586
|
function ModelListEditor(props) {
|
|
552
587
|
const { models, onChange, probe, operations, t, disabled } = props;
|
|
588
|
+
const { catalogProvider } = props;
|
|
553
589
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
554
590
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
591
|
+
const [inheritedCatalog, setInheritedCatalog] = (0, react.useState)(void 0);
|
|
592
|
+
(0, react.useEffect)(() => {
|
|
593
|
+
if (catalogProvider === void 0) return;
|
|
594
|
+
let current = true;
|
|
595
|
+
operations.discoverModels(probe.settingsNs, { provider: catalogProvider }).then((answer) => {
|
|
596
|
+
if (!current) return;
|
|
597
|
+
setInheritedCatalog({
|
|
598
|
+
provider: catalogProvider,
|
|
599
|
+
models: answer.kind === "found" ? answer.models : []
|
|
600
|
+
});
|
|
601
|
+
setFailure(answer.kind === "refused" ? answer.message : void 0);
|
|
602
|
+
});
|
|
603
|
+
return () => {
|
|
604
|
+
current = false;
|
|
605
|
+
};
|
|
606
|
+
}, [
|
|
607
|
+
catalogProvider,
|
|
608
|
+
operations,
|
|
609
|
+
probe.settingsNs
|
|
610
|
+
]);
|
|
611
|
+
const catalog = inheritedCatalog?.provider === catalogProvider ? inheritedCatalog?.models : void 0;
|
|
612
|
+
const inputDefaults = (0, react.useMemo)(() => new Map(catalog?.map((model) => [model.id, model.inputModalities])), [catalog]);
|
|
555
613
|
const [candidates, setCandidates] = (0, react.useState)(void 0);
|
|
556
614
|
const [picked, setPicked] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
557
615
|
const [candidateQuery, setCandidateQuery] = (0, react.useState)("");
|
|
@@ -607,6 +665,10 @@ window.__ModuleLoader__.load({
|
|
|
607
665
|
return;
|
|
608
666
|
}
|
|
609
667
|
const found = answer.models;
|
|
668
|
+
if (catalogProvider !== void 0) setInheritedCatalog({
|
|
669
|
+
provider: catalogProvider,
|
|
670
|
+
models: found
|
|
671
|
+
});
|
|
610
672
|
if (found.length === 0) {
|
|
611
673
|
setFailure(t("fetchEmpty"));
|
|
612
674
|
return;
|
|
@@ -695,110 +757,60 @@ window.__ModuleLoader__.load({
|
|
|
695
757
|
className: ModelsSection_module_css_default["modelEmpty"],
|
|
696
758
|
children: t("modelsEmpty")
|
|
697
759
|
}) : null,
|
|
698
|
-
|
|
699
|
-
className: ModelsSection_module_css_default["
|
|
700
|
-
children:
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
})
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
const next = /* @__PURE__ */ new Set();
|
|
746
|
-
for (const at of current) if (at < index) next.add(at);
|
|
747
|
-
else if (at > index) next.add(at - 1);
|
|
748
|
-
return next;
|
|
749
|
-
});
|
|
750
|
-
setEditing((current) => reindexOnRemove(current, index));
|
|
751
|
-
},
|
|
752
|
-
children: (0, react_jsx_runtime.jsx)(IconTrash, {})
|
|
753
|
-
})
|
|
754
|
-
]
|
|
755
|
-
}), expanded.has(index) ? (0, react_jsx_runtime.jsxs)("div", {
|
|
756
|
-
className: ModelsSection_module_css_default["modelAdvanced"],
|
|
757
|
-
children: [(0, react_jsx_runtime.jsxs)("label", {
|
|
758
|
-
className: ModelsSection_module_css_default["modelField"],
|
|
759
|
-
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
760
|
-
className: ModelsSection_module_css_default["modelFieldLabel"],
|
|
761
|
-
children: t("modelContextWindow")
|
|
762
|
-
}), (0, react_jsx_runtime.jsx)("input", {
|
|
763
|
-
className: ModelsSection_module_css_default["input"],
|
|
764
|
-
type: "text",
|
|
765
|
-
inputMode: "numeric",
|
|
766
|
-
value: capacityText(model, index, "contextWindow"),
|
|
767
|
-
placeholder: CAPACITY_HINT.contextWindow,
|
|
768
|
-
"aria-label": `${t("modelContextWindow")} ${index + 1}`,
|
|
769
|
-
disabled,
|
|
770
|
-
onChange: (event) => {
|
|
771
|
-
editCapacity(index, "contextWindow", event.target.value);
|
|
772
|
-
}
|
|
773
|
-
})]
|
|
774
|
-
}), (0, react_jsx_runtime.jsxs)("label", {
|
|
775
|
-
className: ModelsSection_module_css_default["modelField"],
|
|
776
|
-
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
777
|
-
className: ModelsSection_module_css_default["modelFieldLabel"],
|
|
778
|
-
children: t("modelMaxTokens")
|
|
779
|
-
}), (0, react_jsx_runtime.jsx)("input", {
|
|
780
|
-
className: ModelsSection_module_css_default["input"],
|
|
781
|
-
type: "text",
|
|
782
|
-
inputMode: "numeric",
|
|
783
|
-
value: capacityText(model, index, "maxTokens"),
|
|
784
|
-
placeholder: CAPACITY_HINT.maxTokens,
|
|
785
|
-
"aria-label": `${t("modelMaxTokens")} ${index + 1}`,
|
|
786
|
-
disabled,
|
|
787
|
-
onChange: (event) => {
|
|
788
|
-
editCapacity(index, "maxTokens", event.target.value);
|
|
789
|
-
}
|
|
790
|
-
})]
|
|
791
|
-
})]
|
|
792
|
-
}) : null]
|
|
793
|
-
}, index)),
|
|
794
|
-
(0, react_jsx_runtime.jsx)("button", {
|
|
760
|
+
(0, react_jsx_runtime.jsx)("div", {
|
|
761
|
+
className: ModelsSection_module_css_default["modelList"],
|
|
762
|
+
children: models.map((model, index) => (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
763
|
+
model,
|
|
764
|
+
position: index + 1,
|
|
765
|
+
inputField: "input",
|
|
766
|
+
inputFallback: inputDefaults.get(textOf(model, "id")) ?? props.defaultInput,
|
|
767
|
+
inputLoading: catalogProvider !== void 0 && catalog === void 0,
|
|
768
|
+
expanded: expanded.has(index),
|
|
769
|
+
disabled,
|
|
770
|
+
t,
|
|
771
|
+
contextWindow: {
|
|
772
|
+
value: capacityText(model, index, "contextWindow"),
|
|
773
|
+
placeholder: CAPACITY_HINT.contextWindow,
|
|
774
|
+
onChange: (text) => {
|
|
775
|
+
editCapacity(index, "contextWindow", text);
|
|
776
|
+
}
|
|
777
|
+
},
|
|
778
|
+
maxTokens: {
|
|
779
|
+
value: capacityText(model, index, "maxTokens"),
|
|
780
|
+
placeholder: CAPACITY_HINT.maxTokens,
|
|
781
|
+
onChange: (text) => {
|
|
782
|
+
editCapacity(index, "maxTokens", text);
|
|
783
|
+
}
|
|
784
|
+
},
|
|
785
|
+
onFieldChange: (field, value) => {
|
|
786
|
+
patch(index, { [field]: value });
|
|
787
|
+
},
|
|
788
|
+
onChange: (next) => {
|
|
789
|
+
onChange(models.map((row, at) => at === index ? next : row));
|
|
790
|
+
},
|
|
791
|
+
onToggle: () => {
|
|
792
|
+
toggleExpanded(index);
|
|
793
|
+
},
|
|
794
|
+
onRemove: () => {
|
|
795
|
+
onChange(models.filter((_model, at) => at !== index));
|
|
796
|
+
setExpanded((current) => {
|
|
797
|
+
const next = /* @__PURE__ */ new Set();
|
|
798
|
+
for (const at of current) if (at < index) next.add(at);
|
|
799
|
+
else if (at > index) next.add(at - 1);
|
|
800
|
+
return next;
|
|
801
|
+
});
|
|
802
|
+
setEditing((current) => reindexOnRemove(current, index));
|
|
803
|
+
}
|
|
804
|
+
}, index))
|
|
805
|
+
}),
|
|
806
|
+
(0, react_jsx_runtime.jsxs)("button", {
|
|
795
807
|
type: "button",
|
|
796
808
|
className: ModelsSection_module_css_default["addModelButton"],
|
|
797
809
|
disabled,
|
|
798
810
|
onClick: () => {
|
|
799
811
|
onChange([...models, { id: "" }]);
|
|
800
812
|
},
|
|
801
|
-
children: t("addModel")
|
|
813
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("addModel")]
|
|
802
814
|
}),
|
|
803
815
|
failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
804
816
|
className: ModelsSection_module_css_default["error"],
|
|
@@ -1591,6 +1603,7 @@ window.__ModuleLoader__.load({
|
|
|
1591
1603
|
const models = modelDrafts(modelsOverridden ? customModels : inheritedModels());
|
|
1592
1604
|
const defaultContextWindow = schema.getPath(fallback, ["defaultContextWindow"]);
|
|
1593
1605
|
const defaultMaxTokens = schema.getPath(fallback, ["maxTokens"]);
|
|
1606
|
+
const defaultInput = schema.getPath(fallback, ["defaultInput"]);
|
|
1594
1607
|
const keyPlaceholder = keyLocked ? t("keyEnvLocked") : keyState?.configured === true && props.credentialRequired !== true ? t("keyStored") : family === "pi-ai" ? t("keyPlaceholderNative") : t("keyPlaceholder");
|
|
1595
1608
|
/** What both family editors take: the rows, whose layer owns them, and the two writes. */
|
|
1596
1609
|
const catalogProps = {
|
|
@@ -1711,6 +1724,8 @@ window.__ModuleLoader__.load({
|
|
|
1711
1724
|
defaultMaxTokens: typeof defaultMaxTokens === "number" ? defaultMaxTokens : void 0
|
|
1712
1725
|
}) : (0, react_jsx_runtime.jsx)(ModelListEditor, {
|
|
1713
1726
|
...catalogProps,
|
|
1727
|
+
catalogProvider: props.declared === true ? void 0 : props.provider,
|
|
1728
|
+
defaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,
|
|
1714
1729
|
probe,
|
|
1715
1730
|
probeBlocked: keyFailure,
|
|
1716
1731
|
operations
|
|
@@ -2701,7 +2716,10 @@ window.__ModuleLoader__.load({
|
|
|
2701
2716
|
contextWindowPlaceholder: "Uses the provider default",
|
|
2702
2717
|
maxTokens: "Max output tokens",
|
|
2703
2718
|
maxTokensPlaceholder: "Uses the provider default",
|
|
2704
|
-
modelAdvanced: "
|
|
2719
|
+
modelAdvanced: "Model options",
|
|
2720
|
+
modelInputTypes: "Input types",
|
|
2721
|
+
modelInputText: "Text",
|
|
2722
|
+
modelInputImage: "Image",
|
|
2705
2723
|
addModel: "Add model",
|
|
2706
2724
|
removeModel: "Delete model",
|
|
2707
2725
|
modelsEmpty: "No models will be shown in the selector. Unlisted IDs can still be sent directly.",
|
|
@@ -2716,8 +2734,6 @@ window.__ModuleLoader__.load({
|
|
|
2716
2734
|
advancedHint: "Other fields live in settings.yaml; edit that section directly.",
|
|
2717
2735
|
modelCapacityInvalid: "A capacity must be a number, optionally suffixed K or M.",
|
|
2718
2736
|
modelDuplicate: "Each model ID may appear once.",
|
|
2719
|
-
modelContextWindow: "Context window",
|
|
2720
|
-
modelMaxTokens: "Max output tokens",
|
|
2721
2737
|
fetchModels: "Fetch available models",
|
|
2722
2738
|
fetching: "Asking the provider…",
|
|
2723
2739
|
fetchNeedsBaseUrl: "Enter the base URL first, then fetch.",
|
|
@@ -2807,7 +2823,10 @@ window.__ModuleLoader__.load({
|
|
|
2807
2823
|
contextWindowPlaceholder: "使用提供方默认值",
|
|
2808
2824
|
maxTokens: "最大输出 token 数",
|
|
2809
2825
|
maxTokensPlaceholder: "使用提供方默认值",
|
|
2810
|
-
modelAdvanced: "
|
|
2826
|
+
modelAdvanced: "模型选项",
|
|
2827
|
+
modelInputTypes: "输入类型",
|
|
2828
|
+
modelInputText: "文本",
|
|
2829
|
+
modelInputImage: "图片",
|
|
2811
2830
|
addModel: "添加模型",
|
|
2812
2831
|
removeModel: "删除模型",
|
|
2813
2832
|
modelsEmpty: "模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。",
|
|
@@ -2822,8 +2841,6 @@ window.__ModuleLoader__.load({
|
|
|
2822
2841
|
advancedHint: "其余字段在 settings.yaml 中,请直接编辑对应段。",
|
|
2823
2842
|
modelCapacityInvalid: "容量需为数字,可加 K 或 M 后缀。",
|
|
2824
2843
|
modelDuplicate: "每个模型 ID 只能出现一次。",
|
|
2825
|
-
modelContextWindow: "上下文窗口",
|
|
2826
|
-
modelMaxTokens: "最大输出 token",
|
|
2827
2844
|
fetchModels: "获取可用模型",
|
|
2828
2845
|
fetching: "正在询问提供方…",
|
|
2829
2846
|
fetchNeedsBaseUrl: "请先填写 API 地址,再获取。",
|
|
@@ -60,7 +60,7 @@ export interface DeepSeekModelsEditorProps {
|
|
|
60
60
|
}
|
|
61
61
|
/**
|
|
62
62
|
* Render the direct DeepSeek adapter's model catalog: id and display name on
|
|
63
|
-
* each row, capacities behind the row's own disclosure.
|
|
63
|
+
* each row, capacities and input types behind the row's own disclosure.
|
|
64
64
|
* @param props - effective rows plus the array-level override actions.
|
|
65
65
|
* @returns the catalog editor.
|
|
66
66
|
*/
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** Input-type declarations shared by the DeepSeek and pi-ai catalog editors. */
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import type { DeepSeekModelDraft } from './DeepSeekModelsEditor.tsx';
|
|
4
|
+
import type { ModelsKey } from './locales.ts';
|
|
5
|
+
/** Props of {@link ModelInputTypes}. */
|
|
6
|
+
interface ModelInputTypesProps {
|
|
7
|
+
/** Effective model row, including fields outside the curated editor. */
|
|
8
|
+
model: DeepSeekModelDraft;
|
|
9
|
+
/** Adapter-owned field; pi-ai inherits capabilities when absent or empty. */
|
|
10
|
+
field: 'inputModalities' | 'input';
|
|
11
|
+
/** One-based row position for the accessible group label. */
|
|
12
|
+
position: number;
|
|
13
|
+
/** Prevent changes while read-only or saving. */
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
/** Installed model or provider defaults when the row does not declare input types. */
|
|
16
|
+
fallback?: readonly string[] | undefined;
|
|
17
|
+
/** Section copy. */
|
|
18
|
+
t: (key: ModelsKey) => string;
|
|
19
|
+
/** Replace this row, preserving unrelated configuration. */
|
|
20
|
+
onChange: (model: DeepSeekModelDraft) => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Edit a nonempty set of input types, displaying inherited types before an override exists.
|
|
24
|
+
* @param props - model declaration and row replacement action.
|
|
25
|
+
* @returns the labeled text and image checkboxes.
|
|
26
|
+
*/
|
|
27
|
+
export declare function ModelInputTypes({ model, field, position, disabled, fallback, t, onChange }: ModelInputTypesProps): ReactNode;
|
|
28
|
+
export {};
|
|
29
|
+
//# sourceMappingURL=ModelInputTypes.d.ts.map
|
|
@@ -43,6 +43,10 @@ export interface ProbeTarget {
|
|
|
43
43
|
export interface ModelListEditorProps {
|
|
44
44
|
/** The rows as currently drafted. */
|
|
45
45
|
models: readonly ModelDraft[];
|
|
46
|
+
/** Installed provider whose catalog supplies defaults without endpoint I/O. */
|
|
47
|
+
catalogProvider?: string | undefined;
|
|
48
|
+
/** Route input types for models absent from the installed catalog. */
|
|
49
|
+
defaultInput?: readonly string[] | undefined;
|
|
46
50
|
/** Whether the user layer currently owns the whole array; absent on a create. */
|
|
47
51
|
overridden?: boolean;
|
|
48
52
|
/** Replace the drafted rows. */
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** Shared model fields and actions for both adapter catalog editors. */
|
|
2
|
+
import type { ReactNode } from 'react';
|
|
3
|
+
import type { DeepSeekModelDraft } from './DeepSeekModelsEditor.tsx';
|
|
4
|
+
import type { ModelsKey } from './locales.ts';
|
|
5
|
+
/** A capacity's editable text and adapter-specific inherited hint. */
|
|
6
|
+
interface CapacityInput {
|
|
7
|
+
value: string;
|
|
8
|
+
placeholder: string;
|
|
9
|
+
onChange: (value: string) => void;
|
|
10
|
+
onBlur?: () => void;
|
|
11
|
+
}
|
|
12
|
+
/** Adapter-owned data and actions for one model row. */
|
|
13
|
+
interface ModelRowProps {
|
|
14
|
+
model: DeepSeekModelDraft;
|
|
15
|
+
position: number;
|
|
16
|
+
inputField: 'inputModalities' | 'input';
|
|
17
|
+
inputFallback?: readonly string[] | undefined;
|
|
18
|
+
inputLoading?: boolean;
|
|
19
|
+
expanded: boolean;
|
|
20
|
+
disabled: boolean;
|
|
21
|
+
t: (key: ModelsKey) => string;
|
|
22
|
+
contextWindow: CapacityInput;
|
|
23
|
+
maxTokens: CapacityInput;
|
|
24
|
+
onFieldChange: (field: 'id' | 'name', value: string | undefined) => void;
|
|
25
|
+
onIdBlur?: (value: string) => void;
|
|
26
|
+
onChange: (model: DeepSeekModelDraft) => void;
|
|
27
|
+
onToggle: () => void;
|
|
28
|
+
onRemove: () => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Render consistent model identity, capacity, and input-type controls.
|
|
32
|
+
* @param props - drafted fields and their owning editor's actions.
|
|
33
|
+
* @returns one expandable model entry.
|
|
34
|
+
*/
|
|
35
|
+
export declare function ModelRow(props: ModelRowProps): ReactNode;
|
|
36
|
+
export {};
|
|
37
|
+
//# sourceMappingURL=ModelRow.d.ts.map
|
|
@@ -50,6 +50,9 @@ export declare const en: {
|
|
|
50
50
|
maxTokens: string;
|
|
51
51
|
maxTokensPlaceholder: string;
|
|
52
52
|
modelAdvanced: string;
|
|
53
|
+
modelInputTypes: string;
|
|
54
|
+
modelInputText: string;
|
|
55
|
+
modelInputImage: string;
|
|
53
56
|
addModel: string;
|
|
54
57
|
removeModel: string;
|
|
55
58
|
modelsEmpty: string;
|
|
@@ -64,8 +67,6 @@ export declare const en: {
|
|
|
64
67
|
advancedHint: string;
|
|
65
68
|
modelCapacityInvalid: string;
|
|
66
69
|
modelDuplicate: string;
|
|
67
|
-
modelContextWindow: string;
|
|
68
|
-
modelMaxTokens: string;
|
|
69
70
|
fetchModels: string;
|
|
70
71
|
fetching: string;
|
|
71
72
|
fetchNeedsBaseUrl: string;
|
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.1.6-alpha.
|
|
4
|
+
"version": "0.1.6-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -42,17 +42,17 @@
|
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/react": "~18.3.1",
|
|
44
44
|
"react": "^18.2.0",
|
|
45
|
-
"@deepseek-ai/dsh-remote-mock": "^0.1.6-alpha.
|
|
46
|
-
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.
|
|
47
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.
|
|
48
|
-
"@deepseek-ai/dsh-client-store": "^0.1.6-alpha.
|
|
49
|
-
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.
|
|
50
|
-
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.
|
|
51
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.6-alpha.
|
|
52
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.
|
|
45
|
+
"@deepseek-ai/dsh-remote-mock": "^0.1.6-alpha.2",
|
|
46
|
+
"@deepseek-ai/dsh-api-remotes": "^0.1.6-alpha.2",
|
|
47
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.6-alpha.2",
|
|
48
|
+
"@deepseek-ai/dsh-client-store": "^0.1.6-alpha.2",
|
|
49
|
+
"@deepseek-ai/dsh-client-test-runtime": "^0.1.6-alpha.2",
|
|
50
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.1.6-alpha.2",
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.6-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.6-alpha.2",
|
|
53
53
|
"@deepseek-ai/cordis": "^4.0.2",
|
|
54
|
-
"@deepseek-ai/dsh-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
54
|
+
"@deepseek-ai/dsh-util-values": "^0.1.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-renderer": "^0.1.6-alpha.2"
|
|
56
56
|
},
|
|
57
57
|
"files": [
|
|
58
58
|
"lib/index.js",
|