@qilin-agent/client-ui-settings-models 3.1.6 → 3.1.8
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 +6 -6
- package/README.md +12 -6
- package/README.zh.md +12 -6
- package/lib/client.js +1183 -140
- package/lib/index.js +24 -4
- package/lib/types/client/CustomProviderCard.d.ts +5 -0
- package/lib/types/client/ModelListEditor.d.ts +7 -0
- package/lib/types/client/ModelRow.d.ts +3 -0
- package/lib/types/client/ProviderEditor.d.ts +12 -0
- package/lib/types/client/index.d.ts +4 -2
- package/lib/types/client/locales.d.ts +7 -3
- package/lib/types/client/operations.d.ts +1 -7
- package/lib/types/client/useModelRows.d.ts +41 -0
- package/lib/types/index.d.ts +10 -3
- package/lib/types/onboarding-config.d.ts +16 -0
- package/package.json +18 -13
package/lib/client.js
CHANGED
|
@@ -55,7 +55,7 @@ window.__ModuleLoader__.load({
|
|
|
55
55
|
}
|
|
56
56
|
//#endregion
|
|
57
57
|
//#region \0qilin-css:/home/runner/work/QiLin/QiLin/packages/client/ui-settings-models/src/client/ModelsSection.module.css.mjs
|
|
58
|
-
const css$2 = ".PF5DZW_section{color:var(--qilin-alias-label-primary);flex-direction:column;gap:12px;display:flex}.PF5DZW_title{color:var(--qilin-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.PF5DZW_intro{color:var(--qilin-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.PF5DZW_notice{color:var(--qilin-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}.PF5DZW_savedNotice{color:var(--qilin-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}.PF5DZW_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}.PF5DZW_rowCard{border:.5px solid var(--qilin-alias-border-l4);border-radius:16px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.PF5DZW_rowHead{align-items:center;gap:10px;display:flex}.PF5DZW_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.PF5DZW_rowName{color:var(--qilin-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.PF5DZW_rowTag{border:.5px solid var(--qilin-alias-border-l3);color:var(--qilin-alias-label-secondary);border-radius:4px;flex:none;padding:1px 6px;font-size:11px;line-height:16px}.PF5DZW_credentialDot{box-sizing:border-box;corner-shape:round;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.PF5DZW_credentialDotConfigured{background:var(--qilin-alias-state-success-primary)}.PF5DZW_credentialDotMissing{background:var(--qilin-alias-state-error-primary)}.PF5DZW_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.PF5DZW_primaryButton,.PF5DZW_secondaryButton,.PF5DZW_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}.PF5DZW_primaryButton{background:var(--qilin-alias-button-primary-fill);color:var(--qilin-alias-label-primary-foreground)}.PF5DZW_primaryButton:hover:not(:disabled){background:var(--qilin-alias-button-primary-hover)}.PF5DZW_secondaryButton,.PF5DZW_addButton{border:.5px solid var(--qilin-alias-border-l3);color:var(--qilin-alias-label-primary);background:0 0}.PF5DZW_secondaryButton:hover:not(:disabled),.PF5DZW_addButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover)}.PF5DZW_secondaryButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-solid)}.PF5DZW_dangerButton{box-sizing:border-box;height:36px;color:var(--qilin-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}.PF5DZW_dangerButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-danger)}.PF5DZW_rowActions .PF5DZW_secondaryButton,.PF5DZW_rowActions .PF5DZW_dangerButton{border-radius:14px;height:28px;padding:0 10px;font-size:12px;line-height:18px}.PF5DZW_primaryButton:disabled,.PF5DZW_secondaryButton:disabled,.PF5DZW_dangerButton:disabled,.PF5DZW_addButton:disabled,.PF5DZW_linkButton:disabled,.PF5DZW_addModelButton:disabled{opacity:.4;cursor:default}.PF5DZW_primaryButton:focus-visible,.PF5DZW_secondaryButton:focus-visible,.PF5DZW_dangerButton:focus-visible,.PF5DZW_addButton:focus-visible,.PF5DZW_linkButton:focus-visible,.PF5DZW_addModelButton:focus-visible,.PF5DZW_iconButton:focus-visible,.PF5DZW_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--qilin-focus-ring-color,var(--qilin-alias-state-business-primary));outline:none}.PF5DZW_editor{background:var(--qilin-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;display:flex}.PF5DZW_editorHeader{align-items:baseline;gap:8px;display:flex}.PF5DZW_editorTitle{color:var(--qilin-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.PF5DZW_editorRoute{color:var(--qilin-alias-label-tertiary);font-size:12px;line-height:18px}.PF5DZW_field{flex-direction:column;gap:6px;display:flex}.PF5DZW_fieldLabel{color:var(--qilin-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.PF5DZW_helpButton{border:.5px solid var(--qilin-alias-border-l3);corner-shape:round;width:16px;height:16px;color:var(--qilin-alias-label-tertiary);font:inherit;text-align:center;cursor:help;background:0 0;border-radius:50%;padding:0;font-size:11px;line-height:15px}.PF5DZW_helpButton:hover,.PF5DZW_helpButton:focus-visible{color:var(--qilin-alias-label-primary);border-color:var(--qilin-alias-label-tertiary)}.PF5DZW_linkButton{box-sizing:border-box;height:28px;color:var(--qilin-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}.PF5DZW_linkButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover);color:var(--qilin-alias-label-secondary)}.PF5DZW_advancedHint{color:var(--qilin-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.PF5DZW_editorActions{justify-content:flex-end;gap:8px;display:flex}.PF5DZW_addBlock{flex-direction:column;gap:12px;display:flex}.PF5DZW_addActions{flex-wrap:wrap;gap:10px;display:flex}.PF5DZW_addButton{border:1px dashed var(--qilin-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}.PF5DZW_addCard,.PF5DZW_setupCard{background:var(--qilin-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.PF5DZW_addCard .PF5DZW_editor,.PF5DZW_setupCard .PF5DZW_editor{background:0 0;padding:0}.PF5DZW_customized{border-top:.5px solid var(--qilin-alias-border-l2);padding-top:10px}.PF5DZW_customizedSummary{cursor:pointer;width:fit-content;color:var(--qilin-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}.PF5DZW_customizedSummary::-webkit-details-marker{display:none}.PF5DZW_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)}.PF5DZW_customized[open]>.PF5DZW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.PF5DZW_customizedSummary:hover{color:var(--qilin-alias-label-primary)}.PF5DZW_customizedBody{flex-direction:column;gap:12px;padding-top:12px;display:flex}.PF5DZW_modelCatalog{border-top:.5px solid var(--qilin-alias-border-l2);flex-direction:column;gap:10px;padding-top:12px;display:flex}.PF5DZW_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.PF5DZW_modelCatalogTitle{color:var(--qilin-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.PF5DZW_modelCatalogMeta,.PF5DZW_modelEmpty{color:var(--qilin-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.PF5DZW_modelList{flex-direction:column;gap:8px;display:flex}.PF5DZW_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.PF5DZW_modelEntry{border:.5px solid var(--qilin-alias-border-l4);border-radius:10px;padding:6px}.PF5DZW_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}.PF5DZW_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--qilin-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.PF5DZW_iconButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover);color:var(--qilin-alias-label-primary)}.PF5DZW_iconButton:disabled{cursor:default;opacity:.4}.PF5DZW_iconButtonDanger:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-danger);color:var(--qilin-alias-state-error-primary)}.PF5DZW_modelAdvanced{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 4px 2px;display:grid}.PF5DZW_modelField{flex-direction:column;gap:4px;min-width:0;display:flex}.PF5DZW_modelInputTypes{border:none;grid-column:1/-1;min-width:0;margin:0;padding:0}.PF5DZW_modelInputTypes legend{margin-bottom:4px;padding:0}.PF5DZW_modelInputChoices{flex-wrap:wrap;align-items:center;gap:16px;min-height:32px;display:flex}.PF5DZW_modelFieldLabel{color:var(--qilin-alias-label-tertiary);font-size:12px;line-height:18px}.PF5DZW_modelReasoning{flex-direction:column;grid-column:1/-1;gap:6px;min-width:0;display:flex}.PF5DZW_modelReasoningLabel{align-items:center;gap:6px;display:inline-flex}.PF5DZW_modelReasoningHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.PF5DZW_modelReasoningRow{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;align-items:center;gap:6px;display:grid}.PF5DZW_modelReasoningRow .PF5DZW_selectInput{max-width:none}.PF5DZW_modelReasoningValueInput{font-family:var(--ds-font-family-code);font-size:13px}.PF5DZW_modelEmpty{border:1px dashed var(--qilin-alias-border-l3);text-align:center;border-radius:8px;padding:12px}.PF5DZW_addModelButton{box-sizing:border-box;border:.5px solid var(--qilin-alias-border-l3);height:28px;color:var(--qilin-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}.PF5DZW_addModelButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover)}.PF5DZW_input{box-sizing:border-box;border:.5px solid var(--qilin-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--qilin-alias-bg-layer-1);color:var(--qilin-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.PF5DZW_input{cursor:pointer;max-width:240px}.PF5DZW_input:focus{border-color:var(--qilin-alias-state-business-primary);outline:none}.PF5DZW_input::placeholder{color:var(--qilin-alias-label-dimmed)}.PF5DZW_input:disabled{opacity:.6;cursor:default}.PF5DZW_keyInput{position:relative}.PF5DZW_keyInputFilled{padding-right:40px}.PF5DZW_keyToggle{border-radius:var(--qilin-radius-md);width:32px;color:var(--qilin-alias-label-secondary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute;inset:1px 1px 1px auto}.PF5DZW_keyToggle:hover:not(:disabled){color:var(--qilin-alias-label-primary)}.PF5DZW_keyToggle:focus-visible{outline:var(--qilin-focus-ring-width) solid var(--qilin-focus-ring-color,var(--qilin-alias-state-business-primary));outline-offset:-2px}.PF5DZW_keyToggle:disabled{opacity:.6;cursor:default}.PF5DZW_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}.PF5DZW_error{color:var(--qilin-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.PF5DZW_deleteDialog{width:min(480px,100%)}.PF5DZW_deleteConfirm:not(:disabled){border-color:var(--qilin-alias-state-error-primary);color:var(--qilin-alias-state-error-primary)}.PF5DZW_deleteConfirm:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-danger)}.PF5DZW_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.PF5DZW_customizedSummary:before,.PF5DZW_switchThumb{transition:none}}.PF5DZW_fetchDialog{--qilin-scrollbar-thumb:var(--qilin-alias-scrollbar-bg-l2);--qilin-scrollbar-thumb-hover:var(--qilin-alias-scrollbar-hover-l2);max-width:520px}.PF5DZW_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.PF5DZW_candidateSearch{flex:240px;min-width:0}.PF5DZW_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.PF5DZW_candidate{border-radius:6px}.PF5DZW_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.PF5DZW_candidateId{font-family:var(--ds-font-family-code);overflow-wrap:anywhere;flex:auto;font-size:13px}.PF5DZW_candidateEmpty{color:var(--qilin-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}";
|
|
58
|
+
const css$2 = ".PF5DZW_section{color:var(--qilin-alias-label-primary);flex-direction:column;gap:12px;display:flex}.PF5DZW_title{color:var(--qilin-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.PF5DZW_intro{color:var(--qilin-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.PF5DZW_notice{color:var(--qilin-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}.PF5DZW_savedNotice{color:var(--qilin-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}.PF5DZW_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}.PF5DZW_rowCard{border:1px solid var(--qilin-alias-border-l4);border-radius:16px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.PF5DZW_rowHead{align-items:center;gap:10px;display:flex}.PF5DZW_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.PF5DZW_rowName{color:var(--qilin-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.PF5DZW_rowTag{border:1px solid var(--qilin-alias-border-l3);color:var(--qilin-alias-label-secondary);border-radius:4px;flex:none;padding:1px 6px;font-size:11px;line-height:16px}.PF5DZW_credentialDot{box-sizing:border-box;corner-shape:round;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.PF5DZW_credentialDotConfigured{background:var(--qilin-alias-state-success-primary)}.PF5DZW_credentialDotMissing{background:var(--qilin-alias-state-error-primary)}.PF5DZW_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.PF5DZW_primaryButton,.PF5DZW_secondaryButton,.PF5DZW_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}.PF5DZW_primaryButton{background:var(--qilin-alias-button-primary-fill);color:var(--qilin-alias-label-primary-foreground)}.PF5DZW_primaryButton:hover:not(:disabled){background:var(--qilin-alias-button-primary-hover)}.PF5DZW_secondaryButton,.PF5DZW_addButton{border:1px solid var(--qilin-alias-border-l3);color:var(--qilin-alias-label-primary);background:0 0}.PF5DZW_secondaryButton:hover:not(:disabled),.PF5DZW_addButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover)}.PF5DZW_secondaryButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-solid)}.PF5DZW_dangerButton{box-sizing:border-box;height:36px;color:var(--qilin-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}.PF5DZW_dangerButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-danger)}.PF5DZW_rowActions .PF5DZW_secondaryButton,.PF5DZW_rowActions .PF5DZW_dangerButton{border-radius:14px;height:28px;padding:0 10px;font-size:12px;line-height:18px}.PF5DZW_primaryButton:disabled,.PF5DZW_secondaryButton:disabled,.PF5DZW_dangerButton:disabled,.PF5DZW_addButton:disabled,.PF5DZW_linkButton:disabled,.PF5DZW_addModelButton:disabled{opacity:.4;cursor:default}.PF5DZW_primaryButton:focus-visible,.PF5DZW_secondaryButton:focus-visible,.PF5DZW_dangerButton:focus-visible,.PF5DZW_addButton:focus-visible,.PF5DZW_linkButton:focus-visible,.PF5DZW_addModelButton:focus-visible,.PF5DZW_iconButton:focus-visible,.PF5DZW_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--qilin-focus-ring-color,var(--qilin-alias-state-business-primary));outline:none}.PF5DZW_editor{background:var(--qilin-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;display:flex}.PF5DZW_editorHeader{align-items:baseline;gap:8px;display:flex}.PF5DZW_editorTitle{color:var(--qilin-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.PF5DZW_editorRoute{color:var(--qilin-alias-label-tertiary);font-size:12px;line-height:18px}.PF5DZW_field{flex-direction:column;gap:6px;display:flex}.PF5DZW_fieldLabel{color:var(--qilin-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.PF5DZW_helpButton{border:1px solid var(--qilin-alias-border-l3);corner-shape:round;width:16px;height:16px;color:var(--qilin-alias-label-tertiary);font:inherit;text-align:center;cursor:help;background:0 0;border-radius:50%;padding:0;font-size:11px;line-height:15px}.PF5DZW_helpButton:hover,.PF5DZW_helpButton:focus-visible{color:var(--qilin-alias-label-primary);border-color:var(--qilin-alias-label-tertiary)}.PF5DZW_linkButton{box-sizing:border-box;height:28px;color:var(--qilin-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}.PF5DZW_linkButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover);color:var(--qilin-alias-label-secondary)}.PF5DZW_advancedHint{color:var(--qilin-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.PF5DZW_editorActions{justify-content:flex-end;gap:8px;display:flex}.PF5DZW_addBlock{flex-direction:column;gap:12px;display:flex}.PF5DZW_addActions{flex-wrap:wrap;gap:10px;display:flex}.PF5DZW_addButton{border:1px dashed var(--qilin-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}.PF5DZW_addCard,.PF5DZW_setupCard{background:var(--qilin-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.PF5DZW_addCard .PF5DZW_editor,.PF5DZW_setupCard .PF5DZW_editor{background:0 0;padding:0}.PF5DZW_customized{border-top:1px solid var(--qilin-alias-border-l2);padding-top:10px}.PF5DZW_customizedSummary{cursor:pointer;width:fit-content;color:var(--qilin-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}.PF5DZW_customizedSummary::-webkit-details-marker{display:none}.PF5DZW_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)}.PF5DZW_customized[open]>.PF5DZW_customizedSummary:before{transform:rotate(45deg)translate(-1px,-1px)}.PF5DZW_customizedSummary:hover{color:var(--qilin-alias-label-primary)}.PF5DZW_customizedBody{flex-direction:column;gap:12px;padding-top:12px;display:flex}.PF5DZW_modelCatalog{border-top:1px solid var(--qilin-alias-border-l2);flex-direction:column;gap:10px;padding-top:12px;display:flex;position:relative}.PF5DZW_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.PF5DZW_modelCatalogTitle{color:var(--qilin-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.PF5DZW_modelCatalogMeta,.PF5DZW_modelEmpty{color:var(--qilin-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.PF5DZW_modelList{flex-direction:column;gap:8px;display:flex}.PF5DZW_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.PF5DZW_modelEntry{border:1px solid var(--qilin-alias-border-l4);border-radius:10px;padding:6px;position:relative;container:PF5DZW_model-row/inline-size}.PF5DZW_modelRow{grid-template-columns:auto minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}@container PF5DZW_model-row (width<=440px){.PF5DZW_modelRow{grid-template-columns:auto minmax(0,1fr) auto auto}.PF5DZW_modelRow>input:first-of-type{grid-area:1/2}.PF5DZW_modelRow>input:nth-of-type(2){grid-area:2/2/auto/-1}}.PF5DZW_modelDragHandle:not(:disabled){cursor:grab}.PF5DZW_modelEntry[data-dragging]{opacity:.5}.PF5DZW_modelDragPreview{background:var(--qilin-alias-bg-module-platform)}.PF5DZW_modelEntry:before,.PF5DZW_modelEntry:after{content:\"\";z-index:1;height:4px;position:absolute;left:0;right:0}.PF5DZW_modelEntry:before{top:-4px}.PF5DZW_modelEntry:after{bottom:-4px}.PF5DZW_modelEntry[data-drop-target=before]:before,.PF5DZW_modelEntry[data-drop-target=after]:after{background:linear-gradient(55deg, transparent calc(50% - 1px), var(--qilin-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 0 / 5px 7px no-repeat, linear-gradient(125deg, transparent calc(50% - 1px), var(--qilin-alias-state-business-primary) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) 0 5px / 5px 7px no-repeat, linear-gradient(var(--qilin-alias-state-business-primary) 0 0) 4px 5px / calc(100% - 4px) 2px no-repeat;height:12px}.PF5DZW_modelEntry[data-drop-target=before]:before{top:-10px}.PF5DZW_modelEntry[data-drop-target=after]:after{bottom:-10px}.PF5DZW_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--qilin-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.PF5DZW_iconButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover);color:var(--qilin-alias-label-primary)}.PF5DZW_iconButton:disabled{cursor:default;opacity:.4}.PF5DZW_iconButtonDanger:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-danger);color:var(--qilin-alias-state-error-primary)}.PF5DZW_modelAdvanced{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;padding:8px 4px 2px;display:grid}.PF5DZW_modelField{flex-direction:column;gap:4px;min-width:0;display:flex}.PF5DZW_modelInputTypes{border:none;grid-column:1/-1;min-width:0;margin:0;padding:0}.PF5DZW_modelInputTypes legend{margin-bottom:4px;padding:0}.PF5DZW_modelInputChoices{flex-wrap:wrap;align-items:center;gap:16px;min-height:32px;display:flex}.PF5DZW_modelFieldLabel{color:var(--qilin-alias-label-tertiary);font-size:12px;line-height:18px}.PF5DZW_modelReasoning{flex-direction:column;grid-column:1/-1;gap:6px;min-width:0;display:flex}.PF5DZW_modelReasoningLabel{align-items:center;gap:6px;display:inline-flex}.PF5DZW_modelReasoningHead{justify-content:space-between;align-items:center;gap:8px;display:flex}.PF5DZW_modelReasoningRow{grid-template-columns:minmax(0,1fr) minmax(0,1fr) auto;align-items:center;gap:6px;display:grid}.PF5DZW_modelReasoningRow .PF5DZW_selectInput{max-width:none}.PF5DZW_modelReasoningValueInput{font-family:var(--ds-font-family-code);font-size:13px}.PF5DZW_modelEmpty{border:1px dashed var(--qilin-alias-border-l3);text-align:center;border-radius:8px;padding:12px}.PF5DZW_addModelButton{box-sizing:border-box;border:1px solid var(--qilin-alias-border-l3);height:28px;color:var(--qilin-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}.PF5DZW_addModelButton:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover)}.PF5DZW_input{box-sizing:border-box;border:1px solid var(--qilin-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--qilin-alias-bg-layer-1);color:var(--qilin-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.PF5DZW_input{cursor:pointer;max-width:240px}.PF5DZW_input:focus{border-color:var(--qilin-alias-state-business-primary);outline:none}.PF5DZW_input::placeholder{color:var(--qilin-alias-label-dimmed)}.PF5DZW_input:disabled{opacity:.6;cursor:default}.PF5DZW_keyInput{position:relative}.PF5DZW_keyInputFilled{padding-right:40px}.PF5DZW_keyToggle{border-radius:var(--qilin-radius-md);width:32px;color:var(--qilin-alias-label-secondary);cursor:pointer;background:0 0;border:none;justify-content:center;align-items:center;padding:0;display:inline-flex;position:absolute;inset:1px 1px 1px auto}.PF5DZW_keyToggle:hover:not(:disabled){color:var(--qilin-alias-label-primary)}.PF5DZW_keyToggle:focus-visible{outline:var(--qilin-focus-ring-width) solid var(--qilin-focus-ring-color,var(--qilin-alias-state-business-primary));outline-offset:-2px}.PF5DZW_keyToggle:disabled{opacity:.6;cursor:default}.PF5DZW_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}.PF5DZW_error{color:var(--qilin-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.PF5DZW_deleteDialog{width:min(480px,100%)}.PF5DZW_deleteConfirm:not(:disabled){border-color:var(--qilin-alias-state-error-primary);color:var(--qilin-alias-state-error-primary)}.PF5DZW_deleteConfirm:hover:not(:disabled){background:var(--qilin-alias-interactive-bg-hover-danger)}.PF5DZW_hiddenLabel{clip:rect(0 0 0 0);white-space:nowrap;width:1px;height:1px;position:absolute;overflow:hidden}@media (prefers-reduced-motion:reduce){.PF5DZW_customizedSummary:before,.PF5DZW_switchThumb{transition:none}}.PF5DZW_fetchDialog{--qilin-scrollbar-thumb:var(--qilin-alias-scrollbar-bg-l2);--qilin-scrollbar-thumb-hover:var(--qilin-alias-scrollbar-hover-l2);max-width:520px}.PF5DZW_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.PF5DZW_candidateSearch{flex:240px;min-width:0}.PF5DZW_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.PF5DZW_candidate{border-radius:6px}.PF5DZW_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.PF5DZW_candidateId{font-family:var(--ds-font-family-code);overflow-wrap:anywhere;flex:auto;font-size:13px}.PF5DZW_candidateEmpty{color:var(--qilin-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}";
|
|
59
59
|
const tagId$2 = "@qilin-agent/client-ui-settings-models/ModelsSection.module.css";
|
|
60
60
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$2) + "]") === null) {
|
|
61
61
|
const tag = document.createElement("style");
|
|
@@ -106,11 +106,14 @@ window.__ModuleLoader__.load({
|
|
|
106
106
|
"keyInputFilled": "PF5DZW_keyInputFilled",
|
|
107
107
|
"keyToggle": "PF5DZW_keyToggle",
|
|
108
108
|
"linkButton": "PF5DZW_linkButton",
|
|
109
|
+
"model-row": "PF5DZW_model-row",
|
|
109
110
|
"modelAdvanced": "PF5DZW_modelAdvanced",
|
|
110
111
|
"modelCatalog": "PF5DZW_modelCatalog",
|
|
111
112
|
"modelCatalogHeading": "PF5DZW_modelCatalogHeading",
|
|
112
113
|
"modelCatalogMeta": "PF5DZW_modelCatalogMeta",
|
|
113
114
|
"modelCatalogTitle": "PF5DZW_modelCatalogTitle",
|
|
115
|
+
"modelDragHandle": "PF5DZW_modelDragHandle",
|
|
116
|
+
"modelDragPreview": "PF5DZW_modelDragPreview",
|
|
114
117
|
"modelEmpty": "PF5DZW_modelEmpty",
|
|
115
118
|
"modelEntry": "PF5DZW_modelEntry",
|
|
116
119
|
"modelField": "PF5DZW_modelField",
|
|
@@ -475,6 +478,10 @@ window.__ModuleLoader__.load({
|
|
|
475
478
|
}
|
|
476
479
|
//#endregion
|
|
477
480
|
//#region lib/types/client/ModelRow.js
|
|
481
|
+
function rowHalf(event) {
|
|
482
|
+
const rect = event.currentTarget.getBoundingClientRect();
|
|
483
|
+
return event.clientY < rect.top + rect.height / 2 ? "before" : "after";
|
|
484
|
+
}
|
|
478
485
|
/**
|
|
479
486
|
* Render consistent model identity, capacity, and input-type controls.
|
|
480
487
|
* @param props - drafted fields and their owning editor's actions.
|
|
@@ -482,11 +489,58 @@ window.__ModuleLoader__.load({
|
|
|
482
489
|
*/
|
|
483
490
|
function ModelRow(props) {
|
|
484
491
|
const { model, position, t, disabled } = props;
|
|
492
|
+
const preview = (0, _qilin_agent_client_ui_primitives.useRowDragPreview)(ModelsSection_module_css_default["modelDragPreview"]);
|
|
485
493
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
486
494
|
className: ModelsSection_module_css_default["modelEntry"],
|
|
495
|
+
"data-row-key": props.rowKey,
|
|
496
|
+
"data-dragging": props.order.dragging || void 0,
|
|
497
|
+
"data-drop-target": props.order.dragging ? void 0 : props.order.target,
|
|
498
|
+
onDragOver: (event) => {
|
|
499
|
+
if (!props.order.canDrop) return;
|
|
500
|
+
event.preventDefault();
|
|
501
|
+
event.dataTransfer.dropEffect = "move";
|
|
502
|
+
props.order.onOver(rowHalf(event));
|
|
503
|
+
},
|
|
504
|
+
onDragLeave: (event) => {
|
|
505
|
+
if (event.relatedTarget instanceof Node && event.currentTarget.contains(event.relatedTarget)) return;
|
|
506
|
+
props.order.onLeave();
|
|
507
|
+
},
|
|
508
|
+
onDrop: (event) => {
|
|
509
|
+
if (!props.order.canDrop) return;
|
|
510
|
+
event.preventDefault();
|
|
511
|
+
props.order.onDrop(rowHalf(event));
|
|
512
|
+
},
|
|
487
513
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
488
514
|
className: ModelsSection_module_css_default["modelRow"],
|
|
489
515
|
children: [
|
|
516
|
+
(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.Tooltip, {
|
|
517
|
+
label: t("reorderModelHelp"),
|
|
518
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
519
|
+
type: "button",
|
|
520
|
+
className: `${ModelsSection_module_css_default["iconButton"]} ${ModelsSection_module_css_default["modelDragHandle"]}`,
|
|
521
|
+
"aria-label": `${t("reorderModel")} ${String(position)}`,
|
|
522
|
+
"aria-keyshortcuts": "ArrowUp ArrowDown",
|
|
523
|
+
"aria-description": t("reorderModelHelp"),
|
|
524
|
+
disabled,
|
|
525
|
+
draggable: !disabled,
|
|
526
|
+
onDragStart: (event) => {
|
|
527
|
+
event.dataTransfer.effectAllowed = "move";
|
|
528
|
+
event.dataTransfer.setData("application/x-qilin-model-order", String(position));
|
|
529
|
+
props.order.onStart();
|
|
530
|
+
preview.start(event, event.currentTarget.closest("[data-row-key]"));
|
|
531
|
+
},
|
|
532
|
+
onDragEnd: () => {
|
|
533
|
+
if (preview.clear()) props.order.onEnd();
|
|
534
|
+
},
|
|
535
|
+
onKeyDown: (event) => {
|
|
536
|
+
if (event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
|
|
537
|
+
event.preventDefault();
|
|
538
|
+
event.stopPropagation();
|
|
539
|
+
props.order.onMove(event.key === "ArrowUp" ? -1 : 1);
|
|
540
|
+
},
|
|
541
|
+
children: (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconDragHandleOutlineRegular, { size: 14 })
|
|
542
|
+
})
|
|
543
|
+
}),
|
|
490
544
|
["id", "name"].map((field) => (0, react_jsx_runtime.jsx)("input", {
|
|
491
545
|
className: ModelsSection_module_css_default["input"],
|
|
492
546
|
type: "text",
|
|
@@ -507,7 +561,7 @@ window.__ModuleLoader__.load({
|
|
|
507
561
|
"aria-expanded": props.expanded,
|
|
508
562
|
title: t("modelAdvanced"),
|
|
509
563
|
onClick: props.onToggle,
|
|
510
|
-
children: props.expanded ? (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.
|
|
564
|
+
children: props.expanded ? (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconChevronDownOutlineRegular, {}) : (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconChevronRightOutlineRegular, {})
|
|
511
565
|
}),
|
|
512
566
|
(0, react_jsx_runtime.jsx)("button", {
|
|
513
567
|
type: "button",
|
|
@@ -516,7 +570,7 @@ window.__ModuleLoader__.load({
|
|
|
516
570
|
title: t("removeModel"),
|
|
517
571
|
disabled,
|
|
518
572
|
onClick: props.onRemove,
|
|
519
|
-
children: (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.
|
|
573
|
+
children: (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconTrashOutlineRegular, { size: 14 })
|
|
520
574
|
})
|
|
521
575
|
]
|
|
522
576
|
}), props.expanded ? (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -563,17 +617,108 @@ window.__ModuleLoader__.load({
|
|
|
563
617
|
});
|
|
564
618
|
}
|
|
565
619
|
//#endregion
|
|
566
|
-
//#region lib/types/client/
|
|
620
|
+
//#region lib/types/client/useModelRows.js
|
|
621
|
+
/** Local model-row identities, disclosures, capacity text, and draft ordering. */
|
|
622
|
+
/** One editor-local identity; editing a model ID never replaces its controls. */
|
|
623
|
+
function createRow(key) {
|
|
624
|
+
return {
|
|
625
|
+
key,
|
|
626
|
+
expanded: false,
|
|
627
|
+
editing: /* @__PURE__ */ new Map()
|
|
628
|
+
};
|
|
629
|
+
}
|
|
567
630
|
/**
|
|
568
|
-
*
|
|
569
|
-
*
|
|
570
|
-
*
|
|
571
|
-
*
|
|
631
|
+
* Keep row state with its model through draft moves and removals.
|
|
632
|
+
* @param models - current draft array, owned by the provider card.
|
|
633
|
+
* @param onChange - replaces only that card's draft array.
|
|
634
|
+
* @param disabled - prevents reordering while the card cannot be edited.
|
|
635
|
+
* @returns row state and local editing and ordering actions.
|
|
572
636
|
*/
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
637
|
+
function useModelRows(models, onChange, disabled) {
|
|
638
|
+
const nextKey = (0, react.useRef)(0);
|
|
639
|
+
const [stored, setRows] = (0, react.useState)(() => models.map(() => createRow(nextKey.current++)));
|
|
640
|
+
const [dragged, setDragged] = (0, react.useState)();
|
|
641
|
+
const [target, setTarget] = (0, react.useState)();
|
|
642
|
+
const entries = models.map((model, index) => ({
|
|
643
|
+
model,
|
|
644
|
+
state: stored[index] ?? createRow(nextKey.current++)
|
|
645
|
+
}));
|
|
646
|
+
const rows = entries.map((entry) => entry.state);
|
|
647
|
+
if (stored.length !== models.length) setRows(rows);
|
|
648
|
+
const endDrag = () => {
|
|
649
|
+
setDragged(void 0);
|
|
650
|
+
setTarget(void 0);
|
|
651
|
+
};
|
|
652
|
+
const move = (from, to) => {
|
|
653
|
+
if (disabled || from === to || from < 0 || to < 0 || to >= models.length) return;
|
|
654
|
+
const order = [...entries];
|
|
655
|
+
const moved = order.splice(from, 1);
|
|
656
|
+
order.splice(to, 0, ...moved);
|
|
657
|
+
setRows(order.map((entry) => entry.state));
|
|
658
|
+
onChange(order.map((entry) => entry.model));
|
|
659
|
+
};
|
|
660
|
+
return {
|
|
661
|
+
rows: entries.map(({ model, state }, index) => ({
|
|
662
|
+
...state,
|
|
663
|
+
model,
|
|
664
|
+
order: {
|
|
665
|
+
dragging: dragged === state.key,
|
|
666
|
+
target: target?.key === state.key ? target.half : void 0,
|
|
667
|
+
canDrop: !disabled && dragged !== void 0,
|
|
668
|
+
onStart: () => {
|
|
669
|
+
setDragged(state.key);
|
|
670
|
+
},
|
|
671
|
+
onEnd: endDrag,
|
|
672
|
+
onOver: (half) => {
|
|
673
|
+
setTarget((current) => current?.key === state.key && current.half === half ? current : {
|
|
674
|
+
key: state.key,
|
|
675
|
+
half
|
|
676
|
+
});
|
|
677
|
+
},
|
|
678
|
+
onLeave: () => {
|
|
679
|
+
setTarget((current) => current?.key === state.key ? void 0 : current);
|
|
680
|
+
},
|
|
681
|
+
onDrop: (half) => {
|
|
682
|
+
const from = rows.findIndex((row) => row.key === dragged);
|
|
683
|
+
const insertion = index + (half === "after" ? 1 : 0);
|
|
684
|
+
move(from, insertion > from ? insertion - 1 : insertion);
|
|
685
|
+
endDrag();
|
|
686
|
+
},
|
|
687
|
+
onMove: (offset) => {
|
|
688
|
+
move(index, index + offset);
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
})),
|
|
692
|
+
toggle: (index) => {
|
|
693
|
+
setRows(rows.map((row, at) => at === index ? {
|
|
694
|
+
...row,
|
|
695
|
+
expanded: !row.expanded
|
|
696
|
+
} : row));
|
|
697
|
+
},
|
|
698
|
+
edit: (index, field, text) => {
|
|
699
|
+
setRows(rows.map((row, at) => {
|
|
700
|
+
if (at !== index) return row;
|
|
701
|
+
const editing = new Map(row.editing);
|
|
702
|
+
if (text === void 0) editing.delete(field);
|
|
703
|
+
else editing.set(field, text);
|
|
704
|
+
return {
|
|
705
|
+
...row,
|
|
706
|
+
editing
|
|
707
|
+
};
|
|
708
|
+
}));
|
|
709
|
+
},
|
|
710
|
+
forget: (removed) => {
|
|
711
|
+
setRows(rows.filter((_row, index) => !removed.has(index)));
|
|
712
|
+
endDrag();
|
|
713
|
+
},
|
|
714
|
+
reset: () => {
|
|
715
|
+
setRows(models.map(() => createRow(nextKey.current++)));
|
|
716
|
+
endDrag();
|
|
717
|
+
}
|
|
718
|
+
};
|
|
576
719
|
}
|
|
720
|
+
//#endregion
|
|
721
|
+
//#region lib/types/client/DeepSeekModelsEditor.js
|
|
577
722
|
/** Accepted capacity spellings: a decimal count with an optional K/M suffix. */
|
|
578
723
|
const CAPACITY_PATTERN = /^(\d+(?:\.\d+)?)([km])?$/i;
|
|
579
724
|
/** Decimal suffix scales — `1M` is 1000K, matching how model capacities are quoted. */
|
|
@@ -662,8 +807,7 @@ window.__ModuleLoader__.load({
|
|
|
662
807
|
* @returns the catalog editor.
|
|
663
808
|
*/
|
|
664
809
|
function DeepSeekModelsEditor(props) {
|
|
665
|
-
const
|
|
666
|
-
const [expanded, setExpanded] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
810
|
+
const rowState = useModelRows(props.models, props.onChange, props.disabled);
|
|
667
811
|
const update = (index, key, value) => {
|
|
668
812
|
const next = props.models.map((model, at) => {
|
|
669
813
|
const copy = { ...model };
|
|
@@ -675,61 +819,32 @@ window.__ModuleLoader__.load({
|
|
|
675
819
|
props.onChange(next);
|
|
676
820
|
};
|
|
677
821
|
const remove = (index) => {
|
|
678
|
-
|
|
679
|
-
const next = /* @__PURE__ */ new Map();
|
|
680
|
-
for (const [key, text] of current) {
|
|
681
|
-
const at = rowOf(key);
|
|
682
|
-
if (at === index) continue;
|
|
683
|
-
next.set(at > index ? key.replace(/^\d+/, String(at - 1)) : key, text);
|
|
684
|
-
}
|
|
685
|
-
return next;
|
|
686
|
-
});
|
|
687
|
-
setExpanded((current) => {
|
|
688
|
-
const next = /* @__PURE__ */ new Set();
|
|
689
|
-
for (const at of current) {
|
|
690
|
-
if (at === index) continue;
|
|
691
|
-
next.add(at > index ? at - 1 : at);
|
|
692
|
-
}
|
|
693
|
-
return next;
|
|
694
|
-
});
|
|
822
|
+
rowState.forget(new Set([index]));
|
|
695
823
|
props.onChange(props.models.filter((_model, at) => at !== index).map((model) => ({ ...model })));
|
|
696
824
|
};
|
|
697
825
|
const reset = () => {
|
|
698
|
-
|
|
699
|
-
setExpanded(/* @__PURE__ */ new Set());
|
|
826
|
+
rowState.reset();
|
|
700
827
|
props.onReset();
|
|
701
828
|
};
|
|
702
|
-
const toggle = (index) => {
|
|
703
|
-
setExpanded((current) => {
|
|
704
|
-
const next = new Set(current);
|
|
705
|
-
if (!next.delete(index)) next.add(index);
|
|
706
|
-
return next;
|
|
707
|
-
});
|
|
708
|
-
};
|
|
709
829
|
/** The field's text: its live keystrokes, else the stored count spelled short. */
|
|
710
830
|
const capacityText = (model, index, field) => {
|
|
711
|
-
const typed = editing.get(
|
|
831
|
+
const typed = rowState.rows[index]?.editing.get(field);
|
|
712
832
|
if (typed !== void 0) return typed;
|
|
713
833
|
const value = model[field];
|
|
714
834
|
return typeof value === "number" ? formatCapacity(value) : "";
|
|
715
835
|
};
|
|
716
836
|
const settleCapacity = (index, field) => {
|
|
717
|
-
const
|
|
718
|
-
const typed = editing.get(key);
|
|
837
|
+
const typed = rowState.rows[index]?.editing.get(field);
|
|
719
838
|
if (typed === void 0) return;
|
|
720
839
|
const parsed = parseCapacity(typed);
|
|
721
840
|
if (parsed !== void 0 && Number.isNaN(parsed)) return;
|
|
722
|
-
|
|
723
|
-
const next = new Map(current);
|
|
724
|
-
next.delete(key);
|
|
725
|
-
return next;
|
|
726
|
-
});
|
|
841
|
+
rowState.edit(index, field, void 0);
|
|
727
842
|
};
|
|
728
843
|
const capacityInput = (model, index, field, fallback) => ({
|
|
729
844
|
value: capacityText(model, index, field),
|
|
730
845
|
placeholder: fallback === void 0 ? props.t(field === "contextWindow" ? "contextWindowPlaceholder" : "maxTokensPlaceholder") : formatCapacity(fallback),
|
|
731
846
|
onChange: (text) => {
|
|
732
|
-
|
|
847
|
+
rowState.edit(index, field, text);
|
|
733
848
|
update(index, field, parseCapacity(text));
|
|
734
849
|
},
|
|
735
850
|
onBlur: () => {
|
|
@@ -759,16 +874,21 @@ window.__ModuleLoader__.load({
|
|
|
759
874
|
children: props.t("resetModels")
|
|
760
875
|
}) : null]
|
|
761
876
|
}),
|
|
762
|
-
|
|
763
|
-
className: ModelsSection_module_css_default["modelEmpty"],
|
|
764
|
-
children: props.t("modelsEmpty")
|
|
765
|
-
}) : (0, react_jsx_runtime.jsx)("div", {
|
|
877
|
+
(0, react_jsx_runtime.jsxs)(_qilin_agent_client_ui_primitives.AnimatedRows, {
|
|
766
878
|
className: ModelsSection_module_css_default["modelList"],
|
|
767
|
-
|
|
879
|
+
rowKeys: rowState.rows.map((row) => String(row.key)),
|
|
880
|
+
ready: true,
|
|
881
|
+
resetKey: "",
|
|
882
|
+
children: [props.models.length === 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
883
|
+
className: ModelsSection_module_css_default["modelEmpty"],
|
|
884
|
+
children: props.t("modelsEmpty")
|
|
885
|
+
}) : null, rowState.rows.map(({ model, key, expanded, order }, index) => (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
886
|
+
rowKey: key,
|
|
887
|
+
order,
|
|
768
888
|
model,
|
|
769
889
|
position: index + 1,
|
|
770
890
|
inputField: "inputModalities",
|
|
771
|
-
expanded
|
|
891
|
+
expanded,
|
|
772
892
|
disabled: props.disabled,
|
|
773
893
|
t: props.t,
|
|
774
894
|
contextWindow: capacityInput(model, index, "contextWindow", props.defaultContextWindow),
|
|
@@ -784,12 +904,12 @@ window.__ModuleLoader__.load({
|
|
|
784
904
|
props.onChange(props.models.map((row, at) => at === index ? next : row));
|
|
785
905
|
},
|
|
786
906
|
onToggle: () => {
|
|
787
|
-
toggle(index);
|
|
907
|
+
rowState.toggle(index);
|
|
788
908
|
},
|
|
789
909
|
onRemove: () => {
|
|
790
910
|
remove(index);
|
|
791
911
|
}
|
|
792
|
-
},
|
|
912
|
+
}, key))]
|
|
793
913
|
}),
|
|
794
914
|
(0, react_jsx_runtime.jsxs)("button", {
|
|
795
915
|
type: "button",
|
|
@@ -798,7 +918,7 @@ window.__ModuleLoader__.load({
|
|
|
798
918
|
onClick: () => {
|
|
799
919
|
props.onChange([...props.models.map((model) => ({ ...model })), { id: "" }]);
|
|
800
920
|
},
|
|
801
|
-
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.
|
|
921
|
+
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), props.t("addModel")]
|
|
802
922
|
})
|
|
803
923
|
]
|
|
804
924
|
});
|
|
@@ -871,9 +991,12 @@ window.__ModuleLoader__.load({
|
|
|
871
991
|
* @returns the model-list editor.
|
|
872
992
|
*/
|
|
873
993
|
function ModelListEditor(props) {
|
|
874
|
-
const { models, onChange, probe, operations, t, disabled } = props;
|
|
994
|
+
const { models, onChange, probe, operations, t, disabled, onBusyChange } = props;
|
|
875
995
|
const { catalogProvider } = props;
|
|
876
996
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
997
|
+
(0, react.useEffect)(() => {
|
|
998
|
+
onBusyChange(busy);
|
|
999
|
+
}, [busy, onBusyChange]);
|
|
877
1000
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
878
1001
|
const [inheritedCatalog, setInheritedCatalog] = (0, react.useState)(void 0);
|
|
879
1002
|
(0, react.useEffect)(() => {
|
|
@@ -900,33 +1023,13 @@ window.__ModuleLoader__.load({
|
|
|
900
1023
|
const [candidates, setCandidates] = (0, react.useState)(void 0);
|
|
901
1024
|
const [picked, setPicked] = (0, react.useState)(/* @__PURE__ */ new Set());
|
|
902
1025
|
const [candidateQuery, setCandidateQuery] = (0, react.useState)("");
|
|
903
|
-
const
|
|
904
|
-
const [editing, setEditing] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
905
|
-
/** Buffer key for one capacity field; the row half moves when rows do. */
|
|
906
|
-
const bufferKey = (index, field) => `${String(index)}:${field}`;
|
|
1026
|
+
const rowState = useModelRows(models, onChange, disabled);
|
|
907
1027
|
const editCapacity = (index, field, text) => {
|
|
908
|
-
|
|
1028
|
+
rowState.edit(index, field, text);
|
|
909
1029
|
patch(index, { [field]: parseCapacity(text) });
|
|
910
1030
|
};
|
|
911
1031
|
/** What a capacity field shows: the buffer while typing, else the stored count. */
|
|
912
|
-
const capacityText = (model, index, field) => editing.get(
|
|
913
|
-
/** Drop one row's entries and shift the rows after it down, in one pass. */
|
|
914
|
-
const reindexOnRemove = (current, index) => {
|
|
915
|
-
const next = /* @__PURE__ */ new Map();
|
|
916
|
-
for (const [key, value] of current) {
|
|
917
|
-
const at = Number(key.slice(0, key.indexOf(":")));
|
|
918
|
-
if (at === index) continue;
|
|
919
|
-
next.set(at > index ? key.replace(/^\d+/, String(at - 1)) : key, value);
|
|
920
|
-
}
|
|
921
|
-
return next;
|
|
922
|
-
};
|
|
923
|
-
const toggleExpanded = (index) => {
|
|
924
|
-
setExpanded((current) => {
|
|
925
|
-
const next = new Set(current);
|
|
926
|
-
if (!next.delete(index)) next.add(index);
|
|
927
|
-
return next;
|
|
928
|
-
});
|
|
929
|
-
};
|
|
1032
|
+
const capacityText = (model, index, field) => rowState.rows[index]?.editing.get(field) ?? capacitySpelling(numberOf(model, field));
|
|
930
1033
|
const patch = (index, next) => {
|
|
931
1034
|
onChange(models.map((model, at) => {
|
|
932
1035
|
if (at !== index) return model;
|
|
@@ -1025,7 +1128,10 @@ window.__ModuleLoader__.load({
|
|
|
1025
1128
|
type: "button",
|
|
1026
1129
|
className: ModelsSection_module_css_default["linkButton"],
|
|
1027
1130
|
disabled,
|
|
1028
|
-
onClick:
|
|
1131
|
+
onClick: () => {
|
|
1132
|
+
rowState.reset();
|
|
1133
|
+
props.onReset?.();
|
|
1134
|
+
},
|
|
1029
1135
|
children: t("resetModels")
|
|
1030
1136
|
}) : null,
|
|
1031
1137
|
(0, react_jsx_runtime.jsx)("button", {
|
|
@@ -1044,16 +1150,21 @@ window.__ModuleLoader__.load({
|
|
|
1044
1150
|
className: ModelsSection_module_css_default["modelEmpty"],
|
|
1045
1151
|
children: t("modelsEmpty")
|
|
1046
1152
|
}) : null,
|
|
1047
|
-
(0, react_jsx_runtime.jsx)(
|
|
1153
|
+
(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.AnimatedRows, {
|
|
1048
1154
|
className: ModelsSection_module_css_default["modelList"],
|
|
1049
|
-
|
|
1155
|
+
rowKeys: rowState.rows.map((row) => String(row.key)),
|
|
1156
|
+
ready: true,
|
|
1157
|
+
resetKey: "",
|
|
1158
|
+
children: rowState.rows.map(({ model, key, expanded, order }, index) => (0, react_jsx_runtime.jsx)(ModelRow, {
|
|
1159
|
+
rowKey: key,
|
|
1160
|
+
order,
|
|
1050
1161
|
model,
|
|
1051
1162
|
position: index + 1,
|
|
1052
1163
|
inputField: "input",
|
|
1053
1164
|
inputFallback: inputDefaults.get(textOf(model, "id")) ?? props.defaultInput,
|
|
1054
1165
|
inputLoading: catalogProvider !== void 0 && catalog === void 0,
|
|
1055
1166
|
reasoningLevels: props.reasoningLevels,
|
|
1056
|
-
expanded
|
|
1167
|
+
expanded,
|
|
1057
1168
|
disabled,
|
|
1058
1169
|
t,
|
|
1059
1170
|
contextWindow: {
|
|
@@ -1077,19 +1188,13 @@ window.__ModuleLoader__.load({
|
|
|
1077
1188
|
onChange(models.map((row, at) => at === index ? next : row));
|
|
1078
1189
|
},
|
|
1079
1190
|
onToggle: () => {
|
|
1080
|
-
|
|
1191
|
+
rowState.toggle(index);
|
|
1081
1192
|
},
|
|
1082
1193
|
onRemove: () => {
|
|
1083
1194
|
onChange(models.filter((_model, at) => at !== index));
|
|
1084
|
-
|
|
1085
|
-
const next = /* @__PURE__ */ new Set();
|
|
1086
|
-
for (const at of current) if (at < index) next.add(at);
|
|
1087
|
-
else if (at > index) next.add(at - 1);
|
|
1088
|
-
return next;
|
|
1089
|
-
});
|
|
1090
|
-
setEditing((current) => reindexOnRemove(current, index));
|
|
1195
|
+
rowState.forget(new Set([index]));
|
|
1091
1196
|
}
|
|
1092
|
-
},
|
|
1197
|
+
}, key))
|
|
1093
1198
|
}),
|
|
1094
1199
|
(0, react_jsx_runtime.jsxs)("button", {
|
|
1095
1200
|
type: "button",
|
|
@@ -1098,7 +1203,7 @@ window.__ModuleLoader__.load({
|
|
|
1098
1203
|
onClick: () => {
|
|
1099
1204
|
onChange([...models, { id: "" }]);
|
|
1100
1205
|
},
|
|
1101
|
-
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.
|
|
1206
|
+
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("addModel")]
|
|
1102
1207
|
}),
|
|
1103
1208
|
failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
1104
1209
|
className: ModelsSection_module_css_default["error"],
|
|
@@ -1346,7 +1451,9 @@ window.__ModuleLoader__.load({
|
|
|
1346
1451
|
}
|
|
1347
1452
|
const mirrored = this.describeFace.getSnapshot();
|
|
1348
1453
|
if (mirrored.view === void 0) {
|
|
1349
|
-
|
|
1454
|
+
/* v8 ignore next -- SettingsDescribeFace.ensure settles with a view or the read's error */
|
|
1455
|
+
if (mirrored.error === null) throw new Error("settings describe settled with neither a view nor an error");
|
|
1456
|
+
this.failLoad(mirrored.error);
|
|
1350
1457
|
return;
|
|
1351
1458
|
}
|
|
1352
1459
|
const providers = joinProviderDirectory(registered.value, declared.value);
|
|
@@ -1541,7 +1648,7 @@ window.__ModuleLoader__.load({
|
|
|
1541
1648
|
* @returns the creation card.
|
|
1542
1649
|
*/
|
|
1543
1650
|
function CustomProviderCard(props) {
|
|
1544
|
-
const { taken, protocols, reasoningLevels, operations, t } = props;
|
|
1651
|
+
const { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;
|
|
1545
1652
|
const [openedAt] = (0, react.useState)(() => props.revision);
|
|
1546
1653
|
const [route, setRoute] = (0, react.useState)("");
|
|
1547
1654
|
const [displayName, setDisplayName] = (0, react.useState)("");
|
|
@@ -1550,6 +1657,14 @@ window.__ModuleLoader__.load({
|
|
|
1550
1657
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1551
1658
|
const [models, setModels] = (0, react.useState)([]);
|
|
1552
1659
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
1660
|
+
const [listBusy, setListBusy] = (0, react.useState)(false);
|
|
1661
|
+
(0, react.useEffect)(() => {
|
|
1662
|
+
onBusyChange?.(busy || listBusy);
|
|
1663
|
+
}, [
|
|
1664
|
+
busy,
|
|
1665
|
+
listBusy,
|
|
1666
|
+
onBusyChange
|
|
1667
|
+
]);
|
|
1553
1668
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
1554
1669
|
/**
|
|
1555
1670
|
* The profile write landed. Only the key write can still be outstanding, so
|
|
@@ -1668,7 +1783,7 @@ window.__ModuleLoader__.load({
|
|
|
1668
1783
|
className: ModelsSection_module_css_default["input"],
|
|
1669
1784
|
type: "text",
|
|
1670
1785
|
value: baseURL,
|
|
1671
|
-
placeholder: t("customBaseUrlPlaceholder"),
|
|
1786
|
+
placeholder: t(protocol === "anthropic-messages" ? "customAnthropicBaseUrlPlaceholder" : "customBaseUrlPlaceholder"),
|
|
1672
1787
|
"aria-label": t("baseUrl"),
|
|
1673
1788
|
"aria-invalid": baseUrlInvalid,
|
|
1674
1789
|
disabled: profileDisabled,
|
|
@@ -1736,7 +1851,8 @@ window.__ModuleLoader__.load({
|
|
|
1736
1851
|
probeBlocked: baseUrlInvalid ? "customBaseUrlInvalid" : keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
|
|
1737
1852
|
operations,
|
|
1738
1853
|
t,
|
|
1739
|
-
disabled: profileDisabled
|
|
1854
|
+
disabled: profileDisabled,
|
|
1855
|
+
onBusyChange: setListBusy
|
|
1740
1856
|
}),
|
|
1741
1857
|
failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
|
|
1742
1858
|
className: ModelsSection_module_css_default["error"],
|
|
@@ -1841,8 +1957,16 @@ window.__ModuleLoader__.load({
|
|
|
1841
1957
|
const { namespace, schema, settingsPath, operations, t } = props;
|
|
1842
1958
|
const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
|
|
1843
1959
|
const [keyDraft, setKeyDraft] = (0, react.useState)("");
|
|
1844
|
-
const [keyState, setKeyState] = (0, react.useState)(void 0);
|
|
1845
1960
|
const [busy, setBusy] = (0, react.useState)(false);
|
|
1961
|
+
const [listBusy, setListBusy] = (0, react.useState)(false);
|
|
1962
|
+
const { onBusyChange } = props;
|
|
1963
|
+
(0, react.useEffect)(() => {
|
|
1964
|
+
onBusyChange?.(busy || listBusy);
|
|
1965
|
+
}, [
|
|
1966
|
+
busy,
|
|
1967
|
+
listBusy,
|
|
1968
|
+
onBusyChange
|
|
1969
|
+
]);
|
|
1846
1970
|
const [failure, setFailure] = (0, react.useState)(void 0);
|
|
1847
1971
|
const [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));
|
|
1848
1972
|
const [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);
|
|
@@ -1861,17 +1985,6 @@ window.__ModuleLoader__.load({
|
|
|
1861
1985
|
namespace,
|
|
1862
1986
|
schema
|
|
1863
1987
|
]);
|
|
1864
|
-
(0, react.useEffect)(() => {
|
|
1865
|
-
let stale = false;
|
|
1866
|
-
setKeyState(void 0);
|
|
1867
|
-
operations.describeCredential(keyRef).then((described) => {
|
|
1868
|
-
if (stale) return;
|
|
1869
|
-
setKeyState(described);
|
|
1870
|
-
});
|
|
1871
|
-
return () => {
|
|
1872
|
-
stale = true;
|
|
1873
|
-
};
|
|
1874
|
-
}, [operations, keyRef]);
|
|
1875
1988
|
const stringAt = (source, key) => {
|
|
1876
1989
|
const value = schema.getPath(source, [key]);
|
|
1877
1990
|
return typeof value === "string" && value.trim().length > 0 ? value : void 0;
|
|
@@ -1961,7 +2074,6 @@ window.__ModuleLoader__.load({
|
|
|
1961
2074
|
props.t("settingsPathUnresolvable")
|
|
1962
2075
|
]
|
|
1963
2076
|
});
|
|
1964
|
-
const keyLocked = keyState?.writable === false;
|
|
1965
2077
|
/**
|
|
1966
2078
|
* The catalog beneath the user layer: what the composition entry pinned, or
|
|
1967
2079
|
* else the schema default that `resolve` would supply. The effective value
|
|
@@ -1985,22 +2097,38 @@ window.__ModuleLoader__.load({
|
|
|
1985
2097
|
const defaultContextWindow = schema.getPath(fallback, ["defaultContextWindow"]);
|
|
1986
2098
|
const defaultMaxTokens = schema.getPath(fallback, ["maxTokens"]);
|
|
1987
2099
|
const defaultInput = schema.getPath(fallback, ["defaultInput"]);
|
|
1988
|
-
const
|
|
1989
|
-
const nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;
|
|
2100
|
+
const baseURL = stringAt(fallback, "baseURL") ?? props.defaultBaseURL;
|
|
1990
2101
|
const endpointEnv = props.baseURLEnv ?? [];
|
|
1991
|
-
const baseURL = stringAt(fallback, "baseURL");
|
|
1992
2102
|
const endpointHint = family === "deepseek" ? t("deepSeekEndpointHint") : baseURL === void 0 && endpointEnv.length > 0 ? t("baseUrlEnvironment").replace("{env}", () => endpointEnv.join(", ")) : void 0;
|
|
2103
|
+
const namedRef = stringAt(fallback, "apiKeyEnv");
|
|
2104
|
+
const nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;
|
|
1993
2105
|
const authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];
|
|
1994
2106
|
const visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes("oauth"));
|
|
1995
2107
|
const keyHint = visibleRefs[0];
|
|
1996
|
-
const checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref ===
|
|
2108
|
+
const checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);
|
|
1997
2109
|
const detected = checkedRefs.find(([, info]) => info?.configured === true);
|
|
1998
2110
|
const detectedRef = detected?.[0];
|
|
1999
2111
|
const detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;
|
|
2000
2112
|
const missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);
|
|
2001
2113
|
const savedCredential = detected?.[1]?.source === "file";
|
|
2002
|
-
const credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true
|
|
2003
|
-
const
|
|
2114
|
+
const credentialHint = keyDraft.length > 0 || savedCredential || keyHint === void 0 || props.credentialRequired === true ? void 0 : t(detectedRef === void 0 ? missingRefs ? "keyFallbackMissing" : "keyFallbackUnchecked" : detectedVisibleRef === void 0 ? "keyFallbackDetectedHidden" : "keyFallbackDetected").replace("{hint}", () => detectedVisibleRef ?? keyHint);
|
|
2115
|
+
const keyHelp = visibleRefs.length === 0 ? void 0 : t("keyHelp").replace("{env}", () => visibleRefs.join(" / "));
|
|
2116
|
+
const authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.Tooltip, {
|
|
2117
|
+
label: keyHelp,
|
|
2118
|
+
side: "right",
|
|
2119
|
+
delayMs: 0,
|
|
2120
|
+
focusDelayMs: 0,
|
|
2121
|
+
portal: true,
|
|
2122
|
+
openOnClick: true,
|
|
2123
|
+
children: (0, react_jsx_runtime.jsx)("button", {
|
|
2124
|
+
type: "button",
|
|
2125
|
+
className: ModelsSection_module_css_default["helpButton"],
|
|
2126
|
+
"aria-label": t("authHelp"),
|
|
2127
|
+
children: "?"
|
|
2128
|
+
})
|
|
2129
|
+
});
|
|
2130
|
+
const keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;
|
|
2131
|
+
const keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t("keyPlaceholder") : t(savedCredential ? "keyPlaceholderSaved" : "keyPlaceholderFallback").replace("{hint}", () => keyHint);
|
|
2004
2132
|
/** What both family editors take: the rows, whose layer owns them, and the two writes. */
|
|
2005
2133
|
const catalogProps = {
|
|
2006
2134
|
models,
|
|
@@ -2014,12 +2142,12 @@ window.__ModuleLoader__.load({
|
|
|
2014
2142
|
setDraft((current) => schema.deletePath(current, ["models"]));
|
|
2015
2143
|
}
|
|
2016
2144
|
};
|
|
2017
|
-
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
2145
|
+
return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)("div", {
|
|
2018
2146
|
className: ModelsSection_module_css_default["field"],
|
|
2019
2147
|
children: [
|
|
2020
|
-
(0, react_jsx_runtime.
|
|
2148
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
2021
2149
|
className: ModelsSection_module_css_default["fieldLabel"],
|
|
2022
|
-
children: t("keyInput")
|
|
2150
|
+
children: [t("keyInput"), authHelp]
|
|
2023
2151
|
}),
|
|
2024
2152
|
(0, react_jsx_runtime.jsx)(ApiKeyInput, {
|
|
2025
2153
|
t,
|
|
@@ -2030,7 +2158,7 @@ window.__ModuleLoader__.load({
|
|
|
2030
2158
|
"aria-describedby": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,
|
|
2031
2159
|
required: props.credentialRequired === true,
|
|
2032
2160
|
autoFocus: props.autoFocusCredential === true,
|
|
2033
|
-
disabled
|
|
2161
|
+
disabled,
|
|
2034
2162
|
onChange: (event) => {
|
|
2035
2163
|
setKeyDraft(event.target.value);
|
|
2036
2164
|
}
|
|
@@ -2081,7 +2209,7 @@ window.__ModuleLoader__.load({
|
|
|
2081
2209
|
className: ModelsSection_module_css_default["input"],
|
|
2082
2210
|
type: "text",
|
|
2083
2211
|
value: stringAt(draft, "baseURL") ?? "",
|
|
2084
|
-
placeholder: family === "deepseek" ? t("deepSeekBaseUrl") : baseURL === void 0 ? t(endpointEnv.length > 0 ? "baseUrlConfigured" : "baseUrlDefault") : baseURL,
|
|
2212
|
+
placeholder: family === "deepseek" ? t("deepSeekBaseUrl") : baseURL === void 0 ? t(endpointEnv.length > 0 ? "baseUrlConfigured" : "baseUrlDefault") : t("baseUrlPlaceholder").replace("{url}", () => baseURL),
|
|
2085
2213
|
"aria-describedby": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,
|
|
2086
2214
|
"aria-label": t("baseUrl"),
|
|
2087
2215
|
disabled,
|
|
@@ -2129,7 +2257,8 @@ window.__ModuleLoader__.load({
|
|
|
2129
2257
|
defaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,
|
|
2130
2258
|
probe,
|
|
2131
2259
|
probeBlocked: keyFailure,
|
|
2132
|
-
operations
|
|
2260
|
+
operations,
|
|
2261
|
+
onBusyChange: setListBusy
|
|
2133
2262
|
})
|
|
2134
2263
|
]
|
|
2135
2264
|
})]
|
|
@@ -2171,6 +2300,7 @@ window.__ModuleLoader__.load({
|
|
|
2171
2300
|
props.onClose(false);
|
|
2172
2301
|
},
|
|
2173
2302
|
onSubmit: () => {
|
|
2303
|
+
props.onSubmitCredential?.();
|
|
2174
2304
|
apply();
|
|
2175
2305
|
}
|
|
2176
2306
|
})
|
|
@@ -2199,8 +2329,10 @@ window.__ModuleLoader__.load({
|
|
|
2199
2329
|
displayName: target.displayName,
|
|
2200
2330
|
settingsPath: target.settingsPath,
|
|
2201
2331
|
...target.declared === true ? { declared: true } : {},
|
|
2332
|
+
...target.defaultBaseURL === void 0 ? {} : { defaultBaseURL: target.defaultBaseURL },
|
|
2202
2333
|
...target.baseURLEnv === void 0 ? {} : { baseURLEnv: target.baseURLEnv },
|
|
2203
2334
|
...target.nativeAuth === void 0 ? {} : { nativeAuth: target.nativeAuth },
|
|
2335
|
+
...row.credential === void 0 ? {} : { credential: row.credential },
|
|
2204
2336
|
...row.credentialChecks === void 0 ? {} : { credentialChecks: row.credentialChecks },
|
|
2205
2337
|
...props
|
|
2206
2338
|
});
|
|
@@ -2262,6 +2394,7 @@ window.__ModuleLoader__.load({
|
|
|
2262
2394
|
settingsPath: row.entry.settingsPath,
|
|
2263
2395
|
...credentialRef === void 0 ? {} : { credentialRef },
|
|
2264
2396
|
...row.entry.declared === true ? { declared: true } : {},
|
|
2397
|
+
...row.entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: row.entry.defaultBaseURL },
|
|
2265
2398
|
...row.entry.baseURLEnv === void 0 ? {} : { baseURLEnv: row.entry.baseURLEnv },
|
|
2266
2399
|
...row.entry.nativeAuth === void 0 ? {} : { nativeAuth: row.entry.nativeAuth }
|
|
2267
2400
|
};
|
|
@@ -2307,6 +2440,8 @@ window.__ModuleLoader__.load({
|
|
|
2307
2440
|
const [deleteFailure, setDeleteFailure] = (0, react.useState)(void 0);
|
|
2308
2441
|
const [savedTarget, setSavedTarget] = (0, react.useState)(void 0);
|
|
2309
2442
|
const [declaring, setDeclaring] = (0, react.useState)(false);
|
|
2443
|
+
/** Whether the add card's editor has a write or an interrogation in flight. */
|
|
2444
|
+
const [addBusy, setAddBusy] = (0, react.useState)(false);
|
|
2310
2445
|
const [dismissedSetup, setDismissedSetup] = (0, react.useState)(() => /* @__PURE__ */ new Set());
|
|
2311
2446
|
const announceSaved = (target) => {
|
|
2312
2447
|
controller.load().then(() => {
|
|
@@ -2317,6 +2452,7 @@ window.__ModuleLoader__.load({
|
|
|
2317
2452
|
setEditing(void 0);
|
|
2318
2453
|
setAdding(false);
|
|
2319
2454
|
setDeclaring(false);
|
|
2455
|
+
setAddBusy(false);
|
|
2320
2456
|
if (changed) announceSaved(target);
|
|
2321
2457
|
};
|
|
2322
2458
|
/**
|
|
@@ -2546,6 +2682,7 @@ window.__ModuleLoader__.load({
|
|
|
2546
2682
|
className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["selectInput"]}`,
|
|
2547
2683
|
value: addTarget.provider,
|
|
2548
2684
|
"aria-label": t("provider"),
|
|
2685
|
+
disabled: addBusy,
|
|
2549
2686
|
onChange: (event) => {
|
|
2550
2687
|
const row = addable.find((candidate) => candidate.entry.provider === event.target.value);
|
|
2551
2688
|
/* v8 ignore next -- the select only lists addable rows */
|
|
@@ -2565,6 +2702,7 @@ window.__ModuleLoader__.load({
|
|
|
2565
2702
|
namespace: addNamespace,
|
|
2566
2703
|
schema,
|
|
2567
2704
|
settingsPath: addTarget.settingsPath,
|
|
2705
|
+
...addTarget.defaultBaseURL === void 0 ? {} : { defaultBaseURL: addTarget.defaultBaseURL },
|
|
2568
2706
|
...addTarget.baseURLEnv === void 0 ? {} : { baseURLEnv: addTarget.baseURLEnv },
|
|
2569
2707
|
...addTarget.nativeAuth === void 0 ? {} : { nativeAuth: addTarget.nativeAuth },
|
|
2570
2708
|
...addRow?.credentialChecks === void 0 ? {} : { credentialChecks: addRow.credentialChecks },
|
|
@@ -2573,7 +2711,8 @@ window.__ModuleLoader__.load({
|
|
|
2573
2711
|
readOnly: !state.writable,
|
|
2574
2712
|
onClose: (changed) => {
|
|
2575
2713
|
closeEditor(changed, addTarget);
|
|
2576
|
-
}
|
|
2714
|
+
},
|
|
2715
|
+
onBusyChange: setAddBusy
|
|
2577
2716
|
}, addTarget.provider),
|
|
2578
2717
|
addRow === void 0 ? null : renderSlot("settings.models.provider-card", {
|
|
2579
2718
|
provider: addRow.entry,
|
|
@@ -2613,7 +2752,7 @@ window.__ModuleLoader__.load({
|
|
|
2613
2752
|
setAdding(true);
|
|
2614
2753
|
setEditing(targetOf(first));
|
|
2615
2754
|
},
|
|
2616
|
-
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.
|
|
2755
|
+
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("add")]
|
|
2617
2756
|
}), state.namespaces.has("llm-pi-ai") && (0, react_jsx_runtime.jsxs)("button", {
|
|
2618
2757
|
type: "button",
|
|
2619
2758
|
className: ModelsSection_module_css_default["addButton"],
|
|
@@ -2626,7 +2765,7 @@ window.__ModuleLoader__.load({
|
|
|
2626
2765
|
setEditing(void 0);
|
|
2627
2766
|
setDeclaring(true);
|
|
2628
2767
|
},
|
|
2629
|
-
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.
|
|
2768
|
+
children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("customAdd")]
|
|
2630
2769
|
})]
|
|
2631
2770
|
})
|
|
2632
2771
|
}),
|
|
@@ -2829,10 +2968,6 @@ window.__ModuleLoader__.load({
|
|
|
2829
2968
|
*/
|
|
2830
2969
|
function createModelsOperations(ctx) {
|
|
2831
2970
|
return {
|
|
2832
|
-
describeCredential: async (ref) => {
|
|
2833
|
-
const response = await ctx.remote.credentials.describe([ref]);
|
|
2834
|
-
return response.ok ? response.value[ref] : void 0;
|
|
2835
|
-
},
|
|
2836
2971
|
storeCredential: async (ref, value) => {
|
|
2837
2972
|
const response = await ctx.remote.credentials.set(ref, value);
|
|
2838
2973
|
return response.ok ? void 0 : response.error.message;
|
|
@@ -2920,19 +3055,20 @@ window.__ModuleLoader__.load({
|
|
|
2920
3055
|
keyReveal: "Show secret",
|
|
2921
3056
|
keyHide: "Hide secret",
|
|
2922
3057
|
keyPlaceholder: "Enter your API key",
|
|
2923
|
-
|
|
2924
|
-
keyStored: "Configured — enter a new value to replace",
|
|
2925
|
-
keyEnvLocked: "Provided by the launch environment (read-only)",
|
|
3058
|
+
keyPlaceholderFallback: "Leave blank to use env as auth ({hint})",
|
|
2926
3059
|
keyPlaceholderSaved: "Leave blank to use saved credentials",
|
|
2927
3060
|
keyFallbackMissing: "Env var not detected. Enter an API key, or configure {hint} in your env.",
|
|
2928
3061
|
keyFallbackDetected: "Env var detected. ({hint})",
|
|
2929
3062
|
keyFallbackDetectedHidden: "Env var detected.",
|
|
2930
3063
|
keyFallbackUnchecked: "Environment credential status has not been confirmed.",
|
|
3064
|
+
keyHelp: "Saved credentials are used first. Environment fallbacks shown here, in order: {env}. Sources are launch environment, $cwd/.env, then $QILIN_HOME/.env.",
|
|
3065
|
+
authHelp: "Authentication details",
|
|
2931
3066
|
customized: "Customized settings",
|
|
2932
3067
|
baseUrl: "Base URL",
|
|
2933
|
-
baseUrlDefault: "
|
|
3068
|
+
baseUrlDefault: "No default endpoint",
|
|
2934
3069
|
baseUrlEnvironment: "Provider endpoint configuration: {env}",
|
|
2935
3070
|
baseUrlConfigured: "Provider-configured endpoint",
|
|
3071
|
+
baseUrlPlaceholder: "{url}",
|
|
2936
3072
|
deepSeekBaseUrl: "https://api.deepseek.com/anthropic",
|
|
2937
3073
|
deepSeekEndpointHint: "Use an endpoint compatible with the configured connection.",
|
|
2938
3074
|
models: "Models",
|
|
@@ -2963,6 +3099,8 @@ window.__ModuleLoader__.load({
|
|
|
2963
3099
|
modelReasoningOffValuePlaceholder: "Turns reasoning off",
|
|
2964
3100
|
addModel: "Add model",
|
|
2965
3101
|
removeModel: "Delete model",
|
|
3102
|
+
reorderModel: "Reorder model",
|
|
3103
|
+
reorderModelHelp: "Drag the handle, or focus it and press the up or down arrow key.",
|
|
2966
3104
|
modelsEmpty: "No models will be shown in the selector. Unlisted IDs can still be sent directly.",
|
|
2967
3105
|
keyBlank: "Enter the API key, or leave the field empty to keep the stored one.",
|
|
2968
3106
|
keyBlankNew: "Enter the API key, or leave the field empty if this provider authenticates another way.",
|
|
@@ -3003,6 +3141,7 @@ window.__ModuleLoader__.load({
|
|
|
3003
3141
|
customBaseUrlInvalid: "Enter a valid HTTP or HTTPS URL.",
|
|
3004
3142
|
customNeedsModels: "A custom provider needs at least one model.",
|
|
3005
3143
|
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
3144
|
+
customAnthropicBaseUrlPlaceholder: "https://gateway.example",
|
|
3006
3145
|
settingsPathUnresolvable: "unresolvable settings path",
|
|
3007
3146
|
create: "Create provider",
|
|
3008
3147
|
creating: "Creating…",
|
|
@@ -3044,19 +3183,20 @@ window.__ModuleLoader__.load({
|
|
|
3044
3183
|
keyReveal: "显示密钥",
|
|
3045
3184
|
keyHide: "隐藏密钥",
|
|
3046
3185
|
keyPlaceholder: "输入 API 密钥",
|
|
3047
|
-
|
|
3048
|
-
keyStored: "已配置——输入新值可替换",
|
|
3049
|
-
keyEnvLocked: "由启动环境提供(只读)",
|
|
3186
|
+
keyPlaceholderFallback: "留空使用环境认证({hint})",
|
|
3050
3187
|
keyPlaceholderSaved: "留空使用已保存凭据",
|
|
3051
3188
|
keyFallbackMissing: "未检测到环境变量。请填写 API 密钥,或设置环境变量 {hint}。",
|
|
3052
3189
|
keyFallbackDetected: "已检测到环境变量({hint})",
|
|
3053
3190
|
keyFallbackDetectedHidden: "已检测到环境变量",
|
|
3054
3191
|
keyFallbackUnchecked: "环境凭据状态尚未确认",
|
|
3192
|
+
keyHelp: "优先使用已保存的凭据。此处显示的环境后备按以下顺序排列:{env}。来源依次为启动环境、$cwd/.env、$QILIN_HOME/.env。",
|
|
3193
|
+
authHelp: "认证说明",
|
|
3055
3194
|
customized: "自定义设置",
|
|
3056
3195
|
baseUrl: "API 地址",
|
|
3057
|
-
baseUrlDefault: "
|
|
3196
|
+
baseUrlDefault: "没有默认地址",
|
|
3058
3197
|
baseUrlEnvironment: "提供方地址配置:{env}",
|
|
3059
3198
|
baseUrlConfigured: "由提供方配置地址",
|
|
3199
|
+
baseUrlPlaceholder: "{url}",
|
|
3060
3200
|
deepSeekBaseUrl: "https://api.deepseek.com/anthropic",
|
|
3061
3201
|
deepSeekEndpointHint: "请填写与当前连接配置兼容的 API 地址。",
|
|
3062
3202
|
models: "模型目录",
|
|
@@ -3087,6 +3227,8 @@ window.__ModuleLoader__.load({
|
|
|
3087
3227
|
modelReasoningOffValuePlaceholder: "关闭思考",
|
|
3088
3228
|
addModel: "添加模型",
|
|
3089
3229
|
removeModel: "删除模型",
|
|
3230
|
+
reorderModel: "调整模型顺序",
|
|
3231
|
+
reorderModelHelp: "拖动手柄,或聚焦手柄后按上下方向键。",
|
|
3090
3232
|
modelsEmpty: "模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。",
|
|
3091
3233
|
keyBlank: "请输入 API 密钥;留空则保持已存储的密钥。",
|
|
3092
3234
|
keyBlankNew: "请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。",
|
|
@@ -3127,6 +3269,7 @@ window.__ModuleLoader__.load({
|
|
|
3127
3269
|
customBaseUrlInvalid: "请输入有效的 HTTP 或 HTTPS 地址。",
|
|
3128
3270
|
customNeedsModels: "自定义提供方至少需要一个模型。",
|
|
3129
3271
|
customBaseUrlPlaceholder: "https://gateway.example/v1",
|
|
3272
|
+
customAnthropicBaseUrlPlaceholder: "https://gateway.example",
|
|
3130
3273
|
settingsPathUnresolvable: "无法解析设置路径",
|
|
3131
3274
|
create: "创建提供方",
|
|
3132
3275
|
creating: "创建中…",
|
|
@@ -3138,6 +3281,904 @@ window.__ModuleLoader__.load({
|
|
|
3138
3281
|
keyRequired: "请输入 API 密钥后继续。"
|
|
3139
3282
|
};
|
|
3140
3283
|
//#endregion
|
|
3284
|
+
//#region ../../../vendor/cosmokit/src/misc.ts
|
|
3285
|
+
/** Return true when a value is `null` or `undefined`. */
|
|
3286
|
+
function isNullable(value) {
|
|
3287
|
+
return value === null || value === void 0;
|
|
3288
|
+
}
|
|
3289
|
+
/** Return true for non-array object values. */
|
|
3290
|
+
function isPlainObject(data) {
|
|
3291
|
+
return data && typeof data === "object" && !Array.isArray(data);
|
|
3292
|
+
}
|
|
3293
|
+
/** Filter object entries and return a new object. */
|
|
3294
|
+
function filterKeys(object, filter) {
|
|
3295
|
+
return Object.fromEntries(Object.entries(object).filter(([key, value]) => filter(key, value)));
|
|
3296
|
+
}
|
|
3297
|
+
/** Map object values while preserving the original key set. */
|
|
3298
|
+
function mapValues(object, transform) {
|
|
3299
|
+
return Object.fromEntries(Object.entries(object).map(([key, value]) => [key, transform(value, key)]));
|
|
3300
|
+
}
|
|
3301
|
+
/** Pick selected keys from an object, optionally including `undefined` values. */
|
|
3302
|
+
function pick(source, keys, forced) {
|
|
3303
|
+
if (!keys) return { ...source };
|
|
3304
|
+
const result = {};
|
|
3305
|
+
for (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];
|
|
3306
|
+
return result;
|
|
3307
|
+
}
|
|
3308
|
+
//#endregion
|
|
3309
|
+
//#region ../../../vendor/cosmokit/src/volatile.ts
|
|
3310
|
+
/** Shared config references used by schema validators and plugin runtimes. */
|
|
3311
|
+
const write = Symbol.for("cosmokit.volatile.write");
|
|
3312
|
+
function snapshot(value, ancestors = /* @__PURE__ */ new Set()) {
|
|
3313
|
+
if (typeof value === "function") throw new TypeError("volatile config cannot contain functions");
|
|
3314
|
+
if (value === null || typeof value !== "object") return value;
|
|
3315
|
+
if (ancestors.has(value)) throw new TypeError("volatile config cannot contain cycles");
|
|
3316
|
+
ancestors.add(value);
|
|
3317
|
+
try {
|
|
3318
|
+
if (Array.isArray(value)) return Object.freeze(value.map((item) => snapshot(item, ancestors)));
|
|
3319
|
+
if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new TypeError("volatile config objects must be plain objects or arrays");
|
|
3320
|
+
return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, snapshot(item, ancestors)])));
|
|
3321
|
+
} finally {
|
|
3322
|
+
ancestors.delete(value);
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
/**
|
|
3326
|
+
* Create a detached reference containing an immutable copy of the supplied data.
|
|
3327
|
+
* @param value - validated config data; class instances and functions are unsupported.
|
|
3328
|
+
* @returns a reference whose value is updated only by its owning runtime.
|
|
3329
|
+
*/
|
|
3330
|
+
function createVolatile(value) {
|
|
3331
|
+
let current = snapshot(value);
|
|
3332
|
+
return Object.freeze({
|
|
3333
|
+
get: () => current,
|
|
3334
|
+
[write]: (value) => {
|
|
3335
|
+
current = value;
|
|
3336
|
+
}
|
|
3337
|
+
});
|
|
3338
|
+
}
|
|
3339
|
+
/**
|
|
3340
|
+
* Identify references across ESM/CJS copies of the shared library.
|
|
3341
|
+
* @param value - a parsed config value.
|
|
3342
|
+
* @returns whether the value implements the shared reference protocol.
|
|
3343
|
+
*/
|
|
3344
|
+
function isVolatile(value) {
|
|
3345
|
+
return typeof value === "object" && value !== null && write in value;
|
|
3346
|
+
}
|
|
3347
|
+
//#endregion
|
|
3348
|
+
//#region ../../../vendor/cosmokit/src/types.ts
|
|
3349
|
+
/** Test values using `instanceof` with a `toStringTag` fallback. */
|
|
3350
|
+
function is(type, value) {
|
|
3351
|
+
if (arguments.length === 1) return (value) => is(type, value);
|
|
3352
|
+
return type in globalThis && value instanceof globalThis[type] || Object.prototype.toString.call(value).slice(8, -1) === type;
|
|
3353
|
+
}
|
|
3354
|
+
function isArrayBufferLike(value) {
|
|
3355
|
+
return is("ArrayBuffer", value) || is("SharedArrayBuffer", value);
|
|
3356
|
+
}
|
|
3357
|
+
function isArrayBufferSource(value) {
|
|
3358
|
+
return isArrayBufferLike(value) || ArrayBuffer.isView(value);
|
|
3359
|
+
}
|
|
3360
|
+
let Binary;
|
|
3361
|
+
(function(_Binary) {
|
|
3362
|
+
_Binary.is = isArrayBufferLike;
|
|
3363
|
+
_Binary.isSource = isArrayBufferSource;
|
|
3364
|
+
function fromSource(source) {
|
|
3365
|
+
if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
|
|
3366
|
+
else return source;
|
|
3367
|
+
}
|
|
3368
|
+
_Binary.fromSource = fromSource;
|
|
3369
|
+
function toBase64(source) {
|
|
3370
|
+
source = fromSource(source);
|
|
3371
|
+
if (typeof Buffer !== "undefined") return Buffer.from(source).toString("base64");
|
|
3372
|
+
let binary = "";
|
|
3373
|
+
const bytes = new Uint8Array(source);
|
|
3374
|
+
for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);
|
|
3375
|
+
return btoa(binary);
|
|
3376
|
+
}
|
|
3377
|
+
_Binary.toBase64 = toBase64;
|
|
3378
|
+
function fromBase64(source) {
|
|
3379
|
+
if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "base64"));
|
|
3380
|
+
return Uint8Array.from(atob(source), (c) => c.charCodeAt(0));
|
|
3381
|
+
}
|
|
3382
|
+
_Binary.fromBase64 = fromBase64;
|
|
3383
|
+
function toHex(source) {
|
|
3384
|
+
source = fromSource(source);
|
|
3385
|
+
if (typeof Buffer !== "undefined") return Buffer.from(source).toString("hex");
|
|
3386
|
+
return Array.from(new Uint8Array(source), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
3387
|
+
}
|
|
3388
|
+
_Binary.toHex = toHex;
|
|
3389
|
+
function fromHex(source) {
|
|
3390
|
+
if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "hex"));
|
|
3391
|
+
const hex = source.length % 2 === 0 ? source : source.slice(0, source.length - 1);
|
|
3392
|
+
const buffer = [];
|
|
3393
|
+
for (let i = 0; i < hex.length; i += 2) buffer.push(parseInt(`${hex[i]}${hex[i + 1]}`, 16));
|
|
3394
|
+
return Uint8Array.from(buffer).buffer;
|
|
3395
|
+
}
|
|
3396
|
+
_Binary.fromHex = fromHex;
|
|
3397
|
+
})(Binary || (Binary = {}));
|
|
3398
|
+
Binary.fromBase64;
|
|
3399
|
+
Binary.toBase64;
|
|
3400
|
+
Binary.fromHex;
|
|
3401
|
+
Binary.toHex;
|
|
3402
|
+
/** Deep-clone common JavaScript values while preserving prototypes and cycles. */
|
|
3403
|
+
function clone(source, refs = /* @__PURE__ */ new Map()) {
|
|
3404
|
+
if (!source || typeof source !== "object") return source;
|
|
3405
|
+
if (is("Date", source)) return new Date(source.valueOf());
|
|
3406
|
+
if (is("RegExp", source)) return new RegExp(source.source, source.flags);
|
|
3407
|
+
if (isArrayBufferLike(source)) return source.slice(0);
|
|
3408
|
+
if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
|
|
3409
|
+
const cached = refs.get(source);
|
|
3410
|
+
if (cached) return cached;
|
|
3411
|
+
if (Array.isArray(source)) {
|
|
3412
|
+
const result = [];
|
|
3413
|
+
refs.set(source, result);
|
|
3414
|
+
source.forEach((value, index) => {
|
|
3415
|
+
result[index] = Reflect.apply(clone, null, [value, refs]);
|
|
3416
|
+
});
|
|
3417
|
+
return result;
|
|
3418
|
+
}
|
|
3419
|
+
const result = Object.create(Object.getPrototypeOf(source));
|
|
3420
|
+
refs.set(source, result);
|
|
3421
|
+
for (const key of Reflect.ownKeys(source)) {
|
|
3422
|
+
const descriptor = { ...Reflect.getOwnPropertyDescriptor(source, key) };
|
|
3423
|
+
if ("value" in descriptor) descriptor.value = Reflect.apply(clone, null, [descriptor.value, refs]);
|
|
3424
|
+
Reflect.defineProperty(result, key, descriptor);
|
|
3425
|
+
}
|
|
3426
|
+
return result;
|
|
3427
|
+
}
|
|
3428
|
+
/**
|
|
3429
|
+
* Compare values recursively, treating two volatile references as equal regardless of value.
|
|
3430
|
+
* Strict comparison distinguishes null/undefined, treats opaque objects by identity,
|
|
3431
|
+
* compares URLs by normalized href, treats array holes as undefined, and considers distinct cyclic structures unequal.
|
|
3432
|
+
* @param a - first value.
|
|
3433
|
+
* @param b - second value.
|
|
3434
|
+
* @param strict - whether to require strict data equality outside volatile references.
|
|
3435
|
+
* @returns whether the values compare equal.
|
|
3436
|
+
*/
|
|
3437
|
+
function deepEqual(a, b, strict) {
|
|
3438
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
3439
|
+
function compare(a, b) {
|
|
3440
|
+
if (a === b) return true;
|
|
3441
|
+
if (isVolatile(a) || isVolatile(b)) return isVolatile(a) && isVolatile(b);
|
|
3442
|
+
if (!strict && isNullable(a) && isNullable(b)) return true;
|
|
3443
|
+
if (typeof a !== typeof b || typeof a !== "object" || !a || !b) return false;
|
|
3444
|
+
if (ancestors.has(a)) return false;
|
|
3445
|
+
function check(test, then) {
|
|
3446
|
+
return test(a) ? test(b) ? then(a, b) : false : test(b) ? false : void 0;
|
|
3447
|
+
}
|
|
3448
|
+
ancestors.add(a);
|
|
3449
|
+
try {
|
|
3450
|
+
return check(Array.isArray, (a, b) => {
|
|
3451
|
+
if (a.length !== b.length) return false;
|
|
3452
|
+
for (let index = 0; index < a.length; index++) if (!compare(a[index], b[index])) return false;
|
|
3453
|
+
return true;
|
|
3454
|
+
}) ?? 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) => {
|
|
3455
|
+
if (a.byteLength !== b.byteLength) return false;
|
|
3456
|
+
const viewA = new Uint8Array(a);
|
|
3457
|
+
const viewB = new Uint8Array(b);
|
|
3458
|
+
for (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;
|
|
3459
|
+
return true;
|
|
3460
|
+
}) ?? ((!strict || [a, b].every((value) => Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) && Object.keys({
|
|
3461
|
+
...a,
|
|
3462
|
+
...b
|
|
3463
|
+
}).every((key) => compare(a[key], b[key])));
|
|
3464
|
+
} finally {
|
|
3465
|
+
ancestors.delete(a);
|
|
3466
|
+
}
|
|
3467
|
+
}
|
|
3468
|
+
return compare(a, b);
|
|
3469
|
+
}
|
|
3470
|
+
//#endregion
|
|
3471
|
+
//#region ../../../vendor/cosmokit/src/time.ts
|
|
3472
|
+
let Time;
|
|
3473
|
+
(function(_Time) {
|
|
3474
|
+
_Time.millisecond = 1;
|
|
3475
|
+
const second = _Time.second = 1e3;
|
|
3476
|
+
const minute = _Time.minute = second * 60;
|
|
3477
|
+
const hour = _Time.hour = minute * 60;
|
|
3478
|
+
const day = _Time.day = hour * 24;
|
|
3479
|
+
const week = _Time.week = day * 7;
|
|
3480
|
+
let timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
|
|
3481
|
+
function setTimezoneOffset(offset) {
|
|
3482
|
+
timezoneOffset = offset;
|
|
3483
|
+
}
|
|
3484
|
+
_Time.setTimezoneOffset = setTimezoneOffset;
|
|
3485
|
+
function getTimezoneOffset() {
|
|
3486
|
+
return timezoneOffset;
|
|
3487
|
+
}
|
|
3488
|
+
_Time.getTimezoneOffset = getTimezoneOffset;
|
|
3489
|
+
function getDateNumber(date = /* @__PURE__ */ new Date(), offset) {
|
|
3490
|
+
if (typeof date === "number") date = new Date(date);
|
|
3491
|
+
if (offset === void 0) offset = timezoneOffset;
|
|
3492
|
+
return Math.floor((date.valueOf() / minute - offset) / 1440);
|
|
3493
|
+
}
|
|
3494
|
+
_Time.getDateNumber = getDateNumber;
|
|
3495
|
+
function fromDateNumber(value, offset) {
|
|
3496
|
+
const date = new Date(value * day);
|
|
3497
|
+
if (offset === void 0) offset = timezoneOffset;
|
|
3498
|
+
return new Date(+date + offset * minute);
|
|
3499
|
+
}
|
|
3500
|
+
_Time.fromDateNumber = fromDateNumber;
|
|
3501
|
+
const numeric = /\d+(?:\.\d+)?/.source;
|
|
3502
|
+
const timeRegExp = new RegExp(`^${[
|
|
3503
|
+
"w(?:eek(?:s)?)?",
|
|
3504
|
+
"d(?:ay(?:s)?)?",
|
|
3505
|
+
"h(?:our(?:s)?)?",
|
|
3506
|
+
"m(?:in(?:ute)?(?:s)?)?",
|
|
3507
|
+
"s(?:ec(?:ond)?(?:s)?)?"
|
|
3508
|
+
].map((unit) => `(${numeric}${unit})?`).join("")}$`);
|
|
3509
|
+
function parseTime(source) {
|
|
3510
|
+
const capture = timeRegExp.exec(source);
|
|
3511
|
+
if (!capture) return 0;
|
|
3512
|
+
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);
|
|
3513
|
+
}
|
|
3514
|
+
_Time.parseTime = parseTime;
|
|
3515
|
+
function parseDate(date) {
|
|
3516
|
+
const parsed = parseTime(date);
|
|
3517
|
+
if (parsed) date = Date.now() + parsed;
|
|
3518
|
+
else if (/^\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).toLocaleDateString()}-${date}`;
|
|
3519
|
+
else if (/^\d{1,2}-\d{1,2}-\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).getFullYear()}-${date}`;
|
|
3520
|
+
return date ? new Date(date) : /* @__PURE__ */ new Date();
|
|
3521
|
+
}
|
|
3522
|
+
_Time.parseDate = parseDate;
|
|
3523
|
+
function format(ms) {
|
|
3524
|
+
const abs = Math.abs(ms);
|
|
3525
|
+
if (abs >= day - hour / 2) return Math.round(ms / day) + "d";
|
|
3526
|
+
else if (abs >= hour - minute / 2) return Math.round(ms / hour) + "h";
|
|
3527
|
+
else if (abs >= minute - second / 2) return Math.round(ms / minute) + "m";
|
|
3528
|
+
else if (abs >= second) return Math.round(ms / second) + "s";
|
|
3529
|
+
return ms + "ms";
|
|
3530
|
+
}
|
|
3531
|
+
_Time.format = format;
|
|
3532
|
+
function toDigits(source, length = 2) {
|
|
3533
|
+
return source.toString().padStart(length, "0");
|
|
3534
|
+
}
|
|
3535
|
+
_Time.toDigits = toDigits;
|
|
3536
|
+
function template(template, time = /* @__PURE__ */ new Date()) {
|
|
3537
|
+
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));
|
|
3538
|
+
}
|
|
3539
|
+
_Time.template = template;
|
|
3540
|
+
})(Time || (Time = {}));
|
|
3541
|
+
//#endregion
|
|
3542
|
+
//#region ../../../vendor/schemastery/src/index.ts
|
|
3543
|
+
const kSchema = Symbol.for("schemastery");
|
|
3544
|
+
const kValidationError = Symbol.for("ValidationError");
|
|
3545
|
+
globalThis.__schemastery_index__ ??= 0;
|
|
3546
|
+
globalThis.__schemastery_refs__ = void 0;
|
|
3547
|
+
var ValidationError = class extends TypeError {
|
|
3548
|
+
options;
|
|
3549
|
+
name = "ValidationError";
|
|
3550
|
+
constructor(message, options) {
|
|
3551
|
+
let prefix = "$";
|
|
3552
|
+
for (const segment of options.path || []) if (typeof segment === "string") prefix += "." + segment;
|
|
3553
|
+
else if (typeof segment === "number") prefix += "[" + segment + "]";
|
|
3554
|
+
else if (typeof segment === "symbol") prefix += `[Symbol(${segment.toString()})]`;
|
|
3555
|
+
if (prefix.startsWith(".")) prefix = prefix.slice(1);
|
|
3556
|
+
super((prefix === "$" ? "" : `${prefix} `) + message);
|
|
3557
|
+
this.options = options;
|
|
3558
|
+
}
|
|
3559
|
+
static is(error) {
|
|
3560
|
+
return !!error?.[kValidationError];
|
|
3561
|
+
}
|
|
3562
|
+
};
|
|
3563
|
+
Object.defineProperty(ValidationError.prototype, kValidationError, { value: true });
|
|
3564
|
+
const Schema = function(options) {
|
|
3565
|
+
const schema = function(data, options = {}) {
|
|
3566
|
+
return Schema.resolve(data, schema, options)[0];
|
|
3567
|
+
};
|
|
3568
|
+
if (options.refs) {
|
|
3569
|
+
const refs = mapValues(options.refs, (options) => new Schema(options));
|
|
3570
|
+
const getRef = (uid) => refs[uid];
|
|
3571
|
+
for (const key in refs) {
|
|
3572
|
+
const options = refs[key];
|
|
3573
|
+
options.sKey = getRef(options.sKey);
|
|
3574
|
+
options.inner = getRef(options.inner);
|
|
3575
|
+
options.list = options.list && options.list.map(getRef);
|
|
3576
|
+
options.dict = options.dict && mapValues(options.dict, getRef);
|
|
3577
|
+
}
|
|
3578
|
+
return refs[options.uid];
|
|
3579
|
+
}
|
|
3580
|
+
Object.assign(schema, options);
|
|
3581
|
+
if (typeof schema.callback === "string") try {
|
|
3582
|
+
schema.callback = new Function("return " + schema.callback)();
|
|
3583
|
+
} catch {}
|
|
3584
|
+
Object.defineProperty(schema, "uid", { value: globalThis.__schemastery_index__++ });
|
|
3585
|
+
Object.setPrototypeOf(schema, Schema.prototype);
|
|
3586
|
+
schema.meta ||= {};
|
|
3587
|
+
schema.toString = schema.toString.bind(schema);
|
|
3588
|
+
return schema;
|
|
3589
|
+
};
|
|
3590
|
+
Schema.prototype = Object.create(Function.prototype);
|
|
3591
|
+
Schema.prototype[kSchema] = true;
|
|
3592
|
+
Object.defineProperty(Schema.prototype, "~standard", { get() {
|
|
3593
|
+
return {
|
|
3594
|
+
version: 1,
|
|
3595
|
+
vendor: "schemastery",
|
|
3596
|
+
validate: (value) => {
|
|
3597
|
+
try {
|
|
3598
|
+
return { value: Schema.resolve(value, this, {})[0] };
|
|
3599
|
+
} catch (error) {
|
|
3600
|
+
if (ValidationError.is(error)) return { issues: [{
|
|
3601
|
+
message: error.message,
|
|
3602
|
+
path: error.options.path
|
|
3603
|
+
}] };
|
|
3604
|
+
throw error;
|
|
3605
|
+
}
|
|
3606
|
+
}
|
|
3607
|
+
};
|
|
3608
|
+
} });
|
|
3609
|
+
Schema.ValidationError = ValidationError;
|
|
3610
|
+
Schema.prototype.toJSON = function toJSON() {
|
|
3611
|
+
if (globalThis.__schemastery_refs__) {
|
|
3612
|
+
globalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }));
|
|
3613
|
+
return this.uid;
|
|
3614
|
+
}
|
|
3615
|
+
globalThis.__schemastery_refs__ = { [this.uid]: { ...this } };
|
|
3616
|
+
globalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }));
|
|
3617
|
+
const result = {
|
|
3618
|
+
uid: this.uid,
|
|
3619
|
+
refs: globalThis.__schemastery_refs__
|
|
3620
|
+
};
|
|
3621
|
+
globalThis.__schemastery_refs__ = void 0;
|
|
3622
|
+
return result;
|
|
3623
|
+
};
|
|
3624
|
+
Schema.prototype.set = function set(key, value) {
|
|
3625
|
+
this.dict[key] = value;
|
|
3626
|
+
return this;
|
|
3627
|
+
};
|
|
3628
|
+
Schema.prototype.push = function push(value) {
|
|
3629
|
+
this.list.push(value);
|
|
3630
|
+
return this;
|
|
3631
|
+
};
|
|
3632
|
+
function mergeDesc(original, messages) {
|
|
3633
|
+
const result = typeof original === "string" ? { "": original } : { ...original };
|
|
3634
|
+
for (const locale in messages) {
|
|
3635
|
+
const value = messages[locale];
|
|
3636
|
+
if (value?.$description || value?.$desc) result[locale] = value.$description || value.$desc;
|
|
3637
|
+
else if (typeof value === "string") result[locale] = value;
|
|
3638
|
+
}
|
|
3639
|
+
return result;
|
|
3640
|
+
}
|
|
3641
|
+
function getInner(value) {
|
|
3642
|
+
return value?.$value ?? value?.$inner;
|
|
3643
|
+
}
|
|
3644
|
+
function extractKeys(data) {
|
|
3645
|
+
return filterKeys(data ?? {}, (key) => !key.startsWith("$"));
|
|
3646
|
+
}
|
|
3647
|
+
Schema.prototype.i18n = function i18n(messages) {
|
|
3648
|
+
const schema = Schema(this);
|
|
3649
|
+
const desc = mergeDesc(schema.meta.description, messages);
|
|
3650
|
+
if (Object.keys(desc).length) schema.meta.description = desc;
|
|
3651
|
+
if (schema.dict) schema.dict = mapValues(schema.dict, (inner, key) => {
|
|
3652
|
+
return inner.i18n(mapValues(messages, (data) => getInner(data)?.[key] ?? data?.[key]));
|
|
3653
|
+
});
|
|
3654
|
+
if (schema.list) schema.list = schema.list.map((inner, index) => {
|
|
3655
|
+
return inner.i18n(mapValues(messages, (data = {}) => {
|
|
3656
|
+
if (Array.isArray(getInner(data))) return getInner(data)[index];
|
|
3657
|
+
if (Array.isArray(data)) return data[index];
|
|
3658
|
+
return extractKeys(data);
|
|
3659
|
+
}));
|
|
3660
|
+
});
|
|
3661
|
+
if (schema.inner) schema.inner = schema.inner.i18n(mapValues(messages, (data) => {
|
|
3662
|
+
if (getInner(data)) return getInner(data);
|
|
3663
|
+
return extractKeys(data);
|
|
3664
|
+
}));
|
|
3665
|
+
if (schema.sKey) schema.sKey = schema.sKey.i18n(mapValues(messages, (data) => data?.$key));
|
|
3666
|
+
return schema;
|
|
3667
|
+
};
|
|
3668
|
+
Schema.prototype.extra = function extra(key, value) {
|
|
3669
|
+
const schema = Schema(this);
|
|
3670
|
+
schema.meta = {
|
|
3671
|
+
...schema.meta,
|
|
3672
|
+
[key]: value
|
|
3673
|
+
};
|
|
3674
|
+
return schema;
|
|
3675
|
+
};
|
|
3676
|
+
for (const key of [
|
|
3677
|
+
"required",
|
|
3678
|
+
"disabled",
|
|
3679
|
+
"collapse",
|
|
3680
|
+
"hidden",
|
|
3681
|
+
"loose"
|
|
3682
|
+
]) Object.assign(Schema.prototype, { [key](value = true) {
|
|
3683
|
+
const schema = Schema(this);
|
|
3684
|
+
schema.meta = {
|
|
3685
|
+
...schema.meta,
|
|
3686
|
+
[key]: value
|
|
3687
|
+
};
|
|
3688
|
+
return schema;
|
|
3689
|
+
} });
|
|
3690
|
+
Schema.prototype.deprecated = function deprecated() {
|
|
3691
|
+
const schema = Schema(this);
|
|
3692
|
+
schema.meta.badges ||= [];
|
|
3693
|
+
schema.meta.badges.push({
|
|
3694
|
+
text: "deprecated",
|
|
3695
|
+
type: "danger"
|
|
3696
|
+
});
|
|
3697
|
+
return schema;
|
|
3698
|
+
};
|
|
3699
|
+
Schema.prototype.experimental = function experimental() {
|
|
3700
|
+
const schema = Schema(this);
|
|
3701
|
+
schema.meta.badges ||= [];
|
|
3702
|
+
schema.meta.badges.push({
|
|
3703
|
+
text: "experimental",
|
|
3704
|
+
type: "warning"
|
|
3705
|
+
});
|
|
3706
|
+
return schema;
|
|
3707
|
+
};
|
|
3708
|
+
Schema.prototype.pattern = function pattern(regexp) {
|
|
3709
|
+
const schema = Schema(this);
|
|
3710
|
+
const pattern = pick(regexp, ["source", "flags"]);
|
|
3711
|
+
schema.meta = {
|
|
3712
|
+
...schema.meta,
|
|
3713
|
+
pattern
|
|
3714
|
+
};
|
|
3715
|
+
return schema;
|
|
3716
|
+
};
|
|
3717
|
+
Schema.prototype.simplify = function simplify(value) {
|
|
3718
|
+
if (isVolatile(value)) value = value.get();
|
|
3719
|
+
if (deepEqual(value, this.meta.default, this.type === "dict")) return null;
|
|
3720
|
+
if (isNullable(value)) return value;
|
|
3721
|
+
if (this.type === "object" || this.type === "dict") {
|
|
3722
|
+
const result = {};
|
|
3723
|
+
for (const key in value) {
|
|
3724
|
+
const item = (this.type === "object" ? this.dict[key] : this.inner)?.simplify(value[key]);
|
|
3725
|
+
if (this.type === "dict" || !isNullable(item)) result[key] = item;
|
|
3726
|
+
}
|
|
3727
|
+
if (deepEqual(result, this.meta.default, this.type === "dict")) return null;
|
|
3728
|
+
return result;
|
|
3729
|
+
} else if (this.type === "array" || this.type === "tuple") {
|
|
3730
|
+
const result = [];
|
|
3731
|
+
value.forEach((value, index) => {
|
|
3732
|
+
const schema = this.type === "array" ? this.inner : this.list[index];
|
|
3733
|
+
const item = schema ? schema.simplify(value) : value;
|
|
3734
|
+
result.push(item);
|
|
3735
|
+
});
|
|
3736
|
+
return result;
|
|
3737
|
+
} else if (this.type === "intersect") {
|
|
3738
|
+
const result = {};
|
|
3739
|
+
for (const item of this.list) Object.assign(result, item.simplify(value));
|
|
3740
|
+
return result;
|
|
3741
|
+
} else if (this.type === "union") for (const schema of this.list) try {
|
|
3742
|
+
Schema.resolve(value, schema, {});
|
|
3743
|
+
return schema.simplify(value);
|
|
3744
|
+
} catch {}
|
|
3745
|
+
return value;
|
|
3746
|
+
};
|
|
3747
|
+
Schema.prototype.toString = function toString(inline) {
|
|
3748
|
+
return formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`;
|
|
3749
|
+
};
|
|
3750
|
+
Schema.prototype.role = function role(role, extra) {
|
|
3751
|
+
const schema = Schema(this);
|
|
3752
|
+
schema.meta = {
|
|
3753
|
+
...schema.meta,
|
|
3754
|
+
role,
|
|
3755
|
+
extra
|
|
3756
|
+
};
|
|
3757
|
+
return schema;
|
|
3758
|
+
};
|
|
3759
|
+
for (const key of [
|
|
3760
|
+
"default",
|
|
3761
|
+
"link",
|
|
3762
|
+
"comment",
|
|
3763
|
+
"description",
|
|
3764
|
+
"max",
|
|
3765
|
+
"min",
|
|
3766
|
+
"step"
|
|
3767
|
+
]) Object.assign(Schema.prototype, { [key](value) {
|
|
3768
|
+
const schema = Schema(this);
|
|
3769
|
+
schema.meta = {
|
|
3770
|
+
...schema.meta,
|
|
3771
|
+
[key]: value
|
|
3772
|
+
};
|
|
3773
|
+
return schema;
|
|
3774
|
+
} });
|
|
3775
|
+
Schema.prototype.volatile = function volatile() {
|
|
3776
|
+
if (this.meta.volatile) throw new TypeError("volatile schema is already wrapped");
|
|
3777
|
+
return this.extra("volatile", true);
|
|
3778
|
+
};
|
|
3779
|
+
const resolvers = {};
|
|
3780
|
+
const checkedVolatile = Symbol("checked-volatile-schema");
|
|
3781
|
+
function validateVolatileSchema(schema, path = [], blocked = false, seen = /* @__PURE__ */ new Map()) {
|
|
3782
|
+
const states = seen.get(schema) ?? /* @__PURE__ */ new Set();
|
|
3783
|
+
if (states.has(blocked)) return;
|
|
3784
|
+
states.add(blocked);
|
|
3785
|
+
seen.set(schema, states);
|
|
3786
|
+
if (schema.meta?.volatile && blocked) throw new ValidationError("volatile fields require a fixed object path without an enclosing volatile field", { path });
|
|
3787
|
+
const nested = blocked || !!schema.meta?.volatile;
|
|
3788
|
+
if (schema.dict) for (const [key, child] of Object.entries(schema.dict)) validateVolatileSchema(child, [...path, key], nested, seen);
|
|
3789
|
+
if (schema.sKey) validateVolatileSchema(schema.sKey, [...path, "<key>"], true, seen);
|
|
3790
|
+
if (schema.inner && (schema.type !== "lazy" || schema.inner[kSchema])) validateVolatileSchema(schema.inner, [...path, "*"], true, seen);
|
|
3791
|
+
if (schema.list) for (let index = 0; index < schema.list.length; index++) validateVolatileSchema(schema.list[index], [...path, String(index)], true, seen);
|
|
3792
|
+
}
|
|
3793
|
+
Schema.extend = function extend(type, resolve) {
|
|
3794
|
+
resolvers[type] = resolve;
|
|
3795
|
+
};
|
|
3796
|
+
Schema.resolve = function resolve(data, schema, options = {}, strict = false) {
|
|
3797
|
+
if (!schema) return [data];
|
|
3798
|
+
if (!options[checkedVolatile]) {
|
|
3799
|
+
validateVolatileSchema(schema, options.path);
|
|
3800
|
+
options = {
|
|
3801
|
+
...options,
|
|
3802
|
+
[checkedVolatile]: true
|
|
3803
|
+
};
|
|
3804
|
+
}
|
|
3805
|
+
if (schema.meta?.volatile) {
|
|
3806
|
+
const inner = Schema(schema);
|
|
3807
|
+
inner.meta = {
|
|
3808
|
+
...schema.meta,
|
|
3809
|
+
volatile: false
|
|
3810
|
+
};
|
|
3811
|
+
const [value, adapted] = Schema.resolve(data, inner, options, strict);
|
|
3812
|
+
try {
|
|
3813
|
+
return [createVolatile(value), adapted];
|
|
3814
|
+
} catch (error) {
|
|
3815
|
+
throw new ValidationError(error instanceof Error ? error.message : String(error), options);
|
|
3816
|
+
}
|
|
3817
|
+
}
|
|
3818
|
+
if (options.ignore?.(data, schema)) return [data];
|
|
3819
|
+
if (isNullable(data) && schema.type !== "lazy") {
|
|
3820
|
+
if (schema.meta.required) throw new ValidationError(`missing required value`, options);
|
|
3821
|
+
let current = schema;
|
|
3822
|
+
let fallback = schema.meta.default;
|
|
3823
|
+
while (current?.type === "intersect" && isNullable(fallback)) {
|
|
3824
|
+
current = current.list[0];
|
|
3825
|
+
fallback = current?.meta.default;
|
|
3826
|
+
}
|
|
3827
|
+
if (isNullable(fallback)) return [data];
|
|
3828
|
+
data = clone(fallback);
|
|
3829
|
+
}
|
|
3830
|
+
const callback = resolvers[schema.type];
|
|
3831
|
+
if (!callback) throw new ValidationError(`unsupported type "${schema.type}"`, options);
|
|
3832
|
+
try {
|
|
3833
|
+
return callback(data, schema, options, strict);
|
|
3834
|
+
} catch (error) {
|
|
3835
|
+
if (!schema.meta.loose) throw error;
|
|
3836
|
+
return [schema.meta.default];
|
|
3837
|
+
}
|
|
3838
|
+
};
|
|
3839
|
+
Schema.from = function from(source) {
|
|
3840
|
+
if (isNullable(source)) return Schema.any();
|
|
3841
|
+
else if ([
|
|
3842
|
+
"string",
|
|
3843
|
+
"number",
|
|
3844
|
+
"boolean"
|
|
3845
|
+
].includes(typeof source)) return Schema.const(source).required();
|
|
3846
|
+
else if (source[kSchema]) return source;
|
|
3847
|
+
else if (typeof source === "function") switch (source) {
|
|
3848
|
+
case String: return Schema.string().required();
|
|
3849
|
+
case Number: return Schema.number().required();
|
|
3850
|
+
case Boolean: return Schema.boolean().required();
|
|
3851
|
+
case Function: return Schema.function().required();
|
|
3852
|
+
default: return Schema.is(source).required();
|
|
3853
|
+
}
|
|
3854
|
+
else throw new TypeError(`cannot infer schema from ${source}`);
|
|
3855
|
+
};
|
|
3856
|
+
Schema.lazy = function lazy(builder) {
|
|
3857
|
+
const toJSON = () => {
|
|
3858
|
+
if (!schema.inner[kSchema]) {
|
|
3859
|
+
schema.inner = schema.builder();
|
|
3860
|
+
schema.inner.meta = {
|
|
3861
|
+
...schema.meta,
|
|
3862
|
+
...schema.inner.meta
|
|
3863
|
+
};
|
|
3864
|
+
}
|
|
3865
|
+
return schema.inner.toJSON();
|
|
3866
|
+
};
|
|
3867
|
+
const schema = new Schema({
|
|
3868
|
+
type: "lazy",
|
|
3869
|
+
builder,
|
|
3870
|
+
inner: { toJSON }
|
|
3871
|
+
});
|
|
3872
|
+
return schema;
|
|
3873
|
+
};
|
|
3874
|
+
Schema.natural = function natural() {
|
|
3875
|
+
return Schema.number().step(1).min(0);
|
|
3876
|
+
};
|
|
3877
|
+
Schema.percent = function percent() {
|
|
3878
|
+
return Schema.number().step(.01).min(0).max(1).role("slider");
|
|
3879
|
+
};
|
|
3880
|
+
Schema.date = function date() {
|
|
3881
|
+
return Schema.union([Schema.is(Date), Schema.transform(Schema.string().role("datetime"), (value, options) => {
|
|
3882
|
+
const date = new Date(value);
|
|
3883
|
+
if (isNaN(+date)) throw new ValidationError(`invalid date "${value}"`, options);
|
|
3884
|
+
return date;
|
|
3885
|
+
}, true)]);
|
|
3886
|
+
};
|
|
3887
|
+
Schema.regExp = function regExp(flag = "") {
|
|
3888
|
+
return Schema.union([Schema.is(RegExp), Schema.transform(Schema.string().role("regexp", { flag }), (value, options) => {
|
|
3889
|
+
try {
|
|
3890
|
+
return new RegExp(value, flag);
|
|
3891
|
+
} catch (e) {
|
|
3892
|
+
throw new ValidationError(e.message, options);
|
|
3893
|
+
}
|
|
3894
|
+
}, true)]);
|
|
3895
|
+
};
|
|
3896
|
+
Schema.arrayBuffer = function arrayBuffer(encoding) {
|
|
3897
|
+
return Schema.union([
|
|
3898
|
+
Schema.is(ArrayBuffer),
|
|
3899
|
+
Schema.is(SharedArrayBuffer),
|
|
3900
|
+
Schema.transform(Schema.any(), (value, options) => {
|
|
3901
|
+
if (Binary.isSource(value)) return Binary.fromSource(value);
|
|
3902
|
+
throw new ValidationError(`expected ArrayBufferSource but got ${value}`, options);
|
|
3903
|
+
}, true),
|
|
3904
|
+
...encoding ? [Schema.transform(Schema.string(), (value, options) => {
|
|
3905
|
+
try {
|
|
3906
|
+
return encoding === "base64" ? Binary.fromBase64(value) : Binary.fromHex(value);
|
|
3907
|
+
} catch (e) {
|
|
3908
|
+
throw new ValidationError(e.message, options);
|
|
3909
|
+
}
|
|
3910
|
+
}, true)] : []
|
|
3911
|
+
]);
|
|
3912
|
+
};
|
|
3913
|
+
Schema.extend("lazy", (data, schema, options, strict) => {
|
|
3914
|
+
if (!schema.inner[kSchema]) {
|
|
3915
|
+
schema.inner = schema.builder();
|
|
3916
|
+
schema.inner.meta = {
|
|
3917
|
+
...schema.meta,
|
|
3918
|
+
...schema.inner.meta
|
|
3919
|
+
};
|
|
3920
|
+
validateVolatileSchema(schema.inner, options.path, true);
|
|
3921
|
+
}
|
|
3922
|
+
return Schema.resolve(data, schema.inner, options, strict);
|
|
3923
|
+
});
|
|
3924
|
+
Schema.extend("any", (data) => {
|
|
3925
|
+
return [data];
|
|
3926
|
+
});
|
|
3927
|
+
Schema.extend("never", (data, _, options) => {
|
|
3928
|
+
throw new ValidationError(`expected nullable but got ${data}`, options);
|
|
3929
|
+
});
|
|
3930
|
+
Schema.extend("const", (data, { value }, options) => {
|
|
3931
|
+
if (deepEqual(data, value)) return [value];
|
|
3932
|
+
throw new ValidationError(`expected ${value} but got ${data}`, options);
|
|
3933
|
+
});
|
|
3934
|
+
function checkWithinRange(data, meta, description, options, skipMin = false) {
|
|
3935
|
+
const { max = Infinity, min = -Infinity } = meta;
|
|
3936
|
+
if (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options);
|
|
3937
|
+
if (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options);
|
|
3938
|
+
}
|
|
3939
|
+
Schema.extend("string", (data, { meta }, options) => {
|
|
3940
|
+
if (typeof data !== "string") throw new ValidationError(`expected string but got ${data}`, options);
|
|
3941
|
+
if (meta.pattern) {
|
|
3942
|
+
const regexp = new RegExp(meta.pattern.source, meta.pattern.flags);
|
|
3943
|
+
if (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options);
|
|
3944
|
+
}
|
|
3945
|
+
checkWithinRange(data.length, meta, "string length", options);
|
|
3946
|
+
return [data];
|
|
3947
|
+
});
|
|
3948
|
+
function decimalShift(data, digits) {
|
|
3949
|
+
const str = data.toString();
|
|
3950
|
+
if (str.includes("e")) return data * Math.pow(10, digits);
|
|
3951
|
+
const index = str.indexOf(".");
|
|
3952
|
+
if (index === -1) return data * Math.pow(10, digits);
|
|
3953
|
+
const frac = str.slice(index + 1);
|
|
3954
|
+
const integer = str.slice(0, index);
|
|
3955
|
+
if (frac.length <= digits) return +(integer + frac.padEnd(digits, "0"));
|
|
3956
|
+
return +(integer + frac.slice(0, digits) + "." + frac.slice(digits));
|
|
3957
|
+
}
|
|
3958
|
+
function isMultipleOf(data, min, step) {
|
|
3959
|
+
step = Math.abs(step);
|
|
3960
|
+
if (!/^\d+\.\d+$/.test(step.toString())) return (data - min) % step === 0;
|
|
3961
|
+
const index = step.toString().indexOf(".");
|
|
3962
|
+
const digits = step.toString().slice(index + 1).length;
|
|
3963
|
+
return Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0;
|
|
3964
|
+
}
|
|
3965
|
+
Schema.extend("number", (data, { meta }, options) => {
|
|
3966
|
+
if (typeof data !== "number") throw new ValidationError(`expected number but got ${data}`, options);
|
|
3967
|
+
checkWithinRange(data, meta, "number", options);
|
|
3968
|
+
const { step } = meta;
|
|
3969
|
+
if (step && !isMultipleOf(data, meta.min ?? 0, step)) throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options);
|
|
3970
|
+
return [data];
|
|
3971
|
+
});
|
|
3972
|
+
Schema.extend("boolean", (data, _, options) => {
|
|
3973
|
+
if (typeof data === "boolean") return [data];
|
|
3974
|
+
throw new ValidationError(`expected boolean but got ${data}`, options);
|
|
3975
|
+
});
|
|
3976
|
+
Schema.extend("bitset", (data, { bits, meta }, options) => {
|
|
3977
|
+
let value = 0, keys = [];
|
|
3978
|
+
if (typeof data === "number") {
|
|
3979
|
+
value = data;
|
|
3980
|
+
for (const key in bits) if (data & bits[key]) keys.push(key);
|
|
3981
|
+
} else if (Array.isArray(data)) {
|
|
3982
|
+
keys = data;
|
|
3983
|
+
for (const key of keys) {
|
|
3984
|
+
if (typeof key !== "string") throw new ValidationError(`expected string but got ${key}`, options);
|
|
3985
|
+
if (key in bits) value |= bits[key];
|
|
3986
|
+
}
|
|
3987
|
+
} else throw new ValidationError(`expected number or array but got ${data}`, options);
|
|
3988
|
+
if (value === meta.default) return [value];
|
|
3989
|
+
return [value, keys];
|
|
3990
|
+
});
|
|
3991
|
+
Schema.extend("function", (data, _, options) => {
|
|
3992
|
+
if (typeof data === "function") return [data];
|
|
3993
|
+
throw new ValidationError(`expected function but got ${data}`, options);
|
|
3994
|
+
});
|
|
3995
|
+
Schema.extend("is", (data, { constructor }, options) => {
|
|
3996
|
+
if (typeof constructor === "function") {
|
|
3997
|
+
if (data instanceof constructor) return [data];
|
|
3998
|
+
throw new ValidationError(`expected ${constructor.name} but got ${data}`, options);
|
|
3999
|
+
} else {
|
|
4000
|
+
if (isNullable(data)) throw new ValidationError(`expected ${constructor} but got ${data}`, options);
|
|
4001
|
+
let prototype = Object.getPrototypeOf(data);
|
|
4002
|
+
while (prototype) {
|
|
4003
|
+
if (prototype.constructor?.name === constructor) return [data];
|
|
4004
|
+
prototype = Object.getPrototypeOf(prototype);
|
|
4005
|
+
}
|
|
4006
|
+
throw new ValidationError(`expected ${constructor} but got ${data}`, options);
|
|
4007
|
+
}
|
|
4008
|
+
});
|
|
4009
|
+
function property(data, key, schema, options) {
|
|
4010
|
+
try {
|
|
4011
|
+
const [value, adapted] = Schema.resolve(data[key], schema, {
|
|
4012
|
+
...options,
|
|
4013
|
+
path: [...options.path || [], key]
|
|
4014
|
+
});
|
|
4015
|
+
if (adapted !== void 0) data[key] = adapted;
|
|
4016
|
+
return value;
|
|
4017
|
+
} catch (e) {
|
|
4018
|
+
if (!options?.autofix) throw e;
|
|
4019
|
+
delete data[key];
|
|
4020
|
+
return schema.meta.volatile ? createVolatile(schema.meta.default) : schema.meta.default;
|
|
4021
|
+
}
|
|
4022
|
+
}
|
|
4023
|
+
Schema.extend("array", (data, { inner, meta }, options) => {
|
|
4024
|
+
if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
|
|
4025
|
+
checkWithinRange(data.length, meta, "array length", options, !isNullable(inner.meta.default));
|
|
4026
|
+
return [data.map((_, index) => property(data, index, inner, options))];
|
|
4027
|
+
});
|
|
4028
|
+
Schema.extend("dict", (data, { inner, sKey }, options, strict) => {
|
|
4029
|
+
if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);
|
|
4030
|
+
const result = {};
|
|
4031
|
+
for (const key in data) {
|
|
4032
|
+
let rKey;
|
|
4033
|
+
try {
|
|
4034
|
+
rKey = Schema.resolve(key, sKey, options)[0];
|
|
4035
|
+
} catch (error) {
|
|
4036
|
+
if (strict) continue;
|
|
4037
|
+
throw error;
|
|
4038
|
+
}
|
|
4039
|
+
result[rKey] = property(data, key, inner, options);
|
|
4040
|
+
data[rKey] = data[key];
|
|
4041
|
+
if (key !== rKey) delete data[key];
|
|
4042
|
+
}
|
|
4043
|
+
return [result];
|
|
4044
|
+
});
|
|
4045
|
+
Schema.extend("tuple", (data, { list }, options, strict) => {
|
|
4046
|
+
if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
|
|
4047
|
+
const result = list.map((inner, index) => property(data, index, inner, options));
|
|
4048
|
+
if (strict) return [result];
|
|
4049
|
+
result.push(...data.slice(list.length));
|
|
4050
|
+
return [result];
|
|
4051
|
+
});
|
|
4052
|
+
function merge(result, data) {
|
|
4053
|
+
for (const key in data) {
|
|
4054
|
+
if (key in result) continue;
|
|
4055
|
+
result[key] = data[key];
|
|
4056
|
+
}
|
|
4057
|
+
}
|
|
4058
|
+
Schema.extend("object", (data, { dict }, options, strict) => {
|
|
4059
|
+
if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);
|
|
4060
|
+
const result = {};
|
|
4061
|
+
for (const key in dict) {
|
|
4062
|
+
const value = property(data, key, dict[key], options);
|
|
4063
|
+
if (!isNullable(value) || key in data) result[key] = value;
|
|
4064
|
+
}
|
|
4065
|
+
if (!strict) merge(result, data);
|
|
4066
|
+
return [result];
|
|
4067
|
+
});
|
|
4068
|
+
Schema.extend("union", (data, { list, toString }, options, strict) => {
|
|
4069
|
+
const messages = [];
|
|
4070
|
+
for (const inner of list) try {
|
|
4071
|
+
return Schema.resolve(data, inner, options, strict);
|
|
4072
|
+
} catch (error) {
|
|
4073
|
+
messages.push(error);
|
|
4074
|
+
}
|
|
4075
|
+
throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
|
|
4076
|
+
});
|
|
4077
|
+
Schema.extend("intersect", (data, { list, toString }, options, strict) => {
|
|
4078
|
+
if (!list.length) return [data];
|
|
4079
|
+
let result;
|
|
4080
|
+
for (const inner of list) {
|
|
4081
|
+
const value = Schema.resolve(data, inner, options, true)[0];
|
|
4082
|
+
if (isNullable(value)) continue;
|
|
4083
|
+
if (isNullable(result)) result = value;
|
|
4084
|
+
else if (typeof result !== typeof value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
|
|
4085
|
+
else if (typeof value === "object") merge(result ??= {}, value);
|
|
4086
|
+
else if (result !== value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
|
|
4087
|
+
}
|
|
4088
|
+
if (!strict && isPlainObject(data)) merge(result, data);
|
|
4089
|
+
return [result];
|
|
4090
|
+
});
|
|
4091
|
+
Schema.extend("transform", (data, { inner, callback, preserve }, options) => {
|
|
4092
|
+
const [result, adapted = data] = Schema.resolve(data, inner, options, true);
|
|
4093
|
+
if (preserve) return [callback(result)];
|
|
4094
|
+
else return [callback(result), callback(adapted)];
|
|
4095
|
+
});
|
|
4096
|
+
const formatters = {};
|
|
4097
|
+
function defineMethod(name, keys, format) {
|
|
4098
|
+
formatters[name] = format;
|
|
4099
|
+
Object.assign(Schema, { [name](...args) {
|
|
4100
|
+
const schema = new Schema({ type: name });
|
|
4101
|
+
keys.forEach((key, index) => {
|
|
4102
|
+
switch (key) {
|
|
4103
|
+
case "sKey":
|
|
4104
|
+
schema.sKey = args[index] ?? Schema.string();
|
|
4105
|
+
break;
|
|
4106
|
+
case "inner":
|
|
4107
|
+
schema.inner = Schema.from(args[index]);
|
|
4108
|
+
break;
|
|
4109
|
+
case "list":
|
|
4110
|
+
schema.list = args[index].map(Schema.from);
|
|
4111
|
+
break;
|
|
4112
|
+
case "dict":
|
|
4113
|
+
schema.dict = mapValues(args[index], Schema.from);
|
|
4114
|
+
break;
|
|
4115
|
+
case "bits":
|
|
4116
|
+
schema.bits = {};
|
|
4117
|
+
for (const key in args[index]) {
|
|
4118
|
+
if (typeof args[index][key] !== "number") continue;
|
|
4119
|
+
schema.bits[key] = args[index][key];
|
|
4120
|
+
}
|
|
4121
|
+
break;
|
|
4122
|
+
case "callback": {
|
|
4123
|
+
const callback = schema.callback = args[index];
|
|
4124
|
+
callback["toJSON"] ||= () => callback.toString();
|
|
4125
|
+
break;
|
|
4126
|
+
}
|
|
4127
|
+
case "constructor": {
|
|
4128
|
+
const constructor = schema.constructor = args[index];
|
|
4129
|
+
if (typeof constructor === "function") constructor["toJSON"] ||= () => constructor["name"];
|
|
4130
|
+
break;
|
|
4131
|
+
}
|
|
4132
|
+
default: schema[key] = args[index];
|
|
4133
|
+
}
|
|
4134
|
+
});
|
|
4135
|
+
if (name === "object" || name === "dict") schema.meta.default = {};
|
|
4136
|
+
else if (name === "array" || name === "tuple") schema.meta.default = [];
|
|
4137
|
+
else if (name === "bitset") schema.meta.default = 0;
|
|
4138
|
+
return schema;
|
|
4139
|
+
} });
|
|
4140
|
+
}
|
|
4141
|
+
defineMethod("is", ["constructor"], ({ constructor }) => {
|
|
4142
|
+
if (typeof constructor === "function") return constructor.name;
|
|
4143
|
+
else return constructor;
|
|
4144
|
+
});
|
|
4145
|
+
defineMethod("any", [], () => "any");
|
|
4146
|
+
defineMethod("never", [], () => "never");
|
|
4147
|
+
defineMethod("const", ["value"], ({ value }) => typeof value === "string" ? JSON.stringify(value) : value);
|
|
4148
|
+
defineMethod("string", [], () => "string");
|
|
4149
|
+
defineMethod("number", [], () => "number");
|
|
4150
|
+
defineMethod("boolean", [], () => "boolean");
|
|
4151
|
+
defineMethod("bitset", ["bits"], () => "bitset");
|
|
4152
|
+
defineMethod("function", [], () => "function");
|
|
4153
|
+
defineMethod("array", ["inner"], ({ inner }) => `${inner.toString(true)}[]`);
|
|
4154
|
+
defineMethod("dict", ["inner", "sKey"], ({ inner, sKey }) => `{ [key: ${sKey.toString()}]: ${inner.toString()} }`);
|
|
4155
|
+
defineMethod("tuple", ["list"], ({ list }) => `[${list.map((inner) => inner.toString()).join(", ")}]`);
|
|
4156
|
+
defineMethod("object", ["dict"], ({ dict }) => {
|
|
4157
|
+
if (Object.keys(dict).length === 0) return "{}";
|
|
4158
|
+
return `{ ${Object.entries(dict).map(([key, inner]) => {
|
|
4159
|
+
return `${key}${inner.meta.required ? "" : "?"}: ${inner.toString()}`;
|
|
4160
|
+
}).join(", ")} }`;
|
|
4161
|
+
});
|
|
4162
|
+
defineMethod("union", ["list"], ({ list }, inline) => {
|
|
4163
|
+
const result = list.map(({ toString: format }) => format()).join(" | ");
|
|
4164
|
+
return inline ? `(${result})` : result;
|
|
4165
|
+
});
|
|
4166
|
+
defineMethod("intersect", ["list"], ({ list }) => {
|
|
4167
|
+
return `${list.map((inner) => inner.toString(true)).join(" & ")}`;
|
|
4168
|
+
});
|
|
4169
|
+
defineMethod("transform", [
|
|
4170
|
+
"inner",
|
|
4171
|
+
"callback",
|
|
4172
|
+
"preserve"
|
|
4173
|
+
], ({ inner }, isInner) => inner.toString(isInner));
|
|
4174
|
+
//#endregion
|
|
4175
|
+
//#region lib/types/onboarding-config.js
|
|
4176
|
+
/** Public page-bootstrap options shared by the Host and Client halves. */
|
|
4177
|
+
/** Validate Host configuration and its public page-bootstrap payload. */
|
|
4178
|
+
const Config = Schema.object({ credentialOnboarding: Schema.boolean().default(true) });
|
|
4179
|
+
/** Page-global key carrying only the public onboarding options. */
|
|
4180
|
+
const ONBOARDING_CONFIG_GLOBAL = "__QILIN_MODELS_ONBOARDING__";
|
|
4181
|
+
//#endregion
|
|
3141
4182
|
//#region lib/types/client/index.js
|
|
3142
4183
|
/** Dictionary namespace owned by this plugin. */
|
|
3143
4184
|
const NS = "settings.models";
|
|
@@ -3172,6 +4213,8 @@ window.__ModuleLoader__.load({
|
|
|
3172
4213
|
* @param ctx - client root context.
|
|
3173
4214
|
*/
|
|
3174
4215
|
function apply(ctx) {
|
|
4216
|
+
const payload = globalThis[ONBOARDING_CONFIG_GLOBAL];
|
|
4217
|
+
const configured = Config(payload === void 0 ? {} : payload);
|
|
3175
4218
|
ctx.effect(() => ctx.locale.register(NS, {
|
|
3176
4219
|
zh,
|
|
3177
4220
|
en
|
|
@@ -3227,7 +4270,7 @@ window.__ModuleLoader__.load({
|
|
|
3227
4270
|
}
|
|
3228
4271
|
}
|
|
3229
4272
|
}, ModelsSection));
|
|
3230
|
-
ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
4273
|
+
if (configured.credentialOnboarding) ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
|
|
3231
4274
|
name: "settings.onboarding",
|
|
3232
4275
|
id: "deepseek-official",
|
|
3233
4276
|
order: 0,
|