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