dsh-edge 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +1318 -1075
- package/dist/assets/index-Df-65__b.js +110 -0
- package/dist/assets/index-b24khbeK.css +1 -0
- package/dist/assets/langs/{php-DDkx9sim.js → php-DJl5gRdb.js} +2 -2
- package/dist/assets/langs/{ruby-DCxyoPen.js → ruby-5eNB0pDK.js} +2 -2
- package/dist/assets/vendor-BNsW4eBh.css +1 -0
- package/dist/assets/vendor-CCJJTK99.js +411 -0
- package/dist/index.html +8 -8
- package/dist/plugins/@deepseek-ai/dsh-api-gateway/client.js +1513 -77
- package/dist/plugins/@deepseek-ai/dsh-api-remotes/client.js +3608 -757
- package/dist/plugins/@deepseek-ai/dsh-api-session-controller/client.js +2777 -0
- package/dist/plugins/@deepseek-ai/dsh-api-workspace-controller/client.js +415 -0
- package/dist/plugins/@deepseek-ai/dsh-client-connection/client.js +1975 -7466
- package/dist/plugins/@deepseek-ai/dsh-client-locale/client.js +225 -76
- package/dist/plugins/@deepseek-ai/dsh-client-modules/client.js +67 -15
- package/dist/plugins/@deepseek-ai/dsh-client-ui-agent-preset/client.js +270 -460
- package/dist/plugins/@deepseek-ai/dsh-client-ui-approval/client.js +292 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-attachment/client.js +42 -17
- package/dist/plugins/@deepseek-ai/dsh-client-ui-brand-official/client.js +7 -9
- package/dist/plugins/@deepseek-ai/dsh-client-ui-chat/client.js +8177 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-commands/client.js +22 -10
- package/dist/plugins/@deepseek-ai/dsh-client-ui-conversation/client.js +14950 -8910
- package/dist/plugins/@deepseek-ai/dsh-client-ui-deliverables/client.js +161 -137
- package/dist/plugins/@deepseek-ai/dsh-client-ui-goal/client.js +6 -7
- package/dist/plugins/@deepseek-ai/dsh-client-ui-input-trigger/client.js +268 -40
- package/dist/plugins/@deepseek-ai/dsh-client-ui-jobs/client.js +1 -1
- package/dist/plugins/@deepseek-ai/dsh-client-ui-layout/client.js +45 -11
- package/dist/plugins/@deepseek-ai/dsh-client-ui-message-feedback/client.js +30 -58
- package/dist/plugins/@deepseek-ai/dsh-client-ui-model-selection/client.js +188 -89
- package/dist/plugins/@deepseek-ai/dsh-client-ui-permission-presets/client.js +105 -75
- package/dist/plugins/@deepseek-ai/dsh-client-ui-renderer/client.js +650 -188
- package/dist/plugins/@deepseek-ai/dsh-client-ui-schedule/client.js +307 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-session/client.js +340 -0
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings/client.js +57 -50
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-general/client.js +134 -69
- package/dist/plugins/@deepseek-ai/dsh-client-ui-settings-models/client.js +575 -442
- package/dist/plugins/@deepseek-ai/dsh-client-ui-sidebar/client.js +24 -11
- package/dist/plugins/@deepseek-ai/dsh-client-ui-skill/client.js +13 -9
- package/dist/plugins/@deepseek-ai/dsh-client-ui-subagent/client.js +44 -20
- package/dist/plugins/@deepseek-ai/dsh-client-ui-theme/client.js +265 -94
- package/dist/plugins/@deepseek-ai/dsh-client-ui-tool/client.js +899 -433
- package/dist/plugins/@deepseek-ai/dsh-client-ui-trajectory/client.js +1472 -613
- package/dist/plugins/@deepseek-ai/dsh-client-ui-user-questions/client.js +249 -95
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workflow-run/client.js +5 -5
- package/dist/plugins/@deepseek-ai/dsh-client-ui-workspace/client.js +425 -146
- package/dist/plugins/@deepseek-ai/dsh-typert-registry/client.js +29 -14
- package/dist/plugins/dsh-edge-client-ui/client.js +28 -26
- package/package.json +62 -58
- package/scripts/verify-packed.mjs +1 -1
- package/worker/direct/index.js +2866 -1466
- package/worker/isolated/index.js +2438 -1038
- package/dist/assets/index-C6eRlFa6.css +0 -1
- package/dist/assets/index-ClqxG24t.js +0 -96
- package/dist/assets/vendor-CjyC-hUb.css +0 -1
- package/dist/assets/vendor-D22_Mp1f.js +0 -411
- package/dist/plugins/@deepseek-ai/dsh-client-runtime/client.js +0 -10574
|
@@ -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:.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}";
|
|
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");
|
|
@@ -72,10 +72,12 @@ window.__ModuleLoader__.load({
|
|
|
72
72
|
"addModelButton": "zGbnIq_addModelButton",
|
|
73
73
|
"advancedHint": "zGbnIq_advancedHint",
|
|
74
74
|
"candidate": "zGbnIq_candidate",
|
|
75
|
-
"
|
|
75
|
+
"candidateEmpty": "zGbnIq_candidateEmpty",
|
|
76
76
|
"candidateId": "zGbnIq_candidateId",
|
|
77
77
|
"candidateLabel": "zGbnIq_candidateLabel",
|
|
78
78
|
"candidateList": "zGbnIq_candidateList",
|
|
79
|
+
"candidateSearch": "zGbnIq_candidateSearch",
|
|
80
|
+
"candidateToolbar": "zGbnIq_candidateToolbar",
|
|
79
81
|
"credentialDot": "zGbnIq_credentialDot",
|
|
80
82
|
"credentialDotConfigured": "zGbnIq_credentialDotConfigured",
|
|
81
83
|
"credentialDotMissing": "zGbnIq_credentialDotMissing",
|
|
@@ -126,6 +128,7 @@ window.__ModuleLoader__.load({
|
|
|
126
128
|
"section": "zGbnIq_section",
|
|
127
129
|
"selectInput": "zGbnIq_selectInput",
|
|
128
130
|
"setupCard": "zGbnIq_setupCard",
|
|
131
|
+
"switchThumb": "zGbnIq_switchThumb",
|
|
129
132
|
"title": "zGbnIq_title"
|
|
130
133
|
};
|
|
131
134
|
//#endregion
|
|
@@ -144,13 +147,13 @@ window.__ModuleLoader__.load({
|
|
|
144
147
|
className: ModelsSection_module_css_default["secondaryButton"],
|
|
145
148
|
disabled: props.busy,
|
|
146
149
|
onClick: props.onCancel,
|
|
147
|
-
children: t(props.
|
|
150
|
+
children: t(props.cancelLabelKey ?? "cancel")
|
|
148
151
|
}), (0, react_jsx_runtime.jsx)("button", {
|
|
149
152
|
type: "button",
|
|
150
153
|
className: ModelsSection_module_css_default["primaryButton"],
|
|
151
154
|
disabled: props.submitDisabled,
|
|
152
155
|
onClick: props.onSubmit,
|
|
153
|
-
children: props.busy ? t(props.
|
|
156
|
+
children: props.busy ? t(props.submitBusyLabelKey) : t(props.submitLabelKey)
|
|
154
157
|
})]
|
|
155
158
|
});
|
|
156
159
|
}
|
|
@@ -442,212 +445,6 @@ window.__ModuleLoader__.load({
|
|
|
442
445
|
});
|
|
443
446
|
}
|
|
444
447
|
//#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
448
|
//#region lib/types/client/ModelListEditor.js
|
|
652
449
|
/**
|
|
653
450
|
* The model list of one pi-ai provider profile, plus the action that asks the
|
|
@@ -752,11 +549,12 @@ window.__ModuleLoader__.load({
|
|
|
752
549
|
* @returns the model-list editor.
|
|
753
550
|
*/
|
|
754
551
|
function ModelListEditor(props) {
|
|
755
|
-
const { models, onChange, probe,
|
|
552
|
+
const { models, onChange, probe, operations, t, disabled } = props;
|
|
756
553
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
757
554
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
758
555
|
const [candidates, setCandidates] = (0, react.useState)(void 0);
|
|
759
556
|
const [picked, setPicked] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
557
|
+
const [candidateQuery, setCandidateQuery] = (0, react.useState)("");
|
|
760
558
|
const [expanded, setExpanded] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
761
559
|
const [editing, setEditing] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
762
560
|
/** Buffer key for one capacity field; the row half moves when rows do. */
|
|
@@ -798,27 +596,25 @@ window.__ModuleLoader__.load({
|
|
|
798
596
|
setBusy(true);
|
|
799
597
|
setFailure(void 0);
|
|
800
598
|
try {
|
|
801
|
-
const
|
|
802
|
-
settingsNs: probe.settingsNs,
|
|
599
|
+
const answer = await operations.discoverModels(probe.settingsNs, {
|
|
803
600
|
...probe.provider === void 0 ? {} : { provider: probe.provider },
|
|
804
601
|
...probe.baseURL === void 0 || probe.baseURL.length === 0 ? {} : { baseURL: probe.baseURL },
|
|
805
602
|
...probe.api === void 0 ? {} : { api: probe.api },
|
|
806
603
|
...probe.apiKey === void 0 ? {} : { apiKey: probe.apiKey }
|
|
807
604
|
});
|
|
808
|
-
if (
|
|
809
|
-
setFailure(
|
|
605
|
+
if (answer.kind === "refused") {
|
|
606
|
+
setFailure(answer.message);
|
|
810
607
|
return;
|
|
811
608
|
}
|
|
812
|
-
const found =
|
|
609
|
+
const found = answer.models;
|
|
813
610
|
if (found.length === 0) {
|
|
814
611
|
setFailure(t("fetchEmpty"));
|
|
815
612
|
return;
|
|
816
613
|
}
|
|
817
614
|
const known = new Set(models.map((model) => textOf(model, "id")));
|
|
615
|
+
setCandidateQuery("");
|
|
818
616
|
setCandidates(found);
|
|
819
617
|
setPicked(new Set(found.filter((model) => !known.has(model.id)).map((model) => model.id)));
|
|
820
|
-
} catch (error) {
|
|
821
|
-
setFailure(messageOf(error));
|
|
822
618
|
} finally {
|
|
823
619
|
setBusy(false);
|
|
824
620
|
}
|
|
@@ -826,6 +622,7 @@ window.__ModuleLoader__.load({
|
|
|
826
622
|
const closePicker = () => {
|
|
827
623
|
setCandidates(void 0);
|
|
828
624
|
setPicked(/* @__PURE__ */ new Set());
|
|
625
|
+
setCandidateQuery("");
|
|
829
626
|
};
|
|
830
627
|
const adoptPicked = () => {
|
|
831
628
|
/* v8 ignore next -- the dialog only renders with candidates loaded */
|
|
@@ -846,10 +643,15 @@ window.__ModuleLoader__.load({
|
|
|
846
643
|
});
|
|
847
644
|
};
|
|
848
645
|
const activeCandidates = candidates ?? [];
|
|
849
|
-
const
|
|
850
|
-
const
|
|
646
|
+
const normalizedCandidateQuery = candidateQuery.trim().toLowerCase();
|
|
647
|
+
const visibleCandidates = normalizedCandidateQuery.length === 0 ? activeCandidates : activeCandidates.filter((candidate) => candidate.id.toLowerCase().includes(normalizedCandidateQuery) || candidate.name?.toLowerCase().includes(normalizedCandidateQuery) === true);
|
|
648
|
+
const allVisibleCandidatesPicked = visibleCandidates.length > 0 && visibleCandidates.every((candidate) => picked.has(candidate.id));
|
|
649
|
+
const toggleVisibleCandidates = () => {
|
|
851
650
|
setPicked((current) => {
|
|
852
|
-
|
|
651
|
+
const next = new Set(current);
|
|
652
|
+
if (visibleCandidates.every((candidate) => current.has(candidate.id))) for (const candidate of visibleCandidates) next.delete(candidate.id);
|
|
653
|
+
else for (const candidate of visibleCandidates) next.add(candidate.id);
|
|
654
|
+
return next;
|
|
853
655
|
});
|
|
854
656
|
};
|
|
855
657
|
const askable = probe.provider !== void 0 || probe.baseURL !== void 0 && probe.baseURL.length > 0;
|
|
@@ -1018,17 +820,31 @@ window.__ModuleLoader__.load({
|
|
|
1018
820
|
onClick: adoptPicked,
|
|
1019
821
|
children: t("fetchAdopt")
|
|
1020
822
|
})] }),
|
|
1021
|
-
children: [(0, react_jsx_runtime.
|
|
1022
|
-
className: ModelsSection_module_css_default["
|
|
1023
|
-
children: (0, react_jsx_runtime.jsx)(
|
|
823
|
+
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
824
|
+
className: ModelsSection_module_css_default["candidateToolbar"],
|
|
825
|
+
children: [(0, react_jsx_runtime.jsx)("input", {
|
|
826
|
+
className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["candidateSearch"]}`,
|
|
827
|
+
type: "search",
|
|
828
|
+
value: candidateQuery,
|
|
829
|
+
placeholder: t("fetchSearch"),
|
|
830
|
+
"aria-label": t("fetchSearch"),
|
|
831
|
+
onChange: (event) => {
|
|
832
|
+
setCandidateQuery(event.target.value);
|
|
833
|
+
}
|
|
834
|
+
}), (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
1024
835
|
variant: "ghost",
|
|
1025
836
|
size: "sm",
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
837
|
+
disabled: visibleCandidates.length === 0,
|
|
838
|
+
onClick: toggleVisibleCandidates,
|
|
839
|
+
children: t(allVisibleCandidatesPicked ? "fetchDeselectAll" : "fetchSelectAll")
|
|
840
|
+
})]
|
|
841
|
+
}), visibleCandidates.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
842
|
+
className: ModelsSection_module_css_default["candidateEmpty"],
|
|
843
|
+
role: "status",
|
|
844
|
+
children: t("fetchNoMatches")
|
|
845
|
+
}) : (0, react_jsx_runtime.jsx)("ul", {
|
|
1030
846
|
className: ModelsSection_module_css_default["candidateList"],
|
|
1031
|
-
children:
|
|
847
|
+
children: visibleCandidates.map((candidate) => (0, react_jsx_runtime.jsx)("li", {
|
|
1032
848
|
className: ModelsSection_module_css_default["candidate"],
|
|
1033
849
|
children: (0, react_jsx_runtime.jsxs)("label", {
|
|
1034
850
|
className: ModelsSection_module_css_default["candidateLabel"],
|
|
@@ -1050,6 +866,247 @@ window.__ModuleLoader__.load({
|
|
|
1050
866
|
});
|
|
1051
867
|
}
|
|
1052
868
|
//#endregion
|
|
869
|
+
//#region lib/types/client/store.js
|
|
870
|
+
/**
|
|
871
|
+
* Models settings page store: one snapshot joining the configurable-provider
|
|
872
|
+
* directory (`llm/listProviders` joined with `llm/listConfigurableProviders`),
|
|
873
|
+
* the settings namespaces (shared settings mirror),
|
|
874
|
+
* and the referenced credentials (`credentials/describe`). The host stays the
|
|
875
|
+
* single fact source — every mutation writes through the wire and the page
|
|
876
|
+
* re-renders from the next describe, pushed or refetched.
|
|
877
|
+
*/
|
|
878
|
+
/**
|
|
879
|
+
* Any route key walks a dict schema to the same profile node, so the lookup
|
|
880
|
+
* names one that cannot collide with a configured route.
|
|
881
|
+
*/
|
|
882
|
+
const PROBE_ROUTE = "\0probe";
|
|
883
|
+
/**
|
|
884
|
+
* Join declared configurable providers with the currently registered routes.
|
|
885
|
+
* @param registered - live provider routes in registration order.
|
|
886
|
+
* @param directory - declared configurable providers in declaration order.
|
|
887
|
+
* @returns declared rows followed by live routes with no declaration.
|
|
888
|
+
*/
|
|
889
|
+
function joinProviderDirectory(registered, directory) {
|
|
890
|
+
const active = new Set(registered.map((provider) => provider.id));
|
|
891
|
+
const declared = new Set(directory.map((entry) => entry.provider));
|
|
892
|
+
const rows = directory.map((entry) => ({
|
|
893
|
+
provider: entry.provider,
|
|
894
|
+
displayName: entry.displayName,
|
|
895
|
+
settingsNs: entry.settingsNs,
|
|
896
|
+
settingsPath: [...entry.settingsPath],
|
|
897
|
+
active: active.has(entry.provider),
|
|
898
|
+
...entry.declared === void 0 ? {} : { declared: entry.declared }
|
|
899
|
+
}));
|
|
900
|
+
for (const provider of registered) {
|
|
901
|
+
if (declared.has(provider.id)) continue;
|
|
902
|
+
rows.push({
|
|
903
|
+
provider: provider.id,
|
|
904
|
+
displayName: provider.name,
|
|
905
|
+
settingsNs: "",
|
|
906
|
+
settingsPath: [],
|
|
907
|
+
active: true
|
|
908
|
+
});
|
|
909
|
+
}
|
|
910
|
+
return rows;
|
|
911
|
+
}
|
|
912
|
+
/**
|
|
913
|
+
* Derive the conventional credential reference for a provider route: the v1
|
|
914
|
+
* page never asks for an environment-variable name, so a typed key stores
|
|
915
|
+
* under this derived reference and the profile records it as `apiKeyEnv`.
|
|
916
|
+
* @param provider - provider route id (e.g. `anthropic`, `minimax-cn`).
|
|
917
|
+
* @returns the derived reference name (e.g. `MINIMAX_CN_API_KEY`).
|
|
918
|
+
*/
|
|
919
|
+
function deriveKeyRef(provider) {
|
|
920
|
+
return `${provider.toUpperCase().replace(/[^A-Z0-9]+/g, "_")}_API_KEY`;
|
|
921
|
+
}
|
|
922
|
+
/**
|
|
923
|
+
* The wire protocols a hand-declared route may name, read out of the owning
|
|
924
|
+
* namespace's own schema. This stays a schema read rather than a wire field so
|
|
925
|
+
* the choices the page offers cannot drift from the ones the adapter accepts:
|
|
926
|
+
* both come from the same `Config`.
|
|
927
|
+
* @param namespace - the namespace view whose schema declares the profile shape.
|
|
928
|
+
* @param schema - settings schema operations.
|
|
929
|
+
* @returns the protocol identifiers, or an empty list when the schema has none.
|
|
930
|
+
*/
|
|
931
|
+
function protocolChoices(namespace, schema) {
|
|
932
|
+
if (namespace === void 0) return [];
|
|
933
|
+
const list = schema.nodeAtPath(schema.rehydrate(namespace.schema), [
|
|
934
|
+
"providers",
|
|
935
|
+
PROBE_ROUTE,
|
|
936
|
+
"api"
|
|
937
|
+
]);
|
|
938
|
+
if (list?.type !== "union" || list.list === void 0) return [];
|
|
939
|
+
return list.list.map((entry) => entry.value).filter((value) => typeof value === "string");
|
|
940
|
+
}
|
|
941
|
+
/** The credential reference a resolved profile names (its `apiKeyEnv` field). */
|
|
942
|
+
function apiKeyEnvOf(namespace, path, schema) {
|
|
943
|
+
if (namespace === void 0) return void 0;
|
|
944
|
+
const profile = schema.getPath(namespace.value, path);
|
|
945
|
+
if (typeof profile !== "object" || profile === null) return void 0;
|
|
946
|
+
const ref = profile.apiKeyEnv;
|
|
947
|
+
return typeof ref === "string" && ref.length > 0 ? ref : void 0;
|
|
948
|
+
}
|
|
949
|
+
/** The models settings page controller (one per settings surface). */
|
|
950
|
+
var ModelsSettingsStore = class {
|
|
951
|
+
ctx;
|
|
952
|
+
schema;
|
|
953
|
+
describeFace;
|
|
954
|
+
/** The snapshot the section renders from (uSES-safe store). */
|
|
955
|
+
store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
|
|
956
|
+
status: "idle",
|
|
957
|
+
error: null,
|
|
958
|
+
credentialError: null,
|
|
959
|
+
writable: false,
|
|
960
|
+
rows: [],
|
|
961
|
+
namespaces: /* @__PURE__ */ new Map()
|
|
962
|
+
});
|
|
963
|
+
/** Latest load wins; an older response never overwrites a newer one. */
|
|
964
|
+
generation = 0;
|
|
965
|
+
/**
|
|
966
|
+
* @param ctx - the page plugin's context, whose `remote.llm` and
|
|
967
|
+
* `remote.credentials` namespaces carry the directory and credential reads.
|
|
968
|
+
* @param schema - settings-owned schema and immutable path operations.
|
|
969
|
+
* @param describeFace - the shared mirror's describe face (namespace views and writability).
|
|
970
|
+
*/
|
|
971
|
+
constructor(ctx, schema, describeFace) {
|
|
972
|
+
this.ctx = ctx;
|
|
973
|
+
this.schema = schema;
|
|
974
|
+
this.describeFace = describeFace;
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Refresh the whole page snapshot: the provider directory and the mirror's
|
|
978
|
+
* settings answer in parallel, then one batched credential describe over
|
|
979
|
+
* every referenced ref. Provider failure or absence of an initial settings
|
|
980
|
+
* answer keeps the last good rows and surfaces an error; a failed settings
|
|
981
|
+
* refresh reuses the mirror's held view.
|
|
982
|
+
* @returns nothing; the snapshot carries the outcome.
|
|
983
|
+
*/
|
|
984
|
+
async load() {
|
|
985
|
+
const generation = ++this.generation;
|
|
986
|
+
this.store.update((s) => {
|
|
987
|
+
s.status = "loading";
|
|
988
|
+
s.error = null;
|
|
989
|
+
});
|
|
990
|
+
const [registered, declared] = await Promise.all([
|
|
991
|
+
this.ctx.remote.llm.listProviders(),
|
|
992
|
+
this.ctx.remote.llm.listConfigurableProviders(),
|
|
993
|
+
this.describeFace.ensure()
|
|
994
|
+
]);
|
|
995
|
+
if (!registered.ok) {
|
|
996
|
+
this.failLoad(generation, registered.error.message);
|
|
997
|
+
return;
|
|
998
|
+
}
|
|
999
|
+
if (!declared.ok) {
|
|
1000
|
+
this.failLoad(generation, declared.error.message);
|
|
1001
|
+
return;
|
|
1002
|
+
}
|
|
1003
|
+
const mirrored = this.describeFace.getSnapshot();
|
|
1004
|
+
if (mirrored.view === void 0) {
|
|
1005
|
+
this.failLoad(generation, mirrored.error ?? "settings are unavailable in this browser");
|
|
1006
|
+
return;
|
|
1007
|
+
}
|
|
1008
|
+
const providers = joinProviderDirectory(registered.value, declared.value);
|
|
1009
|
+
const writable = mirrored.view.writable;
|
|
1010
|
+
const views = mirrored.view.namespaces;
|
|
1011
|
+
const namespaces = new Map(views.map((view) => [view.ns, view]));
|
|
1012
|
+
const rows = providers.map((entry) => {
|
|
1013
|
+
const namespace = namespaces.get(entry.settingsNs);
|
|
1014
|
+
return {
|
|
1015
|
+
entry,
|
|
1016
|
+
configured: namespace !== void 0 && (entry.settingsPath.length === 0 || this.schema.getPath(namespace.value, entry.settingsPath) !== void 0),
|
|
1017
|
+
removable: namespace !== void 0 && entry.settingsPath.length > 0 && this.schema.hasPath(namespace.user, entry.settingsPath) && !this.schema.hasPath(namespace.base, entry.settingsPath),
|
|
1018
|
+
apiKeyEnv: apiKeyEnvOf(namespace, entry.settingsPath, this.schema),
|
|
1019
|
+
credential: void 0
|
|
1020
|
+
};
|
|
1021
|
+
});
|
|
1022
|
+
const refs = [...new Set(rows.map((row) => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))];
|
|
1023
|
+
let credentials = {};
|
|
1024
|
+
let credentialError = null;
|
|
1025
|
+
if (refs.length > 0) {
|
|
1026
|
+
const response = await this.ctx.remote.credentials.describe(refs);
|
|
1027
|
+
if (response.ok) credentials = response.value;
|
|
1028
|
+
else credentialError = response.error.message;
|
|
1029
|
+
}
|
|
1030
|
+
if (generation !== this.generation) return;
|
|
1031
|
+
this.store.update((s) => {
|
|
1032
|
+
s.status = "ready";
|
|
1033
|
+
s.error = null;
|
|
1034
|
+
s.credentialError = credentialError;
|
|
1035
|
+
s.writable = writable;
|
|
1036
|
+
s.rows = rows.map((row) => {
|
|
1037
|
+
const named = row.apiKeyEnv === void 0 ? void 0 : credentials[row.apiKeyEnv];
|
|
1038
|
+
const derived = row.apiKeyEnv !== void 0 ? void 0 : credentials[deriveKeyRef(row.entry.provider)];
|
|
1039
|
+
return {
|
|
1040
|
+
...row,
|
|
1041
|
+
...named === void 0 ? {} : { credential: named },
|
|
1042
|
+
...derived === void 0 ? {} : { derivedCredential: derived }
|
|
1043
|
+
};
|
|
1044
|
+
});
|
|
1045
|
+
s.namespaces = namespaces;
|
|
1046
|
+
});
|
|
1047
|
+
}
|
|
1048
|
+
/** Publish one load's failure text, unless a newer load already took over. */
|
|
1049
|
+
failLoad(generation, message) {
|
|
1050
|
+
if (generation !== this.generation) return;
|
|
1051
|
+
this.store.update((s) => {
|
|
1052
|
+
s.status = "error";
|
|
1053
|
+
s.error = message;
|
|
1054
|
+
});
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
/**
|
|
1058
|
+
* Whether a joined row can serve model requests as it stands: the route is
|
|
1059
|
+
* registered with the adapter registry, and whatever credential its resolved
|
|
1060
|
+
* profile names is stored. A profile naming no reference authenticates through
|
|
1061
|
+
* the provider's own path (the Bedrock chain, Vertex ADC, a gateway that needs
|
|
1062
|
+
* nothing), as does a live route with no settings address at all, so neither
|
|
1063
|
+
* owes this page a key.
|
|
1064
|
+
* @param row - one joined provider row.
|
|
1065
|
+
* @returns whether the user already has this provider to talk to.
|
|
1066
|
+
*/
|
|
1067
|
+
function providerUsable(row) {
|
|
1068
|
+
if (!row.entry.active) return false;
|
|
1069
|
+
if (row.apiKeyEnv === void 0) return true;
|
|
1070
|
+
return row.credential?.configured === true;
|
|
1071
|
+
}
|
|
1072
|
+
/**
|
|
1073
|
+
* Project first-run readiness from the provider/settings/credential join used
|
|
1074
|
+
* by the Models page. The step exists to leave the user with a model to talk
|
|
1075
|
+
* to, so ANY usable provider ends it; only when none exists does the official
|
|
1076
|
+
* DeepSeek route — the one route the prompt can offer a key field for — decide
|
|
1077
|
+
* whether prompting can help. A missing official configurable-provider
|
|
1078
|
+
* declaration means the adapter is not repairable by navigating to Models.
|
|
1079
|
+
* @param state - current shared Models join snapshot.
|
|
1080
|
+
* @returns the onboarding state without reading a parallel fact source.
|
|
1081
|
+
*/
|
|
1082
|
+
function onboardingReadiness(state) {
|
|
1083
|
+
if ((state.status === "idle" || state.status === "loading") && state.rows.length === 0) return { kind: "loading" };
|
|
1084
|
+
if (state.status === "error") return {
|
|
1085
|
+
kind: "unavailable",
|
|
1086
|
+
reason: "load-failed"
|
|
1087
|
+
};
|
|
1088
|
+
if (state.rows.some(providerUsable)) return { kind: "provider-ready" };
|
|
1089
|
+
const row = state.rows.find((candidate) => candidate.entry.provider === "deepseek-official" && candidate.entry.settingsNs === "llm-deepseek" && candidate.entry.settingsPath.length === 0);
|
|
1090
|
+
if (row === void 0) return { kind: "adapter-absent" };
|
|
1091
|
+
if (!row.entry.active) return {
|
|
1092
|
+
kind: "unavailable",
|
|
1093
|
+
reason: "provider-inactive"
|
|
1094
|
+
};
|
|
1095
|
+
if (state.credentialError !== null || row.credential === void 0) return {
|
|
1096
|
+
kind: "unavailable",
|
|
1097
|
+
reason: "credentials-unavailable"
|
|
1098
|
+
};
|
|
1099
|
+
if (!state.writable) return {
|
|
1100
|
+
kind: "unavailable",
|
|
1101
|
+
reason: "settings-read-only"
|
|
1102
|
+
};
|
|
1103
|
+
if (!row.credential.writable) return {
|
|
1104
|
+
kind: "unavailable",
|
|
1105
|
+
reason: "credential-read-only"
|
|
1106
|
+
};
|
|
1107
|
+
return { kind: "credential-missing" };
|
|
1108
|
+
}
|
|
1109
|
+
//#endregion
|
|
1053
1110
|
//#region lib/types/client/CustomProviderCard.js
|
|
1054
1111
|
/**
|
|
1055
1112
|
* The card that declares a provider pi-ai does not ship — an OpenAI-compatible
|
|
@@ -1060,7 +1117,7 @@ window.__ModuleLoader__.load({
|
|
|
1060
1117
|
* the provider editor with extra fields: the route id is being *chosen* here,
|
|
1061
1118
|
* and the settings address does not exist until it is. One `settings.mutate`
|
|
1062
1119
|
* sets the whole profile at `providers.<route>`; the key travels separately
|
|
1063
|
-
* through `credentials
|
|
1120
|
+
* through `credentials/set` under the reference the profile records, exactly as
|
|
1064
1121
|
* an existing provider's key does.
|
|
1065
1122
|
*
|
|
1066
1123
|
* The three fields a hand-declared route cannot default — endpoint, protocol,
|
|
@@ -1090,7 +1147,7 @@ window.__ModuleLoader__.load({
|
|
|
1090
1147
|
* @returns the creation card.
|
|
1091
1148
|
*/
|
|
1092
1149
|
function CustomProviderCard(props) {
|
|
1093
|
-
const { taken, protocols,
|
|
1150
|
+
const { taken, protocols, operations, t } = props;
|
|
1094
1151
|
const [openedAt] = (0, react.useState)(() => props.revision);
|
|
1095
1152
|
const [route, setRoute] = (0, react.useState)("");
|
|
1096
1153
|
const [displayName, setDisplayName] = (0, react.useState)("");
|
|
@@ -1128,24 +1185,17 @@ window.__ModuleLoader__.load({
|
|
|
1128
1185
|
baseURL,
|
|
1129
1186
|
models: models.map((model) => ({ ...model }))
|
|
1130
1187
|
};
|
|
1131
|
-
const
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
}],
|
|
1138
|
-
expectedRevision: openedAt
|
|
1139
|
-
});
|
|
1140
|
-
if (!response.result.ok) return response.result.error.message;
|
|
1188
|
+
const written = await operations.writeSettings(NS$1, [{
|
|
1189
|
+
op: "set",
|
|
1190
|
+
path: ["providers", route],
|
|
1191
|
+
value: profile
|
|
1192
|
+
}], openedAt);
|
|
1193
|
+
if (written.kind !== "written") return written.kind === "conflict" ? t("conflict") : written.message;
|
|
1141
1194
|
setCommitted(true);
|
|
1142
1195
|
}
|
|
1143
1196
|
if (storesKey) {
|
|
1144
|
-
const stored = await
|
|
1145
|
-
|
|
1146
|
-
value: keyValue
|
|
1147
|
-
});
|
|
1148
|
-
if (!stored.result.ok) return stored.result.error.message;
|
|
1197
|
+
const stored = await operations.storeCredential(keyRef, keyValue);
|
|
1198
|
+
if (stored !== void 0) return stored;
|
|
1149
1199
|
}
|
|
1150
1200
|
};
|
|
1151
1201
|
const create = async () => {
|
|
@@ -1158,8 +1208,6 @@ window.__ModuleLoader__.load({
|
|
|
1158
1208
|
return;
|
|
1159
1209
|
}
|
|
1160
1210
|
props.onClose(true);
|
|
1161
|
-
} catch (error) {
|
|
1162
|
-
setFailure(messageOf(error));
|
|
1163
1211
|
} finally {
|
|
1164
1212
|
setBusy(false);
|
|
1165
1213
|
}
|
|
@@ -1224,7 +1272,7 @@ window.__ModuleLoader__.load({
|
|
|
1224
1272
|
className: ModelsSection_module_css_default["input"],
|
|
1225
1273
|
type: "text",
|
|
1226
1274
|
value: baseURL,
|
|
1227
|
-
placeholder: "
|
|
1275
|
+
placeholder: t("customBaseUrlPlaceholder"),
|
|
1228
1276
|
"aria-label": t("baseUrl"),
|
|
1229
1277
|
disabled: profileDisabled,
|
|
1230
1278
|
onChange: (event) => {
|
|
@@ -1286,7 +1334,7 @@ window.__ModuleLoader__.load({
|
|
|
1286
1334
|
...keyValue.length === 0 ? {} : { apiKey: keyValue }
|
|
1287
1335
|
},
|
|
1288
1336
|
probeBlocked: keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
|
|
1289
|
-
|
|
1337
|
+
operations,
|
|
1290
1338
|
t,
|
|
1291
1339
|
disabled: profileDisabled
|
|
1292
1340
|
}),
|
|
@@ -1302,8 +1350,8 @@ window.__ModuleLoader__.load({
|
|
|
1302
1350
|
t,
|
|
1303
1351
|
busy,
|
|
1304
1352
|
submitDisabled: disabled || !ready,
|
|
1305
|
-
|
|
1306
|
-
|
|
1353
|
+
submitLabelKey: "create",
|
|
1354
|
+
submitBusyLabelKey: "creating",
|
|
1307
1355
|
onCancel: () => {
|
|
1308
1356
|
props.onClose(committed);
|
|
1309
1357
|
},
|
|
@@ -1319,7 +1367,7 @@ window.__ModuleLoader__.load({
|
|
|
1319
1367
|
/**
|
|
1320
1368
|
* One provider's editor card, hand-written per adapter family: the primary
|
|
1321
1369
|
* 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
|
|
1370
|
+
* environment-variable name — a typed key stores through `credentials/set`
|
|
1323
1371
|
* under the profile's reference, deriving `<ROUTE>_API_KEY` when the profile
|
|
1324
1372
|
* has none. The pi-ai profile records that derivation as `apiKeyEnv` only when
|
|
1325
1373
|
* a key is entered; a blank key materializes a reference-free profile for
|
|
@@ -1391,7 +1439,7 @@ window.__ModuleLoader__.load({
|
|
|
1391
1439
|
* @returns the editor card.
|
|
1392
1440
|
*/
|
|
1393
1441
|
function ProviderEditor(props) {
|
|
1394
|
-
const { namespace, schema, settingsPath,
|
|
1442
|
+
const { namespace, schema, settingsPath, operations, t } = props;
|
|
1395
1443
|
const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
|
|
1396
1444
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1397
1445
|
const [keyState, setKeyState] = (0, react.useState)(void 0);
|
|
@@ -1417,14 +1465,14 @@ window.__ModuleLoader__.load({
|
|
|
1417
1465
|
(0, react.useEffect)(() => {
|
|
1418
1466
|
let stale = false;
|
|
1419
1467
|
setKeyState(void 0);
|
|
1420
|
-
|
|
1421
|
-
if (stale
|
|
1422
|
-
setKeyState(
|
|
1423
|
-
}
|
|
1468
|
+
operations.describeCredential(keyRef).then((described) => {
|
|
1469
|
+
if (stale) return;
|
|
1470
|
+
setKeyState(described);
|
|
1471
|
+
});
|
|
1424
1472
|
return () => {
|
|
1425
1473
|
stale = true;
|
|
1426
1474
|
};
|
|
1427
|
-
}, [
|
|
1475
|
+
}, [operations, keyRef]);
|
|
1428
1476
|
const stringAt = (source, key) => {
|
|
1429
1477
|
const value = schema.getPath(source, [key]);
|
|
1430
1478
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -1472,22 +1520,15 @@ window.__ModuleLoader__.load({
|
|
|
1472
1520
|
value: {}
|
|
1473
1521
|
}] : pathOps(settingsPath, committedOriginal, next);
|
|
1474
1522
|
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);
|
|
1523
|
+
const written = await operations.writeSettings(ns, ops, expectedRevision);
|
|
1524
|
+
if (written.kind !== "written") return written.kind === "conflict" ? t("conflict") : written.message;
|
|
1525
|
+
setCommittedOriginal(schema.getPath(written.view.user, settingsPath));
|
|
1526
|
+
setExpectedRevision(written.view.revision);
|
|
1483
1527
|
setDraft(next);
|
|
1484
1528
|
}
|
|
1485
1529
|
if (keyValue.length > 0) {
|
|
1486
|
-
const stored = await
|
|
1487
|
-
|
|
1488
|
-
value: keyValue
|
|
1489
|
-
});
|
|
1490
|
-
if (!stored.result.ok) return stored.result.error.message;
|
|
1530
|
+
const stored = await operations.storeCredential(keyRef, keyValue);
|
|
1531
|
+
if (stored !== void 0) return stored;
|
|
1491
1532
|
}
|
|
1492
1533
|
setKeyDraft("");
|
|
1493
1534
|
};
|
|
@@ -1501,15 +1542,17 @@ window.__ModuleLoader__.load({
|
|
|
1501
1542
|
return;
|
|
1502
1543
|
}
|
|
1503
1544
|
props.onClose(true);
|
|
1504
|
-
} catch (error) {
|
|
1505
|
-
setFailure(messageOf(error));
|
|
1506
1545
|
} finally {
|
|
1507
1546
|
setBusy(false);
|
|
1508
1547
|
}
|
|
1509
1548
|
};
|
|
1510
|
-
if (node === void 0) return (0, react_jsx_runtime.
|
|
1549
|
+
if (node === void 0) return (0, react_jsx_runtime.jsxs)("p", {
|
|
1511
1550
|
className: ModelsSection_module_css_default["error"],
|
|
1512
|
-
children:
|
|
1551
|
+
children: [
|
|
1552
|
+
props.provider,
|
|
1553
|
+
": ",
|
|
1554
|
+
props.t("settingsPathUnresolvable")
|
|
1555
|
+
]
|
|
1513
1556
|
});
|
|
1514
1557
|
const keyLocked = keyState?.writable === false;
|
|
1515
1558
|
/**
|
|
@@ -1647,7 +1690,7 @@ window.__ModuleLoader__.load({
|
|
|
1647
1690
|
...catalogProps,
|
|
1648
1691
|
probe,
|
|
1649
1692
|
probeBlocked: keyFailure,
|
|
1650
|
-
|
|
1693
|
+
operations
|
|
1651
1694
|
})
|
|
1652
1695
|
]
|
|
1653
1696
|
})]
|
|
@@ -1682,9 +1725,9 @@ window.__ModuleLoader__.load({
|
|
|
1682
1725
|
t,
|
|
1683
1726
|
busy,
|
|
1684
1727
|
submitDisabled: disabled || layout === "unknown" || props.credentialOnly !== true && modelFailure !== void 0 || shownKeyFailure !== void 0 || props.credentialRequired === true && keyValue.length === 0,
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
...props.
|
|
1728
|
+
submitLabelKey: props.submitLabelKey ?? "apply",
|
|
1729
|
+
submitBusyLabelKey: props.submitBusyLabelKey ?? "applying",
|
|
1730
|
+
...props.cancelLabelKey === void 0 ? {} : { cancelLabelKey: props.cancelLabelKey },
|
|
1688
1731
|
onCancel: () => {
|
|
1689
1732
|
props.onClose(false);
|
|
1690
1733
|
},
|
|
@@ -1726,28 +1769,21 @@ window.__ModuleLoader__.load({
|
|
|
1726
1769
|
* and the whole operation safely retryable; both unsets are idempotent.
|
|
1727
1770
|
* The settings removal names the profile rather than rebuilding its whole
|
|
1728
1771
|
* namespace from a partial view.
|
|
1729
|
-
* @param
|
|
1772
|
+
* @param operations - the page's Host operations.
|
|
1730
1773
|
* @param controller - the page store to refresh.
|
|
1731
1774
|
* @param target - the provider's settings address and optional managed credential.
|
|
1732
1775
|
* @returns the failure message, or undefined once the write and reload landed.
|
|
1733
1776
|
*/
|
|
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);
|
|
1777
|
+
async function removeProviderProfile(operations, controller, target) {
|
|
1778
|
+
if (target.credentialRef !== void 0) {
|
|
1779
|
+
const credential = await operations.removeCredential(target.credentialRef);
|
|
1780
|
+
if (credential !== void 0) return credential;
|
|
1750
1781
|
}
|
|
1782
|
+
const written = await operations.writeSettings(target.settingsNs, [{
|
|
1783
|
+
op: "unset",
|
|
1784
|
+
path: [...target.settingsPath]
|
|
1785
|
+
}], void 0);
|
|
1786
|
+
if (written.kind !== "written") return written.message;
|
|
1751
1787
|
await controller.load();
|
|
1752
1788
|
}
|
|
1753
1789
|
/**
|
|
@@ -1764,6 +1800,16 @@ window.__ModuleLoader__.load({
|
|
|
1764
1800
|
if (row.entry.settingsPath.length > 0) return false;
|
|
1765
1801
|
return row.credential?.configured !== true;
|
|
1766
1802
|
}
|
|
1803
|
+
/**
|
|
1804
|
+
* The provider-card seat's credential fact: the reference this page would use
|
|
1805
|
+
* for the row — the profile's `apiKeyEnv`, or the page's derived
|
|
1806
|
+
* `<ROUTE>_API_KEY` while the profile names none — confirmed configured. The
|
|
1807
|
+
* derived half is what keeps the seat consistent with the editor on the
|
|
1808
|
+
* add-provider draft, whose dormant row names no reference yet.
|
|
1809
|
+
*/
|
|
1810
|
+
function keyConfiguredOf(row) {
|
|
1811
|
+
return row.apiKeyEnv !== void 0 ? row.credential?.configured === true : row.derivedCredential?.configured === true;
|
|
1812
|
+
}
|
|
1767
1813
|
function targetOf(row) {
|
|
1768
1814
|
const managedRef = deriveKeyRef(row.entry.provider);
|
|
1769
1815
|
const credentialRef = row.apiKeyEnv === managedRef && row.credential?.configured === true && row.credential.writable ? managedRef : void 0;
|
|
@@ -1790,18 +1836,21 @@ window.__ModuleLoader__.load({
|
|
|
1790
1836
|
* @returns the section, or null while the shell has not injected yet.
|
|
1791
1837
|
*/
|
|
1792
1838
|
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
|
-
|
|
1839
|
+
const { controller, useSnapshot, operations, schema, t, renderSlot } = props;
|
|
1840
|
+
if (controller === void 0 || useSnapshot === void 0 || operations === void 0 || schema === void 0 || t === void 0) return null;
|
|
1841
|
+
return (0, react_jsx_runtime.jsx)(Loaded, {
|
|
1842
|
+
injected: {
|
|
1843
|
+
controller,
|
|
1844
|
+
useSnapshot,
|
|
1845
|
+
operations,
|
|
1846
|
+
schema,
|
|
1847
|
+
t
|
|
1848
|
+
},
|
|
1849
|
+
renderSlot
|
|
1850
|
+
});
|
|
1802
1851
|
}
|
|
1803
|
-
function Loaded({ injected }) {
|
|
1804
|
-
const { controller,
|
|
1852
|
+
function Loaded({ injected, renderSlot }) {
|
|
1853
|
+
const { controller, operations, schema, t } = injected;
|
|
1805
1854
|
const state = injected.useSnapshot((snapshot) => snapshot);
|
|
1806
1855
|
const [editing, setEditing] = (0, react.useState)(void 0);
|
|
1807
1856
|
const [adding, setAdding] = (0, react.useState)(false);
|
|
@@ -1843,7 +1892,7 @@ window.__ModuleLoader__.load({
|
|
|
1843
1892
|
if (deleteTarget === void 0 || deleting) return;
|
|
1844
1893
|
setDeleting(true);
|
|
1845
1894
|
setDeleteFailure(void 0);
|
|
1846
|
-
removeProviderProfile(
|
|
1895
|
+
removeProviderProfile(operations, controller, deleteTarget).then((failure) => {
|
|
1847
1896
|
if (failure !== void 0) {
|
|
1848
1897
|
setDeleteFailure(failure);
|
|
1849
1898
|
return;
|
|
@@ -1882,6 +1931,7 @@ window.__ModuleLoader__.load({
|
|
|
1882
1931
|
const addable = state.rows.filter((row) => !row.configured && row.entry.settingsNs !== "");
|
|
1883
1932
|
const addTarget = adding ? editing : void 0;
|
|
1884
1933
|
const addNamespace = addTarget === void 0 ? void 0 : state.namespaces.get(addTarget.settingsNs);
|
|
1934
|
+
const addRow = addTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === addTarget.provider);
|
|
1885
1935
|
const protocols = protocolChoices(state.namespaces.get("llm-pi-ai"), schema);
|
|
1886
1936
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1887
1937
|
className: ModelsSection_module_css_default["section"],
|
|
@@ -1911,87 +1961,99 @@ window.__ModuleLoader__.load({
|
|
|
1911
1961
|
const namespace = state.namespaces.get(target.settingsNs);
|
|
1912
1962
|
/* v8 ignore next -- the join marks a row configured only when its namespace resolved */
|
|
1913
1963
|
if (namespace === void 0) return null;
|
|
1914
|
-
if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) return (0, react_jsx_runtime.
|
|
1964
|
+
if (needsSetup(row, anyUsable) && !dismissedSetup.has(row.entry.provider)) return (0, react_jsx_runtime.jsxs)("li", {
|
|
1915
1965
|
className: ModelsSection_module_css_default["setupCard"],
|
|
1916
|
-
children: renderProviderEditor({
|
|
1966
|
+
children: [renderProviderEditor({
|
|
1917
1967
|
target,
|
|
1918
1968
|
namespace,
|
|
1919
1969
|
schema,
|
|
1920
|
-
|
|
1970
|
+
operations,
|
|
1921
1971
|
t,
|
|
1922
1972
|
readOnly: !state.writable,
|
|
1923
1973
|
onClose: (changed) => {
|
|
1924
1974
|
closeSetup(changed, target);
|
|
1925
1975
|
}
|
|
1926
|
-
})
|
|
1976
|
+
}), renderSlot("settings.models.provider-card", {
|
|
1977
|
+
provider: row.entry,
|
|
1978
|
+
configured: row.configured,
|
|
1979
|
+
keyConfigured: keyConfiguredOf(row)
|
|
1980
|
+
}, { entryKey: row.entry.settingsNs })]
|
|
1927
1981
|
}, row.entry.provider);
|
|
1928
1982
|
const open = !adding && editing?.provider === row.entry.provider;
|
|
1929
1983
|
const credentialConfigured = row.credential?.configured === true;
|
|
1930
1984
|
const credentialMissing = !credentialConfigured && row.apiKeyEnv !== void 0 && row.credential?.configured === false;
|
|
1931
1985
|
return (0, react_jsx_runtime.jsxs)("li", {
|
|
1932
1986
|
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
|
-
|
|
1987
|
+
children: [
|
|
1988
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
1989
|
+
className: ModelsSection_module_css_default["rowHead"],
|
|
1990
|
+
children: [(0, react_jsx_runtime.jsxs)("span", {
|
|
1991
|
+
className: ModelsSection_module_css_default["rowIdentity"],
|
|
1992
|
+
children: [
|
|
1993
|
+
(0, react_jsx_runtime.jsx)("span", {
|
|
1994
|
+
className: ModelsSection_module_css_default["rowName"],
|
|
1995
|
+
children: row.entry.displayName
|
|
1996
|
+
}),
|
|
1997
|
+
row.entry.declared === true ? (0, react_jsx_runtime.jsx)("span", {
|
|
1998
|
+
className: ModelsSection_module_css_default["rowTag"],
|
|
1999
|
+
children: t("customTag")
|
|
2000
|
+
}) : null,
|
|
2001
|
+
credentialConfigured ? (0, react_jsx_runtime.jsx)("span", {
|
|
2002
|
+
className: `${ModelsSection_module_css_default["credentialDot"]} ${ModelsSection_module_css_default["credentialDotConfigured"]}`,
|
|
2003
|
+
role: "img",
|
|
2004
|
+
"aria-label": t("credentialConfigured"),
|
|
2005
|
+
title: t("credentialConfigured")
|
|
2006
|
+
}) : credentialMissing ? (0, react_jsx_runtime.jsx)("span", {
|
|
2007
|
+
className: `${ModelsSection_module_css_default["credentialDot"]} ${ModelsSection_module_css_default["credentialDotMissing"]}`,
|
|
2008
|
+
role: "img",
|
|
2009
|
+
"aria-label": t("credentialMissing"),
|
|
2010
|
+
title: t("credentialMissing")
|
|
2011
|
+
}) : null
|
|
2012
|
+
]
|
|
2013
|
+
}), (0, react_jsx_runtime.jsxs)("span", {
|
|
2014
|
+
className: ModelsSection_module_css_default["rowActions"],
|
|
2015
|
+
children: [(0, react_jsx_runtime.jsx)("button", {
|
|
2016
|
+
type: "button",
|
|
2017
|
+
className: ModelsSection_module_css_default["secondaryButton"],
|
|
2018
|
+
"aria-label": providerCopy(t("editProvider"), target),
|
|
2019
|
+
onClick: () => {
|
|
2020
|
+
setSavedTarget(void 0);
|
|
2021
|
+
setDeclaring(false);
|
|
2022
|
+
setAdding(false);
|
|
2023
|
+
setEditing(open ? void 0 : target);
|
|
2024
|
+
},
|
|
2025
|
+
children: t("edit")
|
|
2026
|
+
}), row.removable ? (0, react_jsx_runtime.jsx)("button", {
|
|
2027
|
+
type: "button",
|
|
2028
|
+
className: ModelsSection_module_css_default["dangerButton"],
|
|
2029
|
+
"aria-label": providerCopy(t("removeProvider"), target),
|
|
2030
|
+
disabled: !state.writable,
|
|
2031
|
+
onClick: () => {
|
|
2032
|
+
setSavedTarget(void 0);
|
|
2033
|
+
setDeleteFailure(void 0);
|
|
2034
|
+
setDeleteTarget(target);
|
|
2035
|
+
},
|
|
2036
|
+
children: t("remove")
|
|
2037
|
+
}) : null]
|
|
2038
|
+
})]
|
|
2039
|
+
}),
|
|
2040
|
+
renderSlot("settings.models.provider-card", {
|
|
2041
|
+
provider: row.entry,
|
|
2042
|
+
configured: row.configured,
|
|
2043
|
+
keyConfigured: keyConfiguredOf(row)
|
|
2044
|
+
}, { entryKey: row.entry.settingsNs }),
|
|
2045
|
+
open ? renderProviderEditor({
|
|
2046
|
+
target,
|
|
2047
|
+
namespace,
|
|
2048
|
+
schema,
|
|
2049
|
+
operations,
|
|
2050
|
+
t,
|
|
2051
|
+
readOnly: !state.writable,
|
|
2052
|
+
onClose: (changed) => {
|
|
2053
|
+
closeEditor(changed, target);
|
|
2054
|
+
}
|
|
2055
|
+
}) : null
|
|
2056
|
+
]
|
|
1995
2057
|
}, row.entry.provider);
|
|
1996
2058
|
})
|
|
1997
2059
|
}),
|
|
@@ -1999,40 +2061,48 @@ window.__ModuleLoader__.load({
|
|
|
1999
2061
|
className: ModelsSection_module_css_default["addBlock"],
|
|
2000
2062
|
children: addTarget !== void 0 && addNamespace !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
2001
2063
|
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
|
-
|
|
2064
|
+
children: [
|
|
2065
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
2066
|
+
className: ModelsSection_module_css_default["field"],
|
|
2067
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
2068
|
+
className: ModelsSection_module_css_default["fieldLabel"],
|
|
2069
|
+
children: t("provider")
|
|
2070
|
+
}), (0, react_jsx_runtime.jsx)("select", {
|
|
2071
|
+
className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["selectInput"]}`,
|
|
2072
|
+
value: addTarget.provider,
|
|
2073
|
+
"aria-label": t("provider"),
|
|
2074
|
+
onChange: (event) => {
|
|
2075
|
+
const row = addable.find((candidate) => candidate.entry.provider === event.target.value);
|
|
2076
|
+
/* v8 ignore next -- the select only lists addable rows */
|
|
2077
|
+
if (row === void 0) return;
|
|
2078
|
+
setEditing(targetOf(row));
|
|
2079
|
+
},
|
|
2080
|
+
children: addable.map((row) => (0, react_jsx_runtime.jsx)("option", {
|
|
2081
|
+
value: row.entry.provider,
|
|
2082
|
+
children: row.entry.displayName
|
|
2083
|
+
}, row.entry.provider))
|
|
2084
|
+
})]
|
|
2085
|
+
}),
|
|
2086
|
+
(0, react_jsx_runtime.jsx)(ProviderEditor, {
|
|
2087
|
+
provider: addTarget.provider,
|
|
2088
|
+
displayName: addTarget.displayName,
|
|
2089
|
+
hideTitle: true,
|
|
2090
|
+
namespace: addNamespace,
|
|
2091
|
+
schema,
|
|
2092
|
+
settingsPath: addTarget.settingsPath,
|
|
2093
|
+
operations,
|
|
2094
|
+
t,
|
|
2095
|
+
readOnly: !state.writable,
|
|
2096
|
+
onClose: (changed) => {
|
|
2097
|
+
closeEditor(changed, addTarget);
|
|
2098
|
+
}
|
|
2099
|
+
}, addTarget.provider),
|
|
2100
|
+
addRow === void 0 ? null : renderSlot("settings.models.provider-card", {
|
|
2101
|
+
provider: addRow.entry,
|
|
2102
|
+
configured: addRow.configured,
|
|
2103
|
+
keyConfigured: keyConfiguredOf(addRow)
|
|
2104
|
+
}, { entryKey: addRow.entry.settingsNs })
|
|
2105
|
+
]
|
|
2036
2106
|
}) : declaring ? (0, react_jsx_runtime.jsx)("div", {
|
|
2037
2107
|
className: ModelsSection_module_css_default["addCard"],
|
|
2038
2108
|
children: (0, react_jsx_runtime.jsx)(CustomProviderCard, {
|
|
@@ -2040,7 +2110,7 @@ window.__ModuleLoader__.load({
|
|
|
2040
2110
|
protocols,
|
|
2041
2111
|
/* v8 ignore next -- the card only opens from a button disabled without this namespace */
|
|
2042
2112
|
revision: state.namespaces.get("llm-pi-ai")?.revision ?? 0,
|
|
2043
|
-
|
|
2113
|
+
operations,
|
|
2044
2114
|
t,
|
|
2045
2115
|
readOnly: !state.writable,
|
|
2046
2116
|
onClose: (changed) => {
|
|
@@ -2078,6 +2148,7 @@ window.__ModuleLoader__.load({
|
|
|
2078
2148
|
})]
|
|
2079
2149
|
})
|
|
2080
2150
|
}),
|
|
2151
|
+
renderSlot("settings.models.footer", {}),
|
|
2081
2152
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
2082
2153
|
open: deleteTarget !== void 0,
|
|
2083
2154
|
onClose: closeDelete,
|
|
@@ -2203,7 +2274,7 @@ window.__ModuleLoader__.load({
|
|
|
2203
2274
|
* @returns the onboarding modal or null when onboarding needs no intervention.
|
|
2204
2275
|
*/
|
|
2205
2276
|
function DeepSeekOnboardingDialog(props) {
|
|
2206
|
-
const { complete, controller, useModels,
|
|
2277
|
+
const { complete, controller, useModels, operations, schema, t } = props;
|
|
2207
2278
|
const state = useModels((snapshot) => snapshot);
|
|
2208
2279
|
const readiness = onboardingReadiness(state);
|
|
2209
2280
|
(0, react.useEffect)(() => {
|
|
@@ -2245,16 +2316,16 @@ window.__ModuleLoader__.load({
|
|
|
2245
2316
|
namespace,
|
|
2246
2317
|
schema,
|
|
2247
2318
|
settingsPath: row.entry.settingsPath,
|
|
2248
|
-
|
|
2319
|
+
operations,
|
|
2249
2320
|
t,
|
|
2250
2321
|
readOnly: false,
|
|
2251
2322
|
hideTitle: true,
|
|
2252
2323
|
credentialOnly: true,
|
|
2253
2324
|
credentialRequired: true,
|
|
2254
2325
|
autoFocusCredential: true,
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2326
|
+
cancelLabelKey: "onboardingLater",
|
|
2327
|
+
submitLabelKey: "onboardingSave",
|
|
2328
|
+
submitBusyLabelKey: "onboardingSaving",
|
|
2258
2329
|
onClose: finishCredential
|
|
2259
2330
|
})
|
|
2260
2331
|
})]
|
|
@@ -2344,19 +2415,6 @@ window.__ModuleLoader__.load({
|
|
|
2344
2415
|
* again. The acknowledgement is compared for exact equality.
|
|
2345
2416
|
*/
|
|
2346
2417
|
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
2418
|
//#endregion
|
|
2361
2419
|
//#region lib/types/client/welcome-store.js
|
|
2362
2420
|
/**
|
|
@@ -2383,7 +2441,7 @@ window.__ModuleLoader__.load({
|
|
|
2383
2441
|
var WelcomeNoticeStore = class {
|
|
2384
2442
|
scope;
|
|
2385
2443
|
/** uSES-safe state source shared by the registered welcome step. */
|
|
2386
|
-
store = (0,
|
|
2444
|
+
store = (0, _deepseek_ai_dsh_client_store.createSnapshotStore)({
|
|
2387
2445
|
status: "idle",
|
|
2388
2446
|
acknowledged: false,
|
|
2389
2447
|
error: null
|
|
@@ -2484,6 +2542,61 @@ window.__ModuleLoader__.load({
|
|
|
2484
2542
|
}
|
|
2485
2543
|
};
|
|
2486
2544
|
//#endregion
|
|
2545
|
+
//#region lib/types/client/operations.js
|
|
2546
|
+
/**
|
|
2547
|
+
* The Host reads and writes the Models cards perform, as callbacks built in the
|
|
2548
|
+
* plugin body. Cards receive these instead of a context: the outcomes name what
|
|
2549
|
+
* a card renders — a stored view, a stale revision, a refusal message — so the
|
|
2550
|
+
* failure codes and Remote namespaces stay in the apply world.
|
|
2551
|
+
*/
|
|
2552
|
+
/**
|
|
2553
|
+
* Bind the page's Host operations to the plugin's own Remote namespaces.
|
|
2554
|
+
* @param ctx - the page plugin's context, which declares `remote.credentials`,
|
|
2555
|
+
* `remote.llm`, and `remote.settings` in its own `inject`.
|
|
2556
|
+
* @returns the callbacks the section and its cards are injected with.
|
|
2557
|
+
*/
|
|
2558
|
+
function createModelsOperations(ctx) {
|
|
2559
|
+
return {
|
|
2560
|
+
describeCredential: async (ref) => {
|
|
2561
|
+
const response = await ctx.remote.credentials.describe([ref]);
|
|
2562
|
+
return response.ok ? response.value[ref] : void 0;
|
|
2563
|
+
},
|
|
2564
|
+
storeCredential: async (ref, value) => {
|
|
2565
|
+
const response = await ctx.remote.credentials.set(ref, value);
|
|
2566
|
+
return response.ok ? void 0 : response.error.message;
|
|
2567
|
+
},
|
|
2568
|
+
removeCredential: async (ref) => {
|
|
2569
|
+
const response = await ctx.remote.credentials.unset(ref);
|
|
2570
|
+
return response.ok ? void 0 : response.error.message;
|
|
2571
|
+
},
|
|
2572
|
+
writeSettings: async (ns, ops, expectedRevision) => {
|
|
2573
|
+
const response = await ctx.remote.settings.mutate(ns, ops, expectedRevision);
|
|
2574
|
+
if (response.ok) return {
|
|
2575
|
+
kind: "written",
|
|
2576
|
+
view: response.value
|
|
2577
|
+
};
|
|
2578
|
+
const { code, message } = response.error;
|
|
2579
|
+
return code === "settings/conflict" ? {
|
|
2580
|
+
kind: "conflict",
|
|
2581
|
+
message
|
|
2582
|
+
} : {
|
|
2583
|
+
kind: "refused",
|
|
2584
|
+
message
|
|
2585
|
+
};
|
|
2586
|
+
},
|
|
2587
|
+
discoverModels: async (settingsNs, request) => {
|
|
2588
|
+
const response = await ctx.remote.llm.discoverModels(settingsNs, request);
|
|
2589
|
+
return response.ok ? {
|
|
2590
|
+
kind: "found",
|
|
2591
|
+
models: response.value
|
|
2592
|
+
} : {
|
|
2593
|
+
kind: "refused",
|
|
2594
|
+
message: response.error.message
|
|
2595
|
+
};
|
|
2596
|
+
}
|
|
2597
|
+
};
|
|
2598
|
+
}
|
|
2599
|
+
//#endregion
|
|
2487
2600
|
//#region lib/types/client/schema-operations.js
|
|
2488
2601
|
/**
|
|
2489
2602
|
* Hide the Cordis service identity behind bound schema callbacks.
|
|
@@ -2574,6 +2687,8 @@ window.__ModuleLoader__.load({
|
|
|
2574
2687
|
fetchEmpty: "The provider listed no models. Add them by hand.",
|
|
2575
2688
|
fetchTitle: "Choose models to add",
|
|
2576
2689
|
fetchDescription: "These are the models this provider has available. Choose the ones to add.",
|
|
2690
|
+
fetchSearch: "Search models",
|
|
2691
|
+
fetchNoMatches: "No matching models.",
|
|
2577
2692
|
fetchSelectAll: "Select all",
|
|
2578
2693
|
fetchDeselectAll: "Deselect all",
|
|
2579
2694
|
fetchAdopt: "Add selected",
|
|
@@ -2589,11 +2704,13 @@ window.__ModuleLoader__.load({
|
|
|
2589
2704
|
customApiUnset: "Not selected",
|
|
2590
2705
|
customNeedsBaseUrl: "A custom provider needs a base URL.",
|
|
2591
2706
|
customNeedsModels: "A custom provider needs at least one model.",
|
|
2707
|
+
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
2708
|
+
settingsPathUnresolvable: "unresolvable settings path",
|
|
2592
2709
|
create: "Create provider",
|
|
2593
2710
|
creating: "Creating…",
|
|
2594
|
-
welcomeTitle:
|
|
2595
|
-
welcomeBody:
|
|
2596
|
-
welcomeContinue:
|
|
2711
|
+
welcomeTitle: "Internal Testing Notice",
|
|
2712
|
+
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.",
|
|
2713
|
+
welcomeContinue: "Continue",
|
|
2597
2714
|
welcomeError: "The acknowledgement could not be saved. Please try again.",
|
|
2598
2715
|
onboardingTitle: "Add an API key to get started",
|
|
2599
2716
|
onboardingDescription: "Configure the official DeepSeek provider to start building.",
|
|
@@ -2672,6 +2789,8 @@ window.__ModuleLoader__.load({
|
|
|
2672
2789
|
fetchEmpty: "该提供方没有列出任何模型,请手动添加。",
|
|
2673
2790
|
fetchTitle: "选择要添加的模型",
|
|
2674
2791
|
fetchDescription: "以下是模型提供方的可用模型,勾选要添加的模型。",
|
|
2792
|
+
fetchSearch: "搜索模型",
|
|
2793
|
+
fetchNoMatches: "没有匹配的模型。",
|
|
2675
2794
|
fetchSelectAll: "全选",
|
|
2676
2795
|
fetchDeselectAll: "取消全选",
|
|
2677
2796
|
fetchAdopt: "添加所选",
|
|
@@ -2687,11 +2806,13 @@ window.__ModuleLoader__.load({
|
|
|
2687
2806
|
customApiUnset: "未选择",
|
|
2688
2807
|
customNeedsBaseUrl: "自定义提供方需要填写 API 地址。",
|
|
2689
2808
|
customNeedsModels: "自定义提供方至少需要一个模型。",
|
|
2809
|
+
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
2810
|
+
settingsPathUnresolvable: "无法解析设置路径",
|
|
2690
2811
|
create: "创建提供方",
|
|
2691
2812
|
creating: "创建中…",
|
|
2692
|
-
welcomeTitle:
|
|
2693
|
-
welcomeBody:
|
|
2694
|
-
welcomeContinue:
|
|
2813
|
+
welcomeTitle: "内测声明",
|
|
2814
|
+
welcomeBody: "DeepSeek Harness 目前的 0.1 版本仍处在面向 Harness 开发者进行测试的阶段,还有许多地方需要持续改进和打磨,希望听取广大开发者的反馈建议。预计 DeepSeek Harness 的核心插件以及基础 API 都会在接下来的一段时间内快速迭代、持续演化。\n\n我们期待与全球开发者一起,在开源、开放、可复用、可组合的基础设施之上,共同探索智能上限。欢迎全球 Harness 开发者加入 DSH 插件生态。",
|
|
2815
|
+
welcomeContinue: "继续",
|
|
2695
2816
|
welcomeError: "暂时无法保存确认状态,请重试。",
|
|
2696
2817
|
onboardingTitle: "添加一个 API Key 开始使用",
|
|
2697
2818
|
onboardingDescription: "配置 DeepSeek 官方模型,即可开始使用。",
|
|
@@ -2721,8 +2842,10 @@ window.__ModuleLoader__.load({
|
|
|
2721
2842
|
const inject = [
|
|
2722
2843
|
"slots",
|
|
2723
2844
|
"locale",
|
|
2724
|
-
"connection",
|
|
2725
2845
|
"remote",
|
|
2846
|
+
"remote.credentials",
|
|
2847
|
+
"remote.llm",
|
|
2848
|
+
"remote.settings",
|
|
2726
2849
|
"settingsScope",
|
|
2727
2850
|
"settingsSchema"
|
|
2728
2851
|
];
|
|
@@ -2737,21 +2860,21 @@ window.__ModuleLoader__.load({
|
|
|
2737
2860
|
zh,
|
|
2738
2861
|
en
|
|
2739
2862
|
}), "ui-settings-models: copy dictionaries");
|
|
2740
|
-
const connection = ctx.get("connection");
|
|
2741
2863
|
const schema = createSettingsSchemaOperations(ctx.settingsSchema);
|
|
2742
|
-
const
|
|
2864
|
+
const operations = createModelsOperations(ctx);
|
|
2865
|
+
const controller = new ModelsSettingsStore(ctx, schema, ctx.settingsScope.describe());
|
|
2743
2866
|
const t = ctx.locale.bind(NS);
|
|
2744
2867
|
const injected = () => ({
|
|
2745
2868
|
controller,
|
|
2746
2869
|
hooks: { snapshot: controller.store },
|
|
2747
|
-
|
|
2870
|
+
operations,
|
|
2748
2871
|
schema,
|
|
2749
2872
|
t
|
|
2750
2873
|
});
|
|
2751
2874
|
const deepSeekOnboardingInjected = () => ({
|
|
2752
2875
|
controller,
|
|
2753
2876
|
hooks: { models: controller.store },
|
|
2754
|
-
|
|
2877
|
+
operations,
|
|
2755
2878
|
schema,
|
|
2756
2879
|
t
|
|
2757
2880
|
});
|
|
@@ -2786,7 +2909,17 @@ window.__ModuleLoader__.load({
|
|
|
2786
2909
|
id: "models",
|
|
2787
2910
|
order: 10,
|
|
2788
2911
|
label: () => t("nav"),
|
|
2789
|
-
inject: injected
|
|
2912
|
+
inject: injected,
|
|
2913
|
+
children: {
|
|
2914
|
+
"settings.models.provider-card": {
|
|
2915
|
+
kind: "keyed",
|
|
2916
|
+
scope: "root"
|
|
2917
|
+
},
|
|
2918
|
+
"settings.models.footer": {
|
|
2919
|
+
kind: "list",
|
|
2920
|
+
scope: "root"
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2790
2923
|
}, ModelsSection));
|
|
2791
2924
|
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
2792
2925
|
name: "settings.onboarding",
|