@deepseek-ai/dsh-client-ui-settings-models 0.1.1-rc.2 → 0.1.2-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 +93 -11
- package/README.zh.md +95 -13
- package/lib/client.js +535 -430
- package/lib/types/client/CustomProviderCard.d.ts +4 -4
- package/lib/types/client/DeepSeekOnboardingDialog.d.ts +4 -4
- package/lib/types/client/EditorFooter.d.ts +3 -3
- package/lib/types/client/ModelListEditor.d.ts +5 -7
- package/lib/types/client/ModelsSection.d.ts +14 -8
- package/lib/types/client/ProviderEditor.d.ts +8 -7
- package/lib/types/client/WelcomeNotice.d.ts +1 -1
- package/lib/types/client/index.d.ts +4 -2
- package/lib/types/client/locales.d.ts +5 -3
- package/lib/types/client/operations.d.ts +86 -0
- package/lib/types/client/slot-contract.d.ts +60 -0
- package/lib/types/client/store.d.ts +38 -17
- package/lib/types/client/welcome-store.d.ts +2 -1
- package/lib/types/onboarding-copy.d.ts +0 -13
- package/package.json +13 -19
package/lib/client.js
CHANGED
|
@@ -7,7 +7,7 @@ window.__ModuleLoader__.load({
|
|
|
7
7
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
8
|
let react = require("react");
|
|
9
9
|
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
10
|
-
let
|
|
10
|
+
let _deepseek_ai_dsh_client_store = require("@deepseek-ai/dsh-client-store");
|
|
11
11
|
//#region lib/types/client/apiKey.js
|
|
12
12
|
/**
|
|
13
13
|
* Browser-side judgement of a typed API key.
|
|
@@ -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:1px solid var(--dsw-alias-border-l2);border-radius:12px;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:1px 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;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:1px solid var(--dsw-alias-border-l2);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:12px;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:1px 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:1px 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:1px solid var(--dsw-alias-border-l2);border-radius:8px;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:1px solid var(--dsw-alias-border-l2);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:1px solid var(--dsw-alias-border-l2);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{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_candidateActions{justify-content:flex-end;margin-bottom:6px;display:flex}.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}";
|
|
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:1px solid var(--dsw-alias-border-l2);border-radius:12px;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:1px 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;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:1px solid var(--dsw-alias-border-l2);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:12px;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:1px 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:1px 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:1px solid var(--dsw-alias-border-l2);border-radius:8px;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:1px solid var(--dsw-alias-border-l2);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:1px solid var(--dsw-alias-border-l2);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_candidateActions{justify-content:flex-end;margin-bottom:6px;display:flex}.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}";
|
|
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");
|
|
@@ -126,6 +126,7 @@ window.__ModuleLoader__.load({
|
|
|
126
126
|
"section": "zGbnIq_section",
|
|
127
127
|
"selectInput": "zGbnIq_selectInput",
|
|
128
128
|
"setupCard": "zGbnIq_setupCard",
|
|
129
|
+
"switchThumb": "zGbnIq_switchThumb",
|
|
129
130
|
"title": "zGbnIq_title"
|
|
130
131
|
};
|
|
131
132
|
//#endregion
|
|
@@ -144,13 +145,13 @@ window.__ModuleLoader__.load({
|
|
|
144
145
|
className: ModelsSection_module_css_default["secondaryButton"],
|
|
145
146
|
disabled: props.busy,
|
|
146
147
|
onClick: props.onCancel,
|
|
147
|
-
children: t(props.
|
|
148
|
+
children: t(props.cancelLabelKey ?? "cancel")
|
|
148
149
|
}), (0, react_jsx_runtime.jsx)("button", {
|
|
149
150
|
type: "button",
|
|
150
151
|
className: ModelsSection_module_css_default["primaryButton"],
|
|
151
152
|
disabled: props.submitDisabled,
|
|
152
153
|
onClick: props.onSubmit,
|
|
153
|
-
children: props.busy ? t(props.
|
|
154
|
+
children: props.busy ? t(props.submitBusyLabelKey) : t(props.submitLabelKey)
|
|
154
155
|
})]
|
|
155
156
|
});
|
|
156
157
|
}
|
|
@@ -442,212 +443,6 @@ window.__ModuleLoader__.load({
|
|
|
442
443
|
});
|
|
443
444
|
}
|
|
444
445
|
//#endregion
|
|
445
|
-
//#region lib/types/client/store.js
|
|
446
|
-
/**
|
|
447
|
-
* Models settings page store: one snapshot joining the configurable-provider
|
|
448
|
-
* directory (`llm.providers`), the settings namespaces (shared settings mirror),
|
|
449
|
-
* and the referenced credentials (`credentials.describe`). The host stays the
|
|
450
|
-
* single fact source — every mutation writes through the wire and the page
|
|
451
|
-
* re-renders from the next describe, pushed or refetched.
|
|
452
|
-
*/
|
|
453
|
-
/**
|
|
454
|
-
* Any route key walks a dict schema to the same profile node, so the lookup
|
|
455
|
-
* names one that cannot collide with a configured route.
|
|
456
|
-
*/
|
|
457
|
-
const PROBE_ROUTE = "\0probe";
|
|
458
|
-
/**
|
|
459
|
-
* Human text for a rejected wire call. A transport failure rejects with an
|
|
460
|
-
* Error; a host or a runtime can reject with anything, and the page still has
|
|
461
|
-
* to say something.
|
|
462
|
-
* @param error - the rejection value.
|
|
463
|
-
* @returns the message to show.
|
|
464
|
-
*/
|
|
465
|
-
function messageOf(error) {
|
|
466
|
-
return error instanceof Error ? error.message : String(error);
|
|
467
|
-
}
|
|
468
|
-
/**
|
|
469
|
-
* Derive the conventional credential reference for a provider route: the v1
|
|
470
|
-
* page never asks for an environment-variable name, so a typed key stores
|
|
471
|
-
* under this derived reference and the profile records it as `apiKeyEnv`.
|
|
472
|
-
* @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
|
|
473
|
-
* @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
|
|
474
|
-
*/
|
|
475
|
-
function deriveKeyRef(provider) {
|
|
476
|
-
return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
|
|
477
|
-
}
|
|
478
|
-
/**
|
|
479
|
-
* The wire protocols a hand-declared route may name, read out of the owning
|
|
480
|
-
* namespace's own schema. This stays a schema read rather than a wire field so
|
|
481
|
-
* the choices the page offers cannot drift from the ones the adapter accepts:
|
|
482
|
-
* both come from the same `Config`.
|
|
483
|
-
* @param namespace - the namespace view whose schema declares the profile shape.
|
|
484
|
-
* @param schema - settings schema operations.
|
|
485
|
-
* @returns the protocol identifiers, or an empty list when the schema has none.
|
|
486
|
-
*/
|
|
487
|
-
function protocolChoices(namespace, schema) {
|
|
488
|
-
if (namespace === void 0) return [];
|
|
489
|
-
const list = schema.nodeAtPath(schema.rehydrate(namespace.schema), [
|
|
490
|
-
"providers",
|
|
491
|
-
PROBE_ROUTE,
|
|
492
|
-
"api"
|
|
493
|
-
]);
|
|
494
|
-
if (list?.type !== "union" || list.list === void 0) return [];
|
|
495
|
-
return list.list.map((entry) => entry.value).filter((value) => typeof value === "string");
|
|
496
|
-
}
|
|
497
|
-
/** The credential reference a resolved profile names (its `apiKeyEnv` field). */
|
|
498
|
-
function apiKeyEnvOf(namespace, path, schema) {
|
|
499
|
-
if (namespace === void 0) return void 0;
|
|
500
|
-
const profile = schema.getPath(namespace.value, path);
|
|
501
|
-
if (typeof profile !== "object" || profile === null) return void 0;
|
|
502
|
-
const ref = profile.apiKeyEnv;
|
|
503
|
-
return typeof ref === "string" && ref.length > 0 ? ref : void 0;
|
|
504
|
-
}
|
|
505
|
-
/** The models settings page controller (one per settings surface). */
|
|
506
|
-
var ModelsSettingsStore = class {
|
|
507
|
-
api;
|
|
508
|
-
schema;
|
|
509
|
-
describeFace;
|
|
510
|
-
/** The snapshot the section renders from (uSES-safe store). */
|
|
511
|
-
store = (0, _deepseek_ai_dsh_client_runtime_client.createSnapshotStore)({
|
|
512
|
-
status: "idle",
|
|
513
|
-
error: null,
|
|
514
|
-
credentialError: null,
|
|
515
|
-
writable: false,
|
|
516
|
-
rows: [],
|
|
517
|
-
namespaces: /* @__PURE__ */ new Map()
|
|
518
|
-
});
|
|
519
|
-
/** Latest load wins; an older response never overwrites a newer one. */
|
|
520
|
-
generation = 0;
|
|
521
|
-
/**
|
|
522
|
-
* @param api - the wire face (credentials/llm domains, and settings writes).
|
|
523
|
-
* @param describeFace - the shared mirror's describe face (namespace views and writability).
|
|
524
|
-
*/
|
|
525
|
-
constructor(api, schema, describeFace) {
|
|
526
|
-
this.api = api;
|
|
527
|
-
this.schema = schema;
|
|
528
|
-
this.describeFace = describeFace;
|
|
529
|
-
}
|
|
530
|
-
/**
|
|
531
|
-
* Refresh the whole page snapshot: the provider directory and the mirror's
|
|
532
|
-
* settings answer in parallel, then one batched credential describe over
|
|
533
|
-
* every referenced ref. Provider failure or absence of an initial settings
|
|
534
|
-
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
535
|
-
* refresh reuses the mirror's held view.
|
|
536
|
-
* @returns nothing; the snapshot carries the outcome.
|
|
537
|
-
*/
|
|
538
|
-
async load() {
|
|
539
|
-
const generation = ++this.generation;
|
|
540
|
-
this.store.update((s) => {
|
|
541
|
-
s.status = "loading";
|
|
542
|
-
s.error = null;
|
|
543
|
-
});
|
|
544
|
-
let providers;
|
|
545
|
-
let writable;
|
|
546
|
-
let views;
|
|
547
|
-
try {
|
|
548
|
-
const [providersResponse] = await Promise.all([this.api.llm.providers({}), this.describeFace.ensure()]);
|
|
549
|
-
if (!providersResponse.result.ok) throw new Error(providersResponse.result.error.message);
|
|
550
|
-
const mirrored = this.describeFace.getSnapshot();
|
|
551
|
-
if (mirrored.view === void 0) throw new Error(mirrored.error ?? "settings are unavailable in this browser");
|
|
552
|
-
providers = providersResponse.result.value.providers;
|
|
553
|
-
writable = mirrored.view.writable;
|
|
554
|
-
views = mirrored.view.namespaces;
|
|
555
|
-
} catch (error) {
|
|
556
|
-
if (generation !== this.generation) return;
|
|
557
|
-
this.store.update((s) => {
|
|
558
|
-
s.status = "error";
|
|
559
|
-
s.error = error instanceof Error ? error.message : String(error);
|
|
560
|
-
});
|
|
561
|
-
return;
|
|
562
|
-
}
|
|
563
|
-
const namespaces = new Map(views.map((view) => [view.ns, view]));
|
|
564
|
-
const rows = providers.map((entry) => {
|
|
565
|
-
const namespace = namespaces.get(entry.settingsNs);
|
|
566
|
-
return {
|
|
567
|
-
entry,
|
|
568
|
-
configured: namespace !== void 0 && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== void 0),
|
|
569
|
-
removable: namespace !== void 0 && entry.settingsPath.length > 0 && this.schema.hasPath(namespace.user, entry.settingsPath) && !this.schema.hasPath(namespace.base, entry.settingsPath),
|
|
570
|
-
apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),
|
|
571
|
-
credential: void 0
|
|
572
|
-
};
|
|
573
|
-
});
|
|
574
|
-
const refs = [...new Set(rows.flatMap((row) => row.apiKeyEnv === void 0 ? [] : [row.apiKeyEnv]))];
|
|
575
|
-
let credentials = {};
|
|
576
|
-
let credentialError = null;
|
|
577
|
-
if (refs.length > 0) try {
|
|
578
|
-
const response = await this.api.credentials.describe({ refs });
|
|
579
|
-
if (response.result.ok) credentials = response.result.value.credentials;
|
|
580
|
-
else credentialError = response.result.error.message;
|
|
581
|
-
} catch (error) {
|
|
582
|
-
credentialError = messageOf(error);
|
|
583
|
-
}
|
|
584
|
-
if (generation !== this.generation) return;
|
|
585
|
-
this.store.update((s) => {
|
|
586
|
-
s.status = "ready";
|
|
587
|
-
s.error = null;
|
|
588
|
-
s.credentialError = credentialError;
|
|
589
|
-
s.writable = writable;
|
|
590
|
-
s.rows = rows.map((row) => ({
|
|
591
|
-
...row,
|
|
592
|
-
...row.apiKeyEnv !== void 0 && credentials[row.apiKeyEnv] !== void 0 ? { credential: credentials[row.apiKeyEnv] } : {}
|
|
593
|
-
}));
|
|
594
|
-
s.namespaces = namespaces;
|
|
595
|
-
});
|
|
596
|
-
}
|
|
597
|
-
};
|
|
598
|
-
/**
|
|
599
|
-
* Whether a joined row can serve model requests as it stands: the route is
|
|
600
|
-
* registered with the adapter registry, and whatever credential its resolved
|
|
601
|
-
* profile names is stored. A profile naming no reference authenticates through
|
|
602
|
-
* the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
|
|
603
|
-
* nothing), as does a live route with no settings address at all, so neither
|
|
604
|
-
* owes this page a key.
|
|
605
|
-
* @param row - one joined provider row.
|
|
606
|
-
* @returns whether the user already has this provider to talk to.
|
|
607
|
-
*/
|
|
608
|
-
function providerUsable(row) {
|
|
609
|
-
if (!row.entry.active) return false;
|
|
610
|
-
if (row.apiKeyEnv === void 0) return true;
|
|
611
|
-
return row.credential?.configured === true;
|
|
612
|
-
}
|
|
613
|
-
/**
|
|
614
|
-
* Project first-run readiness from the provider/settings/credential join used
|
|
615
|
-
* by the Models page. The step exists to leave the user with a model to talk
|
|
616
|
-
* to, so ANY usable provider ends it; only when none exists does the official
|
|
617
|
-
* DeepSeek route — the one route the prompt can offer a key field for — decide
|
|
618
|
-
* whether prompting can help. A missing official configurable-provider
|
|
619
|
-
* declaration means the adapter is not repairable by navigating to Models.
|
|
620
|
-
* @param state - current shared Models join snapshot.
|
|
621
|
-
* @returns the onboarding state without reading a parallel fact source.
|
|
622
|
-
*/
|
|
623
|
-
function onboardingReadiness(state) {
|
|
624
|
-
if ((state.status === "idle" || state.status === "loading") && state.rows.length === 0) return { kind: "loading" };
|
|
625
|
-
if (state.status === "error") return {
|
|
626
|
-
kind: "unavailable",
|
|
627
|
-
reason: "load-failed"
|
|
628
|
-
};
|
|
629
|
-
if (state.rows.some(providerUsable)) return { kind: "provider-ready" };
|
|
630
|
-
const row = state.rows.find((candidate) => candidate.entry.provider === "deepseek-official" && candidate.entry.settingsNs === "llm-deepseek" && candidate.entry.settingsPath.length === 0);
|
|
631
|
-
if (row === void 0) return { kind: "adapter-absent" };
|
|
632
|
-
if (!row.entry.active) return {
|
|
633
|
-
kind: "unavailable",
|
|
634
|
-
reason: "provider-inactive"
|
|
635
|
-
};
|
|
636
|
-
if (state.credentialError !== null || row.credential === void 0) return {
|
|
637
|
-
kind: "unavailable",
|
|
638
|
-
reason: "credentials-unavailable"
|
|
639
|
-
};
|
|
640
|
-
if (!state.writable) return {
|
|
641
|
-
kind: "unavailable",
|
|
642
|
-
reason: "settings-read-only"
|
|
643
|
-
};
|
|
644
|
-
if (!row.credential.writable) return {
|
|
645
|
-
kind: "unavailable",
|
|
646
|
-
reason: "credential-read-only"
|
|
647
|
-
};
|
|
648
|
-
return { kind: "credential-missing" };
|
|
649
|
-
}
|
|
650
|
-
//#endregion
|
|
651
446
|
//#region lib/types/client/ModelListEditor.js
|
|
652
447
|
/**
|
|
653
448
|
* The model list of one pi-ai provider profile, plus the action that asks the
|
|
@@ -752,7 +547,7 @@ window.__ModuleLoader__.load({
|
|
|
752
547
|
* @returns the model-list editor.
|
|
753
548
|
*/
|
|
754
549
|
function ModelListEditor(props) {
|
|
755
|
-
const { models, onChange, probe,
|
|
550
|
+
const { models, onChange, probe, operations, t, disabled } = props;
|
|
756
551
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
757
552
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
758
553
|
const [candidates, setCandidates] = (0, react.useState)(void 0);
|
|
@@ -798,18 +593,17 @@ window.__ModuleLoader__.load({
|
|
|
798
593
|
setBusy(true);
|
|
799
594
|
setFailure(void 0);
|
|
800
595
|
try {
|
|
801
|
-
const
|
|
802
|
-
settingsNs: probe.settingsNs,
|
|
596
|
+
const answer = await operations.discoverModels(probe.settingsNs, {
|
|
803
597
|
...probe.provider === void 0 ? {} : { provider: probe.provider },
|
|
804
598
|
...probe.baseURL === void 0 || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },
|
|
805
599
|
...probe.api === void 0 ? {} : { api: probe.api },
|
|
806
600
|
...probe.apiKey === void 0 ? {} : { apiKey: probe.apiKey }
|
|
807
601
|
});
|
|
808
|
-
if (
|
|
809
|
-
setFailure(
|
|
602
|
+
if (answer.kind === "refused") {
|
|
603
|
+
setFailure(answer.message);
|
|
810
604
|
return;
|
|
811
605
|
}
|
|
812
|
-
const found =
|
|
606
|
+
const found = answer.models;
|
|
813
607
|
if (found.length === 0) {
|
|
814
608
|
setFailure(t("fetchEmpty"));
|
|
815
609
|
return;
|
|
@@ -817,8 +611,6 @@ window.__ModuleLoader__.load({
|
|
|
817
611
|
const known = new Set(models.map((model) => textOf(model, "id")));
|
|
818
612
|
setCandidates(found);
|
|
819
613
|
setPicked(new Set(found.filter((model) => !known.has(model.id)).map((model) => model.id)));
|
|
820
|
-
} catch (error) {
|
|
821
|
-
setFailure(messageOf(error));
|
|
822
614
|
} finally {
|
|
823
615
|
setBusy(false);
|
|
824
616
|
}
|
|
@@ -1050,6 +842,247 @@ window.__ModuleLoader__.load({
|
|
|
1050
842
|
});
|
|
1051
843
|
}
|
|
1052
844
|
//#endregion
|
|
845
|
+
//#region lib/types/client/store.js
|
|
846
|
+
/**
|
|
847
|
+
* Models settings page store: one snapshot joining the configurable-provider
|
|
848
|
+
* directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),
|
|
849
|
+
* the settings namespaces (shared settings mirror),
|
|
850
|
+
* and the referenced credentials (`credentials/describe`). The host stays the
|
|
851
|
+
* single fact source — every mutation writes through the wire and the page
|
|
852
|
+
* re-renders from the next describe, pushed or refetched.
|
|
853
|
+
*/
|
|
854
|
+
/**
|
|
855
|
+
* Any route key walks a dict schema to the same profile node, so the lookup
|
|
856
|
+
* names one that cannot collide with a configured route.
|
|
857
|
+
*/
|
|
858
|
+
const PROBE_ROUTE = "\0probe";
|
|
859
|
+
/**
|
|
860
|
+
* Join declared configurable providers with the currently registered routes.
|
|
861
|
+
* @param registered - live provider routes in registration order.
|
|
862
|
+
* @param directory - declared configurable providers in declaration order.
|
|
863
|
+
* @returns declared rows followed by live routes with no declaration.
|
|
864
|
+
*/
|
|
865
|
+
function joinProviderDirectory(registered, directory) {
|
|
866
|
+
const active = new Set(registered.map((provider) => provider.id));
|
|
867
|
+
const declared = new Set(directory.map((entry) => entry.provider));
|
|
868
|
+
const rows = directory.map((entry) => ({
|
|
869
|
+
provider: entry.provider,
|
|
870
|
+
displayName: entry.displayName,
|
|
871
|
+
settingsNs: entry.settingsNs,
|
|
872
|
+
settingsPath: [...entry.settingsPath],
|
|
873
|
+
active: active.has(entry.provider),
|
|
874
|
+
...entry.declared === void 0 ? {} : { declared: entry.declared }
|
|
875
|
+
}));
|
|
876
|
+
for (const provider of registered) {
|
|
877
|
+
if (declared.has(provider.id)) continue;
|
|
878
|
+
rows.push({
|
|
879
|
+
provider: provider.id,
|
|
880
|
+
displayName: provider.name,
|
|
881
|
+
settingsNs: "",
|
|
882
|
+
settingsPath: [],
|
|
883
|
+
active: true
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
return rows;
|
|
887
|
+
}
|
|
888
|
+
/**
|
|
889
|
+
* Derive the conventional credential reference for a provider route: the v1
|
|
890
|
+
* page never asks for an environment-variable name, so a typed key stores
|
|
891
|
+
* under this derived reference and the profile records it as `apiKeyEnv`.
|
|
892
|
+
* @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
|
|
893
|
+
* @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
|
|
894
|
+
*/
|
|
895
|
+
function deriveKeyRef(provider) {
|
|
896
|
+
return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
|
|
897
|
+
}
|
|
898
|
+
/**
|
|
899
|
+
* The wire protocols a hand-declared route may name, read out of the owning
|
|
900
|
+
* namespace's own schema. This stays a schema read rather than a wire field so
|
|
901
|
+
* the choices the page offers cannot drift from the ones the adapter accepts:
|
|
902
|
+
* both come from the same `Config`.
|
|
903
|
+
* @param namespace - the namespace view whose schema declares the profile shape.
|
|
904
|
+
* @param schema - settings schema operations.
|
|
905
|
+
* @returns the protocol identifiers, or an empty list when the schema has none.
|
|
906
|
+
*/
|
|
907
|
+
function protocolChoices(namespace, schema) {
|
|
908
|
+
if (namespace === void 0) return [];
|
|
909
|
+
const list = schema.nodeAtPath(schema.rehydrate(namespace.schema), [
|
|
910
|
+
"providers",
|
|
911
|
+
PROBE_ROUTE,
|
|
912
|
+
"api"
|
|
913
|
+
]);
|
|
914
|
+
if (list?.type !== "union" || list.list === void 0) return [];
|
|
915
|
+
return list.list.map((entry) => entry.value).filter((value) => typeof value === "string");
|
|
916
|
+
}
|
|
917
|
+
/** The credential reference a resolved profile names (its `apiKeyEnv` field). */
|
|
918
|
+
function apiKeyEnvOf(namespace, path, schema) {
|
|
919
|
+
if (namespace === void 0) return void 0;
|
|
920
|
+
const profile = schema.getPath(namespace.value, path);
|
|
921
|
+
if (typeof profile !== "object" || profile === null) return void 0;
|
|
922
|
+
const ref = profile.apiKeyEnv;
|
|
923
|
+
return typeof ref === "string" && ref.length > 0 ? ref : void 0;
|
|
924
|
+
}
|
|
925
|
+
/** The models settings page controller (one per settings surface). */
|
|
926
|
+
var ModelsSettingsStore = class {
|
|
927
|
+
ctx;
|
|
928
|
+
schema;
|
|
929
|
+
describeFace;
|
|
930
|
+
/** The snapshot the section renders from (uSES-safe store). */
|
|
931
|
+
store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
|
|
932
|
+
status: "idle",
|
|
933
|
+
error: null,
|
|
934
|
+
credentialError: null,
|
|
935
|
+
writable: false,
|
|
936
|
+
rows: [],
|
|
937
|
+
namespaces: /* @__PURE__ */ new Map()
|
|
938
|
+
});
|
|
939
|
+
/** Latest load wins; an older response never overwrites a newer one. */
|
|
940
|
+
generation = 0;
|
|
941
|
+
/**
|
|
942
|
+
* @param ctx - the page plugin's context, whose `remote.llm` and
|
|
943
|
+
* `remote.credentials` namespaces carry the directory and credential reads.
|
|
944
|
+
* @param schema - settings-owned schema and immutable path operations.
|
|
945
|
+
* @param describeFace - the shared mirror's describe face (namespace views and writability).
|
|
946
|
+
*/
|
|
947
|
+
constructor(ctx, schema, describeFace) {
|
|
948
|
+
this.ctx = ctx;
|
|
949
|
+
this.schema = schema;
|
|
950
|
+
this.describeFace = describeFace;
|
|
951
|
+
}
|
|
952
|
+
/**
|
|
953
|
+
* Refresh the whole page snapshot: the provider directory and the mirror's
|
|
954
|
+
* settings answer in parallel, then one batched credential describe over
|
|
955
|
+
* every referenced ref. Provider failure or absence of an initial settings
|
|
956
|
+
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
957
|
+
* refresh reuses the mirror's held view.
|
|
958
|
+
* @returns nothing; the snapshot carries the outcome.
|
|
959
|
+
*/
|
|
960
|
+
async load() {
|
|
961
|
+
const generation = ++this.generation;
|
|
962
|
+
this.store.update((s) => {
|
|
963
|
+
s.status = "loading";
|
|
964
|
+
s.error = null;
|
|
965
|
+
});
|
|
966
|
+
const [registered, declared] = await Promise.all([
|
|
967
|
+
this.ctx.remote.llm.listProviders(),
|
|
968
|
+
this.ctx.remote.llm.listConfigurableProviders(),
|
|
969
|
+
this.describeFace.ensure()
|
|
970
|
+
]);
|
|
971
|
+
if (!registered.ok) {
|
|
972
|
+
this.failLoad(generation, registered.error.message);
|
|
973
|
+
return;
|
|
974
|
+
}
|
|
975
|
+
if (!declared.ok) {
|
|
976
|
+
this.failLoad(generation, declared.error.message);
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
const mirrored = this.describeFace.getSnapshot();
|
|
980
|
+
if (mirrored.view === void 0) {
|
|
981
|
+
this.failLoad(generation, mirrored.error ?? "settings are unavailable in this browser");
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
const providers = joinProviderDirectory(registered.value, declared.value);
|
|
985
|
+
const writable = mirrored.view.writable;
|
|
986
|
+
const views = mirrored.view.namespaces;
|
|
987
|
+
const namespaces = new Map(views.map((view) => [view.ns, view]));
|
|
988
|
+
const rows = providers.map((entry) => {
|
|
989
|
+
const namespace = namespaces.get(entry.settingsNs);
|
|
990
|
+
return {
|
|
991
|
+
entry,
|
|
992
|
+
configured: namespace !== void 0 && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== void 0),
|
|
993
|
+
removable: namespace !== void 0 && entry.settingsPath.length > 0 && this.schema.hasPath(namespace.user, entry.settingsPath) && !this.schema.hasPath(namespace.base, entry.settingsPath),
|
|
994
|
+
apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),
|
|
995
|
+
credential: void 0
|
|
996
|
+
};
|
|
997
|
+
});
|
|
998
|
+
const refs = [...new Set(rows.map((row) => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))];
|
|
999
|
+
let credentials = {};
|
|
1000
|
+
let credentialError = null;
|
|
1001
|
+
if (refs.length > 0) {
|
|
1002
|
+
const response = await this.ctx.remote.credentials.describe(refs);
|
|
1003
|
+
if (response.ok) credentials = response.value;
|
|
1004
|
+
else credentialError = response.error.message;
|
|
1005
|
+
}
|
|
1006
|
+
if (generation !== this.generation) return;
|
|
1007
|
+
this.store.update((s) => {
|
|
1008
|
+
s.status = "ready";
|
|
1009
|
+
s.error = null;
|
|
1010
|
+
s.credentialError = credentialError;
|
|
1011
|
+
s.writable = writable;
|
|
1012
|
+
s.rows = rows.map((row) => {
|
|
1013
|
+
const named = row.apiKeyEnv === void 0 ? void 0 : credentials[row.apiKeyEnv];
|
|
1014
|
+
const derived = row.apiKeyEnv !== void 0 ? void 0 : credentials[deriveKeyRef(row.entry.provider)];
|
|
1015
|
+
return {
|
|
1016
|
+
...row,
|
|
1017
|
+
...named === void 0 ? {} : { credential: named },
|
|
1018
|
+
...derived === void 0 ? {} : { derivedCredential: derived }
|
|
1019
|
+
};
|
|
1020
|
+
});
|
|
1021
|
+
s.namespaces = namespaces;
|
|
1022
|
+
});
|
|
1023
|
+
}
|
|
1024
|
+
/** Publish one load's failure text, unless a newer load already took over. */
|
|
1025
|
+
failLoad(generation, message) {
|
|
1026
|
+
if (generation !== this.generation) return;
|
|
1027
|
+
this.store.update((s) => {
|
|
1028
|
+
s.status = "error";
|
|
1029
|
+
s.error = message;
|
|
1030
|
+
});
|
|
1031
|
+
}
|
|
1032
|
+
};
|
|
1033
|
+
/**
|
|
1034
|
+
* Whether a joined row can serve model requests as it stands: the route is
|
|
1035
|
+
* registered with the adapter registry, and whatever credential its resolved
|
|
1036
|
+
* profile names is stored. A profile naming no reference authenticates through
|
|
1037
|
+
* the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
|
|
1038
|
+
* nothing), as does a live route with no settings address at all, so neither
|
|
1039
|
+
* owes this page a key.
|
|
1040
|
+
* @param row - one joined provider row.
|
|
1041
|
+
* @returns whether the user already has this provider to talk to.
|
|
1042
|
+
*/
|
|
1043
|
+
function providerUsable(row) {
|
|
1044
|
+
if (!row.entry.active) return false;
|
|
1045
|
+
if (row.apiKeyEnv === void 0) return true;
|
|
1046
|
+
return row.credential?.configured === true;
|
|
1047
|
+
}
|
|
1048
|
+
/**
|
|
1049
|
+
* Project first-run readiness from the provider/settings/credential join used
|
|
1050
|
+
* by the Models page. The step exists to leave the user with a model to talk
|
|
1051
|
+
* to, so ANY usable provider ends it; only when none exists does the official
|
|
1052
|
+
* DeepSeek route — the one route the prompt can offer a key field for — decide
|
|
1053
|
+
* whether prompting can help. A missing official configurable-provider
|
|
1054
|
+
* declaration means the adapter is not repairable by navigating to Models.
|
|
1055
|
+
* @param state - current shared Models join snapshot.
|
|
1056
|
+
* @returns the onboarding state without reading a parallel fact source.
|
|
1057
|
+
*/
|
|
1058
|
+
function onboardingReadiness(state) {
|
|
1059
|
+
if ((state.status === "idle" || state.status === "loading") && state.rows.length === 0) return { kind: "loading" };
|
|
1060
|
+
if (state.status === "error") return {
|
|
1061
|
+
kind: "unavailable",
|
|
1062
|
+
reason: "load-failed"
|
|
1063
|
+
};
|
|
1064
|
+
if (state.rows.some(providerUsable)) return { kind: "provider-ready" };
|
|
1065
|
+
const row = state.rows.find((candidate) => candidate.entry.provider === "deepseek-official" && candidate.entry.settingsNs === "llm-deepseek" && candidate.entry.settingsPath.length === 0);
|
|
1066
|
+
if (row === void 0) return { kind: "adapter-absent" };
|
|
1067
|
+
if (!row.entry.active) return {
|
|
1068
|
+
kind: "unavailable",
|
|
1069
|
+
reason: "provider-inactive"
|
|
1070
|
+
};
|
|
1071
|
+
if (state.credentialError !== null || row.credential === void 0) return {
|
|
1072
|
+
kind: "unavailable",
|
|
1073
|
+
reason: "credentials-unavailable"
|
|
1074
|
+
};
|
|
1075
|
+
if (!state.writable) return {
|
|
1076
|
+
kind: "unavailable",
|
|
1077
|
+
reason: "settings-read-only"
|
|
1078
|
+
};
|
|
1079
|
+
if (!row.credential.writable) return {
|
|
1080
|
+
kind: "unavailable",
|
|
1081
|
+
reason: "credential-read-only"
|
|
1082
|
+
};
|
|
1083
|
+
return { kind: "credential-missing" };
|
|
1084
|
+
}
|
|
1085
|
+
//#endregion
|
|
1053
1086
|
//#region lib/types/client/CustomProviderCard.js
|
|
1054
1087
|
/**
|
|
1055
1088
|
* The card that declares a provider pi-ai does not ship — an OpenAI-compatible
|
|
@@ -1060,7 +1093,7 @@ window.__ModuleLoader__.load({
|
|
|
1060
1093
|
* the provider editor with extra fields: the route id is being *chosen* here,
|
|
1061
1094
|
* and the settings address does not exist until it is. One `settings.mutate`
|
|
1062
1095
|
* sets the whole profile at `providers.<route>`; the key travels separately
|
|
1063
|
-
* through `credentials
|
|
1096
|
+
* through `credentials/set` under the reference the profile records, exactly as
|
|
1064
1097
|
* an existing provider's key does.
|
|
1065
1098
|
*
|
|
1066
1099
|
* The three fields a hand-declared route cannot default — endpoint, protocol,
|
|
@@ -1090,7 +1123,7 @@ window.__ModuleLoader__.load({
|
|
|
1090
1123
|
* @returns the creation card.
|
|
1091
1124
|
*/
|
|
1092
1125
|
function CustomProviderCard(props) {
|
|
1093
|
-
const { taken, protocols,
|
|
1126
|
+
const { taken, protocols, operations, t } = props;
|
|
1094
1127
|
const [openedAt] = (0, react.useState)(() => props.revision);
|
|
1095
1128
|
const [route, setRoute] = (0, react.useState)("");
|
|
1096
1129
|
const [displayName, setDisplayName] = (0, react.useState)("");
|
|
@@ -1128,24 +1161,17 @@ window.__ModuleLoader__.load({
|
|
|
1128
1161
|
baseURL,
|
|
1129
1162
|
models: models.map((model) => ({ ...model }))
|
|
1130
1163
|
};
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
}],
|
|
1138
|
-
expectedRevision: openedAt
|
|
1139
|
-
});
|
|
1140
|
-
if (!response.result.ok) return response.result.error.message;
|
|
1164
|
+
const written = await operations.writeSettings(NS$1, [{
|
|
1165
|
+
op: "set",
|
|
1166
|
+
path: ["providers", route],
|
|
1167
|
+
value: profile
|
|
1168
|
+
}], openedAt);
|
|
1169
|
+
if (written.kind !== "written") return written.kind === "conflict" ? t("conflict") : written.message;
|
|
1141
1170
|
setCommitted(true);
|
|
1142
1171
|
}
|
|
1143
1172
|
if (storesKey) {
|
|
1144
|
-
const stored = await
|
|
1145
|
-
|
|
1146
|
-
value: keyValue
|
|
1147
|
-
});
|
|
1148
|
-
if (!stored.result.ok) return stored.result.error.message;
|
|
1173
|
+
const stored = await operations.storeCredential(keyRef, keyValue);
|
|
1174
|
+
if (stored !== void 0) return stored;
|
|
1149
1175
|
}
|
|
1150
1176
|
};
|
|
1151
1177
|
const create = async () => {
|
|
@@ -1158,8 +1184,6 @@ window.__ModuleLoader__.load({
|
|
|
1158
1184
|
return;
|
|
1159
1185
|
}
|
|
1160
1186
|
props.onClose(true);
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
setFailure(messageOf(error));
|
|
1163
1187
|
} finally {
|
|
1164
1188
|
setBusy(false);
|
|
1165
1189
|
}
|
|
@@ -1224,7 +1248,7 @@ window.__ModuleLoader__.load({
|
|
|
1224
1248
|
className: ModelsSection_module_css_default["input"],
|
|
1225
1249
|
type: "text",
|
|
1226
1250
|
value: baseURL,
|
|
1227
|
-
placeholder: "
|
|
1251
|
+
placeholder: t("customBaseUrlPlaceholder"),
|
|
1228
1252
|
"aria-label": t("baseUrl"),
|
|
1229
1253
|
disabled: profileDisabled,
|
|
1230
1254
|
onChange: (event) => {
|
|
@@ -1286,7 +1310,7 @@ window.__ModuleLoader__.load({
|
|
|
1286
1310
|
...keyValue.length === 0 ? {} : { apiKey: keyValue }
|
|
1287
1311
|
},
|
|
1288
1312
|
probeBlocked: keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
|
|
1289
|
-
|
|
1313
|
+
operations,
|
|
1290
1314
|
t,
|
|
1291
1315
|
disabled: profileDisabled
|
|
1292
1316
|
}),
|
|
@@ -1302,8 +1326,8 @@ window.__ModuleLoader__.load({
|
|
|
1302
1326
|
t,
|
|
1303
1327
|
busy,
|
|
1304
1328
|
submitDisabled: disabled || !ready,
|
|
1305
|
-
|
|
1306
|
-
|
|
1329
|
+
submitLabelKey: "create",
|
|
1330
|
+
submitBusyLabelKey: "creating",
|
|
1307
1331
|
onCancel: () => {
|
|
1308
1332
|
props.onClose(committed);
|
|
1309
1333
|
},
|
|
@@ -1319,7 +1343,7 @@ window.__ModuleLoader__.load({
|
|
|
1319
1343
|
/**
|
|
1320
1344
|
* One provider's editor card, hand-written per adapter family: the primary
|
|
1321
1345
|
* field is a single write-only **API key** input (the page never asks for an
|
|
1322
|
-
* environment-variable name — a typed key stores through `credentials
|
|
1346
|
+
* environment-variable name — a typed key stores through `credentials/set`
|
|
1323
1347
|
* under the profile's reference, deriving `<ROUTE>_API_KEY` when the profile
|
|
1324
1348
|
* has none. The pi-ai profile records that derivation as `apiKeyEnv` only when
|
|
1325
1349
|
* a key is entered; a blank key materializes a reference-free profile for
|
|
@@ -1391,7 +1415,7 @@ window.__ModuleLoader__.load({
|
|
|
1391
1415
|
* @returns the editor card.
|
|
1392
1416
|
*/
|
|
1393
1417
|
function ProviderEditor(props) {
|
|
1394
|
-
const { namespace, schema, settingsPath,
|
|
1418
|
+
const { namespace, schema, settingsPath, operations, t } = props;
|
|
1395
1419
|
const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
|
|
1396
1420
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1397
1421
|
const [keyState, setKeyState] = (0, react.useState)(void 0);
|
|
@@ -1417,14 +1441,14 @@ window.__ModuleLoader__.load({
|
|
|
1417
1441
|
(0, react.useEffect)(() => {
|
|
1418
1442
|
let stale = false;
|
|
1419
1443
|
setKeyState(void 0);
|
|
1420
|
-
|
|
1421
|
-
if (stale
|
|
1422
|
-
setKeyState(
|
|
1423
|
-
}
|
|
1444
|
+
operations.describeCredential(keyRef).then((described) => {
|
|
1445
|
+
if (stale) return;
|
|
1446
|
+
setKeyState(described);
|
|
1447
|
+
});
|
|
1424
1448
|
return () => {
|
|
1425
1449
|
stale = true;
|
|
1426
1450
|
};
|
|
1427
|
-
}, [
|
|
1451
|
+
}, [operations, keyRef]);
|
|
1428
1452
|
const stringAt = (source, key) => {
|
|
1429
1453
|
const value = schema.getPath(source, [key]);
|
|
1430
1454
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -1472,22 +1496,15 @@ window.__ModuleLoader__.load({
|
|
|
1472
1496
|
value: {}
|
|
1473
1497
|
}] : pathOps(settingsPath, committedOriginal, next);
|
|
1474
1498
|
if (ops.length > 0) {
|
|
1475
|
-
const
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
});
|
|
1480
|
-
if (!response.result.ok) return response.result.error.code === "settings-conflict" ? t("conflict") : response.result.error.message;
|
|
1481
|
-
setCommittedOriginal(schema.getPath(response.result.value.user, settingsPath));
|
|
1482
|
-
setExpectedRevision(response.result.value.revision);
|
|
1499
|
+
const written = await operations.writeSettings(ns, ops, expectedRevision);
|
|
1500
|
+
if (written.kind !== "written") return written.kind === "conflict" ? t("conflict") : written.message;
|
|
1501
|
+
setCommittedOriginal(schema.getPath(written.view.user, settingsPath));
|
|
1502
|
+
setExpectedRevision(written.view.revision);
|
|
1483
1503
|
setDraft(next);
|
|
1484
1504
|
}
|
|
1485
1505
|
if (keyValue.length > 0) {
|
|
1486
|
-
const stored = await
|
|
1487
|
-
|
|
1488
|
-
value: keyValue
|
|
1489
|
-
});
|
|
1490
|
-
if (!stored.result.ok) return stored.result.error.message;
|
|
1506
|
+
const stored = await operations.storeCredential(keyRef, keyValue);
|
|
1507
|
+
if (stored !== void 0) return stored;
|
|
1491
1508
|
}
|
|
1492
1509
|
setKeyDraft("");
|
|
1493
1510
|
};
|
|
@@ -1501,15 +1518,17 @@ window.__ModuleLoader__.load({
|
|
|
1501
1518
|
return;
|
|
1502
1519
|
}
|
|
1503
1520
|
props.onClose(true);
|
|
1504
|
-
} catch (error) {
|
|
1505
|
-
setFailure(messageOf(error));
|
|
1506
1521
|
} finally {
|
|
1507
1522
|
setBusy(false);
|
|
1508
1523
|
}
|
|
1509
1524
|
};
|
|
1510
|
-
if (node === void 0) return (0, react_jsx_runtime.
|
|
1525
|
+
if (node === void 0) return (0, react_jsx_runtime.jsxs)("p", {
|
|
1511
1526
|
className: ModelsSection_module_css_default["error"],
|
|
1512
|
-
children:
|
|
1527
|
+
children: [
|
|
1528
|
+
props.provider,
|
|
1529
|
+
": ",
|
|
1530
|
+
props.t("settingsPathUnresolvable")
|
|
1531
|
+
]
|
|
1513
1532
|
});
|
|
1514
1533
|
const keyLocked = keyState?.writable === false;
|
|
1515
1534
|
/**
|
|
@@ -1647,7 +1666,7 @@ window.__ModuleLoader__.load({
|
|
|
1647
1666
|
...catalogProps,
|
|
1648
1667
|
probe,
|
|
1649
1668
|
probeBlocked: keyFailure,
|
|
1650
|
-
|
|
1669
|
+
operations
|
|
1651
1670
|
})
|
|
1652
1671
|
]
|
|
1653
1672
|
})]
|
|
@@ -1682,9 +1701,9 @@ window.__ModuleLoader__.load({
|
|
|
1682
1701
|
t,
|
|
1683
1702
|
busy,
|
|
1684
1703
|
submitDisabled: disabled || layout === "unknown" || props.credentialOnly !== true && modelFailure !== void 0 || shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0,
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
...props.
|
|
1704
|
+
submitLabelKey: props.submitLabelKey ?? "apply",
|
|
1705
|
+
submitBusyLabelKey: props.submitBusyLabelKey ?? "applying",
|
|
1706
|
+
...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey },
|
|
1688
1707
|
onCancel: () => {
|
|
1689
1708
|
props.onClose(false);
|
|
1690
1709
|
},
|
|
@@ -1726,28 +1745,21 @@ window.__ModuleLoader__.load({
|
|
|
1726
1745
|
* and the whole operation safely retryable; both unsets are idempotent.
|
|
1727
1746
|
* The settings removal names the profile rather than rebuilding its whole
|
|
1728
1747
|
* namespace from a partial view.
|
|
1729
|
-
* @param
|
|
1748
|
+
* @param operations - the page's Host operations.
|
|
1730
1749
|
* @param controller - the page store to refresh.
|
|
1731
1750
|
* @param target - the provider's settings address and optional managed credential.
|
|
1732
1751
|
* @returns the failure message, or undefined once the write and reload landed.
|
|
1733
1752
|
*/
|
|
1734
|
-
async function removeProviderProfile(
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
if (!credential.result.ok) return credential.result.error.message;
|
|
1739
|
-
}
|
|
1740
|
-
const response = await api.settings.mutate({
|
|
1741
|
-
ns: target.settingsNs,
|
|
1742
|
-
ops: [{
|
|
1743
|
-
op: "unset",
|
|
1744
|
-
path: [...target.settingsPath]
|
|
1745
|
-
}]
|
|
1746
|
-
});
|
|
1747
|
-
if (!response.result.ok) return response.result.error.message;
|
|
1748
|
-
} catch (error) {
|
|
1749
|
-
return messageOf(error);
|
|
1753
|
+
async function removeProviderProfile(operations, controller, target) {
|
|
1754
|
+
if (target.credentialRef !== void 0) {
|
|
1755
|
+
const credential = await operations.removeCredential(target.credentialRef);
|
|
1756
|
+
if (credential !== void 0) return credential;
|
|
1750
1757
|
}
|
|
1758
|
+
const written = await operations.writeSettings(target.settingsNs, [{
|
|
1759
|
+
op: "unset",
|
|
1760
|
+
path: [...target.settingsPath]
|
|
1761
|
+
}], void 0);
|
|
1762
|
+
if (written.kind !== "written") return written.message;
|
|
1751
1763
|
await controller.load();
|
|
1752
1764
|
}
|
|
1753
1765
|
/**
|
|
@@ -1764,6 +1776,16 @@ window.__ModuleLoader__.load({
|
|
|
1764
1776
|
if (row.entry.settingsPath.length > 0) return false;
|
|
1765
1777
|
return row.credential?.configured !== true;
|
|
1766
1778
|
}
|
|
1779
|
+
/**
|
|
1780
|
+
* The provider-card seat's credential fact: the reference this page would use
|
|
1781
|
+
* for the row — the profile's `apiKeyEnv`, or the page's derived
|
|
1782
|
+
* `<ROUTE>_API_KEY` while the profile names none — confirmed configured. The
|
|
1783
|
+
* derived half is what keeps the seat consistent with the editor on the
|
|
1784
|
+
* add-provider draft, whose dormant row names no reference yet.
|
|
1785
|
+
*/
|
|
1786
|
+
function keyConfiguredOf(row) {
|
|
1787
|
+
return row.apiKeyEnv !== void 0 ? row.credential?.configured === true : row.derivedCredential?.configured === true;
|
|
1788
|
+
}
|
|
1767
1789
|
function targetOf(row) {
|
|
1768
1790
|
const managedRef = deriveKeyRef(row.entry.provider);
|
|
1769
1791
|
const credentialRef = row.apiKeyEnv === managedRef && row.credential?.configured === true && row.credential.writable ? managedRef : void 0;
|
|
@@ -1790,18 +1812,21 @@ window.__ModuleLoader__.load({
|
|
|
1790
1812
|
* @returns the section, or null while the shell has not injected yet.
|
|
1791
1813
|
*/
|
|
1792
1814
|
function ModelsSection(props) {
|
|
1793
|
-
const { controller, useSnapshot,
|
|
1794
|
-
if (controller === void 0 || useSnapshot === void 0 ||
|
|
1795
|
-
return (0, react_jsx_runtime.jsx)(Loaded, {
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1815
|
+
const { controller, useSnapshot, operations, schema, t, renderSlot } = props;
|
|
1816
|
+
if (controller === void 0 || useSnapshot === void 0 || operations === void 0 || schema === void 0 || t === void 0) return null;
|
|
1817
|
+
return (0, react_jsx_runtime.jsx)(Loaded, {
|
|
1818
|
+
injected: {
|
|
1819
|
+
controller,
|
|
1820
|
+
useSnapshot,
|
|
1821
|
+
operations,
|
|
1822
|
+
schema,
|
|
1823
|
+
t
|
|
1824
|
+
},
|
|
1825
|
+
renderSlot
|
|
1826
|
+
});
|
|
1802
1827
|
}
|
|
1803
|
-
function Loaded({ injected }) {
|
|
1804
|
-
const { controller,
|
|
1828
|
+
function Loaded({ injected, renderSlot }) {
|
|
1829
|
+
const { controller, operations, schema, t } = injected;
|
|
1805
1830
|
const state = injected.useSnapshot((snapshot) => snapshot);
|
|
1806
1831
|
const [editing, setEditing] = (0, react.useState)(void 0);
|
|
1807
1832
|
const [adding, setAdding] = (0, react.useState)(false);
|
|
@@ -1843,7 +1868,7 @@ window.__ModuleLoader__.load({
|
|
|
1843
1868
|
if (deleteTarget === void 0 || deleting) return;
|
|
1844
1869
|
setDeleting(true);
|
|
1845
1870
|
setDeleteFailure(void 0);
|
|
1846
|
-
removeProviderProfile(
|
|
1871
|
+
removeProviderProfile(operations, controller, deleteTarget).then((failure) => {
|
|
1847
1872
|
if (failure !== void 0) {
|
|
1848
1873
|
setDeleteFailure(failure);
|
|
1849
1874
|
return;
|
|
@@ -1882,6 +1907,7 @@ window.__ModuleLoader__.load({
|
|
|
1882
1907
|
const addable = state.rows.filter((row) => !row.configured && row.entry.settingsNs !== "");
|
|
1883
1908
|
const addTarget = adding ? editing : void 0;
|
|
1884
1909
|
const addNamespace = addTarget === void 0 ? void 0 : state.namespaces.get(addTarget.settingsNs);
|
|
1910
|
+
const addRow = addTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === addTarget.provider);
|
|
1885
1911
|
const protocols = protocolChoices(state.namespaces.get("llm-pi-ai"), schema);
|
|
1886
1912
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1887
1913
|
className: ModelsSection_module_css_default["section"],
|
|
@@ -1911,87 +1937,99 @@ window.__ModuleLoader__.load({
|
|
|
1911
1937
|
const namespace = state.namespaces.get(target.settingsNs);
|
|
1912
1938
|
/* v8 ignore next -- the join marks a row configured only when its namespace resolved */
|
|
1913
1939
|
if (namespace === void 0) return null;
|
|
1914
|
-
if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) return (0, react_jsx_runtime.
|
|
1940
|
+
if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) return (0, react_jsx_runtime.jsxs)("li", {
|
|
1915
1941
|
className: ModelsSection_module_css_default["setupCard"],
|
|
1916
|
-
children: renderProviderEditor({
|
|
1942
|
+
children: [renderProviderEditor({
|
|
1917
1943
|
target,
|
|
1918
1944
|
namespace,
|
|
1919
1945
|
schema,
|
|
1920
|
-
|
|
1946
|
+
operations,
|
|
1921
1947
|
t,
|
|
1922
1948
|
readOnly: !state.writable,
|
|
1923
1949
|
onClose: (changed) => {
|
|
1924
1950
|
closeSetup(changed, target);
|
|
1925
1951
|
}
|
|
1926
|
-
})
|
|
1952
|
+
}), renderSlot("settings.models.provider-card", {
|
|
1953
|
+
provider: row.entry,
|
|
1954
|
+
configured: row.configured,
|
|
1955
|
+
keyConfigured: keyConfiguredOf(row)
|
|
1956
|
+
}, { entryKey: row.entry.settingsNs })]
|
|
1927
1957
|
}, row.entry.provider);
|
|
1928
1958
|
const open = !adding && editing?.provider === row.entry.provider;
|
|
1929
1959
|
const credentialConfigured = row.credential?.configured === true;
|
|
1930
1960
|
const credentialMissing = !credentialConfigured && row.apiKeyEnv !== void 0 && row.credential?.configured === false;
|
|
1931
1961
|
return (0, react_jsx_runtime.jsxs)("li", {
|
|
1932
1962
|
className: ModelsSection_module_css_default["rowCard"],
|
|
1933
|
-
children: [
|
|
1934
|
-
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1950
|
-
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1963
|
+
children: [
|
|
1964
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
1965
|
+
className: ModelsSection_module_css_default["rowHead"],
|
|
1966
|
+
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
1967
|
+
className: ModelsSection_module_css_default["rowIdentity"],
|
|
1968
|
+
children: [
|
|
1969
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1970
|
+
className: ModelsSection_module_css_default["rowName"],
|
|
1971
|
+
children: row.entry.displayName
|
|
1972
|
+
}),
|
|
1973
|
+
row.entry.declared === true ? (0, react_jsx_runtime.jsx)("span", {
|
|
1974
|
+
className: ModelsSection_module_css_default["rowTag"],
|
|
1975
|
+
children: t("customTag")
|
|
1976
|
+
}) : null,
|
|
1977
|
+
credentialConfigured ? (0, react_jsx_runtime.jsx)("span", {
|
|
1978
|
+
className: `${ModelsSection_module_css_default["credentialDot"]} ${ModelsSection_module_css_default["credentialDotConfigured"]}`,
|
|
1979
|
+
role: "img",
|
|
1980
|
+
"aria-label": t("credentialConfigured"),
|
|
1981
|
+
title: t("credentialConfigured")
|
|
1982
|
+
}) : credentialMissing ? (0, react_jsx_runtime.jsx)("span", {
|
|
1983
|
+
className: `${ModelsSection_module_css_default["credentialDot"]} ${ModelsSection_module_css_default["credentialDotMissing"]}`,
|
|
1984
|
+
role: "img",
|
|
1985
|
+
"aria-label": t("credentialMissing"),
|
|
1986
|
+
title: t("credentialMissing")
|
|
1987
|
+
}) : null
|
|
1988
|
+
]
|
|
1989
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
1990
|
+
className: ModelsSection_module_css_default["rowActions"],
|
|
1991
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
1992
|
+
type: "button",
|
|
1993
|
+
className: ModelsSection_module_css_default["secondaryButton"],
|
|
1994
|
+
"aria-label": providerCopy(t("editProvider"), target),
|
|
1995
|
+
onClick: () => {
|
|
1996
|
+
setSavedTarget(void 0);
|
|
1997
|
+
setDeclaring(false);
|
|
1998
|
+
setAdding(false);
|
|
1999
|
+
setEditing(open ? void 0 : target);
|
|
2000
|
+
},
|
|
2001
|
+
children: t("edit")
|
|
2002
|
+
}), row.removable ? (0, react_jsx_runtime.jsx)("button", {
|
|
2003
|
+
type: "button",
|
|
2004
|
+
className: ModelsSection_module_css_default["dangerButton"],
|
|
2005
|
+
"aria-label": providerCopy(t("removeProvider"), target),
|
|
2006
|
+
disabled: !state.writable,
|
|
2007
|
+
onClick: () => {
|
|
2008
|
+
setSavedTarget(void 0);
|
|
2009
|
+
setDeleteFailure(void 0);
|
|
2010
|
+
setDeleteTarget(target);
|
|
2011
|
+
},
|
|
2012
|
+
children: t("remove")
|
|
2013
|
+
}) : null]
|
|
2014
|
+
})]
|
|
2015
|
+
}),
|
|
2016
|
+
renderSlot("settings.models.provider-card", {
|
|
2017
|
+
provider: row.entry,
|
|
2018
|
+
configured: row.configured,
|
|
2019
|
+
keyConfigured: keyConfiguredOf(row)
|
|
2020
|
+
}, { entryKey: row.entry.settingsNs }),
|
|
2021
|
+
open ? renderProviderEditor({
|
|
2022
|
+
target,
|
|
2023
|
+
namespace,
|
|
2024
|
+
schema,
|
|
2025
|
+
operations,
|
|
2026
|
+
t,
|
|
2027
|
+
readOnly: !state.writable,
|
|
2028
|
+
onClose: (changed) => {
|
|
2029
|
+
closeEditor(changed, target);
|
|
2030
|
+
}
|
|
2031
|
+
}) : null
|
|
2032
|
+
]
|
|
1995
2033
|
}, row.entry.provider);
|
|
1996
2034
|
})
|
|
1997
2035
|
}),
|
|
@@ -1999,40 +2037,48 @@ window.__ModuleLoader__.load({
|
|
|
1999
2037
|
className: ModelsSection_module_css_default["addBlock"],
|
|
2000
2038
|
children: addTarget !== void 0 && addNamespace !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
2001
2039
|
className: ModelsSection_module_css_default["addCard"],
|
|
2002
|
-
children: [
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2040
|
+
children: [
|
|
2041
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
2042
|
+
className: ModelsSection_module_css_default["field"],
|
|
2043
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
2044
|
+
className: ModelsSection_module_css_default["fieldLabel"],
|
|
2045
|
+
children: t("provider")
|
|
2046
|
+
}), (0, react_jsx_runtime.jsx)("select", {
|
|
2047
|
+
className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["selectInput"]}`,
|
|
2048
|
+
value: addTarget.provider,
|
|
2049
|
+
"aria-label": t("provider"),
|
|
2050
|
+
onChange: (event) => {
|
|
2051
|
+
const row = addable.find((candidate) => candidate.entry.provider === event.target.value);
|
|
2052
|
+
/* v8 ignore next -- the select only lists addable rows */
|
|
2053
|
+
if (row === void 0) return;
|
|
2054
|
+
setEditing(targetOf(row));
|
|
2055
|
+
},
|
|
2056
|
+
children: addable.map((row) => (0, react_jsx_runtime.jsx)("option", {
|
|
2057
|
+
value: row.entry.provider,
|
|
2058
|
+
children: row.entry.displayName
|
|
2059
|
+
}, row.entry.provider))
|
|
2060
|
+
})]
|
|
2061
|
+
}),
|
|
2062
|
+
(0, react_jsx_runtime.jsx)(ProviderEditor, {
|
|
2063
|
+
provider: addTarget.provider,
|
|
2064
|
+
displayName: addTarget.displayName,
|
|
2065
|
+
hideTitle: true,
|
|
2066
|
+
namespace: addNamespace,
|
|
2067
|
+
schema,
|
|
2068
|
+
settingsPath: addTarget.settingsPath,
|
|
2069
|
+
operations,
|
|
2070
|
+
t,
|
|
2071
|
+
readOnly: !state.writable,
|
|
2072
|
+
onClose: (changed) => {
|
|
2073
|
+
closeEditor(changed, addTarget);
|
|
2074
|
+
}
|
|
2075
|
+
}, addTarget.provider),
|
|
2076
|
+
addRow === void 0 ? null : renderSlot("settings.models.provider-card", {
|
|
2077
|
+
provider: addRow.entry,
|
|
2078
|
+
configured: addRow.configured,
|
|
2079
|
+
keyConfigured: keyConfiguredOf(addRow)
|
|
2080
|
+
}, { entryKey: addRow.entry.settingsNs })
|
|
2081
|
+
]
|
|
2036
2082
|
}) : declaring ? (0, react_jsx_runtime.jsx)("div", {
|
|
2037
2083
|
className: ModelsSection_module_css_default["addCard"],
|
|
2038
2084
|
children: (0, react_jsx_runtime.jsx)(CustomProviderCard, {
|
|
@@ -2040,7 +2086,7 @@ window.__ModuleLoader__.load({
|
|
|
2040
2086
|
protocols,
|
|
2041
2087
|
/* v8 ignore next -- the card only opens from a button disabled without this namespace */
|
|
2042
2088
|
revision: state.namespaces.get("llm-pi-ai")?.revision ?? 0,
|
|
2043
|
-
|
|
2089
|
+
operations,
|
|
2044
2090
|
t,
|
|
2045
2091
|
readOnly: !state.writable,
|
|
2046
2092
|
onClose: (changed) => {
|
|
@@ -2078,6 +2124,7 @@ window.__ModuleLoader__.load({
|
|
|
2078
2124
|
})]
|
|
2079
2125
|
})
|
|
2080
2126
|
}),
|
|
2127
|
+
renderSlot("settings.models.footer", {}),
|
|
2081
2128
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
2082
2129
|
open: deleteTarget !== void 0,
|
|
2083
2130
|
onClose: closeDelete,
|
|
@@ -2203,7 +2250,7 @@ window.__ModuleLoader__.load({
|
|
|
2203
2250
|
* @returns the onboarding modal or null when onboarding needs no intervention.
|
|
2204
2251
|
*/
|
|
2205
2252
|
function DeepSeekOnboardingDialog(props) {
|
|
2206
|
-
const { complete, controller, useModels,
|
|
2253
|
+
const { complete, controller, useModels, operations, schema, t } = props;
|
|
2207
2254
|
const state = useModels((snapshot) => snapshot);
|
|
2208
2255
|
const readiness = onboardingReadiness(state);
|
|
2209
2256
|
(0, react.useEffect)(() => {
|
|
@@ -2245,16 +2292,16 @@ window.__ModuleLoader__.load({
|
|
|
2245
2292
|
namespace,
|
|
2246
2293
|
schema,
|
|
2247
2294
|
settingsPath: row.entry.settingsPath,
|
|
2248
|
-
|
|
2295
|
+
operations,
|
|
2249
2296
|
t,
|
|
2250
2297
|
readOnly: false,
|
|
2251
2298
|
hideTitle: true,
|
|
2252
2299
|
credentialOnly: true,
|
|
2253
2300
|
credentialRequired: true,
|
|
2254
2301
|
autoFocusCredential: true,
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2302
|
+
cancelLabelKey: "onboardingLater",
|
|
2303
|
+
submitLabelKey: "onboardingSave",
|
|
2304
|
+
submitBusyLabelKey: "onboardingSaving",
|
|
2258
2305
|
onClose: finishCredential
|
|
2259
2306
|
})
|
|
2260
2307
|
})]
|
|
@@ -2344,19 +2391,6 @@ window.__ModuleLoader__.load({
|
|
|
2344
2391
|
* again. The acknowledgement is compared for exact equality.
|
|
2345
2392
|
*/
|
|
2346
2393
|
const WELCOME_NOTICE_VERSION = "2026-08-13.1";
|
|
2347
|
-
/** The complete editable internal-testing notice in both supported GUI locales. */
|
|
2348
|
-
const WELCOME_NOTICE_COPY = {
|
|
2349
|
-
zh: {
|
|
2350
|
-
title: "内测声明",
|
|
2351
|
-
body: "DeepSeek Harness 目前的 0.1 版本仍处在面向 Harness 开发者进行测试的阶段,还有许多地方需要持续改进和打磨,希望听取广大开发者的反馈建议。预计 DeepSeek Harness 的核心插件以及基础 API 都会在接下来的一段时间内快速迭代、持续演化。\n\n我们期待与全球开发者一起,在开源、开放、可复用、可组合的基础设施之上,共同探索智能上限。欢迎全球 Harness 开发者加入 DSH 插件生态。",
|
|
2352
|
-
continueLabel: "继续"
|
|
2353
|
-
},
|
|
2354
|
-
en: {
|
|
2355
|
-
title: "Internal Testing Notice",
|
|
2356
|
-
body: "DeepSeek Harness 0.1 remains in testing for Harness developers. Many areas need further improvement, and we welcome feedback from the developer community. DeepSeek Harness's core plugins and foundational APIs will continue to evolve rapidly over the coming months.\n\nWe look forward to exploring the limits of intelligence with developers around the world, building on open-source, open, reusable, and composable infrastructure. We welcome Harness developers everywhere to join the DSH plugin ecosystem.",
|
|
2357
|
-
continueLabel: "Continue"
|
|
2358
|
-
}
|
|
2359
|
-
};
|
|
2360
2394
|
//#endregion
|
|
2361
2395
|
//#region lib/types/client/welcome-store.js
|
|
2362
2396
|
/**
|
|
@@ -2383,7 +2417,7 @@ window.__ModuleLoader__.load({
|
|
|
2383
2417
|
var WelcomeNoticeStore = class {
|
|
2384
2418
|
scope;
|
|
2385
2419
|
/** uSES-safe state source shared by the registered welcome step. */
|
|
2386
|
-
store = (0,
|
|
2420
|
+
store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
|
|
2387
2421
|
status: "idle",
|
|
2388
2422
|
acknowledged: false,
|
|
2389
2423
|
error: null
|
|
@@ -2484,6 +2518,61 @@ window.__ModuleLoader__.load({
|
|
|
2484
2518
|
}
|
|
2485
2519
|
};
|
|
2486
2520
|
//#endregion
|
|
2521
|
+
//#region lib/types/client/operations.js
|
|
2522
|
+
/**
|
|
2523
|
+
* The Host reads and writes the Models cards perform, as callbacks built in the
|
|
2524
|
+
* plugin body. Cards receive these instead of a context: the outcomes name what
|
|
2525
|
+
* a card renders — a stored view, a stale revision, a refusal message — so the
|
|
2526
|
+
* failure codes and Remote namespaces stay in the apply world.
|
|
2527
|
+
*/
|
|
2528
|
+
/**
|
|
2529
|
+
* Bind the page's Host operations to the plugin's own Remote namespaces.
|
|
2530
|
+
* @param ctx - the page plugin's context, which declares `remote.credentials`,
|
|
2531
|
+
* `remote.llm`, and `remote.settings` in its own `inject`.
|
|
2532
|
+
* @returns the callbacks the section and its cards are injected with.
|
|
2533
|
+
*/
|
|
2534
|
+
function createModelsOperations(ctx) {
|
|
2535
|
+
return {
|
|
2536
|
+
describeCredential: async (ref) => {
|
|
2537
|
+
const response = await ctx.remote.credentials.describe([ref]);
|
|
2538
|
+
return response.ok ? response.value[ref] : void 0;
|
|
2539
|
+
},
|
|
2540
|
+
storeCredential: async (ref, value) => {
|
|
2541
|
+
const response = await ctx.remote.credentials.set(ref, value);
|
|
2542
|
+
return response.ok ? void 0 : response.error.message;
|
|
2543
|
+
},
|
|
2544
|
+
removeCredential: async (ref) => {
|
|
2545
|
+
const response = await ctx.remote.credentials.unset(ref);
|
|
2546
|
+
return response.ok ? void 0 : response.error.message;
|
|
2547
|
+
},
|
|
2548
|
+
writeSettings: async (ns, ops, expectedRevision) => {
|
|
2549
|
+
const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision);
|
|
2550
|
+
if (response.ok) return {
|
|
2551
|
+
kind: "written",
|
|
2552
|
+
view: response.value
|
|
2553
|
+
};
|
|
2554
|
+
const { code, message } = response.error;
|
|
2555
|
+
return code === "settings/conflict" ? {
|
|
2556
|
+
kind: "conflict",
|
|
2557
|
+
message
|
|
2558
|
+
} : {
|
|
2559
|
+
kind: "refused",
|
|
2560
|
+
message
|
|
2561
|
+
};
|
|
2562
|
+
},
|
|
2563
|
+
discoverModels: async (settingsNs, request) => {
|
|
2564
|
+
const response = await ctx.remote.llm.discoverModels(settingsNs, request);
|
|
2565
|
+
return response.ok ? {
|
|
2566
|
+
kind: "found",
|
|
2567
|
+
models: response.value
|
|
2568
|
+
} : {
|
|
2569
|
+
kind: "refused",
|
|
2570
|
+
message: response.error.message
|
|
2571
|
+
};
|
|
2572
|
+
}
|
|
2573
|
+
};
|
|
2574
|
+
}
|
|
2575
|
+
//#endregion
|
|
2487
2576
|
//#region lib/types/client/schema-operations.js
|
|
2488
2577
|
/**
|
|
2489
2578
|
* Hide the Cordis service identity behind bound schema callbacks.
|
|
@@ -2589,11 +2678,13 @@ window.__ModuleLoader__.load({
|
|
|
2589
2678
|
customApiUnset: "Not selected",
|
|
2590
2679
|
customNeedsBaseUrl: "A custom provider needs a base URL.",
|
|
2591
2680
|
customNeedsModels: "A custom provider needs at least one model.",
|
|
2681
|
+
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
2682
|
+
settingsPathUnresolvable: "unresolvable settings path",
|
|
2592
2683
|
create: "Create provider",
|
|
2593
2684
|
creating: "Creating…",
|
|
2594
|
-
welcomeTitle:
|
|
2595
|
-
welcomeBody:
|
|
2596
|
-
welcomeContinue:
|
|
2685
|
+
welcomeTitle: "Internal Testing Notice",
|
|
2686
|
+
welcomeBody: "DeepSeek Harness 0.1 remains in testing for Harness developers. Many areas need further improvement, and we welcome feedback from the developer community. DeepSeek Harness's core plugins and foundational APIs will continue to evolve rapidly over the coming months.\n\nWe look forward to exploring the limits of intelligence with developers around the world, building on open-source, open, reusable, and composable infrastructure. We welcome Harness developers everywhere to join the DSH plugin ecosystem.",
|
|
2687
|
+
welcomeContinue: "Continue",
|
|
2597
2688
|
welcomeError: "The acknowledgement could not be saved. Please try again.",
|
|
2598
2689
|
onboardingTitle: "Add an API key to get started",
|
|
2599
2690
|
onboardingDescription: "Configure the official DeepSeek provider to start building.",
|
|
@@ -2687,11 +2778,13 @@ window.__ModuleLoader__.load({
|
|
|
2687
2778
|
customApiUnset: "未选择",
|
|
2688
2779
|
customNeedsBaseUrl: "自定义提供方需要填写 API 地址。",
|
|
2689
2780
|
customNeedsModels: "自定义提供方至少需要一个模型。",
|
|
2781
|
+
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
2782
|
+
settingsPathUnresolvable: "无法解析设置路径",
|
|
2690
2783
|
create: "创建提供方",
|
|
2691
2784
|
creating: "创建中…",
|
|
2692
|
-
welcomeTitle:
|
|
2693
|
-
welcomeBody:
|
|
2694
|
-
welcomeContinue:
|
|
2785
|
+
welcomeTitle: "内测声明",
|
|
2786
|
+
welcomeBody: "DeepSeek Harness 目前的 0.1 版本仍处在面向 Harness 开发者进行测试的阶段,还有许多地方需要持续改进和打磨,希望听取广大开发者的反馈建议。预计 DeepSeek Harness 的核心插件以及基础 API 都会在接下来的一段时间内快速迭代、持续演化。\n\n我们期待与全球开发者一起,在开源、开放、可复用、可组合的基础设施之上,共同探索智能上限。欢迎全球 Harness 开发者加入 DSH 插件生态。",
|
|
2787
|
+
welcomeContinue: "继续",
|
|
2695
2788
|
welcomeError: "暂时无法保存确认状态,请重试。",
|
|
2696
2789
|
onboardingTitle: "添加一个 API Key 开始使用",
|
|
2697
2790
|
onboardingDescription: "配置 DeepSeek 官方模型,即可开始使用。",
|
|
@@ -2721,8 +2814,10 @@ window.__ModuleLoader__.load({
|
|
|
2721
2814
|
const inject = [
|
|
2722
2815
|
"slots",
|
|
2723
2816
|
"locale",
|
|
2724
|
-
"connection",
|
|
2725
2817
|
"remote",
|
|
2818
|
+
"remote.credentials",
|
|
2819
|
+
"remote.llm",
|
|
2820
|
+
"remote.settings",
|
|
2726
2821
|
"settingsScope",
|
|
2727
2822
|
"settingsSchema"
|
|
2728
2823
|
];
|
|
@@ -2737,21 +2832,21 @@ window.__ModuleLoader__.load({
|
|
|
2737
2832
|
zh,
|
|
2738
2833
|
en
|
|
2739
2834
|
}), "ui-settings-models: copy dictionaries");
|
|
2740
|
-
const connection = ctx.get("connection");
|
|
2741
2835
|
const schema = createSettingsSchemaOperations(ctx.settingsSchema);
|
|
2742
|
-
const
|
|
2836
|
+
const operations = createModelsOperations(ctx);
|
|
2837
|
+
const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe());
|
|
2743
2838
|
const t = ctx.locale.bind(NS);
|
|
2744
2839
|
const injected = () => ({
|
|
2745
2840
|
controller,
|
|
2746
2841
|
hooks: { snapshot: controller.store },
|
|
2747
|
-
|
|
2842
|
+
operations,
|
|
2748
2843
|
schema,
|
|
2749
2844
|
t
|
|
2750
2845
|
});
|
|
2751
2846
|
const deepSeekOnboardingInjected = () => ({
|
|
2752
2847
|
controller,
|
|
2753
2848
|
hooks: { models: controller.store },
|
|
2754
|
-
|
|
2849
|
+
operations,
|
|
2755
2850
|
schema,
|
|
2756
2851
|
t
|
|
2757
2852
|
});
|
|
@@ -2786,7 +2881,17 @@ window.__ModuleLoader__.load({
|
|
|
2786
2881
|
id: "models",
|
|
2787
2882
|
order: 10,
|
|
2788
2883
|
label: () => t("nav"),
|
|
2789
|
-
inject: injected
|
|
2884
|
+
inject: injected,
|
|
2885
|
+
children: {
|
|
2886
|
+
"settings.models.provider-card": {
|
|
2887
|
+
kind: "keyed",
|
|
2888
|
+
scope: "root"
|
|
2889
|
+
},
|
|
2890
|
+
"settings.models.footer": {
|
|
2891
|
+
kind: "list",
|
|
2892
|
+
scope: "root"
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2790
2895
|
}, ModelsSection));
|
|
2791
2896
|
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
2792
2897
|
name: "settings.onboarding",
|