@deepseek-ai/dsh-client-ui-settings-models 0.1.6-alpha.2 → 0.1.7-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +14 -9
- package/README.zh.md +25 -20
- package/lib/client.js +1245 -179
- package/lib/index.js +24 -4
- package/lib/types/client/CustomProviderCard.d.ts +13 -5
- package/lib/types/client/DeepSeekOnboardingDialog.d.ts +4 -2
- package/lib/types/client/ModelListEditor.d.ts +7 -0
- package/lib/types/client/ModelsSection.d.ts +13 -5
- package/lib/types/client/ProviderEditor.d.ts +8 -2
- package/lib/types/client/locales.d.ts +12 -4
- package/lib/types/client/protocol-label.d.ts +16 -0
- package/lib/types/client/slot-contract.d.ts +9 -0
- package/lib/types/client/welcome-store.d.ts +2 -2
- package/lib/types/index.d.ts +10 -3
- package/lib/types/onboarding-config.d.ts +12 -0
- package/lib/types/onboarding-copy.d.ts +1 -1
- package/package.json +17 -13
package/lib/client.js
CHANGED
|
@@ -55,7 +55,7 @@ window.__ModuleLoader__.load({
|
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
57
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-models/src/client/ModelsSection.module.css.mjs
|
|
58
|
-
const css$3 = ".zGbnIq_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.zGbnIq_title{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.zGbnIq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.zGbnIq_notice{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}.zGbnIq_savedNotice{color:var(--dsw-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}.zGbnIq_rowCard{border:.5px solid var(--dsw-alias-border-l4);border-radius:16px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.zGbnIq_rowHead{align-items:center;gap:10px;display:flex}.zGbnIq_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.zGbnIq_rowName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.zGbnIq_rowTag{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:1px 6px;font-size:11px;line-height:16px}.zGbnIq_credentialDot{box-sizing:border-box;corner-shape:round;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.zGbnIq_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.zGbnIq_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.zGbnIq_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.zGbnIq_primaryButton,.zGbnIq_secondaryButton,.zGbnIq_addButton{box-sizing:border-box;height:36px;font:inherit;cursor:pointer;border:none;border-radius:18px;justify-content:center;align-items:center;gap:4px;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.zGbnIq_primaryButton{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.zGbnIq_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.zGbnIq_secondaryButton,.zGbnIq_addButton{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary);background:0 0}.zGbnIq_secondaryButton:hover:not(:disabled),.zGbnIq_addButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_secondaryButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.zGbnIq_dangerButton{box-sizing:border-box;height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:18px;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.zGbnIq_dangerButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_rowActions .zGbnIq_secondaryButton,.zGbnIq_rowActions .zGbnIq_dangerButton{border-radius:14px;height:28px;padding:0 10px;font-size:12px;line-height:18px}.zGbnIq_primaryButton:disabled,.zGbnIq_secondaryButton:disabled,.zGbnIq_dangerButton:disabled,.zGbnIq_addButton:disabled,.zGbnIq_linkButton:disabled,.zGbnIq_addModelButton:disabled{opacity:.4;cursor:default}.zGbnIq_primaryButton:focus-visible,.zGbnIq_secondaryButton:focus-visible,.zGbnIq_dangerButton:focus-visible,.zGbnIq_addButton:focus-visible,.zGbnIq_linkButton:focus-visible,.zGbnIq_addModelButton:focus-visible,.zGbnIq_iconButton:focus-visible,.zGbnIq_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3);outline:none}.zGbnIq_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;display:flex}.zGbnIq_editorHeader{align-items:baseline;gap:8px;display:flex}.zGbnIq_editorTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.zGbnIq_editorRoute{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_field{flex-direction:column;gap:6px;display:flex}.zGbnIq_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.zGbnIq_linkButton{box-sizing:border-box;height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:14px;align-items:center;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.zGbnIq_advancedHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_editorActions{justify-content:flex-end;gap:8px;display:flex}.zGbnIq_addBlock{flex-direction:column;gap:12px;display:flex}.zGbnIq_addActions{flex-wrap:wrap;gap:10px;display:flex}.zGbnIq_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}.zGbnIq_addCard,.zGbnIq_setupCard{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.zGbnIq_addCard .zGbnIq_editor,.zGbnIq_setupCard .zGbnIq_editor{background:0 0;padding:0}.zGbnIq_customized{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:10px}.zGbnIq_customizedSummary{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);border-radius:6px;align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.zGbnIq_customizedSummary::-webkit-details-marker{display:none}.zGbnIq_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.zGbnIq_customized[open]>.zGbnIq_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.zGbnIq_customizedSummary:hover{color:var(--dsw-alias-label-primary)}.zGbnIq_customizedBody{flex-direction:column;gap:12px;padding-top:12px;display:flex}.zGbnIq_modelCatalog{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding-top:12px;display:flex}.zGbnIq_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.zGbnIq_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.zGbnIq_modelCatalogMeta,.zGbnIq_modelEmpty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_modelList{flex-direction:column;gap:8px;display:flex}.zGbnIq_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.zGbnIq_modelEntry{border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;padding:6px}.zGbnIq_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}.zGbnIq_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.zGbnIq_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.zGbnIq_iconButton:disabled{cursor:default;opacity:.4}.zGbnIq_iconButtonDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.zGbnIq_modelAdvanced{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 4px 2px;display:grid}.zGbnIq_modelField{flex-direction:column;gap:4px;min-width:0;display:flex}.zGbnIq_modelInputTypes{border:none;grid-column:1/-1;min-width:0;margin:0;padding:0}.zGbnIq_modelInputTypes legend{margin-bottom:4px;padding:0}.zGbnIq_modelInputChoices{flex-wrap:wrap;align-items:center;gap:16px;min-height:32px;display:flex}.zGbnIq_modelFieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_modelEmpty{border:1px dashed var(--dsw-alias-border-l3);text-align:center;border-radius:8px;padding:12px}.zGbnIq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;align-self:flex-start;align-items:center;gap:4px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_addModelButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.zGbnIq_input{cursor:pointer;max-width:240px}.zGbnIq_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.zGbnIq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.zGbnIq_input:disabled{opacity:.6;cursor:default}.zGbnIq_selectInput{appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.zGbnIq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_deleteDialog{width:min(480px,100%)}.zGbnIq_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.zGbnIq_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.zGbnIq_customizedSummary:before,.zGbnIq_switchThumb{transition:none}}.zGbnIq_fetchDialog{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);max-width:520px}.zGbnIq_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.zGbnIq_candidateSearch{flex:240px;min-width:0}.zGbnIq_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.zGbnIq_candidate{border-radius:6px}.zGbnIq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.zGbnIq_candidateId{font-family:var(--ds-font-family-code);overflow-wrap:anywhere;flex:auto;font-size:13px}.zGbnIq_candidateEmpty{color:var(--dsw-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}";
|
|
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{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_addModes{flex-direction:column;align-items:flex-start;gap:8px;display:flex}.zGbnIq_addPanel{flex-direction:column;gap:14px;display:flex}.zGbnIq_addPanel[hidden]{display:none}.zGbnIq_addCard,.zGbnIq_setupCard{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.zGbnIq_addCard .zGbnIq_editor,.zGbnIq_setupCard .zGbnIq_editor{background:0 0;padding:0}.zGbnIq_customized{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:10px}.zGbnIq_customizedSummary{cursor:pointer;width:fit-content;color:var(--dsw-alias-label-secondary);border-radius:6px;align-items:center;gap:6px;margin-left:-4px;padding:2px 4px;font-size:12px;font-weight:500;line-height:18px;list-style:none;display:flex}.zGbnIq_customizedSummary::-webkit-details-marker{display:none}.zGbnIq_customizedSummary:before{content:\"\";border-bottom:1.5px solid;border-right:1.5px solid;width:5px;height:5px;transition:transform .12s;transform:rotate(-45deg)translate(-1px,-1px)}.zGbnIq_customized[open]>.zGbnIq_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.zGbnIq_customizedSummary:hover{color:var(--dsw-alias-label-primary)}.zGbnIq_customizedBody{flex-direction:column;gap:12px;padding-top:12px;display:flex}.zGbnIq_modelCatalog{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:10px;padding-top:12px;display:flex}.zGbnIq_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.zGbnIq_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.zGbnIq_modelCatalogMeta,.zGbnIq_modelEmpty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.zGbnIq_modelList{flex-direction:column;gap:8px;display:flex}.zGbnIq_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.zGbnIq_modelEntry{border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;padding:6px}.zGbnIq_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}.zGbnIq_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.zGbnIq_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.zGbnIq_iconButton:disabled{cursor:default;opacity:.4}.zGbnIq_iconButtonDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.zGbnIq_modelAdvanced{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 4px 2px;display:grid}.zGbnIq_modelField{flex-direction:column;gap:4px;min-width:0;display:flex}.zGbnIq_modelInputTypes{border:none;grid-column:1/-1;min-width:0;margin:0;padding:0}.zGbnIq_modelInputTypes legend{margin-bottom:4px;padding:0}.zGbnIq_modelInputChoices{flex-wrap:wrap;align-items:center;gap:16px;min-height:32px;display:flex}.zGbnIq_modelFieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.zGbnIq_modelEmpty{border:1px dashed var(--dsw-alias-border-l3);text-align:center;border-radius:8px;padding:12px}.zGbnIq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;align-self:flex-start;align-items:center;gap:4px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.zGbnIq_addModelButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.zGbnIq_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.zGbnIq_input{cursor:pointer;max-width:240px}.zGbnIq_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.zGbnIq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.zGbnIq_input:disabled{opacity:.6;cursor:default}.zGbnIq_selectInput{appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E\");background-position:right 12px center;background-repeat:no-repeat;background-size:12px 12px;padding-right:32px}.zGbnIq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.zGbnIq_deleteDialog{width:min(480px,100%)}.zGbnIq_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.zGbnIq_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.zGbnIq_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.zGbnIq_customizedSummary:before,.zGbnIq_switchThumb{transition:none}}.zGbnIq_fetchDialog{--dsh-scrollbar-thumb:var(--dsw-alias-scrollbar-bg-l2);--dsh-scrollbar-thumb-hover:var(--dsw-alias-scrollbar-hover-l2);max-width:520px}.zGbnIq_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.zGbnIq_candidateSearch{flex:240px;min-width:0}.zGbnIq_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.zGbnIq_candidate{border-radius:6px}.zGbnIq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.zGbnIq_candidateId{font-family:var(--ds-font-family-code);overflow-wrap:anywhere;flex:auto;font-size:13px}.zGbnIq_candidateEmpty{color:var(--dsw-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}";
|
|
59
59
|
const tagId$3 = "@deepseek-ai/dsh-client-ui-settings-models/ModelsSection.module.css";
|
|
60
60
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
61
61
|
const tag = document.createElement("style");
|
|
@@ -70,6 +70,8 @@ window.__ModuleLoader__.load({
|
|
|
70
70
|
"addButton": "zGbnIq_addButton",
|
|
71
71
|
"addCard": "zGbnIq_addCard",
|
|
72
72
|
"addModelButton": "zGbnIq_addModelButton",
|
|
73
|
+
"addModes": "zGbnIq_addModes",
|
|
74
|
+
"addPanel": "zGbnIq_addPanel",
|
|
73
75
|
"advancedHint": "zGbnIq_advancedHint",
|
|
74
76
|
"candidate": "zGbnIq_candidate",
|
|
75
77
|
"candidateEmpty": "zGbnIq_candidateEmpty",
|
|
@@ -231,7 +233,7 @@ window.__ModuleLoader__.load({
|
|
|
231
233
|
"aria-expanded": props.expanded,
|
|
232
234
|
title: t("modelAdvanced"),
|
|
233
235
|
onClick: props.onToggle,
|
|
234
|
-
children: props.expanded ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
236
|
+
children: props.expanded ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineRegular, {}) : (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronRightOutlineRegular, {})
|
|
235
237
|
}),
|
|
236
238
|
(0, react_jsx_runtime.jsx)("button", {
|
|
237
239
|
type: "button",
|
|
@@ -240,7 +242,7 @@ window.__ModuleLoader__.load({
|
|
|
240
242
|
title: t("removeModel"),
|
|
241
243
|
disabled,
|
|
242
244
|
onClick: props.onRemove,
|
|
243
|
-
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
245
|
+
children: (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconTrashOutlineRegular, { size: 14 })
|
|
244
246
|
})
|
|
245
247
|
]
|
|
246
248
|
}), props.expanded ? (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -511,7 +513,7 @@ window.__ModuleLoader__.load({
|
|
|
511
513
|
onClick: () => {
|
|
512
514
|
props.onChange([...props.models.map((model) => ({ ...model })), { id: "" }]);
|
|
513
515
|
},
|
|
514
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
516
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), props.t("addModel")]
|
|
515
517
|
})
|
|
516
518
|
]
|
|
517
519
|
});
|
|
@@ -584,9 +586,12 @@ window.__ModuleLoader__.load({
|
|
|
584
586
|
* @returns the model-list editor.
|
|
585
587
|
*/
|
|
586
588
|
function ModelListEditor(props) {
|
|
587
|
-
const { models, onChange, probe, operations, t, disabled } = props;
|
|
589
|
+
const { models, onChange, probe, operations, t, disabled, onBusyChange } = props;
|
|
588
590
|
const { catalogProvider } = props;
|
|
589
591
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
592
|
+
(0, react.useEffect)(() => {
|
|
593
|
+
onBusyChange(busy);
|
|
594
|
+
}, [busy, onBusyChange]);
|
|
590
595
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
591
596
|
const [inheritedCatalog, setInheritedCatalog] = (0, react.useState)(void 0);
|
|
592
597
|
(0, react.useEffect)(() => {
|
|
@@ -810,7 +815,7 @@ window.__ModuleLoader__.load({
|
|
|
810
815
|
onClick: () => {
|
|
811
816
|
onChange([...models, { id: "" }]);
|
|
812
817
|
},
|
|
813
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
818
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("addModel")]
|
|
814
819
|
}),
|
|
815
820
|
failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
816
821
|
className: ModelsSection_module_css_default["error"],
|
|
@@ -1120,18 +1125,46 @@ window.__ModuleLoader__.load({
|
|
|
1120
1125
|
return { kind: "credential-missing" };
|
|
1121
1126
|
}
|
|
1122
1127
|
//#endregion
|
|
1128
|
+
//#region lib/types/client/protocol-label.js
|
|
1129
|
+
/**
|
|
1130
|
+
* Product names for the wire protocols a pi-ai route may speak. The pickers
|
|
1131
|
+
* show these instead of the schema identifiers (`openai-completions`), which
|
|
1132
|
+
* are what `settings.yaml` carries and what the option values stay.
|
|
1133
|
+
*/
|
|
1134
|
+
/** The protocols this page names, keyed by their schema identifier. */
|
|
1135
|
+
const PROTOCOL_LABEL_KEYS = {
|
|
1136
|
+
"openai-completions": "protocolOpenAiCompletions",
|
|
1137
|
+
"openai-responses": "protocolOpenAiResponses",
|
|
1138
|
+
"anthropic-messages": "protocolAnthropicMessages"
|
|
1139
|
+
};
|
|
1140
|
+
/**
|
|
1141
|
+
* The picker text for one protocol identifier.
|
|
1142
|
+
* @param t - section copy.
|
|
1143
|
+
* @param protocol - the schema identifier of the protocol.
|
|
1144
|
+
* @returns the product name this page knows the protocol by; a protocol the
|
|
1145
|
+
* adapter adds before this page names it shows its identifier, the spelling
|
|
1146
|
+
* `settings.yaml` needs anyway.
|
|
1147
|
+
*/
|
|
1148
|
+
function protocolLabel(t, protocol) {
|
|
1149
|
+
const key = PROTOCOL_LABEL_KEYS[protocol];
|
|
1150
|
+
return key === void 0 ? protocol : t(key);
|
|
1151
|
+
}
|
|
1152
|
+
//#endregion
|
|
1123
1153
|
//#region lib/types/client/CustomProviderCard.js
|
|
1124
1154
|
/**
|
|
1125
1155
|
* The card that declares a provider pi-ai does not ship — an OpenAI-compatible
|
|
1126
1156
|
* gateway, a self-hosted server, or a provider newer than the installed
|
|
1127
1157
|
* catalog.
|
|
1128
1158
|
*
|
|
1129
|
-
* This is a create, not an edit, which is why it is its own
|
|
1159
|
+
* This is a create, not an edit, which is why it is its own form rather than
|
|
1130
1160
|
* the provider editor with extra fields: the route id is being *chosen* here,
|
|
1131
|
-
* and the settings address does not exist until it is.
|
|
1132
|
-
*
|
|
1133
|
-
*
|
|
1134
|
-
*
|
|
1161
|
+
* and the settings address does not exist until it is. It renders as the
|
|
1162
|
+
* custom-API panel of the section's add card; the card's mode switch names it
|
|
1163
|
+
* when both modes are offered, and with the custom mode alone the card shows
|
|
1164
|
+
* this form directly. One `settings.mutate` sets the whole profile at
|
|
1165
|
+
* `providers.<route>`; the key travels separately through `credentials/set`
|
|
1166
|
+
* under the reference the profile records, exactly as an existing provider's
|
|
1167
|
+
* key does.
|
|
1135
1168
|
*
|
|
1136
1169
|
* The three fields a hand-declared route cannot default — endpoint, protocol,
|
|
1137
1170
|
* and at least one model — are required here rather than at load, so the
|
|
@@ -1168,7 +1201,7 @@ window.__ModuleLoader__.load({
|
|
|
1168
1201
|
* @returns the creation card.
|
|
1169
1202
|
*/
|
|
1170
1203
|
function CustomProviderCard(props) {
|
|
1171
|
-
const { taken, protocols, operations, t } = props;
|
|
1204
|
+
const { taken, protocols, operations, t, onBusyChange } = props;
|
|
1172
1205
|
const [openedAt] = (0, react.useState)(() => props.revision);
|
|
1173
1206
|
const [route, setRoute] = (0, react.useState)("");
|
|
1174
1207
|
const [displayName, setDisplayName] = (0, react.useState)("");
|
|
@@ -1177,6 +1210,14 @@ window.__ModuleLoader__.load({
|
|
|
1177
1210
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1178
1211
|
const [models, setModels] = (0, react.useState)([]);
|
|
1179
1212
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
1213
|
+
const [listBusy, setListBusy] = (0, react.useState)(false);
|
|
1214
|
+
(0, react.useEffect)(() => {
|
|
1215
|
+
onBusyChange?.(busy || listBusy);
|
|
1216
|
+
}, [
|
|
1217
|
+
busy,
|
|
1218
|
+
listBusy,
|
|
1219
|
+
onBusyChange
|
|
1220
|
+
]);
|
|
1180
1221
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
1181
1222
|
/**
|
|
1182
1223
|
* The profile write landed. Only the key write can still be outstanding, so
|
|
@@ -1238,13 +1279,6 @@ window.__ModuleLoader__.load({
|
|
|
1238
1279
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1239
1280
|
className: ModelsSection_module_css_default["editor"],
|
|
1240
1281
|
children: [
|
|
1241
|
-
(0, react_jsx_runtime.jsx)("div", {
|
|
1242
|
-
className: ModelsSection_module_css_default["editorHeader"],
|
|
1243
|
-
children: (0, react_jsx_runtime.jsx)("span", {
|
|
1244
|
-
className: ModelsSection_module_css_default["editorTitle"],
|
|
1245
|
-
children: t("customTitle")
|
|
1246
|
-
})
|
|
1247
|
-
}),
|
|
1248
1282
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
1249
1283
|
className: ModelsSection_module_css_default["field"],
|
|
1250
1284
|
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
@@ -1295,7 +1329,7 @@ window.__ModuleLoader__.load({
|
|
|
1295
1329
|
className: ModelsSection_module_css_default["input"],
|
|
1296
1330
|
type: "text",
|
|
1297
1331
|
value: baseURL,
|
|
1298
|
-
placeholder: t("customBaseUrlPlaceholder"),
|
|
1332
|
+
placeholder: t(protocol === "anthropic-messages" ? "customAnthropicBaseUrlPlaceholder" : "customBaseUrlPlaceholder"),
|
|
1299
1333
|
"aria-label": t("baseUrl"),
|
|
1300
1334
|
"aria-invalid": baseUrlInvalid,
|
|
1301
1335
|
disabled: profileDisabled,
|
|
@@ -1323,7 +1357,7 @@ window.__ModuleLoader__.load({
|
|
|
1323
1357
|
},
|
|
1324
1358
|
children: protocols.map((choice) => (0, react_jsx_runtime.jsx)("option", {
|
|
1325
1359
|
value: choice,
|
|
1326
|
-
children: choice
|
|
1360
|
+
children: protocolLabel(t, choice)
|
|
1327
1361
|
}, choice))
|
|
1328
1362
|
})]
|
|
1329
1363
|
}),
|
|
@@ -1364,7 +1398,8 @@ window.__ModuleLoader__.load({
|
|
|
1364
1398
|
probeBlocked: baseUrlInvalid ? "customBaseUrlInvalid" : keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
|
|
1365
1399
|
operations,
|
|
1366
1400
|
t,
|
|
1367
|
-
disabled: profileDisabled
|
|
1401
|
+
disabled: profileDisabled,
|
|
1402
|
+
onBusyChange: setListBusy
|
|
1368
1403
|
}),
|
|
1369
1404
|
failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
1370
1405
|
className: ModelsSection_module_css_default["error"],
|
|
@@ -1408,9 +1443,9 @@ window.__ModuleLoader__.load({
|
|
|
1408
1443
|
* Reasoning effort is deliberately absent: it is a per-MODEL capability, and
|
|
1409
1444
|
* the models under one provider disagree about it, so a provider-scoped
|
|
1410
1445
|
* control can only be set to a value some of them reject. The composer's
|
|
1411
|
-
* model picker offers each model its own levels; `
|
|
1446
|
+
* model picker offers each model its own levels; `cordis.patch.yml` keeps the
|
|
1412
1447
|
* profile field for a deployment that knows its route. Everything else stays
|
|
1413
|
-
* owned by `
|
|
1448
|
+
* owned by `cordis.patch.yml`. Profile edits land as minimal `settings.mutate`
|
|
1414
1449
|
* path ops against the stored section — the card names only the fields it can
|
|
1415
1450
|
* see instead of rebuilding the whole subtree from a partial descriptor.
|
|
1416
1451
|
*/
|
|
@@ -1470,6 +1505,15 @@ window.__ModuleLoader__.load({
|
|
|
1470
1505
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1471
1506
|
const [keyState, setKeyState] = (0, react.useState)(void 0);
|
|
1472
1507
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
1508
|
+
const [listBusy, setListBusy] = (0, react.useState)(false);
|
|
1509
|
+
const { onBusyChange } = props;
|
|
1510
|
+
(0, react.useEffect)(() => {
|
|
1511
|
+
onBusyChange?.(busy || listBusy);
|
|
1512
|
+
}, [
|
|
1513
|
+
busy,
|
|
1514
|
+
listBusy,
|
|
1515
|
+
onBusyChange
|
|
1516
|
+
]);
|
|
1473
1517
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
1474
1518
|
const [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));
|
|
1475
1519
|
const [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);
|
|
@@ -1681,7 +1725,7 @@ window.__ModuleLoader__.load({
|
|
|
1681
1725
|
className: ModelsSection_module_css_default["input"],
|
|
1682
1726
|
type: "text",
|
|
1683
1727
|
value: stringAt(draft, "baseURL") ?? "",
|
|
1684
|
-
placeholder: family === "deepseek" ? t(
|
|
1728
|
+
placeholder: family === "deepseek" ? t("deepSeekBaseUrl") : stringAt(fallback, "baseURL") ?? t("baseUrlDefault"),
|
|
1685
1729
|
"aria-describedby": family === "deepseek" ? `${props.provider}-endpoint-hint` : void 0,
|
|
1686
1730
|
"aria-label": t("baseUrl"),
|
|
1687
1731
|
disabled,
|
|
@@ -1714,7 +1758,7 @@ window.__ModuleLoader__.load({
|
|
|
1714
1758
|
children: t("customApiUnset")
|
|
1715
1759
|
}) : null, protocols.map((choice) => (0, react_jsx_runtime.jsx)("option", {
|
|
1716
1760
|
value: choice,
|
|
1717
|
-
children: choice
|
|
1761
|
+
children: protocolLabel(t, choice)
|
|
1718
1762
|
}, choice))]
|
|
1719
1763
|
})]
|
|
1720
1764
|
}) : null,
|
|
@@ -1728,7 +1772,8 @@ window.__ModuleLoader__.load({
|
|
|
1728
1772
|
defaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,
|
|
1729
1773
|
probe,
|
|
1730
1774
|
probeBlocked: keyFailure,
|
|
1731
|
-
operations
|
|
1775
|
+
operations,
|
|
1776
|
+
onBusyChange: setListBusy
|
|
1732
1777
|
})
|
|
1733
1778
|
]
|
|
1734
1779
|
})]
|
|
@@ -1785,11 +1830,19 @@ window.__ModuleLoader__.load({
|
|
|
1785
1830
|
* solid configured or missing dots. A whole-section provider without a
|
|
1786
1831
|
* configured key renders as its open setup card instead of a row, but only in
|
|
1787
1832
|
* the first-run posture — no provider on the page can serve requests yet — and
|
|
1788
|
-
* only until the user closes that card
|
|
1789
|
-
*
|
|
1790
|
-
*
|
|
1791
|
-
*
|
|
1792
|
-
*
|
|
1833
|
+
* only until the user closes that card. The add flow is one card behind one
|
|
1834
|
+
* button: a mode switch chooses between adopting a dormant directory provider
|
|
1835
|
+
* (the catalog select over the provider editor) and declaring a custom model
|
|
1836
|
+
* API (the create form). A panel mounts the first time its mode is shown and
|
|
1837
|
+
* stays mounted, hidden, while the card is open and its mode stays offered,
|
|
1838
|
+
* so switching modes discards neither draft and an unvisited mode costs
|
|
1839
|
+
* nothing; the switch holds still while either panel has a write or an
|
|
1840
|
+
* endpoint interrogation in flight, since a switch underneath one would
|
|
1841
|
+
* orphan the answer. Each card kind owns its own open state, so closing one
|
|
1842
|
+
* never discards a draft in another. Every
|
|
1843
|
+
* mutation writes through the wire, while a provider removal first requires
|
|
1844
|
+
* confirmation; the page re-renders from pushed invalidations or the
|
|
1845
|
+
* post-apply reload.
|
|
1793
1846
|
*/
|
|
1794
1847
|
/** Render an editor for either the setup posture or an expanded provider row. */
|
|
1795
1848
|
function renderProviderEditor({ target, ...props }) {
|
|
@@ -1891,30 +1944,48 @@ window.__ModuleLoader__.load({
|
|
|
1891
1944
|
const { controller, operations, schema, t } = injected;
|
|
1892
1945
|
const state = injected.useSnapshot((snapshot) => snapshot);
|
|
1893
1946
|
const [editing, setEditing] = (0, react.useState)(void 0);
|
|
1894
|
-
const [
|
|
1947
|
+
const [addOpen, setAddOpen] = (0, react.useState)(false);
|
|
1948
|
+
const [addMode, setAddMode] = (0, react.useState)("catalog");
|
|
1949
|
+
/** The modes shown since the add card opened; each keeps its panel mounted. */
|
|
1950
|
+
const [visited, setVisited] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
1951
|
+
/** Whether each add panel has a write or an interrogation in flight. */
|
|
1952
|
+
const [catalogBusy, setCatalogBusy] = (0, react.useState)(false);
|
|
1953
|
+
const [customBusy, setCustomBusy] = (0, react.useState)(false);
|
|
1954
|
+
/** Base of the add card's tab and panel ids. */
|
|
1955
|
+
const addId = (0, react.useId)();
|
|
1895
1956
|
const [deleteTarget, setDeleteTarget] = (0, react.useState)(void 0);
|
|
1896
1957
|
const [deleting, setDeleting] = (0, react.useState)(false);
|
|
1897
1958
|
const [deleteFailure, setDeleteFailure] = (0, react.useState)(void 0);
|
|
1898
1959
|
const [savedTarget, setSavedTarget] = (0, react.useState)(void 0);
|
|
1899
|
-
const [declaring, setDeclaring] = (0, react.useState)(false);
|
|
1900
1960
|
const [dismissedSetup, setDismissedSetup] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
1901
1961
|
const announceSaved = (target) => {
|
|
1902
1962
|
controller.load().then(() => {
|
|
1903
1963
|
setSavedTarget(target);
|
|
1904
1964
|
});
|
|
1905
1965
|
};
|
|
1906
|
-
|
|
1966
|
+
/**
|
|
1967
|
+
* Close the add card whole. The catalog target is forgotten with it, since
|
|
1968
|
+
* `editing` doubles as the row editor's target once the card is closed and a
|
|
1969
|
+
* refresh could otherwise open the row of a provider the draft never saved.
|
|
1970
|
+
* The busy flags reset here because a panel that closes itself on success
|
|
1971
|
+
* unmounts before it can report idle.
|
|
1972
|
+
*/
|
|
1973
|
+
const closeAdd = () => {
|
|
1907
1974
|
setEditing(void 0);
|
|
1908
|
-
|
|
1909
|
-
|
|
1975
|
+
setAddOpen(false);
|
|
1976
|
+
setCatalogBusy(false);
|
|
1977
|
+
setCustomBusy(false);
|
|
1978
|
+
};
|
|
1979
|
+
const closeEditor = (changed, target) => {
|
|
1980
|
+
closeAdd();
|
|
1910
1981
|
if (changed) announceSaved(target);
|
|
1911
1982
|
};
|
|
1912
1983
|
/**
|
|
1913
|
-
* Close a setup card, which owns none of the state above: the row-editor
|
|
1914
|
-
*
|
|
1915
|
-
*
|
|
1916
|
-
*
|
|
1917
|
-
*
|
|
1984
|
+
* Close a setup card, which owns none of the state above: the row-editor
|
|
1985
|
+
* and add cards each own one of those, so clearing them here would discard
|
|
1986
|
+
* a draft the user opened beside this card. Dismissal is this card's own —
|
|
1987
|
+
* the provider falls back to an ordinary row for the rest of the session,
|
|
1988
|
+
* and reopens through Edit.
|
|
1918
1989
|
*/
|
|
1919
1990
|
const closeSetup = (changed, target) => {
|
|
1920
1991
|
setDismissedSetup((previous) => new Set([...previous, target.provider]));
|
|
@@ -1967,11 +2038,37 @@ window.__ModuleLoader__.load({
|
|
|
1967
2038
|
const anyUsable = state.rows.some(providerUsable);
|
|
1968
2039
|
const configured = state.rows.filter((row) => row.configured);
|
|
1969
2040
|
const configurable = state.rows.filter((row) => state.namespaces.has(row.entry.settingsNs));
|
|
1970
|
-
const addable =
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
2041
|
+
const addable = state.rows.flatMap((row) => {
|
|
2042
|
+
const namespace = state.namespaces.get(row.entry.settingsNs);
|
|
2043
|
+
return namespace === void 0 || row.configured ? [] : [{
|
|
2044
|
+
row,
|
|
2045
|
+
namespace
|
|
2046
|
+
}];
|
|
2047
|
+
});
|
|
2048
|
+
const piAi = state.namespaces.get("llm-pi-ai");
|
|
2049
|
+
const protocols = protocolChoices(piAi, schema);
|
|
2050
|
+
const catalogOffered = configurable.length > 0;
|
|
2051
|
+
const catalogEnabled = addable.length > 0;
|
|
2052
|
+
const customOffered = piAi !== void 0;
|
|
2053
|
+
const customEnabled = protocols.length > 0;
|
|
2054
|
+
const bothOffered = catalogOffered && customOffered;
|
|
2055
|
+
const mode = bothOffered ? addMode : customOffered ? "custom" : "catalog";
|
|
2056
|
+
const mounted = (candidate) => mode === candidate || visited.has(candidate);
|
|
2057
|
+
const switchLocked = catalogBusy || customBusy;
|
|
2058
|
+
const draft = (() => {
|
|
2059
|
+
if (!addOpen || !catalogOffered) return void 0;
|
|
2060
|
+
const kept = editing === void 0 ? void 0 : state.namespaces.get(editing.settingsNs);
|
|
2061
|
+
if (editing !== void 0 && kept !== void 0) return {
|
|
2062
|
+
target: editing,
|
|
2063
|
+
namespace: kept
|
|
2064
|
+
};
|
|
2065
|
+
const first = addable[0];
|
|
2066
|
+
return first === void 0 ? void 0 : {
|
|
2067
|
+
target: targetOf(first.row),
|
|
2068
|
+
namespace: first.namespace
|
|
2069
|
+
};
|
|
2070
|
+
})();
|
|
2071
|
+
const addRow = draft === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === draft.target.provider);
|
|
1975
2072
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
1976
2073
|
className: ModelsSection_module_css_default["section"],
|
|
1977
2074
|
children: [
|
|
@@ -2027,7 +2124,7 @@ window.__ModuleLoader__.load({
|
|
|
2027
2124
|
}, { entryKey: row.entry.settingsNs })
|
|
2028
2125
|
]
|
|
2029
2126
|
}, row.entry.provider);
|
|
2030
|
-
const open = !
|
|
2127
|
+
const open = !addOpen && editing?.provider === row.entry.provider;
|
|
2031
2128
|
const credentialConfigured = row.credential?.configured === true;
|
|
2032
2129
|
const credentialMissing = !credentialConfigured && row.apiKeyEnv !== void 0 && row.credential?.configured === false;
|
|
2033
2130
|
return (0, react_jsx_runtime.jsxs)("li", {
|
|
@@ -2066,8 +2163,7 @@ window.__ModuleLoader__.load({
|
|
|
2066
2163
|
"aria-label": providerCopy(t("editProvider"), target),
|
|
2067
2164
|
onClick: () => {
|
|
2068
2165
|
setSavedTarget(void 0);
|
|
2069
|
-
|
|
2070
|
-
setAdding(false);
|
|
2166
|
+
setAddOpen(false);
|
|
2071
2167
|
setEditing(open ? void 0 : target);
|
|
2072
2168
|
},
|
|
2073
2169
|
children: t("edit")
|
|
@@ -2108,94 +2204,136 @@ window.__ModuleLoader__.load({
|
|
|
2108
2204
|
}),
|
|
2109
2205
|
(0, react_jsx_runtime.jsx)("div", {
|
|
2110
2206
|
className: ModelsSection_module_css_default["addBlock"],
|
|
2111
|
-
children:
|
|
2207
|
+
children: addOpen ? (0, react_jsx_runtime.jsxs)("div", {
|
|
2112
2208
|
className: ModelsSection_module_css_default["addCard"],
|
|
2113
2209
|
children: [
|
|
2114
2210
|
(0, react_jsx_runtime.jsxs)("div", {
|
|
2115
|
-
className: ModelsSection_module_css_default["
|
|
2116
|
-
children: [(0, react_jsx_runtime.jsx)(
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2211
|
+
className: ModelsSection_module_css_default["addModes"],
|
|
2212
|
+
children: [bothOffered ? (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.SegmentedControl, {
|
|
2213
|
+
id: addId,
|
|
2214
|
+
label: t("addMode"),
|
|
2215
|
+
value: mode,
|
|
2216
|
+
disabled: switchLocked,
|
|
2217
|
+
options: [{
|
|
2218
|
+
value: "catalog",
|
|
2219
|
+
label: t("addCatalog"),
|
|
2220
|
+
disabled: !catalogEnabled,
|
|
2221
|
+
...catalogEnabled ? {} : { title: t("addCatalogExhausted") }
|
|
2222
|
+
}, {
|
|
2223
|
+
value: "custom",
|
|
2224
|
+
label: t("addCustom"),
|
|
2225
|
+
disabled: !customEnabled,
|
|
2226
|
+
...customEnabled ? {} : { title: t("addCustomUnavailable") }
|
|
2227
|
+
}],
|
|
2228
|
+
onChange: (next) => {
|
|
2229
|
+
setAddMode(next);
|
|
2230
|
+
setVisited((previous) => new Set([...previous, next]));
|
|
2231
|
+
}
|
|
2232
|
+
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
2233
|
+
className: ModelsSection_module_css_default["editorHeader"],
|
|
2234
|
+
children: (0, react_jsx_runtime.jsx)("span", {
|
|
2235
|
+
className: ModelsSection_module_css_default["editorTitle"],
|
|
2236
|
+
children: t(mode === "catalog" ? "addCatalog" : "addCustom")
|
|
2237
|
+
})
|
|
2238
|
+
}), (0, react_jsx_runtime.jsx)("p", {
|
|
2239
|
+
className: ModelsSection_module_css_default["advancedHint"],
|
|
2240
|
+
children: t(mode === "catalog" ? "addCatalogHint" : "addCustomHint")
|
|
2133
2241
|
})]
|
|
2134
2242
|
}),
|
|
2135
|
-
(0, react_jsx_runtime.
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2243
|
+
mounted("catalog") && draft !== void 0 ? (0, react_jsx_runtime.jsxs)("div", {
|
|
2244
|
+
id: `${addId}-catalog-panel`,
|
|
2245
|
+
...bothOffered ? {
|
|
2246
|
+
role: "tabpanel",
|
|
2247
|
+
"aria-labelledby": `${addId}-catalog`
|
|
2248
|
+
} : {},
|
|
2249
|
+
hidden: mode !== "catalog",
|
|
2250
|
+
className: ModelsSection_module_css_default["addPanel"],
|
|
2251
|
+
children: [
|
|
2252
|
+
(0, react_jsx_runtime.jsxs)("div", {
|
|
2253
|
+
className: ModelsSection_module_css_default["field"],
|
|
2254
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
2255
|
+
className: ModelsSection_module_css_default["fieldLabel"],
|
|
2256
|
+
children: t("provider")
|
|
2257
|
+
}), (0, react_jsx_runtime.jsx)("select", {
|
|
2258
|
+
className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["selectInput"]}`,
|
|
2259
|
+
value: draft.target.provider,
|
|
2260
|
+
"aria-label": t("provider"),
|
|
2261
|
+
disabled: catalogBusy,
|
|
2262
|
+
onChange: (event) => {
|
|
2263
|
+
const picked = addable.find((candidate) => candidate.row.entry.provider === event.target.value);
|
|
2264
|
+
/* v8 ignore next -- the select only lists addable rows */
|
|
2265
|
+
if (picked === void 0) return;
|
|
2266
|
+
setEditing(targetOf(picked.row));
|
|
2267
|
+
},
|
|
2268
|
+
children: addable.map(({ row }) => (0, react_jsx_runtime.jsx)("option", {
|
|
2269
|
+
value: row.entry.provider,
|
|
2270
|
+
children: row.entry.displayName
|
|
2271
|
+
}, row.entry.provider))
|
|
2272
|
+
})]
|
|
2273
|
+
}),
|
|
2274
|
+
(0, react_jsx_runtime.jsx)(ProviderEditor, {
|
|
2275
|
+
provider: draft.target.provider,
|
|
2276
|
+
displayName: draft.target.displayName,
|
|
2277
|
+
hideTitle: true,
|
|
2278
|
+
namespace: draft.namespace,
|
|
2279
|
+
schema,
|
|
2280
|
+
settingsPath: draft.target.settingsPath,
|
|
2281
|
+
operations,
|
|
2282
|
+
t,
|
|
2283
|
+
readOnly: !state.writable,
|
|
2284
|
+
onClose: (changed) => {
|
|
2285
|
+
closeEditor(changed, draft.target);
|
|
2286
|
+
},
|
|
2287
|
+
onBusyChange: setCatalogBusy
|
|
2288
|
+
}, draft.target.provider),
|
|
2289
|
+
addRow === void 0 ? null : renderSlot("settings.models.provider-card", {
|
|
2290
|
+
provider: addRow.entry,
|
|
2291
|
+
configured: addRow.configured,
|
|
2292
|
+
keyConfigured: keyConfiguredOf(addRow)
|
|
2293
|
+
}, { entryKey: addRow.entry.settingsNs })
|
|
2294
|
+
]
|
|
2295
|
+
}) : null,
|
|
2296
|
+
mounted("custom") && piAi !== void 0 ? (0, react_jsx_runtime.jsx)("div", {
|
|
2297
|
+
id: `${addId}-custom-panel`,
|
|
2298
|
+
...bothOffered ? {
|
|
2299
|
+
role: "tabpanel",
|
|
2300
|
+
"aria-labelledby": `${addId}-custom`
|
|
2301
|
+
} : {},
|
|
2302
|
+
hidden: mode !== "custom",
|
|
2303
|
+
className: ModelsSection_module_css_default["addPanel"],
|
|
2304
|
+
children: (0, react_jsx_runtime.jsx)(CustomProviderCard, {
|
|
2305
|
+
taken: state.rows.map((row) => row.entry.provider),
|
|
2306
|
+
protocols,
|
|
2307
|
+
revision: piAi.revision,
|
|
2308
|
+
operations,
|
|
2309
|
+
t,
|
|
2310
|
+
readOnly: !state.writable,
|
|
2311
|
+
onClose: (changed) => {
|
|
2312
|
+
closeAdd();
|
|
2313
|
+
if (changed) controller.load();
|
|
2314
|
+
},
|
|
2315
|
+
onBusyChange: setCustomBusy
|
|
2316
|
+
})
|
|
2317
|
+
}) : null
|
|
2154
2318
|
]
|
|
2155
|
-
}) :
|
|
2156
|
-
className: ModelsSection_module_css_default["addCard"],
|
|
2157
|
-
children: (0, react_jsx_runtime.jsx)(CustomProviderCard, {
|
|
2158
|
-
taken: state.rows.map((row) => row.entry.provider),
|
|
2159
|
-
protocols,
|
|
2160
|
-
/* v8 ignore next -- the card only opens from a button disabled without this namespace */
|
|
2161
|
-
revision: state.namespaces.get("llm-pi-ai")?.revision ?? 0,
|
|
2162
|
-
operations,
|
|
2163
|
-
t,
|
|
2164
|
-
readOnly: !state.writable,
|
|
2165
|
-
onClose: (changed) => {
|
|
2166
|
-
setDeclaring(false);
|
|
2167
|
-
if (changed) controller.load();
|
|
2168
|
-
}
|
|
2169
|
-
})
|
|
2170
|
-
}) : (0, react_jsx_runtime.jsxs)("div", {
|
|
2319
|
+
}) : catalogOffered || customOffered ? (0, react_jsx_runtime.jsx)("div", {
|
|
2171
2320
|
className: ModelsSection_module_css_default["addActions"],
|
|
2172
|
-
children:
|
|
2321
|
+
children: (0, react_jsx_runtime.jsxs)("button", {
|
|
2173
2322
|
type: "button",
|
|
2174
2323
|
className: ModelsSection_module_css_default["addButton"],
|
|
2175
|
-
disabled:
|
|
2324
|
+
disabled: !state.writable || !catalogEnabled && !customEnabled,
|
|
2176
2325
|
onClick: () => {
|
|
2177
2326
|
const first = addable[0];
|
|
2178
|
-
|
|
2179
|
-
if (first === void 0) return;
|
|
2327
|
+
const initial = catalogEnabled ? "catalog" : "custom";
|
|
2180
2328
|
setSavedTarget(void 0);
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2329
|
+
setEditing(first === void 0 ? void 0 : targetOf(first.row));
|
|
2330
|
+
setAddMode(initial);
|
|
2331
|
+
setVisited(new Set([initial]));
|
|
2332
|
+
setAddOpen(true);
|
|
2184
2333
|
},
|
|
2185
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.
|
|
2186
|
-
})
|
|
2187
|
-
|
|
2188
|
-
className: ModelsSection_module_css_default["addButton"],
|
|
2189
|
-
disabled: protocols.length === 0 || !state.writable,
|
|
2190
|
-
onClick: () => {
|
|
2191
|
-
setSavedTarget(void 0);
|
|
2192
|
-
setAdding(false);
|
|
2193
|
-
setEditing(void 0);
|
|
2194
|
-
setDeclaring(true);
|
|
2195
|
-
},
|
|
2196
|
-
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("customAdd")]
|
|
2197
|
-
})]
|
|
2198
|
-
})
|
|
2334
|
+
children: [(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("add")]
|
|
2335
|
+
})
|
|
2336
|
+
}) : null
|
|
2199
2337
|
}),
|
|
2200
2338
|
renderSlot("settings.models.footer", {}),
|
|
2201
2339
|
(0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Modal, {
|
|
@@ -2228,7 +2366,7 @@ window.__ModuleLoader__.load({
|
|
|
2228
2366
|
}
|
|
2229
2367
|
//#endregion
|
|
2230
2368
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-models/src/client/OnboardingModal.module.css.mjs
|
|
2231
|
-
const css$2 = ".jLrgrW_dialog{width:min(600px,100%);padding:0}.jLrgrW_content{box-sizing:border-box;flex-direction:column;
|
|
2369
|
+
const css$2 = ".jLrgrW_dialog{width:min(600px,100%);max-height:100%;padding:0}.jLrgrW_content{box-sizing:border-box;flex-direction:column;min-height:0;padding:28px;display:flex;overflow-y:auto}.jLrgrW_title{color:var(--dsw-alias-label-primary);outline:none;margin:0;font-size:20px;font-weight:500;line-height:28px}.jLrgrW_body{margin-top:20px}@media (width<=560px){.jLrgrW_content{padding:24px}}";
|
|
2232
2370
|
const tagId$2 = "@deepseek-ai/dsh-client-ui-settings-models/OnboardingModal.module.css";
|
|
2233
2371
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
2234
2372
|
const tag = document.createElement("style");
|
|
@@ -2323,20 +2461,34 @@ window.__ModuleLoader__.load({
|
|
|
2323
2461
|
* @returns the onboarding modal or null when onboarding needs no intervention.
|
|
2324
2462
|
*/
|
|
2325
2463
|
function DeepSeekOnboardingDialog(props) {
|
|
2326
|
-
const { complete, controller, useModels, operations, schema, t } = props;
|
|
2464
|
+
const { complete, controller, useModels, operations, schema, t, renderSlot, automatic, explicit = false } = props;
|
|
2465
|
+
const [apiKey, setApiKey] = (0, react.useState)(explicit);
|
|
2327
2466
|
const state = useModels((snapshot) => snapshot);
|
|
2328
2467
|
const readiness = onboardingReadiness(state);
|
|
2329
2468
|
(0, react.useEffect)(() => {
|
|
2330
|
-
if (state.status === "idle") controller.load();
|
|
2331
|
-
}, [
|
|
2469
|
+
if ((automatic || explicit) && state.status === "idle") controller.load();
|
|
2470
|
+
}, [
|
|
2471
|
+
controller,
|
|
2472
|
+
state.status,
|
|
2473
|
+
automatic,
|
|
2474
|
+
explicit
|
|
2475
|
+
]);
|
|
2332
2476
|
(0, react.useEffect)(() => {
|
|
2333
|
-
if (readiness.kind === "adapter-absent" || readiness.kind === "provider-ready" || readiness.kind === "unavailable") complete();
|
|
2334
|
-
}, [
|
|
2477
|
+
if (!automatic && !explicit || readiness.kind === "adapter-absent" || !explicit && readiness.kind === "provider-ready" || readiness.kind === "unavailable") complete();
|
|
2478
|
+
}, [
|
|
2479
|
+
complete,
|
|
2480
|
+
readiness.kind,
|
|
2481
|
+
explicit,
|
|
2482
|
+
automatic
|
|
2483
|
+
]);
|
|
2484
|
+
if (!automatic && !explicit) return null;
|
|
2335
2485
|
switch (readiness.kind) {
|
|
2336
2486
|
case "loading":
|
|
2337
2487
|
case "adapter-absent":
|
|
2338
|
-
case "provider-ready":
|
|
2339
2488
|
case "unavailable": return null;
|
|
2489
|
+
case "provider-ready":
|
|
2490
|
+
if (!explicit) return null;
|
|
2491
|
+
break;
|
|
2340
2492
|
case "credential-missing": break;
|
|
2341
2493
|
/* v8 ignore next -- every current readiness variant is handled above */
|
|
2342
2494
|
default: return assertNever$1(readiness);
|
|
@@ -2352,7 +2504,7 @@ window.__ModuleLoader__.load({
|
|
|
2352
2504
|
}
|
|
2353
2505
|
controller.load();
|
|
2354
2506
|
};
|
|
2355
|
-
|
|
2507
|
+
const editor = (0, react_jsx_runtime.jsxs)(OnboardingModal, {
|
|
2356
2508
|
title: t("onboardingTitle"),
|
|
2357
2509
|
children: [(0, react_jsx_runtime.jsx)("p", {
|
|
2358
2510
|
className: DeepSeekOnboardingDialog_module_css_default.description,
|
|
@@ -2379,6 +2531,12 @@ window.__ModuleLoader__.load({
|
|
|
2379
2531
|
})
|
|
2380
2532
|
})]
|
|
2381
2533
|
});
|
|
2534
|
+
return apiKey ? editor : renderSlot("settings.models.sign-in", {
|
|
2535
|
+
complete,
|
|
2536
|
+
useApiKey: () => {
|
|
2537
|
+
setApiKey(true);
|
|
2538
|
+
}
|
|
2539
|
+
}, { fallback: editor });
|
|
2382
2540
|
}
|
|
2383
2541
|
//#endregion
|
|
2384
2542
|
//#region \0dsh-css:/home/runner/work/deepseek-harness/deepseek-harness/packages/client/ui-settings-models/src/client/WelcomeNotice.module.css.mjs
|
|
@@ -2456,7 +2614,7 @@ window.__ModuleLoader__.load({
|
|
|
2456
2614
|
//#endregion
|
|
2457
2615
|
//#region lib/types/onboarding-copy.js
|
|
2458
2616
|
/** Durable settings namespace for product-wide GUI onboarding facts. */
|
|
2459
|
-
const WELCOME_NOTICE_SETTINGS_NAMESPACE = "ui-
|
|
2617
|
+
const WELCOME_NOTICE_SETTINGS_NAMESPACE = "ui-settings-general";
|
|
2460
2618
|
/** Field storing the last welcome notice version the user acknowledged. */
|
|
2461
2619
|
const WELCOME_NOTICE_ACK_FIELD = "welcomeNoticeVersion";
|
|
2462
2620
|
/**
|
|
@@ -2472,16 +2630,6 @@ window.__ModuleLoader__.load({
|
|
|
2472
2630
|
* remote browser's memory-mode scope never answers and the acknowledgement
|
|
2473
2631
|
* stays process-local here.
|
|
2474
2632
|
*/
|
|
2475
|
-
/**
|
|
2476
|
-
* Accept any object section verbatim; a malformed durable value reads as an
|
|
2477
|
-
* empty section, so the notice treats it as unacknowledged instead of leaving
|
|
2478
|
-
* the scope stuck on its previous value.
|
|
2479
|
-
* @param section - the wire section value.
|
|
2480
|
-
* @returns the section object, or an empty one for non-object values.
|
|
2481
|
-
*/
|
|
2482
|
-
function decodeWelcomeSection(section) {
|
|
2483
|
-
return typeof section === "object" && section !== null && !Array.isArray(section) ? section : {};
|
|
2484
|
-
}
|
|
2485
2633
|
/* v8 ignore next 3 -- closed-union default only defends future source widening */
|
|
2486
2634
|
function assertNever(_value) {
|
|
2487
2635
|
throw new Error("unexpected welcome settings status");
|
|
@@ -2680,7 +2828,14 @@ window.__ModuleLoader__.load({
|
|
|
2680
2828
|
deleteDescriptionWithCredential: "Deleting {provider} removes its configuration and stored API key.",
|
|
2681
2829
|
deleteConfirm: "Delete {provider}",
|
|
2682
2830
|
deleting: "Deleting {provider}…",
|
|
2683
|
-
add: "Add provider",
|
|
2831
|
+
add: "Add model provider",
|
|
2832
|
+
addMode: "How to add",
|
|
2833
|
+
addCatalog: "Third-party model provider",
|
|
2834
|
+
addCustom: "Custom model API",
|
|
2835
|
+
addCatalogHint: "Pick OpenAI, Anthropic, Kimi, or another provider from the built-in catalog and enter its API key.",
|
|
2836
|
+
addCustomHint: "Connect a relay, a self-hosted server, or any other OpenAI- or Anthropic-compatible endpoint by its base URL, protocol, and models.",
|
|
2837
|
+
addCatalogExhausted: "Every catalog provider is already configured.",
|
|
2838
|
+
addCustomUnavailable: "No API protocol is available to declare.",
|
|
2684
2839
|
provider: "Provider",
|
|
2685
2840
|
close: "Close",
|
|
2686
2841
|
cancel: "Cancel",
|
|
@@ -2701,9 +2856,8 @@ window.__ModuleLoader__.load({
|
|
|
2701
2856
|
customized: "Customized settings",
|
|
2702
2857
|
baseUrl: "Base URL",
|
|
2703
2858
|
baseUrlDefault: "Provider default",
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
deepSeekEndpointHint: "Use an endpoint compatible with the configured connection.",
|
|
2859
|
+
deepSeekBaseUrl: "https://api.deepseek.com/anthropic",
|
|
2860
|
+
deepSeekEndpointHint: "Use an API endpoint compatible with Anthropic Messages.",
|
|
2707
2861
|
models: "Models",
|
|
2708
2862
|
modelsInherited: "Using the adapter defaults",
|
|
2709
2863
|
modelsCustomized: "Customized model catalog",
|
|
@@ -2731,7 +2885,7 @@ window.__ModuleLoader__.load({
|
|
|
2731
2885
|
modelNameInvalid: "Display name cannot be empty.",
|
|
2732
2886
|
modelContextInvalid: "Context window must be a positive count, like 131072, 256K, or 1M.",
|
|
2733
2887
|
modelMaxTokensInvalid: "Max output tokens must be a positive count, like 8192, 64K, or 1M.",
|
|
2734
|
-
advancedHint: "Other fields live in
|
|
2888
|
+
advancedHint: "Other fields live in cordis.patch.yml; edit that section directly.",
|
|
2735
2889
|
modelCapacityInvalid: "A capacity must be a number, optionally suffixed K or M.",
|
|
2736
2890
|
modelDuplicate: "Each model ID may appear once.",
|
|
2737
2891
|
fetchModels: "Fetch available models",
|
|
@@ -2745,8 +2899,6 @@ window.__ModuleLoader__.load({
|
|
|
2745
2899
|
fetchSelectAll: "Select all",
|
|
2746
2900
|
fetchDeselectAll: "Deselect all",
|
|
2747
2901
|
fetchAdopt: "Add selected",
|
|
2748
|
-
customAdd: "Add a custom provider",
|
|
2749
|
-
customTitle: "Custom provider",
|
|
2750
2902
|
customTag: "Custom",
|
|
2751
2903
|
customRoute: "Provider ID",
|
|
2752
2904
|
customRouteHint: "Lowercase identifier, starting with a letter, that uniquely names this provider in requests and as its credential name.",
|
|
@@ -2755,10 +2907,14 @@ window.__ModuleLoader__.load({
|
|
|
2755
2907
|
customDisplayName: "Display name",
|
|
2756
2908
|
customApi: "API protocol",
|
|
2757
2909
|
customApiUnset: "Not selected",
|
|
2910
|
+
protocolOpenAiCompletions: "OpenAI Chat Completions",
|
|
2911
|
+
protocolOpenAiResponses: "OpenAI Responses",
|
|
2912
|
+
protocolAnthropicMessages: "Anthropic Messages",
|
|
2758
2913
|
customNeedsBaseUrl: "A custom provider needs a base URL.",
|
|
2759
2914
|
customBaseUrlInvalid: "Enter a valid HTTP or HTTPS URL.",
|
|
2760
2915
|
customNeedsModels: "A custom provider needs at least one model.",
|
|
2761
2916
|
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
2917
|
+
customAnthropicBaseUrlPlaceholder: "https://gateway.example",
|
|
2762
2918
|
settingsPathUnresolvable: "unresolvable settings path",
|
|
2763
2919
|
create: "Create provider",
|
|
2764
2920
|
creating: "Creating…",
|
|
@@ -2777,7 +2933,7 @@ window.__ModuleLoader__.load({
|
|
|
2777
2933
|
const zh = {
|
|
2778
2934
|
nav: "模型",
|
|
2779
2935
|
title: "模型",
|
|
2780
|
-
intro: "
|
|
2936
|
+
intro: "填入各提供商的 API 密钥即可使用其模型。",
|
|
2781
2937
|
edit: "编辑",
|
|
2782
2938
|
editProvider: "编辑 {provider}",
|
|
2783
2939
|
remove: "删除",
|
|
@@ -2787,8 +2943,15 @@ window.__ModuleLoader__.load({
|
|
|
2787
2943
|
deleteDescriptionWithCredential: "删除 {provider} 会移除其配置和存储的 API 密钥。",
|
|
2788
2944
|
deleteConfirm: "删除 {provider}",
|
|
2789
2945
|
deleting: "正在删除 {provider}…",
|
|
2790
|
-
add: "
|
|
2791
|
-
|
|
2946
|
+
add: "添加模型提供商",
|
|
2947
|
+
addMode: "添加方式",
|
|
2948
|
+
addCatalog: "第三方模型提供商",
|
|
2949
|
+
addCustom: "自定义模型 API",
|
|
2950
|
+
addCatalogHint: "从内置目录中选择 OpenAI、Anthropic、Kimi 等提供商,填入其 API 密钥即可使用。",
|
|
2951
|
+
addCustomHint: "连接中转站、自部署服务或其他兼容 OpenAI / Anthropic 协议的接口,需填写 API 地址、协议和模型。",
|
|
2952
|
+
addCatalogExhausted: "目录中的提供商都已添加。",
|
|
2953
|
+
addCustomUnavailable: "没有可用的 API 协议。",
|
|
2954
|
+
provider: "提供商",
|
|
2792
2955
|
close: "关闭",
|
|
2793
2956
|
cancel: "取消",
|
|
2794
2957
|
apply: "保存",
|
|
@@ -2797,7 +2960,7 @@ window.__ModuleLoader__.load({
|
|
|
2797
2960
|
credentialConfigured: "API 密钥已配置",
|
|
2798
2961
|
credentialMissing: "API 密钥缺失",
|
|
2799
2962
|
readOnly: "当前部署的设置文档为只读。",
|
|
2800
|
-
loadFailed: "
|
|
2963
|
+
loadFailed: "加载提供商目录失败",
|
|
2801
2964
|
conflict: "这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。",
|
|
2802
2965
|
retry: "重试",
|
|
2803
2966
|
keyInput: "API 密钥",
|
|
@@ -2807,10 +2970,9 @@ window.__ModuleLoader__.load({
|
|
|
2807
2970
|
keyEnvLocked: "由启动环境提供(只读)",
|
|
2808
2971
|
customized: "自定义设置",
|
|
2809
2972
|
baseUrl: "API 地址",
|
|
2810
|
-
baseUrlDefault: "
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
deepSeekEndpointHint: "请填写与当前连接配置兼容的 API 地址。",
|
|
2973
|
+
baseUrlDefault: "提供商默认",
|
|
2974
|
+
deepSeekBaseUrl: "https://api.deepseek.com/anthropic",
|
|
2975
|
+
deepSeekEndpointHint: "请填写兼容 Anthropic Messages 协议的 API 地址。",
|
|
2814
2976
|
models: "模型目录",
|
|
2815
2977
|
modelsInherited: "正在使用适配器默认模型",
|
|
2816
2978
|
modelsCustomized: "已自定义模型目录",
|
|
@@ -2820,9 +2982,9 @@ window.__ModuleLoader__.load({
|
|
|
2820
2982
|
modelName: "显示名称",
|
|
2821
2983
|
modelNamePlaceholder: "留空时使用模型 ID",
|
|
2822
2984
|
contextWindow: "上下文窗口",
|
|
2823
|
-
contextWindowPlaceholder: "
|
|
2985
|
+
contextWindowPlaceholder: "使用提供商默认值",
|
|
2824
2986
|
maxTokens: "最大输出 token 数",
|
|
2825
|
-
maxTokensPlaceholder: "
|
|
2987
|
+
maxTokensPlaceholder: "使用提供商默认值",
|
|
2826
2988
|
modelAdvanced: "模型选项",
|
|
2827
2989
|
modelInputTypes: "输入类型",
|
|
2828
2990
|
modelInputText: "文本",
|
|
@@ -2831,43 +2993,45 @@ window.__ModuleLoader__.load({
|
|
|
2831
2993
|
removeModel: "删除模型",
|
|
2832
2994
|
modelsEmpty: "模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。",
|
|
2833
2995
|
keyBlank: "请输入 API 密钥;留空则保持已存储的密钥。",
|
|
2834
|
-
keyBlankNew: "请输入 API
|
|
2996
|
+
keyBlankNew: "请输入 API 密钥;若该提供商以其他方式鉴权,可以留空。",
|
|
2835
2997
|
keyIllegalCharacters: "该 API 密钥格式错误,请检查。",
|
|
2836
2998
|
modelIdRequired: "模型 ID 不能为空。",
|
|
2837
2999
|
modelIdDuplicate: "模型 ID 不能重复。",
|
|
2838
3000
|
modelNameInvalid: "显示名称不能为空。",
|
|
2839
3001
|
modelContextInvalid: "上下文窗口必须是正数,例如 131072、256K 或 1M。",
|
|
2840
3002
|
modelMaxTokensInvalid: "最大输出 token 数必须是正数,例如 8192、64K 或 1M。",
|
|
2841
|
-
advancedHint: "其余字段在
|
|
3003
|
+
advancedHint: "其余字段在 cordis.patch.yml 中,请直接编辑对应段。",
|
|
2842
3004
|
modelCapacityInvalid: "容量需为数字,可加 K 或 M 后缀。",
|
|
2843
3005
|
modelDuplicate: "每个模型 ID 只能出现一次。",
|
|
2844
3006
|
fetchModels: "获取可用模型",
|
|
2845
|
-
fetching: "
|
|
3007
|
+
fetching: "正在询问提供商…",
|
|
2846
3008
|
fetchNeedsBaseUrl: "请先填写 API 地址,再获取。",
|
|
2847
|
-
fetchEmpty: "
|
|
3009
|
+
fetchEmpty: "该提供商没有列出任何模型,请手动添加。",
|
|
2848
3010
|
fetchTitle: "选择要添加的模型",
|
|
2849
|
-
fetchDescription: "
|
|
3011
|
+
fetchDescription: "以下是模型提供商的可用模型,勾选要添加的模型。",
|
|
2850
3012
|
fetchSearch: "搜索模型",
|
|
2851
3013
|
fetchNoMatches: "没有匹配的模型。",
|
|
2852
3014
|
fetchSelectAll: "全选",
|
|
2853
3015
|
fetchDeselectAll: "取消全选",
|
|
2854
3016
|
fetchAdopt: "添加所选",
|
|
2855
|
-
customAdd: "添加自定义提供方",
|
|
2856
|
-
customTitle: "自定义提供方",
|
|
2857
3017
|
customTag: "自定义",
|
|
2858
3018
|
customRoute: "Provider ID",
|
|
2859
|
-
customRouteHint: "
|
|
3019
|
+
customRouteHint: "以小写字母开头的标识,在请求中唯一标识该提供商,并用于派生凭据名。",
|
|
2860
3020
|
customRouteInvalid: "需以小写字母开头,之后可用小写字母、数字和短横线。",
|
|
2861
|
-
customRouteTaken: "
|
|
3021
|
+
customRouteTaken: "已有提供商使用了这个 ID。",
|
|
2862
3022
|
customDisplayName: "显示名称",
|
|
2863
3023
|
customApi: "API 协议",
|
|
2864
3024
|
customApiUnset: "未选择",
|
|
2865
|
-
|
|
3025
|
+
protocolOpenAiCompletions: "OpenAI Chat Completions",
|
|
3026
|
+
protocolOpenAiResponses: "OpenAI Responses",
|
|
3027
|
+
protocolAnthropicMessages: "Anthropic Messages",
|
|
3028
|
+
customNeedsBaseUrl: "自定义模型 API 需要填写 API 地址。",
|
|
2866
3029
|
customBaseUrlInvalid: "请输入有效的 HTTP 或 HTTPS 地址。",
|
|
2867
|
-
customNeedsModels: "
|
|
3030
|
+
customNeedsModels: "自定义模型 API 至少需要一个模型。",
|
|
2868
3031
|
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
3032
|
+
customAnthropicBaseUrlPlaceholder: "https://gateway.example",
|
|
2869
3033
|
settingsPathUnresolvable: "无法解析设置路径",
|
|
2870
|
-
create: "
|
|
3034
|
+
create: "创建提供商",
|
|
2871
3035
|
creating: "创建中…",
|
|
2872
3036
|
welcomeTitle: "内测声明",
|
|
2873
3037
|
welcomeBody: "DeepSeek Harness 目前的 0.1 版本仍处在面向 Harness 开发者进行测试的阶段,还有许多地方需要持续改进和打磨,希望听取广大开发者的反馈建议。预计 DeepSeek Harness 的核心插件以及基础 API 都会在接下来的一段时间内快速迭代、持续演化。\n\n我们期待与全球开发者一起,在开源、开放、可复用、可组合的基础设施之上,共同探索智能上限。欢迎全球 Harness 开发者加入 DSH 插件生态。",
|
|
@@ -2881,6 +3045,904 @@ window.__ModuleLoader__.load({
|
|
|
2881
3045
|
keyRequired: "请输入 API 密钥后继续。"
|
|
2882
3046
|
};
|
|
2883
3047
|
//#endregion
|
|
3048
|
+
//#region ../../../vendor/cosmokit/src/misc.ts
|
|
3049
|
+
/** Return true when a value is `null` or `undefined`. */
|
|
3050
|
+
function isNullable(value) {
|
|
3051
|
+
return value === null || value === void 0;
|
|
3052
|
+
}
|
|
3053
|
+
/** Return true for non-array object values. */
|
|
3054
|
+
function isPlainObject(data) {
|
|
3055
|
+
return data && typeof data === "object" && !Array.isArray(data);
|
|
3056
|
+
}
|
|
3057
|
+
/** Filter object entries and return a new object. */
|
|
3058
|
+
function filterKeys(object, filter) {
|
|
3059
|
+
return Object.fromEntries(Object.entries(object).filter(([key, value]) => filter(key, value)));
|
|
3060
|
+
}
|
|
3061
|
+
/** Map object values while preserving the original key set. */
|
|
3062
|
+
function mapValues(object, transform) {
|
|
3063
|
+
return Object.fromEntries(Object.entries(object).map(([key, value]) => [key, transform(value, key)]));
|
|
3064
|
+
}
|
|
3065
|
+
/** Pick selected keys from an object, optionally including `undefined` values. */
|
|
3066
|
+
function pick(source, keys, forced) {
|
|
3067
|
+
if (!keys) return { ...source };
|
|
3068
|
+
const result = {};
|
|
3069
|
+
for (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];
|
|
3070
|
+
return result;
|
|
3071
|
+
}
|
|
3072
|
+
//#endregion
|
|
3073
|
+
//#region ../../../vendor/cosmokit/src/volatile.ts
|
|
3074
|
+
/** Shared config references used by schema validators and plugin runtimes. */
|
|
3075
|
+
const write = Symbol.for("cosmokit.volatile.write");
|
|
3076
|
+
function snapshot(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
3077
|
+
if (typeof value === "function") throw new TypeError("volatile config cannot contain functions");
|
|
3078
|
+
if (value === null || typeof value !== "object") return value;
|
|
3079
|
+
if (ancestors.has(value)) throw new TypeError("volatile config cannot contain cycles");
|
|
3080
|
+
ancestors.add(value);
|
|
3081
|
+
try {
|
|
3082
|
+
if (Array.isArray(value)) return Object.freeze(value.map((item) => snapshot(item, ancestors)));
|
|
3083
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new TypeError("volatile config objects must be plain objects or arrays");
|
|
3084
|
+
return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, snapshot(item, ancestors)])));
|
|
3085
|
+
} finally {
|
|
3086
|
+
ancestors.delete(value);
|
|
3087
|
+
}
|
|
3088
|
+
}
|
|
3089
|
+
/**
|
|
3090
|
+
* Create a detached reference containing an immutable copy of the supplied data.
|
|
3091
|
+
* @param value - validated config data; class instances and functions are unsupported.
|
|
3092
|
+
* @returns a reference whose value is updated only by its owning runtime.
|
|
3093
|
+
*/
|
|
3094
|
+
function createVolatile(value) {
|
|
3095
|
+
let current = snapshot(value);
|
|
3096
|
+
return Object.freeze({
|
|
3097
|
+
get: () => current,
|
|
3098
|
+
[write]: (value) => {
|
|
3099
|
+
current = value;
|
|
3100
|
+
}
|
|
3101
|
+
});
|
|
3102
|
+
}
|
|
3103
|
+
/**
|
|
3104
|
+
* Identify references across ESM/CJS copies of the shared library.
|
|
3105
|
+
* @param value - a parsed config value.
|
|
3106
|
+
* @returns whether the value implements the shared reference protocol.
|
|
3107
|
+
*/
|
|
3108
|
+
function isVolatile(value) {
|
|
3109
|
+
return typeof value === "object" && value !== null && write in value;
|
|
3110
|
+
}
|
|
3111
|
+
//#endregion
|
|
3112
|
+
//#region ../../../vendor/cosmokit/src/types.ts
|
|
3113
|
+
/** Test values using `instanceof` with a `toStringTag` fallback. */
|
|
3114
|
+
function is(type, value) {
|
|
3115
|
+
if (arguments.length === 1) return (value) => is(type, value);
|
|
3116
|
+
return type in globalThis && value instanceof globalThis[type] || Object.prototype.toString.call(value).slice(8, -1) === type;
|
|
3117
|
+
}
|
|
3118
|
+
function isArrayBufferLike(value) {
|
|
3119
|
+
return is("ArrayBuffer", value) || is("SharedArrayBuffer", value);
|
|
3120
|
+
}
|
|
3121
|
+
function isArrayBufferSource(value) {
|
|
3122
|
+
return isArrayBufferLike(value) || ArrayBuffer.isView(value);
|
|
3123
|
+
}
|
|
3124
|
+
let Binary;
|
|
3125
|
+
(function(_Binary) {
|
|
3126
|
+
_Binary.is = isArrayBufferLike;
|
|
3127
|
+
_Binary.isSource = isArrayBufferSource;
|
|
3128
|
+
function fromSource(source) {
|
|
3129
|
+
if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
|
|
3130
|
+
else return source;
|
|
3131
|
+
}
|
|
3132
|
+
_Binary.fromSource = fromSource;
|
|
3133
|
+
function toBase64(source) {
|
|
3134
|
+
source = fromSource(source);
|
|
3135
|
+
if (typeof Buffer !== "undefined") return Buffer.from(source).toString("base64");
|
|
3136
|
+
let binary = "";
|
|
3137
|
+
const bytes = new Uint8Array(source);
|
|
3138
|
+
for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);
|
|
3139
|
+
return btoa(binary);
|
|
3140
|
+
}
|
|
3141
|
+
_Binary.toBase64 = toBase64;
|
|
3142
|
+
function fromBase64(source) {
|
|
3143
|
+
if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "base64"));
|
|
3144
|
+
return Uint8Array.from(atob(source), (c) => c.charCodeAt(0));
|
|
3145
|
+
}
|
|
3146
|
+
_Binary.fromBase64 = fromBase64;
|
|
3147
|
+
function toHex(source) {
|
|
3148
|
+
source = fromSource(source);
|
|
3149
|
+
if (typeof Buffer !== "undefined") return Buffer.from(source).toString("hex");
|
|
3150
|
+
return Array.from(new Uint8Array(source), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
3151
|
+
}
|
|
3152
|
+
_Binary.toHex = toHex;
|
|
3153
|
+
function fromHex(source) {
|
|
3154
|
+
if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "hex"));
|
|
3155
|
+
const hex = source.length % 2 === 0 ? source : source.slice(0, source.length - 1);
|
|
3156
|
+
const buffer = [];
|
|
3157
|
+
for (let i = 0; i < hex.length; i += 2) buffer.push(parseInt(`${hex[i]}${hex[i + 1]}`, 16));
|
|
3158
|
+
return Uint8Array.from(buffer).buffer;
|
|
3159
|
+
}
|
|
3160
|
+
_Binary.fromHex = fromHex;
|
|
3161
|
+
})(Binary || (Binary = {}));
|
|
3162
|
+
Binary.fromBase64;
|
|
3163
|
+
Binary.toBase64;
|
|
3164
|
+
Binary.fromHex;
|
|
3165
|
+
Binary.toHex;
|
|
3166
|
+
/** Deep-clone common JavaScript values while preserving prototypes and cycles. */
|
|
3167
|
+
function clone(source, refs = /* @__PURE__ */ new Map()) {
|
|
3168
|
+
if (!source || typeof source !== "object") return source;
|
|
3169
|
+
if (is("Date", source)) return new Date(source.valueOf());
|
|
3170
|
+
if (is("RegExp", source)) return new RegExp(source.source, source.flags);
|
|
3171
|
+
if (isArrayBufferLike(source)) return source.slice(0);
|
|
3172
|
+
if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
|
|
3173
|
+
const cached = refs.get(source);
|
|
3174
|
+
if (cached) return cached;
|
|
3175
|
+
if (Array.isArray(source)) {
|
|
3176
|
+
const result = [];
|
|
3177
|
+
refs.set(source, result);
|
|
3178
|
+
source.forEach((value, index) => {
|
|
3179
|
+
result[index] = Reflect.apply(clone, null, [value, refs]);
|
|
3180
|
+
});
|
|
3181
|
+
return result;
|
|
3182
|
+
}
|
|
3183
|
+
const result = Object.create(Object.getPrototypeOf(source));
|
|
3184
|
+
refs.set(source, result);
|
|
3185
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
3186
|
+
const descriptor = { ...Reflect.getOwnPropertyDescriptor(source, key) };
|
|
3187
|
+
if ("value" in descriptor) descriptor.value = Reflect.apply(clone, null, [descriptor.value, refs]);
|
|
3188
|
+
Reflect.defineProperty(result, key, descriptor);
|
|
3189
|
+
}
|
|
3190
|
+
return result;
|
|
3191
|
+
}
|
|
3192
|
+
/**
|
|
3193
|
+
* Compare values recursively, treating two volatile references as equal regardless of value.
|
|
3194
|
+
* Strict comparison distinguishes null/undefined, treats opaque objects by identity,
|
|
3195
|
+
* compares URLs by normalized href, treats array holes as undefined, and considers distinct cyclic structures unequal.
|
|
3196
|
+
* @param a - first value.
|
|
3197
|
+
* @param b - second value.
|
|
3198
|
+
* @param strict - whether to require strict data equality outside volatile references.
|
|
3199
|
+
* @returns whether the values compare equal.
|
|
3200
|
+
*/
|
|
3201
|
+
function deepEqual(a, b, strict) {
|
|
3202
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
3203
|
+
function compare(a, b) {
|
|
3204
|
+
if (a === b) return true;
|
|
3205
|
+
if (isVolatile(a) || isVolatile(b)) return isVolatile(a) && isVolatile(b);
|
|
3206
|
+
if (!strict && isNullable(a) && isNullable(b)) return true;
|
|
3207
|
+
if (typeof a !== typeof b || typeof a !== "object" || !a || !b) return false;
|
|
3208
|
+
if (ancestors.has(a)) return false;
|
|
3209
|
+
function check(test, then) {
|
|
3210
|
+
return test(a) ? test(b) ? then(a, b) : false : test(b) ? false : void 0;
|
|
3211
|
+
}
|
|
3212
|
+
ancestors.add(a);
|
|
3213
|
+
try {
|
|
3214
|
+
return check(Array.isArray, (a, b) => {
|
|
3215
|
+
if (a.length !== b.length) return false;
|
|
3216
|
+
for (let index = 0; index < a.length; index++) if (!compare(a[index], b[index])) return false;
|
|
3217
|
+
return true;
|
|
3218
|
+
}) ?? check(is("Date"), (a, b) => a.valueOf() === b.valueOf()) ?? check(is("URL"), (a, b) => a.href === b.href) ?? check(is("RegExp"), (a, b) => a.source === b.source && a.flags === b.flags) ?? check(isArrayBufferLike, (a, b) => {
|
|
3219
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
3220
|
+
const viewA = new Uint8Array(a);
|
|
3221
|
+
const viewB = new Uint8Array(b);
|
|
3222
|
+
for (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;
|
|
3223
|
+
return true;
|
|
3224
|
+
}) ?? ((!strict || [a, b].every((value) => Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) && Object.keys({
|
|
3225
|
+
...a,
|
|
3226
|
+
...b
|
|
3227
|
+
}).every((key) => compare(a[key], b[key])));
|
|
3228
|
+
} finally {
|
|
3229
|
+
ancestors.delete(a);
|
|
3230
|
+
}
|
|
3231
|
+
}
|
|
3232
|
+
return compare(a, b);
|
|
3233
|
+
}
|
|
3234
|
+
//#endregion
|
|
3235
|
+
//#region ../../../vendor/cosmokit/src/time.ts
|
|
3236
|
+
let Time;
|
|
3237
|
+
(function(_Time) {
|
|
3238
|
+
_Time.millisecond = 1;
|
|
3239
|
+
const second = _Time.second = 1e3;
|
|
3240
|
+
const minute = _Time.minute = second * 60;
|
|
3241
|
+
const hour = _Time.hour = minute * 60;
|
|
3242
|
+
const day = _Time.day = hour * 24;
|
|
3243
|
+
const week = _Time.week = day * 7;
|
|
3244
|
+
let timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
3245
|
+
function setTimezoneOffset(offset) {
|
|
3246
|
+
timezoneOffset = offset;
|
|
3247
|
+
}
|
|
3248
|
+
_Time.setTimezoneOffset = setTimezoneOffset;
|
|
3249
|
+
function getTimezoneOffset() {
|
|
3250
|
+
return timezoneOffset;
|
|
3251
|
+
}
|
|
3252
|
+
_Time.getTimezoneOffset = getTimezoneOffset;
|
|
3253
|
+
function getDateNumber(date = /* @__PURE__ */ new Date(), offset) {
|
|
3254
|
+
if (typeof date === "number") date = new Date(date);
|
|
3255
|
+
if (offset === void 0) offset = timezoneOffset;
|
|
3256
|
+
return Math.floor((date.valueOf() / minute - offset) / 1440);
|
|
3257
|
+
}
|
|
3258
|
+
_Time.getDateNumber = getDateNumber;
|
|
3259
|
+
function fromDateNumber(value, offset) {
|
|
3260
|
+
const date = new Date(value * day);
|
|
3261
|
+
if (offset === void 0) offset = timezoneOffset;
|
|
3262
|
+
return new Date(+date + offset * minute);
|
|
3263
|
+
}
|
|
3264
|
+
_Time.fromDateNumber = fromDateNumber;
|
|
3265
|
+
const numeric = /\d+(?:\.\d+)?/.source;
|
|
3266
|
+
const timeRegExp = new RegExp(`^${[
|
|
3267
|
+
"w(?:eek(?:s)?)?",
|
|
3268
|
+
"d(?:ay(?:s)?)?",
|
|
3269
|
+
"h(?:our(?:s)?)?",
|
|
3270
|
+
"m(?:in(?:ute)?(?:s)?)?",
|
|
3271
|
+
"s(?:ec(?:ond)?(?:s)?)?"
|
|
3272
|
+
].map((unit) => `(${numeric}${unit})?`).join("")}$`);
|
|
3273
|
+
function parseTime(source) {
|
|
3274
|
+
const capture = timeRegExp.exec(source);
|
|
3275
|
+
if (!capture) return 0;
|
|
3276
|
+
return (parseFloat(capture[1]) * week || 0) + (parseFloat(capture[2]) * day || 0) + (parseFloat(capture[3]) * hour || 0) + (parseFloat(capture[4]) * minute || 0) + (parseFloat(capture[5]) * second || 0);
|
|
3277
|
+
}
|
|
3278
|
+
_Time.parseTime = parseTime;
|
|
3279
|
+
function parseDate(date) {
|
|
3280
|
+
const parsed = parseTime(date);
|
|
3281
|
+
if (parsed) date = Date.now() + parsed;
|
|
3282
|
+
else if (/^\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).toLocaleDateString()}-${date}`;
|
|
3283
|
+
else if (/^\d{1,2}-\d{1,2}-\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).getFullYear()}-${date}`;
|
|
3284
|
+
return date ? new Date(date) : /* @__PURE__ */ new Date();
|
|
3285
|
+
}
|
|
3286
|
+
_Time.parseDate = parseDate;
|
|
3287
|
+
function format(ms) {
|
|
3288
|
+
const abs = Math.abs(ms);
|
|
3289
|
+
if (abs >= day - hour / 2) return Math.round(ms / day) + "d";
|
|
3290
|
+
else if (abs >= hour - minute / 2) return Math.round(ms / hour) + "h";
|
|
3291
|
+
else if (abs >= minute - second / 2) return Math.round(ms / minute) + "m";
|
|
3292
|
+
else if (abs >= second) return Math.round(ms / second) + "s";
|
|
3293
|
+
return ms + "ms";
|
|
3294
|
+
}
|
|
3295
|
+
_Time.format = format;
|
|
3296
|
+
function toDigits(source, length = 2) {
|
|
3297
|
+
return source.toString().padStart(length, "0");
|
|
3298
|
+
}
|
|
3299
|
+
_Time.toDigits = toDigits;
|
|
3300
|
+
function template(template, time = /* @__PURE__ */ new Date()) {
|
|
3301
|
+
return template.replace("yyyy", time.getFullYear().toString()).replace("yy", time.getFullYear().toString().slice(2)).replace("MM", toDigits(time.getMonth() + 1)).replace("dd", toDigits(time.getDate())).replace("hh", toDigits(time.getHours())).replace("mm", toDigits(time.getMinutes())).replace("ss", toDigits(time.getSeconds())).replace("SSS", toDigits(time.getMilliseconds(), 3));
|
|
3302
|
+
}
|
|
3303
|
+
_Time.template = template;
|
|
3304
|
+
})(Time || (Time = {}));
|
|
3305
|
+
//#endregion
|
|
3306
|
+
//#region ../../../vendor/schemastery/src/index.ts
|
|
3307
|
+
const kSchema = Symbol.for("schemastery");
|
|
3308
|
+
const kValidationError = Symbol.for("ValidationError");
|
|
3309
|
+
globalThis.__schemastery_index__ ??= 0;
|
|
3310
|
+
globalThis.__schemastery_refs__ = void 0;
|
|
3311
|
+
var ValidationError = class extends TypeError {
|
|
3312
|
+
options;
|
|
3313
|
+
name = "ValidationError";
|
|
3314
|
+
constructor(message, options) {
|
|
3315
|
+
let prefix = "$";
|
|
3316
|
+
for (const segment of options.path || []) if (typeof segment === "string") prefix += "." + segment;
|
|
3317
|
+
else if (typeof segment === "number") prefix += "[" + segment + "]";
|
|
3318
|
+
else if (typeof segment === "symbol") prefix += `[Symbol(${segment.toString()})]`;
|
|
3319
|
+
if (prefix.startsWith(".")) prefix = prefix.slice(1);
|
|
3320
|
+
super((prefix === "$" ? "" : `${prefix} `) + message);
|
|
3321
|
+
this.options = options;
|
|
3322
|
+
}
|
|
3323
|
+
static is(error) {
|
|
3324
|
+
return !!error?.[kValidationError];
|
|
3325
|
+
}
|
|
3326
|
+
};
|
|
3327
|
+
Object.defineProperty(ValidationError.prototype, kValidationError, { value: true });
|
|
3328
|
+
const Schema = function(options) {
|
|
3329
|
+
const schema = function(data, options = {}) {
|
|
3330
|
+
return Schema.resolve(data, schema, options)[0];
|
|
3331
|
+
};
|
|
3332
|
+
if (options.refs) {
|
|
3333
|
+
const refs = mapValues(options.refs, (options) => new Schema(options));
|
|
3334
|
+
const getRef = (uid) => refs[uid];
|
|
3335
|
+
for (const key in refs) {
|
|
3336
|
+
const options = refs[key];
|
|
3337
|
+
options.sKey = getRef(options.sKey);
|
|
3338
|
+
options.inner = getRef(options.inner);
|
|
3339
|
+
options.list = options.list && options.list.map(getRef);
|
|
3340
|
+
options.dict = options.dict && mapValues(options.dict, getRef);
|
|
3341
|
+
}
|
|
3342
|
+
return refs[options.uid];
|
|
3343
|
+
}
|
|
3344
|
+
Object.assign(schema, options);
|
|
3345
|
+
if (typeof schema.callback === "string") try {
|
|
3346
|
+
schema.callback = new Function("return " + schema.callback)();
|
|
3347
|
+
} catch {}
|
|
3348
|
+
Object.defineProperty(schema, "uid", { value: globalThis.__schemastery_index__++ });
|
|
3349
|
+
Object.setPrototypeOf(schema, Schema.prototype);
|
|
3350
|
+
schema.meta ||= {};
|
|
3351
|
+
schema.toString = schema.toString.bind(schema);
|
|
3352
|
+
return schema;
|
|
3353
|
+
};
|
|
3354
|
+
Schema.prototype = Object.create(Function.prototype);
|
|
3355
|
+
Schema.prototype[kSchema] = true;
|
|
3356
|
+
Object.defineProperty(Schema.prototype, "~standard", { get() {
|
|
3357
|
+
return {
|
|
3358
|
+
version: 1,
|
|
3359
|
+
vendor: "schemastery",
|
|
3360
|
+
validate: (value) => {
|
|
3361
|
+
try {
|
|
3362
|
+
return { value: Schema.resolve(value, this, {})[0] };
|
|
3363
|
+
} catch (error) {
|
|
3364
|
+
if (ValidationError.is(error)) return { issues: [{
|
|
3365
|
+
message: error.message,
|
|
3366
|
+
path: error.options.path
|
|
3367
|
+
}] };
|
|
3368
|
+
throw error;
|
|
3369
|
+
}
|
|
3370
|
+
}
|
|
3371
|
+
};
|
|
3372
|
+
} });
|
|
3373
|
+
Schema.ValidationError = ValidationError;
|
|
3374
|
+
Schema.prototype.toJSON = function toJSON() {
|
|
3375
|
+
if (globalThis.__schemastery_refs__) {
|
|
3376
|
+
globalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }));
|
|
3377
|
+
return this.uid;
|
|
3378
|
+
}
|
|
3379
|
+
globalThis.__schemastery_refs__ = { [this.uid]: { ...this } };
|
|
3380
|
+
globalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }));
|
|
3381
|
+
const result = {
|
|
3382
|
+
uid: this.uid,
|
|
3383
|
+
refs: globalThis.__schemastery_refs__
|
|
3384
|
+
};
|
|
3385
|
+
globalThis.__schemastery_refs__ = void 0;
|
|
3386
|
+
return result;
|
|
3387
|
+
};
|
|
3388
|
+
Schema.prototype.set = function set(key, value) {
|
|
3389
|
+
this.dict[key] = value;
|
|
3390
|
+
return this;
|
|
3391
|
+
};
|
|
3392
|
+
Schema.prototype.push = function push(value) {
|
|
3393
|
+
this.list.push(value);
|
|
3394
|
+
return this;
|
|
3395
|
+
};
|
|
3396
|
+
function mergeDesc(original, messages) {
|
|
3397
|
+
const result = typeof original === "string" ? { "": original } : { ...original };
|
|
3398
|
+
for (const locale in messages) {
|
|
3399
|
+
const value = messages[locale];
|
|
3400
|
+
if (value?.$description || value?.$desc) result[locale] = value.$description || value.$desc;
|
|
3401
|
+
else if (typeof value === "string") result[locale] = value;
|
|
3402
|
+
}
|
|
3403
|
+
return result;
|
|
3404
|
+
}
|
|
3405
|
+
function getInner(value) {
|
|
3406
|
+
return value?.$value ?? value?.$inner;
|
|
3407
|
+
}
|
|
3408
|
+
function extractKeys(data) {
|
|
3409
|
+
return filterKeys(data ?? {}, (key) => !key.startsWith("$"));
|
|
3410
|
+
}
|
|
3411
|
+
Schema.prototype.i18n = function i18n(messages) {
|
|
3412
|
+
const schema = Schema(this);
|
|
3413
|
+
const desc = mergeDesc(schema.meta.description, messages);
|
|
3414
|
+
if (Object.keys(desc).length) schema.meta.description = desc;
|
|
3415
|
+
if (schema.dict) schema.dict = mapValues(schema.dict, (inner, key) => {
|
|
3416
|
+
return inner.i18n(mapValues(messages, (data) => getInner(data)?.[key] ?? data?.[key]));
|
|
3417
|
+
});
|
|
3418
|
+
if (schema.list) schema.list = schema.list.map((inner, index) => {
|
|
3419
|
+
return inner.i18n(mapValues(messages, (data = {}) => {
|
|
3420
|
+
if (Array.isArray(getInner(data))) return getInner(data)[index];
|
|
3421
|
+
if (Array.isArray(data)) return data[index];
|
|
3422
|
+
return extractKeys(data);
|
|
3423
|
+
}));
|
|
3424
|
+
});
|
|
3425
|
+
if (schema.inner) schema.inner = schema.inner.i18n(mapValues(messages, (data) => {
|
|
3426
|
+
if (getInner(data)) return getInner(data);
|
|
3427
|
+
return extractKeys(data);
|
|
3428
|
+
}));
|
|
3429
|
+
if (schema.sKey) schema.sKey = schema.sKey.i18n(mapValues(messages, (data) => data?.$key));
|
|
3430
|
+
return schema;
|
|
3431
|
+
};
|
|
3432
|
+
Schema.prototype.extra = function extra(key, value) {
|
|
3433
|
+
const schema = Schema(this);
|
|
3434
|
+
schema.meta = {
|
|
3435
|
+
...schema.meta,
|
|
3436
|
+
[key]: value
|
|
3437
|
+
};
|
|
3438
|
+
return schema;
|
|
3439
|
+
};
|
|
3440
|
+
for (const key of [
|
|
3441
|
+
"required",
|
|
3442
|
+
"disabled",
|
|
3443
|
+
"collapse",
|
|
3444
|
+
"hidden",
|
|
3445
|
+
"loose"
|
|
3446
|
+
]) Object.assign(Schema.prototype, { [key](value = true) {
|
|
3447
|
+
const schema = Schema(this);
|
|
3448
|
+
schema.meta = {
|
|
3449
|
+
...schema.meta,
|
|
3450
|
+
[key]: value
|
|
3451
|
+
};
|
|
3452
|
+
return schema;
|
|
3453
|
+
} });
|
|
3454
|
+
Schema.prototype.deprecated = function deprecated() {
|
|
3455
|
+
const schema = Schema(this);
|
|
3456
|
+
schema.meta.badges ||= [];
|
|
3457
|
+
schema.meta.badges.push({
|
|
3458
|
+
text: "deprecated",
|
|
3459
|
+
type: "danger"
|
|
3460
|
+
});
|
|
3461
|
+
return schema;
|
|
3462
|
+
};
|
|
3463
|
+
Schema.prototype.experimental = function experimental() {
|
|
3464
|
+
const schema = Schema(this);
|
|
3465
|
+
schema.meta.badges ||= [];
|
|
3466
|
+
schema.meta.badges.push({
|
|
3467
|
+
text: "experimental",
|
|
3468
|
+
type: "warning"
|
|
3469
|
+
});
|
|
3470
|
+
return schema;
|
|
3471
|
+
};
|
|
3472
|
+
Schema.prototype.pattern = function pattern(regexp) {
|
|
3473
|
+
const schema = Schema(this);
|
|
3474
|
+
const pattern = pick(regexp, ["source", "flags"]);
|
|
3475
|
+
schema.meta = {
|
|
3476
|
+
...schema.meta,
|
|
3477
|
+
pattern
|
|
3478
|
+
};
|
|
3479
|
+
return schema;
|
|
3480
|
+
};
|
|
3481
|
+
Schema.prototype.simplify = function simplify(value) {
|
|
3482
|
+
if (isVolatile(value)) value = value.get();
|
|
3483
|
+
if (deepEqual(value, this.meta.default, this.type === "dict")) return null;
|
|
3484
|
+
if (isNullable(value)) return value;
|
|
3485
|
+
if (this.type === "object" || this.type === "dict") {
|
|
3486
|
+
const result = {};
|
|
3487
|
+
for (const key in value) {
|
|
3488
|
+
const item = (this.type === "object" ? this.dict[key] : this.inner)?.simplify(value[key]);
|
|
3489
|
+
if (this.type === "dict" || !isNullable(item)) result[key] = item;
|
|
3490
|
+
}
|
|
3491
|
+
if (deepEqual(result, this.meta.default, this.type === "dict")) return null;
|
|
3492
|
+
return result;
|
|
3493
|
+
} else if (this.type === "array" || this.type === "tuple") {
|
|
3494
|
+
const result = [];
|
|
3495
|
+
value.forEach((value, index) => {
|
|
3496
|
+
const schema = this.type === "array" ? this.inner : this.list[index];
|
|
3497
|
+
const item = schema ? schema.simplify(value) : value;
|
|
3498
|
+
result.push(item);
|
|
3499
|
+
});
|
|
3500
|
+
return result;
|
|
3501
|
+
} else if (this.type === "intersect") {
|
|
3502
|
+
const result = {};
|
|
3503
|
+
for (const item of this.list) Object.assign(result, item.simplify(value));
|
|
3504
|
+
return result;
|
|
3505
|
+
} else if (this.type === "union") for (const schema of this.list) try {
|
|
3506
|
+
Schema.resolve(value, schema, {});
|
|
3507
|
+
return schema.simplify(value);
|
|
3508
|
+
} catch {}
|
|
3509
|
+
return value;
|
|
3510
|
+
};
|
|
3511
|
+
Schema.prototype.toString = function toString(inline) {
|
|
3512
|
+
return formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`;
|
|
3513
|
+
};
|
|
3514
|
+
Schema.prototype.role = function role(role, extra) {
|
|
3515
|
+
const schema = Schema(this);
|
|
3516
|
+
schema.meta = {
|
|
3517
|
+
...schema.meta,
|
|
3518
|
+
role,
|
|
3519
|
+
extra
|
|
3520
|
+
};
|
|
3521
|
+
return schema;
|
|
3522
|
+
};
|
|
3523
|
+
for (const key of [
|
|
3524
|
+
"default",
|
|
3525
|
+
"link",
|
|
3526
|
+
"comment",
|
|
3527
|
+
"description",
|
|
3528
|
+
"max",
|
|
3529
|
+
"min",
|
|
3530
|
+
"step"
|
|
3531
|
+
]) Object.assign(Schema.prototype, { [key](value) {
|
|
3532
|
+
const schema = Schema(this);
|
|
3533
|
+
schema.meta = {
|
|
3534
|
+
...schema.meta,
|
|
3535
|
+
[key]: value
|
|
3536
|
+
};
|
|
3537
|
+
return schema;
|
|
3538
|
+
} });
|
|
3539
|
+
Schema.prototype.volatile = function volatile() {
|
|
3540
|
+
if (this.meta.volatile) throw new TypeError("volatile schema is already wrapped");
|
|
3541
|
+
return this.extra("volatile", true);
|
|
3542
|
+
};
|
|
3543
|
+
const resolvers = {};
|
|
3544
|
+
const checkedVolatile = Symbol("checked-volatile-schema");
|
|
3545
|
+
function validateVolatileSchema(schema, path = [], blocked = false, seen = /* @__PURE__ */ new Map()) {
|
|
3546
|
+
const states = seen.get(schema) ?? /* @__PURE__ */ new Set();
|
|
3547
|
+
if (states.has(blocked)) return;
|
|
3548
|
+
states.add(blocked);
|
|
3549
|
+
seen.set(schema, states);
|
|
3550
|
+
if (schema.meta?.volatile && blocked) throw new ValidationError("volatile fields require a fixed object path without an enclosing volatile field", { path });
|
|
3551
|
+
const nested = blocked || !!schema.meta?.volatile;
|
|
3552
|
+
if (schema.dict) for (const [key, child] of Object.entries(schema.dict)) validateVolatileSchema(child, [...path, key], nested, seen);
|
|
3553
|
+
if (schema.sKey) validateVolatileSchema(schema.sKey, [...path, "<key>"], true, seen);
|
|
3554
|
+
if (schema.inner && (schema.type !== "lazy" || schema.inner[kSchema])) validateVolatileSchema(schema.inner, [...path, "*"], true, seen);
|
|
3555
|
+
if (schema.list) for (let index = 0; index < schema.list.length; index++) validateVolatileSchema(schema.list[index], [...path, String(index)], true, seen);
|
|
3556
|
+
}
|
|
3557
|
+
Schema.extend = function extend(type, resolve) {
|
|
3558
|
+
resolvers[type] = resolve;
|
|
3559
|
+
};
|
|
3560
|
+
Schema.resolve = function resolve(data, schema, options = {}, strict = false) {
|
|
3561
|
+
if (!schema) return [data];
|
|
3562
|
+
if (!options[checkedVolatile]) {
|
|
3563
|
+
validateVolatileSchema(schema, options.path);
|
|
3564
|
+
options = {
|
|
3565
|
+
...options,
|
|
3566
|
+
[checkedVolatile]: true
|
|
3567
|
+
};
|
|
3568
|
+
}
|
|
3569
|
+
if (schema.meta?.volatile) {
|
|
3570
|
+
const inner = Schema(schema);
|
|
3571
|
+
inner.meta = {
|
|
3572
|
+
...schema.meta,
|
|
3573
|
+
volatile: false
|
|
3574
|
+
};
|
|
3575
|
+
const [value, adapted] = Schema.resolve(data, inner, options, strict);
|
|
3576
|
+
try {
|
|
3577
|
+
return [createVolatile(value), adapted];
|
|
3578
|
+
} catch (error) {
|
|
3579
|
+
throw new ValidationError(error instanceof Error ? error.message : String(error), options);
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
if (options.ignore?.(data, schema)) return [data];
|
|
3583
|
+
if (isNullable(data) && schema.type !== "lazy") {
|
|
3584
|
+
if (schema.meta.required) throw new ValidationError(`missing required value`, options);
|
|
3585
|
+
let current = schema;
|
|
3586
|
+
let fallback = schema.meta.default;
|
|
3587
|
+
while (current?.type === "intersect" && isNullable(fallback)) {
|
|
3588
|
+
current = current.list[0];
|
|
3589
|
+
fallback = current?.meta.default;
|
|
3590
|
+
}
|
|
3591
|
+
if (isNullable(fallback)) return [data];
|
|
3592
|
+
data = clone(fallback);
|
|
3593
|
+
}
|
|
3594
|
+
const callback = resolvers[schema.type];
|
|
3595
|
+
if (!callback) throw new ValidationError(`unsupported type "${schema.type}"`, options);
|
|
3596
|
+
try {
|
|
3597
|
+
return callback(data, schema, options, strict);
|
|
3598
|
+
} catch (error) {
|
|
3599
|
+
if (!schema.meta.loose) throw error;
|
|
3600
|
+
return [schema.meta.default];
|
|
3601
|
+
}
|
|
3602
|
+
};
|
|
3603
|
+
Schema.from = function from(source) {
|
|
3604
|
+
if (isNullable(source)) return Schema.any();
|
|
3605
|
+
else if ([
|
|
3606
|
+
"string",
|
|
3607
|
+
"number",
|
|
3608
|
+
"boolean"
|
|
3609
|
+
].includes(typeof source)) return Schema.const(source).required();
|
|
3610
|
+
else if (source[kSchema]) return source;
|
|
3611
|
+
else if (typeof source === "function") switch (source) {
|
|
3612
|
+
case String: return Schema.string().required();
|
|
3613
|
+
case Number: return Schema.number().required();
|
|
3614
|
+
case Boolean: return Schema.boolean().required();
|
|
3615
|
+
case Function: return Schema.function().required();
|
|
3616
|
+
default: return Schema.is(source).required();
|
|
3617
|
+
}
|
|
3618
|
+
else throw new TypeError(`cannot infer schema from ${source}`);
|
|
3619
|
+
};
|
|
3620
|
+
Schema.lazy = function lazy(builder) {
|
|
3621
|
+
const toJSON = () => {
|
|
3622
|
+
if (!schema.inner[kSchema]) {
|
|
3623
|
+
schema.inner = schema.builder();
|
|
3624
|
+
schema.inner.meta = {
|
|
3625
|
+
...schema.meta,
|
|
3626
|
+
...schema.inner.meta
|
|
3627
|
+
};
|
|
3628
|
+
}
|
|
3629
|
+
return schema.inner.toJSON();
|
|
3630
|
+
};
|
|
3631
|
+
const schema = new Schema({
|
|
3632
|
+
type: "lazy",
|
|
3633
|
+
builder,
|
|
3634
|
+
inner: { toJSON }
|
|
3635
|
+
});
|
|
3636
|
+
return schema;
|
|
3637
|
+
};
|
|
3638
|
+
Schema.natural = function natural() {
|
|
3639
|
+
return Schema.number().step(1).min(0);
|
|
3640
|
+
};
|
|
3641
|
+
Schema.percent = function percent() {
|
|
3642
|
+
return Schema.number().step(.01).min(0).max(1).role("slider");
|
|
3643
|
+
};
|
|
3644
|
+
Schema.date = function date() {
|
|
3645
|
+
return Schema.union([Schema.is(Date), Schema.transform(Schema.string().role("datetime"), (value, options) => {
|
|
3646
|
+
const date = new Date(value);
|
|
3647
|
+
if (isNaN(+date)) throw new ValidationError(`invalid date "${value}"`, options);
|
|
3648
|
+
return date;
|
|
3649
|
+
}, true)]);
|
|
3650
|
+
};
|
|
3651
|
+
Schema.regExp = function regExp(flag = "") {
|
|
3652
|
+
return Schema.union([Schema.is(RegExp), Schema.transform(Schema.string().role("regexp", { flag }), (value, options) => {
|
|
3653
|
+
try {
|
|
3654
|
+
return new RegExp(value, flag);
|
|
3655
|
+
} catch (e) {
|
|
3656
|
+
throw new ValidationError(e.message, options);
|
|
3657
|
+
}
|
|
3658
|
+
}, true)]);
|
|
3659
|
+
};
|
|
3660
|
+
Schema.arrayBuffer = function arrayBuffer(encoding) {
|
|
3661
|
+
return Schema.union([
|
|
3662
|
+
Schema.is(ArrayBuffer),
|
|
3663
|
+
Schema.is(SharedArrayBuffer),
|
|
3664
|
+
Schema.transform(Schema.any(), (value, options) => {
|
|
3665
|
+
if (Binary.isSource(value)) return Binary.fromSource(value);
|
|
3666
|
+
throw new ValidationError(`expected ArrayBufferSource but got ${value}`, options);
|
|
3667
|
+
}, true),
|
|
3668
|
+
...encoding ? [Schema.transform(Schema.string(), (value, options) => {
|
|
3669
|
+
try {
|
|
3670
|
+
return encoding === "base64" ? Binary.fromBase64(value) : Binary.fromHex(value);
|
|
3671
|
+
} catch (e) {
|
|
3672
|
+
throw new ValidationError(e.message, options);
|
|
3673
|
+
}
|
|
3674
|
+
}, true)] : []
|
|
3675
|
+
]);
|
|
3676
|
+
};
|
|
3677
|
+
Schema.extend("lazy", (data, schema, options, strict) => {
|
|
3678
|
+
if (!schema.inner[kSchema]) {
|
|
3679
|
+
schema.inner = schema.builder();
|
|
3680
|
+
schema.inner.meta = {
|
|
3681
|
+
...schema.meta,
|
|
3682
|
+
...schema.inner.meta
|
|
3683
|
+
};
|
|
3684
|
+
validateVolatileSchema(schema.inner, options.path, true);
|
|
3685
|
+
}
|
|
3686
|
+
return Schema.resolve(data, schema.inner, options, strict);
|
|
3687
|
+
});
|
|
3688
|
+
Schema.extend("any", (data) => {
|
|
3689
|
+
return [data];
|
|
3690
|
+
});
|
|
3691
|
+
Schema.extend("never", (data, _, options) => {
|
|
3692
|
+
throw new ValidationError(`expected nullable but got ${data}`, options);
|
|
3693
|
+
});
|
|
3694
|
+
Schema.extend("const", (data, { value }, options) => {
|
|
3695
|
+
if (deepEqual(data, value)) return [value];
|
|
3696
|
+
throw new ValidationError(`expected ${value} but got ${data}`, options);
|
|
3697
|
+
});
|
|
3698
|
+
function checkWithinRange(data, meta, description, options, skipMin = false) {
|
|
3699
|
+
const { max = Infinity, min = -Infinity } = meta;
|
|
3700
|
+
if (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options);
|
|
3701
|
+
if (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options);
|
|
3702
|
+
}
|
|
3703
|
+
Schema.extend("string", (data, { meta }, options) => {
|
|
3704
|
+
if (typeof data !== "string") throw new ValidationError(`expected string but got ${data}`, options);
|
|
3705
|
+
if (meta.pattern) {
|
|
3706
|
+
const regexp = new RegExp(meta.pattern.source, meta.pattern.flags);
|
|
3707
|
+
if (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options);
|
|
3708
|
+
}
|
|
3709
|
+
checkWithinRange(data.length, meta, "string length", options);
|
|
3710
|
+
return [data];
|
|
3711
|
+
});
|
|
3712
|
+
function decimalShift(data, digits) {
|
|
3713
|
+
const str = data.toString();
|
|
3714
|
+
if (str.includes("e")) return data * Math.pow(10, digits);
|
|
3715
|
+
const index = str.indexOf(".");
|
|
3716
|
+
if (index === -1) return data * Math.pow(10, digits);
|
|
3717
|
+
const frac = str.slice(index + 1);
|
|
3718
|
+
const integer = str.slice(0, index);
|
|
3719
|
+
if (frac.length <= digits) return +(integer + frac.padEnd(digits, "0"));
|
|
3720
|
+
return +(integer + frac.slice(0, digits) + "." + frac.slice(digits));
|
|
3721
|
+
}
|
|
3722
|
+
function isMultipleOf(data, min, step) {
|
|
3723
|
+
step = Math.abs(step);
|
|
3724
|
+
if (!/^\d+\.\d+$/.test(step.toString())) return (data - min) % step === 0;
|
|
3725
|
+
const index = step.toString().indexOf(".");
|
|
3726
|
+
const digits = step.toString().slice(index + 1).length;
|
|
3727
|
+
return Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0;
|
|
3728
|
+
}
|
|
3729
|
+
Schema.extend("number", (data, { meta }, options) => {
|
|
3730
|
+
if (typeof data !== "number") throw new ValidationError(`expected number but got ${data}`, options);
|
|
3731
|
+
checkWithinRange(data, meta, "number", options);
|
|
3732
|
+
const { step } = meta;
|
|
3733
|
+
if (step && !isMultipleOf(data, meta.min ?? 0, step)) throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options);
|
|
3734
|
+
return [data];
|
|
3735
|
+
});
|
|
3736
|
+
Schema.extend("boolean", (data, _, options) => {
|
|
3737
|
+
if (typeof data === "boolean") return [data];
|
|
3738
|
+
throw new ValidationError(`expected boolean but got ${data}`, options);
|
|
3739
|
+
});
|
|
3740
|
+
Schema.extend("bitset", (data, { bits, meta }, options) => {
|
|
3741
|
+
let value = 0, keys = [];
|
|
3742
|
+
if (typeof data === "number") {
|
|
3743
|
+
value = data;
|
|
3744
|
+
for (const key in bits) if (data & bits[key]) keys.push(key);
|
|
3745
|
+
} else if (Array.isArray(data)) {
|
|
3746
|
+
keys = data;
|
|
3747
|
+
for (const key of keys) {
|
|
3748
|
+
if (typeof key !== "string") throw new ValidationError(`expected string but got ${key}`, options);
|
|
3749
|
+
if (key in bits) value |= bits[key];
|
|
3750
|
+
}
|
|
3751
|
+
} else throw new ValidationError(`expected number or array but got ${data}`, options);
|
|
3752
|
+
if (value === meta.default) return [value];
|
|
3753
|
+
return [value, keys];
|
|
3754
|
+
});
|
|
3755
|
+
Schema.extend("function", (data, _, options) => {
|
|
3756
|
+
if (typeof data === "function") return [data];
|
|
3757
|
+
throw new ValidationError(`expected function but got ${data}`, options);
|
|
3758
|
+
});
|
|
3759
|
+
Schema.extend("is", (data, { constructor }, options) => {
|
|
3760
|
+
if (typeof constructor === "function") {
|
|
3761
|
+
if (data instanceof constructor) return [data];
|
|
3762
|
+
throw new ValidationError(`expected ${constructor.name} but got ${data}`, options);
|
|
3763
|
+
} else {
|
|
3764
|
+
if (isNullable(data)) throw new ValidationError(`expected ${constructor} but got ${data}`, options);
|
|
3765
|
+
let prototype = Object.getPrototypeOf(data);
|
|
3766
|
+
while (prototype) {
|
|
3767
|
+
if (prototype.constructor?.name === constructor) return [data];
|
|
3768
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
3769
|
+
}
|
|
3770
|
+
throw new ValidationError(`expected ${constructor} but got ${data}`, options);
|
|
3771
|
+
}
|
|
3772
|
+
});
|
|
3773
|
+
function property(data, key, schema, options) {
|
|
3774
|
+
try {
|
|
3775
|
+
const [value, adapted] = Schema.resolve(data[key], schema, {
|
|
3776
|
+
...options,
|
|
3777
|
+
path: [...options.path || [], key]
|
|
3778
|
+
});
|
|
3779
|
+
if (adapted !== void 0) data[key] = adapted;
|
|
3780
|
+
return value;
|
|
3781
|
+
} catch (e) {
|
|
3782
|
+
if (!options?.autofix) throw e;
|
|
3783
|
+
delete data[key];
|
|
3784
|
+
return schema.meta.volatile ? createVolatile(schema.meta.default) : schema.meta.default;
|
|
3785
|
+
}
|
|
3786
|
+
}
|
|
3787
|
+
Schema.extend("array", (data, { inner, meta }, options) => {
|
|
3788
|
+
if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
|
|
3789
|
+
checkWithinRange(data.length, meta, "array length", options, !isNullable(inner.meta.default));
|
|
3790
|
+
return [data.map((_, index) => property(data, index, inner, options))];
|
|
3791
|
+
});
|
|
3792
|
+
Schema.extend("dict", (data, { inner, sKey }, options, strict) => {
|
|
3793
|
+
if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);
|
|
3794
|
+
const result = {};
|
|
3795
|
+
for (const key in data) {
|
|
3796
|
+
let rKey;
|
|
3797
|
+
try {
|
|
3798
|
+
rKey = Schema.resolve(key, sKey, options)[0];
|
|
3799
|
+
} catch (error) {
|
|
3800
|
+
if (strict) continue;
|
|
3801
|
+
throw error;
|
|
3802
|
+
}
|
|
3803
|
+
result[rKey] = property(data, key, inner, options);
|
|
3804
|
+
data[rKey] = data[key];
|
|
3805
|
+
if (key !== rKey) delete data[key];
|
|
3806
|
+
}
|
|
3807
|
+
return [result];
|
|
3808
|
+
});
|
|
3809
|
+
Schema.extend("tuple", (data, { list }, options, strict) => {
|
|
3810
|
+
if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
|
|
3811
|
+
const result = list.map((inner, index) => property(data, index, inner, options));
|
|
3812
|
+
if (strict) return [result];
|
|
3813
|
+
result.push(...data.slice(list.length));
|
|
3814
|
+
return [result];
|
|
3815
|
+
});
|
|
3816
|
+
function merge(result, data) {
|
|
3817
|
+
for (const key in data) {
|
|
3818
|
+
if (key in result) continue;
|
|
3819
|
+
result[key] = data[key];
|
|
3820
|
+
}
|
|
3821
|
+
}
|
|
3822
|
+
Schema.extend("object", (data, { dict }, options, strict) => {
|
|
3823
|
+
if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);
|
|
3824
|
+
const result = {};
|
|
3825
|
+
for (const key in dict) {
|
|
3826
|
+
const value = property(data, key, dict[key], options);
|
|
3827
|
+
if (!isNullable(value) || key in data) result[key] = value;
|
|
3828
|
+
}
|
|
3829
|
+
if (!strict) merge(result, data);
|
|
3830
|
+
return [result];
|
|
3831
|
+
});
|
|
3832
|
+
Schema.extend("union", (data, { list, toString }, options, strict) => {
|
|
3833
|
+
const messages = [];
|
|
3834
|
+
for (const inner of list) try {
|
|
3835
|
+
return Schema.resolve(data, inner, options, strict);
|
|
3836
|
+
} catch (error) {
|
|
3837
|
+
messages.push(error);
|
|
3838
|
+
}
|
|
3839
|
+
throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
|
|
3840
|
+
});
|
|
3841
|
+
Schema.extend("intersect", (data, { list, toString }, options, strict) => {
|
|
3842
|
+
if (!list.length) return [data];
|
|
3843
|
+
let result;
|
|
3844
|
+
for (const inner of list) {
|
|
3845
|
+
const value = Schema.resolve(data, inner, options, true)[0];
|
|
3846
|
+
if (isNullable(value)) continue;
|
|
3847
|
+
if (isNullable(result)) result = value;
|
|
3848
|
+
else if (typeof result !== typeof value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
|
|
3849
|
+
else if (typeof value === "object") merge(result ??= {}, value);
|
|
3850
|
+
else if (result !== value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
|
|
3851
|
+
}
|
|
3852
|
+
if (!strict && isPlainObject(data)) merge(result, data);
|
|
3853
|
+
return [result];
|
|
3854
|
+
});
|
|
3855
|
+
Schema.extend("transform", (data, { inner, callback, preserve }, options) => {
|
|
3856
|
+
const [result, adapted = data] = Schema.resolve(data, inner, options, true);
|
|
3857
|
+
if (preserve) return [callback(result)];
|
|
3858
|
+
else return [callback(result), callback(adapted)];
|
|
3859
|
+
});
|
|
3860
|
+
const formatters = {};
|
|
3861
|
+
function defineMethod(name, keys, format) {
|
|
3862
|
+
formatters[name] = format;
|
|
3863
|
+
Object.assign(Schema, { [name](...args) {
|
|
3864
|
+
const schema = new Schema({ type: name });
|
|
3865
|
+
keys.forEach((key, index) => {
|
|
3866
|
+
switch (key) {
|
|
3867
|
+
case "sKey":
|
|
3868
|
+
schema.sKey = args[index] ?? Schema.string();
|
|
3869
|
+
break;
|
|
3870
|
+
case "inner":
|
|
3871
|
+
schema.inner = Schema.from(args[index]);
|
|
3872
|
+
break;
|
|
3873
|
+
case "list":
|
|
3874
|
+
schema.list = args[index].map(Schema.from);
|
|
3875
|
+
break;
|
|
3876
|
+
case "dict":
|
|
3877
|
+
schema.dict = mapValues(args[index], Schema.from);
|
|
3878
|
+
break;
|
|
3879
|
+
case "bits":
|
|
3880
|
+
schema.bits = {};
|
|
3881
|
+
for (const key in args[index]) {
|
|
3882
|
+
if (typeof args[index][key] !== "number") continue;
|
|
3883
|
+
schema.bits[key] = args[index][key];
|
|
3884
|
+
}
|
|
3885
|
+
break;
|
|
3886
|
+
case "callback": {
|
|
3887
|
+
const callback = schema.callback = args[index];
|
|
3888
|
+
callback["toJSON"] ||= () => callback.toString();
|
|
3889
|
+
break;
|
|
3890
|
+
}
|
|
3891
|
+
case "constructor": {
|
|
3892
|
+
const constructor = schema.constructor = args[index];
|
|
3893
|
+
if (typeof constructor === "function") constructor["toJSON"] ||= () => constructor["name"];
|
|
3894
|
+
break;
|
|
3895
|
+
}
|
|
3896
|
+
default: schema[key] = args[index];
|
|
3897
|
+
}
|
|
3898
|
+
});
|
|
3899
|
+
if (name === "object" || name === "dict") schema.meta.default = {};
|
|
3900
|
+
else if (name === "array" || name === "tuple") schema.meta.default = [];
|
|
3901
|
+
else if (name === "bitset") schema.meta.default = 0;
|
|
3902
|
+
return schema;
|
|
3903
|
+
} });
|
|
3904
|
+
}
|
|
3905
|
+
defineMethod("is", ["constructor"], ({ constructor }) => {
|
|
3906
|
+
if (typeof constructor === "function") return constructor.name;
|
|
3907
|
+
else return constructor;
|
|
3908
|
+
});
|
|
3909
|
+
defineMethod("any", [], () => "any");
|
|
3910
|
+
defineMethod("never", [], () => "never");
|
|
3911
|
+
defineMethod("const", ["value"], ({ value }) => typeof value === "string" ? JSON.stringify(value) : value);
|
|
3912
|
+
defineMethod("string", [], () => "string");
|
|
3913
|
+
defineMethod("number", [], () => "number");
|
|
3914
|
+
defineMethod("boolean", [], () => "boolean");
|
|
3915
|
+
defineMethod("bitset", ["bits"], () => "bitset");
|
|
3916
|
+
defineMethod("function", [], () => "function");
|
|
3917
|
+
defineMethod("array", ["inner"], ({ inner }) => `${inner.toString(true)}[]`);
|
|
3918
|
+
defineMethod("dict", ["inner", "sKey"], ({ inner, sKey }) => `{ [key: ${sKey.toString()}]: ${inner.toString()} }`);
|
|
3919
|
+
defineMethod("tuple", ["list"], ({ list }) => `[${list.map((inner) => inner.toString()).join(", ")}]`);
|
|
3920
|
+
defineMethod("object", ["dict"], ({ dict }) => {
|
|
3921
|
+
if (Object.keys(dict).length === 0) return "{}";
|
|
3922
|
+
return `{ ${Object.entries(dict).map(([key, inner]) => {
|
|
3923
|
+
return `${key}${inner.meta.required ? "" : "?"}: ${inner.toString()}`;
|
|
3924
|
+
}).join(", ")} }`;
|
|
3925
|
+
});
|
|
3926
|
+
defineMethod("union", ["list"], ({ list }, inline) => {
|
|
3927
|
+
const result = list.map(({ toString: format }) => format()).join(" | ");
|
|
3928
|
+
return inline ? `(${result})` : result;
|
|
3929
|
+
});
|
|
3930
|
+
defineMethod("intersect", ["list"], ({ list }) => {
|
|
3931
|
+
return `${list.map((inner) => inner.toString(true)).join(" & ")}`;
|
|
3932
|
+
});
|
|
3933
|
+
defineMethod("transform", [
|
|
3934
|
+
"inner",
|
|
3935
|
+
"callback",
|
|
3936
|
+
"preserve"
|
|
3937
|
+
], ({ inner }, isInner) => inner.toString(isInner));
|
|
3938
|
+
//#endregion
|
|
3939
|
+
//#region lib/types/onboarding-config.js
|
|
3940
|
+
/** Public page-bootstrap options shared by the Host and Client halves. */
|
|
3941
|
+
/** Validate Host configuration and its public page-bootstrap payload. */
|
|
3942
|
+
const Config = Schema.object({ credentialOnboarding: Schema.boolean().default(true) });
|
|
3943
|
+
/** Page-global key carrying only the public onboarding options. */
|
|
3944
|
+
const ONBOARDING_CONFIG_GLOBAL = "__DSH_MODELS_ONBOARDING__";
|
|
3945
|
+
//#endregion
|
|
2884
3946
|
//#region lib/types/client/index.js
|
|
2885
3947
|
/** Dictionary namespace owned by this plugin. */
|
|
2886
3948
|
const NS = "settings.models";
|
|
@@ -2905,7 +3967,7 @@ window.__ModuleLoader__.load({
|
|
|
2905
3967
|
"remote.credentials",
|
|
2906
3968
|
"remote.llm",
|
|
2907
3969
|
"remote.settings",
|
|
2908
|
-
"
|
|
3970
|
+
"configForms",
|
|
2909
3971
|
"settingsSchema"
|
|
2910
3972
|
];
|
|
2911
3973
|
/**
|
|
@@ -2915,13 +3977,15 @@ window.__ModuleLoader__.load({
|
|
|
2915
3977
|
* @param ctx - client root context.
|
|
2916
3978
|
*/
|
|
2917
3979
|
function apply(ctx) {
|
|
3980
|
+
const payload = globalThis[ONBOARDING_CONFIG_GLOBAL];
|
|
3981
|
+
const credentialOnboarding = Config(payload === void 0 ? {} : payload).credentialOnboarding && !("dshDesktop" in globalThis);
|
|
2918
3982
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
2919
3983
|
zh,
|
|
2920
3984
|
en
|
|
2921
3985
|
}), "ui-settings-models: copy dictionaries");
|
|
2922
3986
|
const schema = createSettingsSchemaOperations(ctx.settingsSchema);
|
|
2923
3987
|
const operations = createModelsOperations(ctx);
|
|
2924
|
-
const controller = new ModelsSettingsStore(ctx, schema, ctx.
|
|
3988
|
+
const controller = new ModelsSettingsStore(ctx, schema, ctx.configForms.describe());
|
|
2925
3989
|
const t = ctx.locale.bind(NS);
|
|
2926
3990
|
const injected = () => ({
|
|
2927
3991
|
controller,
|
|
@@ -2931,16 +3995,14 @@ window.__ModuleLoader__.load({
|
|
|
2931
3995
|
t
|
|
2932
3996
|
});
|
|
2933
3997
|
const deepSeekOnboardingInjected = () => ({
|
|
3998
|
+
automatic: credentialOnboarding,
|
|
2934
3999
|
controller,
|
|
2935
4000
|
hooks: { models: controller.store },
|
|
2936
4001
|
operations,
|
|
2937
4002
|
schema,
|
|
2938
4003
|
t
|
|
2939
4004
|
});
|
|
2940
|
-
const welcomeController = new WelcomeNoticeStore(ctx.
|
|
2941
|
-
namespace: WELCOME_NOTICE_SETTINGS_NAMESPACE,
|
|
2942
|
-
decode: decodeWelcomeSection
|
|
2943
|
-
}));
|
|
4005
|
+
const welcomeController = new WelcomeNoticeStore(ctx.configForms.get(WELCOME_NOTICE_SETTINGS_NAMESPACE));
|
|
2944
4006
|
const welcomeInjected = () => ({
|
|
2945
4007
|
controller: welcomeController,
|
|
2946
4008
|
hooks: { welcome: welcomeController.store },
|
|
@@ -2989,6 +4051,10 @@ window.__ModuleLoader__.load({
|
|
|
2989
4051
|
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
2990
4052
|
name: "settings.onboarding",
|
|
2991
4053
|
id: "deepseek-official",
|
|
4054
|
+
children: { "settings.models.sign-in": {
|
|
4055
|
+
kind: "single",
|
|
4056
|
+
scope: "root"
|
|
4057
|
+
} },
|
|
2992
4058
|
order: 0,
|
|
2993
4059
|
inject: deepSeekOnboardingInjected
|
|
2994
4060
|
}, DeepSeekOnboardingDialog));
|