@qilin-agent/client-ui-settings-models 3.1.5 → 3.1.7

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/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_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_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_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:.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}";
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");
@@ -96,11 +96,15 @@ window.__ModuleLoader__.load({
96
96
  "fetchDialog": "PF5DZW_fetchDialog",
97
97
  "field": "PF5DZW_field",
98
98
  "fieldLabel": "PF5DZW_fieldLabel",
99
+ "helpButton": "PF5DZW_helpButton",
99
100
  "hiddenLabel": "PF5DZW_hiddenLabel",
100
101
  "iconButton": "PF5DZW_iconButton",
101
102
  "iconButtonDanger": "PF5DZW_iconButtonDanger",
102
103
  "input": "PF5DZW_input",
103
104
  "intro": "PF5DZW_intro",
105
+ "keyInput": "PF5DZW_keyInput",
106
+ "keyInputFilled": "PF5DZW_keyInputFilled",
107
+ "keyToggle": "PF5DZW_keyToggle",
104
108
  "linkButton": "PF5DZW_linkButton",
105
109
  "modelAdvanced": "PF5DZW_modelAdvanced",
106
110
  "modelCatalog": "PF5DZW_modelCatalog",
@@ -115,6 +119,11 @@ window.__ModuleLoader__.load({
115
119
  "modelInputTypes": "PF5DZW_modelInputTypes",
116
120
  "modelList": "PF5DZW_modelList",
117
121
  "modelListHead": "PF5DZW_modelListHead",
122
+ "modelReasoning": "PF5DZW_modelReasoning",
123
+ "modelReasoningHead": "PF5DZW_modelReasoningHead",
124
+ "modelReasoningLabel": "PF5DZW_modelReasoningLabel",
125
+ "modelReasoningRow": "PF5DZW_modelReasoningRow",
126
+ "modelReasoningValueInput": "PF5DZW_modelReasoningValueInput",
118
127
  "modelRow": "PF5DZW_modelRow",
119
128
  "notice": "PF5DZW_notice",
120
129
  "primaryButton": "PF5DZW_primaryButton",
@@ -134,6 +143,55 @@ window.__ModuleLoader__.load({
134
143
  "title": "PF5DZW_title"
135
144
  };
136
145
  //#endregion
146
+ //#region lib/types/client/ApiKeyInput.js
147
+ /** Write-only credential input with the same reveal behavior as masked conversation text. */
148
+ const EYE_CONTOUR = "M1.5 8C2.9 5.25 5.25 3.5 8 3.5C10.75 3.5 13.1 5.25 14.5 8C13.1 10.75 10.75 12.5 8 12.5C5.25 12.5 2.9 10.75 1.5 8Z";
149
+ const EYE_PATH = `${EYE_CONTOUR}M10 8C10 9.1 9.1 10 8 10C6.9 10 6 9.1 6 8C6 6.9 6.9 6 8 6C9.1 6 10 6.9 10 8Z`;
150
+ const EYE_OFF_PATH = `${EYE_CONTOUR}M2.5 2.5L13.5 13.5`;
151
+ /**
152
+ * Reveal only a nonempty draft; a different value starts masked, as in SecretText.
153
+ * @param props - current draft, input attributes, and translated control labels.
154
+ * @returns a password input with an optional reveal button.
155
+ */
156
+ function ApiKeyInput({ value, t, ...props }) {
157
+ const [revealedValue, setRevealedValue] = (0, react.useState)();
158
+ const revealed = value.length > 0 && revealedValue === value;
159
+ return (0, react_jsx_runtime.jsxs)("div", {
160
+ className: ModelsSection_module_css_default["keyInput"],
161
+ children: [(0, react_jsx_runtime.jsx)("input", {
162
+ ...props,
163
+ className: `${ModelsSection_module_css_default["input"]} ${value.length > 0 ? ModelsSection_module_css_default["keyInputFilled"] : ""}`,
164
+ type: revealed ? "text" : "password",
165
+ autoComplete: "new-password",
166
+ value,
167
+ onChange: (event) => {
168
+ setRevealedValue(void 0);
169
+ props.onChange?.(event);
170
+ }
171
+ }), value.length === 0 ? null : (0, react_jsx_runtime.jsx)("button", {
172
+ type: "button",
173
+ className: ModelsSection_module_css_default["keyToggle"],
174
+ "aria-label": t(revealed ? "keyHide" : "keyReveal"),
175
+ "aria-pressed": revealed,
176
+ disabled: props.disabled,
177
+ onClick: () => {
178
+ setRevealedValue(revealed ? void 0 : value);
179
+ },
180
+ children: (0, react_jsx_runtime.jsx)("svg", {
181
+ width: "16",
182
+ height: "16",
183
+ viewBox: "0 0 16 16",
184
+ fill: "none",
185
+ stroke: "currentColor",
186
+ strokeWidth: 1.3,
187
+ strokeLinecap: "round",
188
+ "aria-hidden": "true",
189
+ children: (0, react_jsx_runtime.jsx)("path", { d: revealed ? EYE_OFF_PATH : EYE_PATH })
190
+ })
191
+ })]
192
+ });
193
+ }
194
+ //#endregion
137
195
  //#region lib/types/client/EditorFooter.js
138
196
  /**
139
197
  * Render one provider card's action row.
@@ -198,6 +256,224 @@ window.__ModuleLoader__.load({
198
256
  });
199
257
  }
200
258
  //#endregion
259
+ //#region lib/types/client/ModelReasoningEfforts.js
260
+ /** Reasoning-level declarations for a model on a hand-declared pi-ai route. */
261
+ /** Levels a model offers when the switch is turned on, where the schema lists them: Off plus the common OpenAI-compatible trio. */
262
+ const INITIAL_LEVELS = [
263
+ "off",
264
+ "low",
265
+ "medium",
266
+ "high"
267
+ ];
268
+ /** The wire value a level sends unless its row says otherwise; `null` is the Off entry that sends nothing. */
269
+ function defaultValue(level) {
270
+ return level === "off" ? null : level;
271
+ }
272
+ /**
273
+ * Whether pi-ai accepts a stored value: a non-empty string, or nothing for Off.
274
+ * @param level - the declared level.
275
+ * @param wire - the value stored for it.
276
+ * @returns whether the adapter would resolve the entry.
277
+ */
278
+ function acceptedValue(level, wire) {
279
+ return typeof wire === "string" ? wire.length > 0 : wire === null && level === "off";
280
+ }
281
+ /**
282
+ * Read the declared levels from a row in their stored order, including a key
283
+ * the offered levels do not name, so an edit never drops it.
284
+ * @param model - model row as drafted.
285
+ * @returns the entries; empty for a valueless field, which pi-ai refuses, and
286
+ * `undefined` when the field is absent or `false`.
287
+ */
288
+ function readEfforts(model) {
289
+ const value = model["reasoningEfforts"];
290
+ if (value === null) return [];
291
+ if (typeof value !== "object" || Array.isArray(value)) return void 0;
292
+ return Object.entries(value);
293
+ }
294
+ /**
295
+ * Replace a row's declared levels, preserving every other field.
296
+ * @param model - model row as drafted.
297
+ * @param entries - the levels to write in row order, or `undefined` to remove the field.
298
+ * @returns the replacement row.
299
+ */
300
+ function withEfforts(model, entries) {
301
+ const next = { ...model };
302
+ if (entries === void 0) {
303
+ Reflect.deleteProperty(next, "reasoningEfforts");
304
+ return next;
305
+ }
306
+ next["reasoningEfforts"] = Object.fromEntries(entries);
307
+ return next;
308
+ }
309
+ /**
310
+ * Mirror the pi-ai refusals of a hand-declared `reasoningEfforts`, so a card
311
+ * names the row instead of failing at the write.
312
+ * @param value - drafted `models` value, or `undefined` while inherited.
313
+ * @returns the first refused row, or `undefined` when the adapter will accept every row.
314
+ */
315
+ function validateReasoningEfforts(value) {
316
+ for (const [index, model] of modelDrafts(value).entries()) {
317
+ const entries = readEfforts(model);
318
+ if (entries === void 0) continue;
319
+ if (entries.some(([level, wire]) => !acceptedValue(level, wire))) return {
320
+ index,
321
+ key: "modelReasoningValueRequired"
322
+ };
323
+ if (!entries.some(([level]) => level !== "off")) return {
324
+ index,
325
+ key: "modelReasoningNeedsLevel"
326
+ };
327
+ }
328
+ }
329
+ /**
330
+ * Edit the `reasoningEfforts` a hand-declared pi-ai model offers: a switch,
331
+ * then one row per level pairing the level with the value sent for it. Every
332
+ * row is read from the model, so a reused instance shows its new model.
333
+ * @param props - model declaration and row replacement action.
334
+ * @returns the reasoning-level group.
335
+ */
336
+ function ModelReasoningEfforts({ model, levels, position, disabled, t, onChange }) {
337
+ const entries = readEfforts(model);
338
+ const [typing, setTyping] = (0, react.useState)(void 0);
339
+ const label = `${t("modelReasoning")} ${String(position)}`;
340
+ const used = entries?.map(([level]) => level) ?? [];
341
+ const write = (next) => {
342
+ onChange(withEfforts(model, next));
343
+ };
344
+ const replaceAt = (current, index, entry) => current.map((existing, at) => at === index ? entry : existing);
345
+ const changeLevel = (current, index, from, wire, to) => {
346
+ write(replaceAt(current, index, [to, typeof wire === "string" && wire.length > 0 && wire !== from && from !== "off" && to !== "off" ? wire : defaultValue(to)]));
347
+ };
348
+ const addLevel = (current) => {
349
+ const highest = Math.max(-1, ...used.map((level) => levels.indexOf(level)));
350
+ const level = levels.find((candidate, index) => index > highest && !used.includes(candidate)) ?? levels.find((candidate) => !used.includes(candidate));
351
+ /* v8 ignore next -- the add button is disabled once every level has a row */
352
+ if (level === void 0) return;
353
+ write([...current, [level, defaultValue(level)]]);
354
+ };
355
+ const editValue = (current, index, level, text) => {
356
+ setTyping({
357
+ level,
358
+ text
359
+ });
360
+ const trimmed = text.trim();
361
+ write(replaceAt(current, index, [level, trimmed.length === 0 ? defaultValue(level) : trimmed]));
362
+ };
363
+ const leaveValue = (current, index, level, wire) => {
364
+ setTyping(void 0);
365
+ if (!acceptedValue(level, wire)) write(replaceAt(current, index, [level, defaultValue(level)]));
366
+ };
367
+ const choicesFor = (level) => [...levels.includes(level) ? [] : [level], ...levels.filter((choice) => choice === level || !used.includes(choice))];
368
+ const initialEntries = INITIAL_LEVELS.filter((level) => levels.includes(level)).map((level) => [level, defaultValue(level)]);
369
+ const refused = entries?.some(([level, wire]) => !acceptedValue(level, wire)) === true;
370
+ const missingLevel = entries !== void 0 && !used.some((level) => level !== "off");
371
+ return (0, react_jsx_runtime.jsxs)("div", {
372
+ className: ModelsSection_module_css_default["modelReasoning"],
373
+ role: "group",
374
+ "aria-label": label,
375
+ children: [(0, react_jsx_runtime.jsxs)("div", {
376
+ className: ModelsSection_module_css_default["modelReasoningHead"],
377
+ children: [(0, react_jsx_runtime.jsxs)("span", {
378
+ className: `${ModelsSection_module_css_default["modelFieldLabel"]} ${ModelsSection_module_css_default["modelReasoningLabel"]}`,
379
+ children: [t("modelReasoning"), (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.Tooltip, {
380
+ label: t("modelReasoningHelpText"),
381
+ side: "right",
382
+ delayMs: 0,
383
+ focusDelayMs: 0,
384
+ portal: true,
385
+ openOnClick: true,
386
+ children: (0, react_jsx_runtime.jsx)("button", {
387
+ type: "button",
388
+ className: ModelsSection_module_css_default["helpButton"],
389
+ "aria-label": t("modelReasoningHelp"),
390
+ children: "?"
391
+ })
392
+ })]
393
+ }), (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.Switch, {
394
+ checked: entries !== void 0,
395
+ label,
396
+ disabled,
397
+ onChange: (on) => {
398
+ write(on ? initialEntries : void 0);
399
+ }
400
+ })]
401
+ }), entries === void 0 ? null : (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
402
+ entries.length > 0 ? (0, react_jsx_runtime.jsxs)("div", {
403
+ className: ModelsSection_module_css_default["modelReasoningRow"],
404
+ "aria-hidden": "true",
405
+ children: [(0, react_jsx_runtime.jsx)("span", {
406
+ className: ModelsSection_module_css_default["modelFieldLabel"],
407
+ children: t("modelReasoningLevel")
408
+ }), (0, react_jsx_runtime.jsx)("span", {
409
+ className: ModelsSection_module_css_default["modelFieldLabel"],
410
+ children: t("modelReasoningValue")
411
+ })]
412
+ }) : null,
413
+ entries.map(([level, wire], index) => (0, react_jsx_runtime.jsxs)("div", {
414
+ className: ModelsSection_module_css_default["modelReasoningRow"],
415
+ children: [
416
+ (0, react_jsx_runtime.jsx)("select", {
417
+ className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["selectInput"]}`,
418
+ value: level,
419
+ "aria-label": `${t("modelReasoningLevel")} ${String(index + 1)}`,
420
+ disabled,
421
+ onChange: (event) => {
422
+ changeLevel(entries, index, level, wire, event.target.value);
423
+ },
424
+ children: choicesFor(level).map((choice) => (0, react_jsx_runtime.jsx)("option", {
425
+ value: choice,
426
+ children: choice
427
+ }, choice))
428
+ }),
429
+ (0, react_jsx_runtime.jsx)("input", {
430
+ className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["modelReasoningValueInput"]}`,
431
+ type: "text",
432
+ value: typing?.level === level ? typing.text : typeof wire === "string" ? wire : "",
433
+ placeholder: level === "off" ? t("modelReasoningOffValuePlaceholder") : level,
434
+ "aria-label": `${level} ${t("modelReasoningValue")}`,
435
+ "aria-invalid": !acceptedValue(level, wire),
436
+ disabled: disabled || level === "off",
437
+ onChange: (event) => {
438
+ editValue(entries, index, level, event.target.value);
439
+ },
440
+ onBlur: () => {
441
+ leaveValue(entries, index, level, wire);
442
+ }
443
+ }),
444
+ (0, react_jsx_runtime.jsx)("button", {
445
+ type: "button",
446
+ className: `${ModelsSection_module_css_default["iconButton"]} ${ModelsSection_module_css_default["iconButtonDanger"]}`,
447
+ "aria-label": `${t("modelReasoningRemove")} ${level}`,
448
+ title: t("modelReasoningRemove"),
449
+ disabled,
450
+ onClick: () => {
451
+ write(entries.filter((_entry, at) => at !== index));
452
+ },
453
+ children: (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconTrashOutlineRegular, { size: 14 })
454
+ })
455
+ ]
456
+ }, index)),
457
+ refused ? (0, react_jsx_runtime.jsx)("p", {
458
+ className: ModelsSection_module_css_default["error"],
459
+ children: t("modelReasoningValueRequired")
460
+ }) : missingLevel ? (0, react_jsx_runtime.jsx)("p", {
461
+ className: ModelsSection_module_css_default["error"],
462
+ children: t("modelReasoningNeedsLevel")
463
+ }) : null,
464
+ (0, react_jsx_runtime.jsxs)("button", {
465
+ type: "button",
466
+ className: ModelsSection_module_css_default["addModelButton"],
467
+ disabled: disabled || levels.every((level) => used.includes(level)),
468
+ onClick: () => {
469
+ addLevel(entries);
470
+ },
471
+ children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("modelReasoningAdd")]
472
+ })
473
+ ] })]
474
+ });
475
+ }
476
+ //#endregion
201
477
  //#region lib/types/client/ModelRow.js
202
478
  /**
203
479
  * Render consistent model identity, capacity, and input-type controls.
@@ -231,7 +507,7 @@ window.__ModuleLoader__.load({
231
507
  "aria-expanded": props.expanded,
232
508
  title: t("modelAdvanced"),
233
509
  onClick: props.onToggle,
234
- children: props.expanded ? (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconChevronDownOutline14, {}) : (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconChevronRightOutline14, {})
510
+ 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, {})
235
511
  }),
236
512
  (0, react_jsx_runtime.jsx)("button", {
237
513
  type: "button",
@@ -240,38 +516,49 @@ window.__ModuleLoader__.load({
240
516
  title: t("removeModel"),
241
517
  disabled,
242
518
  onClick: props.onRemove,
243
- children: (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconTrashOutline16, { size: 14 })
519
+ children: (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconTrashOutlineRegular, { size: 14 })
244
520
  })
245
521
  ]
246
522
  }), props.expanded ? (0, react_jsx_runtime.jsxs)("div", {
247
523
  className: ModelsSection_module_css_default["modelAdvanced"],
248
- children: [["contextWindow", "maxTokens"].map((field) => (0, react_jsx_runtime.jsxs)("label", {
249
- className: ModelsSection_module_css_default["modelField"],
250
- children: [(0, react_jsx_runtime.jsx)("span", {
251
- className: ModelsSection_module_css_default["modelFieldLabel"],
252
- children: t(field)
253
- }), (0, react_jsx_runtime.jsx)("input", {
254
- className: ModelsSection_module_css_default["input"],
255
- type: "text",
256
- inputMode: "numeric",
257
- value: props[field].value,
258
- placeholder: props[field].placeholder,
259
- "aria-label": `${t(field)} ${String(position)}`,
524
+ children: [
525
+ ["contextWindow", "maxTokens"].map((field) => (0, react_jsx_runtime.jsxs)("label", {
526
+ className: ModelsSection_module_css_default["modelField"],
527
+ children: [(0, react_jsx_runtime.jsx)("span", {
528
+ className: ModelsSection_module_css_default["modelFieldLabel"],
529
+ children: t(field)
530
+ }), (0, react_jsx_runtime.jsx)("input", {
531
+ className: ModelsSection_module_css_default["input"],
532
+ type: "text",
533
+ inputMode: "numeric",
534
+ value: props[field].value,
535
+ placeholder: props[field].placeholder,
536
+ "aria-label": `${t(field)} ${String(position)}`,
537
+ disabled,
538
+ onChange: (event) => {
539
+ props[field].onChange(event.target.value);
540
+ },
541
+ onBlur: props[field].onBlur
542
+ })]
543
+ }, field)),
544
+ (0, react_jsx_runtime.jsx)(ModelInputTypes, {
545
+ model,
546
+ field: props.inputField,
547
+ position,
548
+ fallback: props.inputFallback,
549
+ disabled: disabled || props.inputLoading === true,
550
+ t,
551
+ onChange: props.onChange
552
+ }),
553
+ props.reasoningLevels !== void 0 && props.reasoningLevels.length > 0 ? (0, react_jsx_runtime.jsx)(ModelReasoningEfforts, {
554
+ model,
555
+ levels: props.reasoningLevels,
556
+ position,
260
557
  disabled,
261
- onChange: (event) => {
262
- props[field].onChange(event.target.value);
263
- },
264
- onBlur: props[field].onBlur
265
- })]
266
- }, field)), (0, react_jsx_runtime.jsx)(ModelInputTypes, {
267
- model,
268
- field: props.inputField,
269
- position,
270
- fallback: props.inputFallback,
271
- disabled: disabled || props.inputLoading === true,
272
- t,
273
- onChange: props.onChange
274
- })]
558
+ t,
559
+ onChange: props.onChange
560
+ }) : null
561
+ ]
275
562
  }) : null]
276
563
  });
277
564
  }
@@ -511,7 +798,7 @@ window.__ModuleLoader__.load({
511
798
  onClick: () => {
512
799
  props.onChange([...props.models.map((model) => ({ ...model })), { id: "" }]);
513
800
  },
514
- children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutline16, { size: 14 }), props.t("addModel")]
801
+ children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), props.t("addModel")]
515
802
  })
516
803
  ]
517
804
  });
@@ -584,9 +871,12 @@ window.__ModuleLoader__.load({
584
871
  * @returns the model-list editor.
585
872
  */
586
873
  function ModelListEditor(props) {
587
- const { models, onChange, probe, operations, t, disabled } = props;
874
+ const { models, onChange, probe, operations, t, disabled, onBusyChange } = props;
588
875
  const { catalogProvider } = props;
589
876
  const [busy, setBusy] = (0, react.useState)(false);
877
+ (0, react.useEffect)(() => {
878
+ onBusyChange(busy);
879
+ }, [busy, onBusyChange]);
590
880
  const [failure, setFailure] = (0, react.useState)(void 0);
591
881
  const [inheritedCatalog, setInheritedCatalog] = (0, react.useState)(void 0);
592
882
  (0, react.useEffect)(() => {
@@ -765,6 +1055,7 @@ window.__ModuleLoader__.load({
765
1055
  inputField: "input",
766
1056
  inputFallback: inputDefaults.get(textOf(model, "id")) ?? props.defaultInput,
767
1057
  inputLoading: catalogProvider !== void 0 && catalog === void 0,
1058
+ reasoningLevels: props.reasoningLevels,
768
1059
  expanded: expanded.has(index),
769
1060
  disabled,
770
1061
  t,
@@ -810,7 +1101,7 @@ window.__ModuleLoader__.load({
810
1101
  onClick: () => {
811
1102
  onChange([...models, { id: "" }]);
812
1103
  },
813
- children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("addModel")]
1104
+ children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("addModel")]
814
1105
  }),
815
1106
  failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
816
1107
  className: ModelsSection_module_css_default["error"],
@@ -908,6 +1199,9 @@ window.__ModuleLoader__.load({
908
1199
  settingsPath: [...entry.settingsPath],
909
1200
  active: active.has(entry.provider),
910
1201
  ...entry.declared === void 0 ? {} : { declared: entry.declared },
1202
+ ...entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: entry.defaultBaseURL },
1203
+ ...entry.baseURLEnv === void 0 ? {} : { baseURLEnv: entry.baseURLEnv },
1204
+ ...entry.nativeAuth === void 0 ? {} : { nativeAuth: entry.nativeAuth },
911
1205
  ...entry.error === void 0 ? {} : { error: entry.error }
912
1206
  }));
913
1207
  for (const provider of registered) {
@@ -951,6 +1245,26 @@ window.__ModuleLoader__.load({
951
1245
  if (list?.type !== "union" || list.list === void 0) return [];
952
1246
  return list.list.map((entry) => entry.value).filter((value) => typeof value === "string");
953
1247
  }
1248
+ /**
1249
+ * The reasoning levels a hand-declared route's models may declare, read out of
1250
+ * the owning namespace's own schema for the same reason as
1251
+ * {@link protocolChoices}: the levels the page offers and the keys the
1252
+ * adapter accepts in `reasoningEfforts` come from the same `Config`.
1253
+ * @param namespace - the namespace view whose schema declares the profile shape.
1254
+ * @param schema - settings schema operations.
1255
+ * @returns the levels in the schema's escalation order, or an empty list when the schema has none.
1256
+ */
1257
+ function reasoningLevelChoices(namespace, schema) {
1258
+ if (namespace === void 0) return [];
1259
+ const path = [
1260
+ "providers",
1261
+ PROBE_ROUTE,
1262
+ "models",
1263
+ "0",
1264
+ "reasoningEfforts"
1265
+ ];
1266
+ return (((schema.nodeAtPath(schema.rehydrate(namespace.schema), path)?.list ?? []).find((branch) => branch.type === "dict")?.sKey)?.list ?? []).map((entry) => entry.value).filter((value) => typeof value === "string");
1267
+ }
954
1268
  /** The credential reference a resolved profile names (its `apiKeyEnv` field). */
955
1269
  function apiKeyEnvOf(namespace, path, schema) {
956
1270
  if (namespace === void 0) return void 0;
@@ -975,6 +1289,8 @@ window.__ModuleLoader__.load({
975
1289
  });
976
1290
  /** Latest load wins; an older response never overwrites a newer one. */
977
1291
  generation = 0;
1292
+ /** Callers follow the current refresh's outcome, including callers whose read was superseded. */
1293
+ pendingLoads = /* @__PURE__ */ new Set();
978
1294
  /**
979
1295
  * @param ctx - the page plugin's context, whose `remote.llm` and
980
1296
  * `remote.credentials` namespaces carry the directory and credential reads.
@@ -991,11 +1307,28 @@ window.__ModuleLoader__.load({
991
1307
  * settings answer in parallel, then one batched credential describe over
992
1308
  * every referenced ref. Provider failure or absence of an initial settings
993
1309
  * answer keeps the last good rows and surfaces an error; a failed settings
994
- * refresh reuses the mirror's held view.
995
- * @returns nothing; the snapshot carries the outcome.
1310
+ * refresh reuses the mirror's held view. Concurrent callers resolve only
1311
+ * after the current refresh publishes its ready or error snapshot.
1312
+ * @returns resolution after the current snapshot is published.
1313
+ * @throws the current read's unexpected rejection; superseded rejections are ignored.
996
1314
  */
997
- async load() {
1315
+ load() {
1316
+ const pending = Promise.withResolvers();
1317
+ this.pendingLoads.add(pending);
998
1318
  const generation = ++this.generation;
1319
+ this.read(generation).then(() => {
1320
+ this.settleLoads(generation, (load) => {
1321
+ load.resolve();
1322
+ });
1323
+ }, (error) => {
1324
+ this.settleLoads(generation, (load) => {
1325
+ load.reject(error);
1326
+ });
1327
+ });
1328
+ return pending.promise;
1329
+ }
1330
+ /** Publish one joined answer; stale answers leave the current refresh in charge. */
1331
+ async read(generation) {
999
1332
  this.store.update((s) => {
1000
1333
  s.status = "loading";
1001
1334
  s.error = null;
@@ -1005,17 +1338,20 @@ window.__ModuleLoader__.load({
1005
1338
  this.ctx.remote.llm.listConfigurableProviders(),
1006
1339
  this.describeFace.ensure()
1007
1340
  ]);
1341
+ if (generation !== this.generation) return;
1008
1342
  if (!registered.ok) {
1009
- this.failLoad(generation, registered.error.message);
1343
+ this.failLoad(registered.error.message);
1010
1344
  return;
1011
1345
  }
1012
1346
  if (!declared.ok) {
1013
- this.failLoad(generation, declared.error.message);
1347
+ this.failLoad(declared.error.message);
1014
1348
  return;
1015
1349
  }
1016
1350
  const mirrored = this.describeFace.getSnapshot();
1017
1351
  if (mirrored.view === void 0) {
1018
- this.failLoad(generation, mirrored.error ?? "settings are unavailable in this browser");
1352
+ /* v8 ignore next -- SettingsDescribeFace.ensure settles with a view or the read's error */
1353
+ if (mirrored.error === null) throw new Error("settings describe settled with neither a view nor an error");
1354
+ this.failLoad(mirrored.error);
1019
1355
  return;
1020
1356
  }
1021
1357
  const providers = joinProviderDirectory(registered.value, declared.value);
@@ -1032,14 +1368,20 @@ window.__ModuleLoader__.load({
1032
1368
  credential: void 0
1033
1369
  };
1034
1370
  });
1035
- const refs = [...new Set(rows.map((row) => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))];
1036
- let credentials = {};
1371
+ const refs = [...new Set(rows.flatMap((row) => row.apiKeyEnv === void 0 ? [deriveKeyRef(row.entry.provider), ...row.entry.nativeAuth?.env ?? []] : [row.apiKeyEnv]))];
1372
+ const credentials = {};
1037
1373
  let credentialError = null;
1038
- if (refs.length > 0) {
1039
- const response = await this.ctx.remote.credentials.describe(refs);
1040
- if (response.ok) credentials = response.value;
1041
- else credentialError = response.error.message;
1374
+ for (let index = 0; index < refs.length; index += 64) {
1375
+ const response = await this.ctx.remote.credentials.describe(refs.slice(index, index + 64));
1376
+ if (response.ok) Object.assign(credentials, response.value);
1377
+ else {
1378
+ credentialError = response.error.message;
1379
+ break;
1380
+ }
1042
1381
  }
1382
+ /* v8 ignore next -- the credential describe answers in one promise, so a read
1383
+ * superseded at the earlier generation check never reaches this second guard;
1384
+ * it stays for a future multi-batch describe where supersede windows reopen. */
1043
1385
  if (generation !== this.generation) return;
1044
1386
  this.store.update((s) => {
1045
1387
  s.status = "ready";
@@ -1052,15 +1394,25 @@ window.__ModuleLoader__.load({
1052
1394
  return {
1053
1395
  ...row,
1054
1396
  ...named === void 0 ? {} : { credential: named },
1055
- ...derived === void 0 ? {} : { derivedCredential: derived }
1397
+ ...derived === void 0 ? {} : { derivedCredential: derived },
1398
+ ...credentialError === null ? { credentialChecks: Object.fromEntries((row.apiKeyEnv === void 0 ? row.entry.nativeAuth?.env ?? [] : [row.apiKeyEnv]).flatMap((ref) => {
1399
+ const info = credentials[ref];
1400
+ return info === void 0 ? [] : [[ref, info]];
1401
+ })) } : {}
1056
1402
  };
1057
1403
  });
1058
1404
  s.namespaces = namespaces;
1059
1405
  });
1060
1406
  }
1061
- /** Publish one load's failure text, unless a newer load already took over. */
1062
- failLoad(generation, message) {
1407
+ /** Settle callers only while this read still owns the current refresh. */
1408
+ settleLoads(generation, settle) {
1063
1409
  if (generation !== this.generation) return;
1410
+ const pending = [...this.pendingLoads];
1411
+ this.pendingLoads.clear();
1412
+ for (const load of pending) settle(load);
1413
+ }
1414
+ /** Publish one load's failure text; the caller checked the current generation. */
1415
+ failLoad(message) {
1064
1416
  this.store.update((s) => {
1065
1417
  s.status = "error";
1066
1418
  s.error = message;
@@ -1162,11 +1514,12 @@ window.__ModuleLoader__.load({
1162
1514
  * and at least one model — are required here rather than at load, so the
1163
1515
  * failure names the field while the user is still looking at it.
1164
1516
  *
1165
- * There is deliberately no reasoning-effort control, here or on the editor
1166
- * card: effort is a per-MODEL capability, and the models under one provider
1167
- * disagree about it, so a provider-scoped control can only be set to a value
1168
- * some of them reject. The composer's model picker offers each model its own
1169
- * levels instead.
1517
+ * There is deliberately no provider-scoped reasoning-effort control, here or
1518
+ * on the editor card: effort is a per-MODEL capability, and the models under
1519
+ * one provider disagree about it, so a provider-scoped control can only be set
1520
+ * to a value some of them reject. Each model row of a hand-declared route
1521
+ * declares its own `reasoningEfforts` instead, and the composer's model picker
1522
+ * offers each model those levels.
1170
1523
  */
1171
1524
  /** The settings namespace a hand-declared provider is written into. */
1172
1525
  const NS$1 = "llm-pi-ai";
@@ -1193,7 +1546,7 @@ window.__ModuleLoader__.load({
1193
1546
  * @returns the creation card.
1194
1547
  */
1195
1548
  function CustomProviderCard(props) {
1196
- const { taken, protocols, operations, t } = props;
1549
+ const { taken, protocols, reasoningLevels, operations, t, onBusyChange } = props;
1197
1550
  const [openedAt] = (0, react.useState)(() => props.revision);
1198
1551
  const [route, setRoute] = (0, react.useState)("");
1199
1552
  const [displayName, setDisplayName] = (0, react.useState)("");
@@ -1202,6 +1555,14 @@ window.__ModuleLoader__.load({
1202
1555
  const [keyDraft, setKeyDraft] = (0, react.useState)("");
1203
1556
  const [models, setModels] = (0, react.useState)([]);
1204
1557
  const [busy, setBusy] = (0, react.useState)(false);
1558
+ const [listBusy, setListBusy] = (0, react.useState)(false);
1559
+ (0, react.useEffect)(() => {
1560
+ onBusyChange?.(busy || listBusy);
1561
+ }, [
1562
+ busy,
1563
+ listBusy,
1564
+ onBusyChange
1565
+ ]);
1205
1566
  const [failure, setFailure] = (0, react.useState)(void 0);
1206
1567
  /**
1207
1568
  * The profile write landed. Only the key write can still be outstanding, so
@@ -1216,7 +1577,7 @@ window.__ModuleLoader__.load({
1216
1577
  const routeTaken = taken.includes(route);
1217
1578
  const normalizedBaseURL = baseURL.trim();
1218
1579
  const baseUrlInvalid = baseURL.length > 0 && !isHttpUrl(normalizedBaseURL);
1219
- const modelFailure = validateDeepSeekModels(models);
1580
+ const modelFailure = validateDeepSeekModels(models) ?? validateReasoningEfforts(models);
1220
1581
  const keyFailure = apiKeyFailure(keyDraft);
1221
1582
  const keyValue = keyDraft.trim();
1222
1583
  const ready = route.length > 0 && !routeInvalid && !routeTaken && normalizedBaseURL.length > 0 && !baseUrlInvalid && models.length > 0 && modelFailure === void 0 && keyFailure === void 0;
@@ -1320,7 +1681,7 @@ window.__ModuleLoader__.load({
1320
1681
  className: ModelsSection_module_css_default["input"],
1321
1682
  type: "text",
1322
1683
  value: baseURL,
1323
- placeholder: t("customBaseUrlPlaceholder"),
1684
+ placeholder: t(protocol === "anthropic-messages" ? "customAnthropicBaseUrlPlaceholder" : "customBaseUrlPlaceholder"),
1324
1685
  "aria-label": t("baseUrl"),
1325
1686
  "aria-invalid": baseUrlInvalid,
1326
1687
  disabled: profileDisabled,
@@ -1359,10 +1720,8 @@ window.__ModuleLoader__.load({
1359
1720
  className: ModelsSection_module_css_default["fieldLabel"],
1360
1721
  children: t("keyInput")
1361
1722
  }),
1362
- (0, react_jsx_runtime.jsx)("input", {
1363
- className: ModelsSection_module_css_default["input"],
1364
- type: "password",
1365
- autoComplete: "off",
1723
+ (0, react_jsx_runtime.jsx)(ApiKeyInput, {
1724
+ t,
1366
1725
  value: keyDraft,
1367
1726
  placeholder: t("keyPlaceholder"),
1368
1727
  "aria-label": t("keyInput"),
@@ -1380,6 +1739,7 @@ window.__ModuleLoader__.load({
1380
1739
  (0, react_jsx_runtime.jsx)(ModelListEditor, {
1381
1740
  models,
1382
1741
  onChange: setModels,
1742
+ reasoningLevels,
1383
1743
  probe: {
1384
1744
  settingsNs: NS$1,
1385
1745
  baseURL: normalizedBaseURL,
@@ -1389,7 +1749,8 @@ window.__ModuleLoader__.load({
1389
1749
  probeBlocked: baseUrlInvalid ? "customBaseUrlInvalid" : keyFailure === "keyBlank" ? "keyBlankNew" : keyFailure,
1390
1750
  operations,
1391
1751
  t,
1392
- disabled: profileDisabled
1752
+ disabled: profileDisabled,
1753
+ onBusyChange: setListBusy
1393
1754
  }),
1394
1755
  failure !== void 0 ? (0, react_jsx_runtime.jsx)("p", {
1395
1756
  className: ModelsSection_module_css_default["error"],
@@ -1430,11 +1791,12 @@ window.__ModuleLoader__.load({
1430
1791
  * display name and wire protocol of a pi-ai route the adapter does not ship —
1431
1792
  * the two fields the create card asked that route for, editable here for the
1432
1793
  * same reason).
1433
- * Reasoning effort is deliberately absent: it is a per-MODEL capability, and
1434
- * the models under one provider disagree about it, so a provider-scoped
1435
- * control can only be set to a value some of them reject. The composer's
1436
- * model picker offers each model its own levels; `settings.yaml` keeps the
1437
- * profile field for a deployment that knows its route. Everything else stays
1794
+ * There is deliberately no provider-scoped reasoning-effort control, here or
1795
+ * on the editor card: effort is a per-MODEL capability, and the models under
1796
+ * one provider disagree about it, so a provider-scoped control can only be set
1797
+ * to a value some of them reject. Each model row of a hand-declared route
1798
+ * declares its own `reasoningEfforts` instead, and the composer's model picker
1799
+ * offers each model those levels. Everything else stays
1438
1800
  * owned by `settings.yaml`. Profile edits land as minimal `settings.mutate`
1439
1801
  * path ops against the stored section — the card names only the fields it can
1440
1802
  * see instead of rebuilding the whole subtree from a partial descriptor.
@@ -1493,8 +1855,16 @@ window.__ModuleLoader__.load({
1493
1855
  const { namespace, schema, settingsPath, operations, t } = props;
1494
1856
  const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
1495
1857
  const [keyDraft, setKeyDraft] = (0, react.useState)("");
1496
- const [keyState, setKeyState] = (0, react.useState)(void 0);
1497
1858
  const [busy, setBusy] = (0, react.useState)(false);
1859
+ const [listBusy, setListBusy] = (0, react.useState)(false);
1860
+ const { onBusyChange } = props;
1861
+ (0, react.useEffect)(() => {
1862
+ onBusyChange?.(busy || listBusy);
1863
+ }, [
1864
+ busy,
1865
+ listBusy,
1866
+ onBusyChange
1867
+ ]);
1498
1868
  const [failure, setFailure] = (0, react.useState)(void 0);
1499
1869
  const [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));
1500
1870
  const [expectedRevision, setExpectedRevision] = (0, react.useState)(() => namespace.revision);
@@ -1513,17 +1883,6 @@ window.__ModuleLoader__.load({
1513
1883
  namespace,
1514
1884
  schema
1515
1885
  ]);
1516
- (0, react.useEffect)(() => {
1517
- let stale = false;
1518
- setKeyState(void 0);
1519
- operations.describeCredential(keyRef).then((described) => {
1520
- if (stale) return;
1521
- setKeyState(described);
1522
- });
1523
- return () => {
1524
- stale = true;
1525
- };
1526
- }, [operations, keyRef]);
1527
1886
  const stringAt = (source, key) => {
1528
1887
  const value = schema.getPath(source, [key]);
1529
1888
  return typeof value === "string" && value.trim().length > 0 ? value : void 0;
@@ -1532,7 +1891,15 @@ window.__ModuleLoader__.load({
1532
1891
  const value = next === void 0 || next.trim().length === 0 ? void 0 : next;
1533
1892
  setDraft((current) => value === void 0 ? schema.deletePath(current, [key]) : schema.setPath(current, [key], value));
1534
1893
  };
1535
- const modelFailure = validateDeepSeekModels(schema.getPath(draft, ["models"]));
1894
+ const reasoningLevels = (0, react.useMemo)(() => layout === "pi-ai" && props.declared === true ? reasoningLevelChoices(namespace, schema) : [], [
1895
+ layout,
1896
+ props.declared,
1897
+ namespace,
1898
+ schema
1899
+ ]);
1900
+ const editsReasoning = reasoningLevels.length > 0;
1901
+ const validateModels = (value) => validateDeepSeekModels(value) ?? (editsReasoning ? validateReasoningEfforts(value) : void 0);
1902
+ const modelFailure = validateModels(schema.getPath(draft, ["models"]));
1536
1903
  const keyFailure = apiKeyFailure(keyDraft);
1537
1904
  const keyValue = keyDraft.trim();
1538
1905
  const shownKeyFailure = (props.credentialRequired === true && keyDraft.length > 0 && keyValue.length === 0 ? "keyRequired" : void 0) ?? keyFailure;
@@ -1555,7 +1922,7 @@ window.__ModuleLoader__.load({
1555
1922
  const ns = namespace.ns;
1556
1923
  const next = layout === "pi-ai" && stringAt(draft, "apiKeyEnv") === void 0 && stringAt(fallback, "apiKeyEnv") === void 0 && keyValue.length > 0 ? schema.setPath(draft, ["apiKeyEnv"], keyRef) : draft;
1557
1924
  if (props.credentialOnly !== true) {
1558
- const failure = validateDeepSeekModels(schema.getPath(next, ["models"]));
1925
+ const failure = validateModels(schema.getPath(next, ["models"]));
1559
1926
  /* v8 ignore next 3 -- unreachable from the card: the same failure disables submit */
1560
1927
  if (failure !== void 0) return `${t("model")} ${String(failure.index + 1)}: ${t(failure.key)}`;
1561
1928
  }
@@ -1605,7 +1972,6 @@ window.__ModuleLoader__.load({
1605
1972
  props.t("settingsPathUnresolvable")
1606
1973
  ]
1607
1974
  });
1608
- const keyLocked = keyState?.writable === false;
1609
1975
  /**
1610
1976
  * The catalog beneath the user layer: what the composition entry pinned, or
1611
1977
  * else the schema default that `resolve` would supply. The effective value
@@ -1629,7 +1995,38 @@ window.__ModuleLoader__.load({
1629
1995
  const defaultContextWindow = schema.getPath(fallback, ["defaultContextWindow"]);
1630
1996
  const defaultMaxTokens = schema.getPath(fallback, ["maxTokens"]);
1631
1997
  const defaultInput = schema.getPath(fallback, ["defaultInput"]);
1632
- const keyPlaceholder = keyLocked ? t("keyEnvLocked") : keyState?.configured === true && props.credentialRequired !== true ? t("keyStored") : family === "pi-ai" ? t("keyPlaceholderNative") : t("keyPlaceholder");
1998
+ const baseURL = stringAt(fallback, "baseURL") ?? props.defaultBaseURL;
1999
+ const endpointEnv = props.baseURLEnv ?? [];
2000
+ const endpointHint = family === "deepseek" ? t("deepSeekEndpointHint") : baseURL === void 0 && endpointEnv.length > 0 ? t("baseUrlEnvironment").replace("{env}", () => endpointEnv.join(", ")) : void 0;
2001
+ const namedRef = stringAt(fallback, "apiKeyEnv");
2002
+ const nativeAuth = namedRef === void 0 ? props.nativeAuth : void 0;
2003
+ const authRefs = namedRef === void 0 ? (nativeAuth?.env ?? []).filter((ref) => !endpointEnv.includes(ref)) : [namedRef];
2004
+ const visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes("oauth"));
2005
+ const keyHint = visibleRefs[0];
2006
+ const checkedRefs = authRefs.map((ref) => [ref, props.credentialChecks?.[ref] ?? (ref === namedRef ? props.credential : void 0)]);
2007
+ const detected = checkedRefs.find(([, info]) => info?.configured === true);
2008
+ const detectedRef = detected?.[0];
2009
+ const detectedVisibleRef = detectedRef === void 0 || !visibleRefs.includes(detectedRef) ? void 0 : detectedRef;
2010
+ const missingRefs = checkedRefs.length > 0 && checkedRefs.every(([, info]) => info?.configured === false);
2011
+ const savedCredential = detected?.[1]?.source === "file";
2012
+ 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);
2013
+ const keyHelp = visibleRefs.length === 0 ? void 0 : t("keyHelp").replace("{env}", () => visibleRefs.join(" / "));
2014
+ const authHelp = keyHelp === void 0 ? null : (0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.Tooltip, {
2015
+ label: keyHelp,
2016
+ side: "right",
2017
+ delayMs: 0,
2018
+ focusDelayMs: 0,
2019
+ portal: true,
2020
+ openOnClick: true,
2021
+ children: (0, react_jsx_runtime.jsx)("button", {
2022
+ type: "button",
2023
+ className: ModelsSection_module_css_default["helpButton"],
2024
+ "aria-label": t("authHelp"),
2025
+ children: "?"
2026
+ })
2027
+ });
2028
+ const keylessNativeAuth = nativeAuth?.env.length === 0 && nativeAuth.oauth;
2029
+ const keyPlaceholder = keyHint === void 0 || props.credentialRequired === true ? t("keyPlaceholder") : t(savedCredential ? "keyPlaceholderSaved" : "keyPlaceholderFallback").replace("{hint}", () => keyHint);
1633
2030
  /** What both family editors take: the rows, whose layer owns them, and the two writes. */
1634
2031
  const catalogProps = {
1635
2032
  models,
@@ -1643,28 +2040,32 @@ window.__ModuleLoader__.load({
1643
2040
  setDraft((current) => schema.deletePath(current, ["models"]));
1644
2041
  }
1645
2042
  };
1646
- return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [(0, react_jsx_runtime.jsxs)("div", {
2043
+ return (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [keylessNativeAuth ? null : (0, react_jsx_runtime.jsxs)("div", {
1647
2044
  className: ModelsSection_module_css_default["field"],
1648
2045
  children: [
1649
- (0, react_jsx_runtime.jsx)("span", {
2046
+ (0, react_jsx_runtime.jsxs)("span", {
1650
2047
  className: ModelsSection_module_css_default["fieldLabel"],
1651
- children: t("keyInput")
2048
+ children: [t("keyInput"), authHelp]
1652
2049
  }),
1653
- (0, react_jsx_runtime.jsx)("input", {
1654
- className: ModelsSection_module_css_default["input"],
1655
- type: "password",
1656
- autoComplete: "off",
2050
+ (0, react_jsx_runtime.jsx)(ApiKeyInput, {
2051
+ t,
1657
2052
  value: keyDraft,
1658
2053
  placeholder: keyPlaceholder,
1659
2054
  "aria-label": t("keyInput"),
1660
2055
  "aria-invalid": shownKeyFailure !== void 0,
2056
+ "aria-describedby": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,
1661
2057
  required: props.credentialRequired === true,
1662
2058
  autoFocus: props.autoFocusCredential === true,
1663
- disabled: disabled || keyLocked,
2059
+ disabled,
1664
2060
  onChange: (event) => {
1665
2061
  setKeyDraft(event.target.value);
1666
2062
  }
1667
2063
  }),
2064
+ credentialHint === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
2065
+ id: `${props.provider}-credential-hint`,
2066
+ className: ModelsSection_module_css_default[missingRefs ? "notice" : detectedRef === void 0 ? "advancedHint" : "savedNotice"],
2067
+ children: credentialHint
2068
+ }),
1668
2069
  shownKeyFailure === void 0 ? null : (0, react_jsx_runtime.jsx)("p", {
1669
2070
  className: ModelsSection_module_css_default["error"],
1670
2071
  children: t(shownKeyFailure)
@@ -1706,19 +2107,19 @@ window.__ModuleLoader__.load({
1706
2107
  className: ModelsSection_module_css_default["input"],
1707
2108
  type: "text",
1708
2109
  value: stringAt(draft, "baseURL") ?? "",
1709
- placeholder: family === "deepseek" ? t("deepSeekBaseUrl") : stringAt(fallback, "baseURL") ?? t("baseUrlDefault"),
1710
- "aria-describedby": family === "deepseek" ? `${props.provider}-endpoint-hint` : void 0,
2110
+ placeholder: family === "deepseek" ? t("deepSeekBaseUrl") : baseURL === void 0 ? t(endpointEnv.length > 0 ? "baseUrlConfigured" : "baseUrlDefault") : t("baseUrlPlaceholder").replace("{url}", () => baseURL),
2111
+ "aria-describedby": endpointHint === void 0 ? void 0 : `${props.provider}-endpoint-hint`,
1711
2112
  "aria-label": t("baseUrl"),
1712
2113
  disabled,
1713
2114
  onChange: (event) => {
1714
2115
  setField("baseURL", event.target.value === "" ? void 0 : event.target.value);
1715
2116
  }
1716
2117
  }),
1717
- family === "deepseek" ? (0, react_jsx_runtime.jsx)("span", {
2118
+ endpointHint === void 0 ? null : (0, react_jsx_runtime.jsx)("span", {
1718
2119
  id: `${props.provider}-endpoint-hint`,
1719
2120
  className: ModelsSection_module_css_default["advancedHint"],
1720
- children: t("deepSeekEndpointHint")
1721
- }) : null
2121
+ children: endpointHint
2122
+ })
1722
2123
  ]
1723
2124
  }),
1724
2125
  ownsIdentity ? (0, react_jsx_runtime.jsxs)("div", {
@@ -1750,10 +2151,12 @@ window.__ModuleLoader__.load({
1750
2151
  }) : (0, react_jsx_runtime.jsx)(ModelListEditor, {
1751
2152
  ...catalogProps,
1752
2153
  catalogProvider: props.declared === true ? void 0 : props.provider,
2154
+ reasoningLevels,
1753
2155
  defaultInput: Array.isArray(defaultInput) ? defaultInput : void 0,
1754
2156
  probe,
1755
2157
  probeBlocked: keyFailure,
1756
- operations
2158
+ operations,
2159
+ onBusyChange: setListBusy
1757
2160
  })
1758
2161
  ]
1759
2162
  })]
@@ -1795,6 +2198,7 @@ window.__ModuleLoader__.load({
1795
2198
  props.onClose(false);
1796
2199
  },
1797
2200
  onSubmit: () => {
2201
+ props.onSubmitCredential?.();
1798
2202
  apply();
1799
2203
  }
1800
2204
  })
@@ -1817,12 +2221,17 @@ window.__ModuleLoader__.load({
1817
2221
  * re-renders from pushed invalidations or the post-apply reload.
1818
2222
  */
1819
2223
  /** Render an editor for either the setup posture or an expanded provider row. */
1820
- function renderProviderEditor({ target, ...props }) {
2224
+ function renderProviderEditor({ target, row, ...props }) {
1821
2225
  return (0, react_jsx_runtime.jsx)(ProviderEditor, {
1822
2226
  provider: target.provider,
1823
2227
  displayName: target.displayName,
1824
2228
  settingsPath: target.settingsPath,
1825
2229
  ...target.declared === true ? { declared: true } : {},
2230
+ ...target.defaultBaseURL === void 0 ? {} : { defaultBaseURL: target.defaultBaseURL },
2231
+ ...target.baseURLEnv === void 0 ? {} : { baseURLEnv: target.baseURLEnv },
2232
+ ...target.nativeAuth === void 0 ? {} : { nativeAuth: target.nativeAuth },
2233
+ ...row.credential === void 0 ? {} : { credential: row.credential },
2234
+ ...row.credentialChecks === void 0 ? {} : { credentialChecks: row.credentialChecks },
1826
2235
  ...props
1827
2236
  });
1828
2237
  }
@@ -1882,7 +2291,10 @@ window.__ModuleLoader__.load({
1882
2291
  settingsNs: row.entry.settingsNs,
1883
2292
  settingsPath: row.entry.settingsPath,
1884
2293
  ...credentialRef === void 0 ? {} : { credentialRef },
1885
- ...row.entry.declared === true ? { declared: true } : {}
2294
+ ...row.entry.declared === true ? { declared: true } : {},
2295
+ ...row.entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: row.entry.defaultBaseURL },
2296
+ ...row.entry.baseURLEnv === void 0 ? {} : { baseURLEnv: row.entry.baseURLEnv },
2297
+ ...row.entry.nativeAuth === void 0 ? {} : { nativeAuth: row.entry.nativeAuth }
1886
2298
  };
1887
2299
  }
1888
2300
  /** Stable visible and accessible identity for one provider target. */
@@ -1926,6 +2338,8 @@ window.__ModuleLoader__.load({
1926
2338
  const [deleteFailure, setDeleteFailure] = (0, react.useState)(void 0);
1927
2339
  const [savedTarget, setSavedTarget] = (0, react.useState)(void 0);
1928
2340
  const [declaring, setDeclaring] = (0, react.useState)(false);
2341
+ /** Whether the add card's editor has a write or an interrogation in flight. */
2342
+ const [addBusy, setAddBusy] = (0, react.useState)(false);
1929
2343
  const [dismissedSetup, setDismissedSetup] = (0, react.useState)(() => /* @__PURE__ */ new Set());
1930
2344
  const announceSaved = (target) => {
1931
2345
  controller.load().then(() => {
@@ -1936,6 +2350,7 @@ window.__ModuleLoader__.load({
1936
2350
  setEditing(void 0);
1937
2351
  setAdding(false);
1938
2352
  setDeclaring(false);
2353
+ setAddBusy(false);
1939
2354
  if (changed) announceSaved(target);
1940
2355
  };
1941
2356
  /**
@@ -2011,6 +2426,7 @@ window.__ModuleLoader__.load({
2011
2426
  const addNamespace = addTarget === void 0 ? void 0 : state.namespaces.get(addTarget.settingsNs);
2012
2427
  const addRow = addTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === addTarget.provider);
2013
2428
  const protocols = protocolChoices(state.namespaces.get("llm-pi-ai"), schema);
2429
+ const reasoningLevels = reasoningLevelChoices(state.namespaces.get("llm-pi-ai"), schema);
2014
2430
  return (0, react_jsx_runtime.jsxs)("div", {
2015
2431
  className: ModelsSection_module_css_default["section"],
2016
2432
  children: [
@@ -2050,6 +2466,7 @@ window.__ModuleLoader__.load({
2050
2466
  error,
2051
2467
  renderProviderEditor({
2052
2468
  target,
2469
+ row,
2053
2470
  namespace,
2054
2471
  schema,
2055
2472
  operations,
@@ -2135,6 +2552,7 @@ window.__ModuleLoader__.load({
2135
2552
  }, { entryKey: row.entry.settingsNs }),
2136
2553
  open ? renderProviderEditor({
2137
2554
  target,
2555
+ row,
2138
2556
  namespace,
2139
2557
  schema,
2140
2558
  operations,
@@ -2162,6 +2580,7 @@ window.__ModuleLoader__.load({
2162
2580
  className: `${ModelsSection_module_css_default["input"]} ${ModelsSection_module_css_default["selectInput"]}`,
2163
2581
  value: addTarget.provider,
2164
2582
  "aria-label": t("provider"),
2583
+ disabled: addBusy,
2165
2584
  onChange: (event) => {
2166
2585
  const row = addable.find((candidate) => candidate.entry.provider === event.target.value);
2167
2586
  /* v8 ignore next -- the select only lists addable rows */
@@ -2181,12 +2600,17 @@ window.__ModuleLoader__.load({
2181
2600
  namespace: addNamespace,
2182
2601
  schema,
2183
2602
  settingsPath: addTarget.settingsPath,
2603
+ ...addTarget.defaultBaseURL === void 0 ? {} : { defaultBaseURL: addTarget.defaultBaseURL },
2604
+ ...addTarget.baseURLEnv === void 0 ? {} : { baseURLEnv: addTarget.baseURLEnv },
2605
+ ...addTarget.nativeAuth === void 0 ? {} : { nativeAuth: addTarget.nativeAuth },
2606
+ ...addRow?.credentialChecks === void 0 ? {} : { credentialChecks: addRow.credentialChecks },
2184
2607
  operations,
2185
2608
  t,
2186
2609
  readOnly: !state.writable,
2187
2610
  onClose: (changed) => {
2188
2611
  closeEditor(changed, addTarget);
2189
- }
2612
+ },
2613
+ onBusyChange: setAddBusy
2190
2614
  }, addTarget.provider),
2191
2615
  addRow === void 0 ? null : renderSlot("settings.models.provider-card", {
2192
2616
  provider: addRow.entry,
@@ -2199,6 +2623,7 @@ window.__ModuleLoader__.load({
2199
2623
  children: (0, react_jsx_runtime.jsx)(CustomProviderCard, {
2200
2624
  taken: state.rows.map((row) => row.entry.provider),
2201
2625
  protocols,
2626
+ reasoningLevels,
2202
2627
  /* v8 ignore next -- the card only opens from a button disabled without this namespace */
2203
2628
  revision: state.namespaces.get("llm-pi-ai")?.revision ?? 0,
2204
2629
  operations,
@@ -2225,7 +2650,7 @@ window.__ModuleLoader__.load({
2225
2650
  setAdding(true);
2226
2651
  setEditing(targetOf(first));
2227
2652
  },
2228
- children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("add")]
2653
+ children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("add")]
2229
2654
  }), state.namespaces.has("llm-pi-ai") && (0, react_jsx_runtime.jsxs)("button", {
2230
2655
  type: "button",
2231
2656
  className: ModelsSection_module_css_default["addButton"],
@@ -2238,7 +2663,7 @@ window.__ModuleLoader__.load({
2238
2663
  setEditing(void 0);
2239
2664
  setDeclaring(true);
2240
2665
  },
2241
- children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutline16, { size: 14 }), t("customAdd")]
2666
+ children: [(0, react_jsx_runtime.jsx)(_qilin_agent_client_ui_primitives.IconPlusOutlineRegular, { size: 14 }), t("customAdd")]
2242
2667
  })]
2243
2668
  })
2244
2669
  }),
@@ -2441,10 +2866,6 @@ window.__ModuleLoader__.load({
2441
2866
  */
2442
2867
  function createModelsOperations(ctx) {
2443
2868
  return {
2444
- describeCredential: async (ref) => {
2445
- const response = await ctx.remote.credentials.describe([ref]);
2446
- return response.ok ? response.value[ref] : void 0;
2447
- },
2448
2869
  storeCredential: async (ref, value) => {
2449
2870
  const response = await ctx.remote.credentials.set(ref, value);
2450
2871
  return response.ok ? void 0 : response.error.message;
@@ -2529,13 +2950,23 @@ window.__ModuleLoader__.load({
2529
2950
  conflict: "Someone else changed these settings while this card was open. Close it and reopen to edit the current values.",
2530
2951
  retry: "Retry",
2531
2952
  keyInput: "API key",
2953
+ keyReveal: "Show secret",
2954
+ keyHide: "Hide secret",
2532
2955
  keyPlaceholder: "Enter your API key",
2533
- keyPlaceholderNative: "Enter an API key, or leave blank to use environment authentication",
2534
- keyStored: "Configured — enter a new value to replace",
2535
- keyEnvLocked: "Provided by the launch environment (read-only)",
2956
+ keyPlaceholderFallback: "Leave blank to use env as auth ({hint})",
2957
+ keyPlaceholderSaved: "Leave blank to use saved credentials",
2958
+ keyFallbackMissing: "Env var not detected. Enter an API key, or configure {hint} in your env.",
2959
+ keyFallbackDetected: "Env var detected. ({hint})",
2960
+ keyFallbackDetectedHidden: "Env var detected.",
2961
+ keyFallbackUnchecked: "Environment credential status has not been confirmed.",
2962
+ keyHelp: "Saved credentials are used first. Environment fallbacks shown here, in order: {env}. Sources are launch environment, $cwd/.env, then $QILIN_HOME/.env.",
2963
+ authHelp: "Authentication details",
2536
2964
  customized: "Customized settings",
2537
2965
  baseUrl: "Base URL",
2538
- baseUrlDefault: "Provider default",
2966
+ baseUrlDefault: "No default endpoint",
2967
+ baseUrlEnvironment: "Provider endpoint configuration: {env}",
2968
+ baseUrlConfigured: "Provider-configured endpoint",
2969
+ baseUrlPlaceholder: "{url}",
2539
2970
  deepSeekBaseUrl: "https://api.deepseek.com/anthropic",
2540
2971
  deepSeekEndpointHint: "Use an endpoint compatible with the configured connection.",
2541
2972
  models: "Models",
@@ -2554,6 +2985,16 @@ window.__ModuleLoader__.load({
2554
2985
  modelInputTypes: "Input types",
2555
2986
  modelInputText: "Text",
2556
2987
  modelInputImage: "Image",
2988
+ modelReasoning: "Reasoning levels",
2989
+ modelReasoningLevel: "Level",
2990
+ modelReasoningValue: "API value",
2991
+ modelReasoningHelp: "About reasoning levels",
2992
+ modelReasoningHelpText: "The API value is sent in the request's reasoning-effort field, such as OpenAI's reasoning_effort. It defaults to the level name; where the model provider's API documentation specifies a different value, follow it. Off turns reasoning off and needs no value; a value already written in the configuration is kept and sent.",
2993
+ modelReasoningNeedsLevel: "Add at least one level besides Off, or turn reasoning levels off.",
2994
+ modelReasoningValueRequired: "Every level besides Off needs an API value, and no value can be empty.",
2995
+ modelReasoningAdd: "Add level",
2996
+ modelReasoningRemove: "Delete level",
2997
+ modelReasoningOffValuePlaceholder: "Turns reasoning off",
2557
2998
  addModel: "Add model",
2558
2999
  removeModel: "Delete model",
2559
3000
  modelsEmpty: "No models will be shown in the selector. Unlisted IDs can still be sent directly.",
@@ -2596,6 +3037,7 @@ window.__ModuleLoader__.load({
2596
3037
  customBaseUrlInvalid: "Enter a valid HTTP or HTTPS URL.",
2597
3038
  customNeedsModels: "A custom provider needs at least one model.",
2598
3039
  customBaseUrlPlaceholder: "https://gateway.example/v1",
3040
+ customAnthropicBaseUrlPlaceholder: "https://gateway.example",
2599
3041
  settingsPathUnresolvable: "unresolvable settings path",
2600
3042
  create: "Create provider",
2601
3043
  creating: "Creating…",
@@ -2634,13 +3076,23 @@ window.__ModuleLoader__.load({
2634
3076
  conflict: "这张卡片打开期间,这些设置已被其他地方改动。请关闭后重新打开,在当前值上编辑。",
2635
3077
  retry: "重试",
2636
3078
  keyInput: "API 密钥",
3079
+ keyReveal: "显示密钥",
3080
+ keyHide: "隐藏密钥",
2637
3081
  keyPlaceholder: "输入 API 密钥",
2638
- keyPlaceholderNative: "输入 API 密钥,或留空使用环境认证",
2639
- keyStored: "已配置——输入新值可替换",
2640
- keyEnvLocked: "由启动环境提供(只读)",
3082
+ keyPlaceholderFallback: "留空使用环境认证({hint})",
3083
+ keyPlaceholderSaved: "留空使用已保存凭据",
3084
+ keyFallbackMissing: "未检测到环境变量。请填写 API 密钥,或设置环境变量 {hint}。",
3085
+ keyFallbackDetected: "已检测到环境变量({hint})",
3086
+ keyFallbackDetectedHidden: "已检测到环境变量",
3087
+ keyFallbackUnchecked: "环境凭据状态尚未确认",
3088
+ keyHelp: "优先使用已保存的凭据。此处显示的环境后备按以下顺序排列:{env}。来源依次为启动环境、$cwd/.env、$QILIN_HOME/.env。",
3089
+ authHelp: "认证说明",
2641
3090
  customized: "自定义设置",
2642
3091
  baseUrl: "API 地址",
2643
- baseUrlDefault: "提供方默认",
3092
+ baseUrlDefault: "没有默认地址",
3093
+ baseUrlEnvironment: "提供方地址配置:{env}",
3094
+ baseUrlConfigured: "由提供方配置地址",
3095
+ baseUrlPlaceholder: "{url}",
2644
3096
  deepSeekBaseUrl: "https://api.deepseek.com/anthropic",
2645
3097
  deepSeekEndpointHint: "请填写与当前连接配置兼容的 API 地址。",
2646
3098
  models: "模型目录",
@@ -2659,6 +3111,16 @@ window.__ModuleLoader__.load({
2659
3111
  modelInputTypes: "输入类型",
2660
3112
  modelInputText: "文本",
2661
3113
  modelInputImage: "图片",
3114
+ modelReasoning: "推理等级",
3115
+ modelReasoningLevel: "档位",
3116
+ modelReasoningValue: "API 参数值",
3117
+ modelReasoningHelp: "推理等级说明",
3118
+ modelReasoningHelpText: "API 参数值会写入请求的推理强度字段(如 OpenAI 的 reasoning_effort),默认与档位名相同;如有不同,以模型提供商的 API 文档为准。Off 表示关闭思考,不需要填写参数值;配置中已写入的值会保留并发送。",
3119
+ modelReasoningNeedsLevel: "至少添加一个 Off 以外的档位;不需要思考请关闭推理等级。",
3120
+ modelReasoningValueRequired: "Off 以外的档位都需要填写 API 参数值,且参数值不能为空字符串。",
3121
+ modelReasoningAdd: "添加档位",
3122
+ modelReasoningRemove: "删除档位",
3123
+ modelReasoningOffValuePlaceholder: "关闭思考",
2662
3124
  addModel: "添加模型",
2663
3125
  removeModel: "删除模型",
2664
3126
  modelsEmpty: "模型选择器中将不显示任何模型;目录外 ID 仍可直接发送。",
@@ -2701,6 +3163,7 @@ window.__ModuleLoader__.load({
2701
3163
  customBaseUrlInvalid: "请输入有效的 HTTP 或 HTTPS 地址。",
2702
3164
  customNeedsModels: "自定义提供方至少需要一个模型。",
2703
3165
  customBaseUrlPlaceholder: "https://gateway.example/v1",
3166
+ customAnthropicBaseUrlPlaceholder: "https://gateway.example",
2704
3167
  settingsPathUnresolvable: "无法解析设置路径",
2705
3168
  create: "创建提供方",
2706
3169
  creating: "创建中…",
@@ -2712,6 +3175,904 @@ window.__ModuleLoader__.load({
2712
3175
  keyRequired: "请输入 API 密钥后继续。"
2713
3176
  };
2714
3177
  //#endregion
3178
+ //#region ../../../vendor/cosmokit/src/misc.ts
3179
+ /** Return true when a value is `null` or `undefined`. */
3180
+ function isNullable(value) {
3181
+ return value === null || value === void 0;
3182
+ }
3183
+ /** Return true for non-array object values. */
3184
+ function isPlainObject(data) {
3185
+ return data && typeof data === "object" && !Array.isArray(data);
3186
+ }
3187
+ /** Filter object entries and return a new object. */
3188
+ function filterKeys(object, filter) {
3189
+ return Object.fromEntries(Object.entries(object).filter(([key, value]) => filter(key, value)));
3190
+ }
3191
+ /** Map object values while preserving the original key set. */
3192
+ function mapValues(object, transform) {
3193
+ return Object.fromEntries(Object.entries(object).map(([key, value]) => [key, transform(value, key)]));
3194
+ }
3195
+ /** Pick selected keys from an object, optionally including `undefined` values. */
3196
+ function pick(source, keys, forced) {
3197
+ if (!keys) return { ...source };
3198
+ const result = {};
3199
+ for (const key of keys) if (forced || source[key] !== void 0) result[key] = source[key];
3200
+ return result;
3201
+ }
3202
+ //#endregion
3203
+ //#region ../../../vendor/cosmokit/src/volatile.ts
3204
+ /** Shared config references used by schema validators and plugin runtimes. */
3205
+ const write = Symbol.for("cosmokit.volatile.write");
3206
+ function snapshot(value, ancestors = /* @__PURE__ */ new Set()) {
3207
+ if (typeof value === "function") throw new TypeError("volatile config cannot contain functions");
3208
+ if (value === null || typeof value !== "object") return value;
3209
+ if (ancestors.has(value)) throw new TypeError("volatile config cannot contain cycles");
3210
+ ancestors.add(value);
3211
+ try {
3212
+ if (Array.isArray(value)) return Object.freeze(value.map((item) => snapshot(item, ancestors)));
3213
+ if (Object.getPrototypeOf(value) !== Object.prototype && Object.getPrototypeOf(value) !== null) throw new TypeError("volatile config objects must be plain objects or arrays");
3214
+ return Object.freeze(Object.fromEntries(Object.entries(value).map(([key, item]) => [key, snapshot(item, ancestors)])));
3215
+ } finally {
3216
+ ancestors.delete(value);
3217
+ }
3218
+ }
3219
+ /**
3220
+ * Create a detached reference containing an immutable copy of the supplied data.
3221
+ * @param value - validated config data; class instances and functions are unsupported.
3222
+ * @returns a reference whose value is updated only by its owning runtime.
3223
+ */
3224
+ function createVolatile(value) {
3225
+ let current = snapshot(value);
3226
+ return Object.freeze({
3227
+ get: () => current,
3228
+ [write]: (value) => {
3229
+ current = value;
3230
+ }
3231
+ });
3232
+ }
3233
+ /**
3234
+ * Identify references across ESM/CJS copies of the shared library.
3235
+ * @param value - a parsed config value.
3236
+ * @returns whether the value implements the shared reference protocol.
3237
+ */
3238
+ function isVolatile(value) {
3239
+ return typeof value === "object" && value !== null && write in value;
3240
+ }
3241
+ //#endregion
3242
+ //#region ../../../vendor/cosmokit/src/types.ts
3243
+ /** Test values using `instanceof` with a `toStringTag` fallback. */
3244
+ function is(type, value) {
3245
+ if (arguments.length === 1) return (value) => is(type, value);
3246
+ return type in globalThis && value instanceof globalThis[type] || Object.prototype.toString.call(value).slice(8, -1) === type;
3247
+ }
3248
+ function isArrayBufferLike(value) {
3249
+ return is("ArrayBuffer", value) || is("SharedArrayBuffer", value);
3250
+ }
3251
+ function isArrayBufferSource(value) {
3252
+ return isArrayBufferLike(value) || ArrayBuffer.isView(value);
3253
+ }
3254
+ let Binary;
3255
+ (function(_Binary) {
3256
+ _Binary.is = isArrayBufferLike;
3257
+ _Binary.isSource = isArrayBufferSource;
3258
+ function fromSource(source) {
3259
+ if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
3260
+ else return source;
3261
+ }
3262
+ _Binary.fromSource = fromSource;
3263
+ function toBase64(source) {
3264
+ source = fromSource(source);
3265
+ if (typeof Buffer !== "undefined") return Buffer.from(source).toString("base64");
3266
+ let binary = "";
3267
+ const bytes = new Uint8Array(source);
3268
+ for (let i = 0; i < bytes.byteLength; i++) binary += String.fromCharCode(bytes[i]);
3269
+ return btoa(binary);
3270
+ }
3271
+ _Binary.toBase64 = toBase64;
3272
+ function fromBase64(source) {
3273
+ if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "base64"));
3274
+ return Uint8Array.from(atob(source), (c) => c.charCodeAt(0));
3275
+ }
3276
+ _Binary.fromBase64 = fromBase64;
3277
+ function toHex(source) {
3278
+ source = fromSource(source);
3279
+ if (typeof Buffer !== "undefined") return Buffer.from(source).toString("hex");
3280
+ return Array.from(new Uint8Array(source), (byte) => byte.toString(16).padStart(2, "0")).join("");
3281
+ }
3282
+ _Binary.toHex = toHex;
3283
+ function fromHex(source) {
3284
+ if (typeof Buffer !== "undefined") return fromSource(Buffer.from(source, "hex"));
3285
+ const hex = source.length % 2 === 0 ? source : source.slice(0, source.length - 1);
3286
+ const buffer = [];
3287
+ for (let i = 0; i < hex.length; i += 2) buffer.push(parseInt(`${hex[i]}${hex[i + 1]}`, 16));
3288
+ return Uint8Array.from(buffer).buffer;
3289
+ }
3290
+ _Binary.fromHex = fromHex;
3291
+ })(Binary || (Binary = {}));
3292
+ Binary.fromBase64;
3293
+ Binary.toBase64;
3294
+ Binary.fromHex;
3295
+ Binary.toHex;
3296
+ /** Deep-clone common JavaScript values while preserving prototypes and cycles. */
3297
+ function clone(source, refs = /* @__PURE__ */ new Map()) {
3298
+ if (!source || typeof source !== "object") return source;
3299
+ if (is("Date", source)) return new Date(source.valueOf());
3300
+ if (is("RegExp", source)) return new RegExp(source.source, source.flags);
3301
+ if (isArrayBufferLike(source)) return source.slice(0);
3302
+ if (ArrayBuffer.isView(source)) return source.buffer.slice(source.byteOffset, source.byteOffset + source.byteLength);
3303
+ const cached = refs.get(source);
3304
+ if (cached) return cached;
3305
+ if (Array.isArray(source)) {
3306
+ const result = [];
3307
+ refs.set(source, result);
3308
+ source.forEach((value, index) => {
3309
+ result[index] = Reflect.apply(clone, null, [value, refs]);
3310
+ });
3311
+ return result;
3312
+ }
3313
+ const result = Object.create(Object.getPrototypeOf(source));
3314
+ refs.set(source, result);
3315
+ for (const key of Reflect.ownKeys(source)) {
3316
+ const descriptor = { ...Reflect.getOwnPropertyDescriptor(source, key) };
3317
+ if ("value" in descriptor) descriptor.value = Reflect.apply(clone, null, [descriptor.value, refs]);
3318
+ Reflect.defineProperty(result, key, descriptor);
3319
+ }
3320
+ return result;
3321
+ }
3322
+ /**
3323
+ * Compare values recursively, treating two volatile references as equal regardless of value.
3324
+ * Strict comparison distinguishes null/undefined, treats opaque objects by identity,
3325
+ * compares URLs by normalized href, treats array holes as undefined, and considers distinct cyclic structures unequal.
3326
+ * @param a - first value.
3327
+ * @param b - second value.
3328
+ * @param strict - whether to require strict data equality outside volatile references.
3329
+ * @returns whether the values compare equal.
3330
+ */
3331
+ function deepEqual(a, b, strict) {
3332
+ const ancestors = /* @__PURE__ */ new Set();
3333
+ function compare(a, b) {
3334
+ if (a === b) return true;
3335
+ if (isVolatile(a) || isVolatile(b)) return isVolatile(a) && isVolatile(b);
3336
+ if (!strict && isNullable(a) && isNullable(b)) return true;
3337
+ if (typeof a !== typeof b || typeof a !== "object" || !a || !b) return false;
3338
+ if (ancestors.has(a)) return false;
3339
+ function check(test, then) {
3340
+ return test(a) ? test(b) ? then(a, b) : false : test(b) ? false : void 0;
3341
+ }
3342
+ ancestors.add(a);
3343
+ try {
3344
+ return check(Array.isArray, (a, b) => {
3345
+ if (a.length !== b.length) return false;
3346
+ for (let index = 0; index < a.length; index++) if (!compare(a[index], b[index])) return false;
3347
+ return true;
3348
+ }) ?? 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) => {
3349
+ if (a.byteLength !== b.byteLength) return false;
3350
+ const viewA = new Uint8Array(a);
3351
+ const viewB = new Uint8Array(b);
3352
+ for (let i = 0; i < viewA.length; i++) if (viewA[i] !== viewB[i]) return false;
3353
+ return true;
3354
+ }) ?? ((!strict || [a, b].every((value) => Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null)) && Object.keys({
3355
+ ...a,
3356
+ ...b
3357
+ }).every((key) => compare(a[key], b[key])));
3358
+ } finally {
3359
+ ancestors.delete(a);
3360
+ }
3361
+ }
3362
+ return compare(a, b);
3363
+ }
3364
+ //#endregion
3365
+ //#region ../../../vendor/cosmokit/src/time.ts
3366
+ let Time;
3367
+ (function(_Time) {
3368
+ _Time.millisecond = 1;
3369
+ const second = _Time.second = 1e3;
3370
+ const minute = _Time.minute = second * 60;
3371
+ const hour = _Time.hour = minute * 60;
3372
+ const day = _Time.day = hour * 24;
3373
+ const week = _Time.week = day * 7;
3374
+ let timezoneOffset = (/* @__PURE__ */ new Date()).getTimezoneOffset();
3375
+ function setTimezoneOffset(offset) {
3376
+ timezoneOffset = offset;
3377
+ }
3378
+ _Time.setTimezoneOffset = setTimezoneOffset;
3379
+ function getTimezoneOffset() {
3380
+ return timezoneOffset;
3381
+ }
3382
+ _Time.getTimezoneOffset = getTimezoneOffset;
3383
+ function getDateNumber(date = /* @__PURE__ */ new Date(), offset) {
3384
+ if (typeof date === "number") date = new Date(date);
3385
+ if (offset === void 0) offset = timezoneOffset;
3386
+ return Math.floor((date.valueOf() / minute - offset) / 1440);
3387
+ }
3388
+ _Time.getDateNumber = getDateNumber;
3389
+ function fromDateNumber(value, offset) {
3390
+ const date = new Date(value * day);
3391
+ if (offset === void 0) offset = timezoneOffset;
3392
+ return new Date(+date + offset * minute);
3393
+ }
3394
+ _Time.fromDateNumber = fromDateNumber;
3395
+ const numeric = /\d+(?:\.\d+)?/.source;
3396
+ const timeRegExp = new RegExp(`^${[
3397
+ "w(?:eek(?:s)?)?",
3398
+ "d(?:ay(?:s)?)?",
3399
+ "h(?:our(?:s)?)?",
3400
+ "m(?:in(?:ute)?(?:s)?)?",
3401
+ "s(?:ec(?:ond)?(?:s)?)?"
3402
+ ].map((unit) => `(${numeric}${unit})?`).join("")}$`);
3403
+ function parseTime(source) {
3404
+ const capture = timeRegExp.exec(source);
3405
+ if (!capture) return 0;
3406
+ 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);
3407
+ }
3408
+ _Time.parseTime = parseTime;
3409
+ function parseDate(date) {
3410
+ const parsed = parseTime(date);
3411
+ if (parsed) date = Date.now() + parsed;
3412
+ else if (/^\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).toLocaleDateString()}-${date}`;
3413
+ else if (/^\d{1,2}-\d{1,2}-\d{1,2}(:\d{1,2}){1,2}$/.test(date)) date = `${(/* @__PURE__ */ new Date()).getFullYear()}-${date}`;
3414
+ return date ? new Date(date) : /* @__PURE__ */ new Date();
3415
+ }
3416
+ _Time.parseDate = parseDate;
3417
+ function format(ms) {
3418
+ const abs = Math.abs(ms);
3419
+ if (abs >= day - hour / 2) return Math.round(ms / day) + "d";
3420
+ else if (abs >= hour - minute / 2) return Math.round(ms / hour) + "h";
3421
+ else if (abs >= minute - second / 2) return Math.round(ms / minute) + "m";
3422
+ else if (abs >= second) return Math.round(ms / second) + "s";
3423
+ return ms + "ms";
3424
+ }
3425
+ _Time.format = format;
3426
+ function toDigits(source, length = 2) {
3427
+ return source.toString().padStart(length, "0");
3428
+ }
3429
+ _Time.toDigits = toDigits;
3430
+ function template(template, time = /* @__PURE__ */ new Date()) {
3431
+ 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));
3432
+ }
3433
+ _Time.template = template;
3434
+ })(Time || (Time = {}));
3435
+ //#endregion
3436
+ //#region ../../../vendor/schemastery/src/index.ts
3437
+ const kSchema = Symbol.for("schemastery");
3438
+ const kValidationError = Symbol.for("ValidationError");
3439
+ globalThis.__schemastery_index__ ??= 0;
3440
+ globalThis.__schemastery_refs__ = void 0;
3441
+ var ValidationError = class extends TypeError {
3442
+ options;
3443
+ name = "ValidationError";
3444
+ constructor(message, options) {
3445
+ let prefix = "$";
3446
+ for (const segment of options.path || []) if (typeof segment === "string") prefix += "." + segment;
3447
+ else if (typeof segment === "number") prefix += "[" + segment + "]";
3448
+ else if (typeof segment === "symbol") prefix += `[Symbol(${segment.toString()})]`;
3449
+ if (prefix.startsWith(".")) prefix = prefix.slice(1);
3450
+ super((prefix === "$" ? "" : `${prefix} `) + message);
3451
+ this.options = options;
3452
+ }
3453
+ static is(error) {
3454
+ return !!error?.[kValidationError];
3455
+ }
3456
+ };
3457
+ Object.defineProperty(ValidationError.prototype, kValidationError, { value: true });
3458
+ const Schema = function(options) {
3459
+ const schema = function(data, options = {}) {
3460
+ return Schema.resolve(data, schema, options)[0];
3461
+ };
3462
+ if (options.refs) {
3463
+ const refs = mapValues(options.refs, (options) => new Schema(options));
3464
+ const getRef = (uid) => refs[uid];
3465
+ for (const key in refs) {
3466
+ const options = refs[key];
3467
+ options.sKey = getRef(options.sKey);
3468
+ options.inner = getRef(options.inner);
3469
+ options.list = options.list && options.list.map(getRef);
3470
+ options.dict = options.dict && mapValues(options.dict, getRef);
3471
+ }
3472
+ return refs[options.uid];
3473
+ }
3474
+ Object.assign(schema, options);
3475
+ if (typeof schema.callback === "string") try {
3476
+ schema.callback = new Function("return " + schema.callback)();
3477
+ } catch {}
3478
+ Object.defineProperty(schema, "uid", { value: globalThis.__schemastery_index__++ });
3479
+ Object.setPrototypeOf(schema, Schema.prototype);
3480
+ schema.meta ||= {};
3481
+ schema.toString = schema.toString.bind(schema);
3482
+ return schema;
3483
+ };
3484
+ Schema.prototype = Object.create(Function.prototype);
3485
+ Schema.prototype[kSchema] = true;
3486
+ Object.defineProperty(Schema.prototype, "~standard", { get() {
3487
+ return {
3488
+ version: 1,
3489
+ vendor: "schemastery",
3490
+ validate: (value) => {
3491
+ try {
3492
+ return { value: Schema.resolve(value, this, {})[0] };
3493
+ } catch (error) {
3494
+ if (ValidationError.is(error)) return { issues: [{
3495
+ message: error.message,
3496
+ path: error.options.path
3497
+ }] };
3498
+ throw error;
3499
+ }
3500
+ }
3501
+ };
3502
+ } });
3503
+ Schema.ValidationError = ValidationError;
3504
+ Schema.prototype.toJSON = function toJSON() {
3505
+ if (globalThis.__schemastery_refs__) {
3506
+ globalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }));
3507
+ return this.uid;
3508
+ }
3509
+ globalThis.__schemastery_refs__ = { [this.uid]: { ...this } };
3510
+ globalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }));
3511
+ const result = {
3512
+ uid: this.uid,
3513
+ refs: globalThis.__schemastery_refs__
3514
+ };
3515
+ globalThis.__schemastery_refs__ = void 0;
3516
+ return result;
3517
+ };
3518
+ Schema.prototype.set = function set(key, value) {
3519
+ this.dict[key] = value;
3520
+ return this;
3521
+ };
3522
+ Schema.prototype.push = function push(value) {
3523
+ this.list.push(value);
3524
+ return this;
3525
+ };
3526
+ function mergeDesc(original, messages) {
3527
+ const result = typeof original === "string" ? { "": original } : { ...original };
3528
+ for (const locale in messages) {
3529
+ const value = messages[locale];
3530
+ if (value?.$description || value?.$desc) result[locale] = value.$description || value.$desc;
3531
+ else if (typeof value === "string") result[locale] = value;
3532
+ }
3533
+ return result;
3534
+ }
3535
+ function getInner(value) {
3536
+ return value?.$value ?? value?.$inner;
3537
+ }
3538
+ function extractKeys(data) {
3539
+ return filterKeys(data ?? {}, (key) => !key.startsWith("$"));
3540
+ }
3541
+ Schema.prototype.i18n = function i18n(messages) {
3542
+ const schema = Schema(this);
3543
+ const desc = mergeDesc(schema.meta.description, messages);
3544
+ if (Object.keys(desc).length) schema.meta.description = desc;
3545
+ if (schema.dict) schema.dict = mapValues(schema.dict, (inner, key) => {
3546
+ return inner.i18n(mapValues(messages, (data) => getInner(data)?.[key] ?? data?.[key]));
3547
+ });
3548
+ if (schema.list) schema.list = schema.list.map((inner, index) => {
3549
+ return inner.i18n(mapValues(messages, (data = {}) => {
3550
+ if (Array.isArray(getInner(data))) return getInner(data)[index];
3551
+ if (Array.isArray(data)) return data[index];
3552
+ return extractKeys(data);
3553
+ }));
3554
+ });
3555
+ if (schema.inner) schema.inner = schema.inner.i18n(mapValues(messages, (data) => {
3556
+ if (getInner(data)) return getInner(data);
3557
+ return extractKeys(data);
3558
+ }));
3559
+ if (schema.sKey) schema.sKey = schema.sKey.i18n(mapValues(messages, (data) => data?.$key));
3560
+ return schema;
3561
+ };
3562
+ Schema.prototype.extra = function extra(key, value) {
3563
+ const schema = Schema(this);
3564
+ schema.meta = {
3565
+ ...schema.meta,
3566
+ [key]: value
3567
+ };
3568
+ return schema;
3569
+ };
3570
+ for (const key of [
3571
+ "required",
3572
+ "disabled",
3573
+ "collapse",
3574
+ "hidden",
3575
+ "loose"
3576
+ ]) Object.assign(Schema.prototype, { [key](value = true) {
3577
+ const schema = Schema(this);
3578
+ schema.meta = {
3579
+ ...schema.meta,
3580
+ [key]: value
3581
+ };
3582
+ return schema;
3583
+ } });
3584
+ Schema.prototype.deprecated = function deprecated() {
3585
+ const schema = Schema(this);
3586
+ schema.meta.badges ||= [];
3587
+ schema.meta.badges.push({
3588
+ text: "deprecated",
3589
+ type: "danger"
3590
+ });
3591
+ return schema;
3592
+ };
3593
+ Schema.prototype.experimental = function experimental() {
3594
+ const schema = Schema(this);
3595
+ schema.meta.badges ||= [];
3596
+ schema.meta.badges.push({
3597
+ text: "experimental",
3598
+ type: "warning"
3599
+ });
3600
+ return schema;
3601
+ };
3602
+ Schema.prototype.pattern = function pattern(regexp) {
3603
+ const schema = Schema(this);
3604
+ const pattern = pick(regexp, ["source", "flags"]);
3605
+ schema.meta = {
3606
+ ...schema.meta,
3607
+ pattern
3608
+ };
3609
+ return schema;
3610
+ };
3611
+ Schema.prototype.simplify = function simplify(value) {
3612
+ if (isVolatile(value)) value = value.get();
3613
+ if (deepEqual(value, this.meta.default, this.type === "dict")) return null;
3614
+ if (isNullable(value)) return value;
3615
+ if (this.type === "object" || this.type === "dict") {
3616
+ const result = {};
3617
+ for (const key in value) {
3618
+ const item = (this.type === "object" ? this.dict[key] : this.inner)?.simplify(value[key]);
3619
+ if (this.type === "dict" || !isNullable(item)) result[key] = item;
3620
+ }
3621
+ if (deepEqual(result, this.meta.default, this.type === "dict")) return null;
3622
+ return result;
3623
+ } else if (this.type === "array" || this.type === "tuple") {
3624
+ const result = [];
3625
+ value.forEach((value, index) => {
3626
+ const schema = this.type === "array" ? this.inner : this.list[index];
3627
+ const item = schema ? schema.simplify(value) : value;
3628
+ result.push(item);
3629
+ });
3630
+ return result;
3631
+ } else if (this.type === "intersect") {
3632
+ const result = {};
3633
+ for (const item of this.list) Object.assign(result, item.simplify(value));
3634
+ return result;
3635
+ } else if (this.type === "union") for (const schema of this.list) try {
3636
+ Schema.resolve(value, schema, {});
3637
+ return schema.simplify(value);
3638
+ } catch {}
3639
+ return value;
3640
+ };
3641
+ Schema.prototype.toString = function toString(inline) {
3642
+ return formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`;
3643
+ };
3644
+ Schema.prototype.role = function role(role, extra) {
3645
+ const schema = Schema(this);
3646
+ schema.meta = {
3647
+ ...schema.meta,
3648
+ role,
3649
+ extra
3650
+ };
3651
+ return schema;
3652
+ };
3653
+ for (const key of [
3654
+ "default",
3655
+ "link",
3656
+ "comment",
3657
+ "description",
3658
+ "max",
3659
+ "min",
3660
+ "step"
3661
+ ]) Object.assign(Schema.prototype, { [key](value) {
3662
+ const schema = Schema(this);
3663
+ schema.meta = {
3664
+ ...schema.meta,
3665
+ [key]: value
3666
+ };
3667
+ return schema;
3668
+ } });
3669
+ Schema.prototype.volatile = function volatile() {
3670
+ if (this.meta.volatile) throw new TypeError("volatile schema is already wrapped");
3671
+ return this.extra("volatile", true);
3672
+ };
3673
+ const resolvers = {};
3674
+ const checkedVolatile = Symbol("checked-volatile-schema");
3675
+ function validateVolatileSchema(schema, path = [], blocked = false, seen = /* @__PURE__ */ new Map()) {
3676
+ const states = seen.get(schema) ?? /* @__PURE__ */ new Set();
3677
+ if (states.has(blocked)) return;
3678
+ states.add(blocked);
3679
+ seen.set(schema, states);
3680
+ if (schema.meta?.volatile && blocked) throw new ValidationError("volatile fields require a fixed object path without an enclosing volatile field", { path });
3681
+ const nested = blocked || !!schema.meta?.volatile;
3682
+ if (schema.dict) for (const [key, child] of Object.entries(schema.dict)) validateVolatileSchema(child, [...path, key], nested, seen);
3683
+ if (schema.sKey) validateVolatileSchema(schema.sKey, [...path, "<key>"], true, seen);
3684
+ if (schema.inner && (schema.type !== "lazy" || schema.inner[kSchema])) validateVolatileSchema(schema.inner, [...path, "*"], true, seen);
3685
+ if (schema.list) for (let index = 0; index < schema.list.length; index++) validateVolatileSchema(schema.list[index], [...path, String(index)], true, seen);
3686
+ }
3687
+ Schema.extend = function extend(type, resolve) {
3688
+ resolvers[type] = resolve;
3689
+ };
3690
+ Schema.resolve = function resolve(data, schema, options = {}, strict = false) {
3691
+ if (!schema) return [data];
3692
+ if (!options[checkedVolatile]) {
3693
+ validateVolatileSchema(schema, options.path);
3694
+ options = {
3695
+ ...options,
3696
+ [checkedVolatile]: true
3697
+ };
3698
+ }
3699
+ if (schema.meta?.volatile) {
3700
+ const inner = Schema(schema);
3701
+ inner.meta = {
3702
+ ...schema.meta,
3703
+ volatile: false
3704
+ };
3705
+ const [value, adapted] = Schema.resolve(data, inner, options, strict);
3706
+ try {
3707
+ return [createVolatile(value), adapted];
3708
+ } catch (error) {
3709
+ throw new ValidationError(error instanceof Error ? error.message : String(error), options);
3710
+ }
3711
+ }
3712
+ if (options.ignore?.(data, schema)) return [data];
3713
+ if (isNullable(data) && schema.type !== "lazy") {
3714
+ if (schema.meta.required) throw new ValidationError(`missing required value`, options);
3715
+ let current = schema;
3716
+ let fallback = schema.meta.default;
3717
+ while (current?.type === "intersect" && isNullable(fallback)) {
3718
+ current = current.list[0];
3719
+ fallback = current?.meta.default;
3720
+ }
3721
+ if (isNullable(fallback)) return [data];
3722
+ data = clone(fallback);
3723
+ }
3724
+ const callback = resolvers[schema.type];
3725
+ if (!callback) throw new ValidationError(`unsupported type "${schema.type}"`, options);
3726
+ try {
3727
+ return callback(data, schema, options, strict);
3728
+ } catch (error) {
3729
+ if (!schema.meta.loose) throw error;
3730
+ return [schema.meta.default];
3731
+ }
3732
+ };
3733
+ Schema.from = function from(source) {
3734
+ if (isNullable(source)) return Schema.any();
3735
+ else if ([
3736
+ "string",
3737
+ "number",
3738
+ "boolean"
3739
+ ].includes(typeof source)) return Schema.const(source).required();
3740
+ else if (source[kSchema]) return source;
3741
+ else if (typeof source === "function") switch (source) {
3742
+ case String: return Schema.string().required();
3743
+ case Number: return Schema.number().required();
3744
+ case Boolean: return Schema.boolean().required();
3745
+ case Function: return Schema.function().required();
3746
+ default: return Schema.is(source).required();
3747
+ }
3748
+ else throw new TypeError(`cannot infer schema from ${source}`);
3749
+ };
3750
+ Schema.lazy = function lazy(builder) {
3751
+ const toJSON = () => {
3752
+ if (!schema.inner[kSchema]) {
3753
+ schema.inner = schema.builder();
3754
+ schema.inner.meta = {
3755
+ ...schema.meta,
3756
+ ...schema.inner.meta
3757
+ };
3758
+ }
3759
+ return schema.inner.toJSON();
3760
+ };
3761
+ const schema = new Schema({
3762
+ type: "lazy",
3763
+ builder,
3764
+ inner: { toJSON }
3765
+ });
3766
+ return schema;
3767
+ };
3768
+ Schema.natural = function natural() {
3769
+ return Schema.number().step(1).min(0);
3770
+ };
3771
+ Schema.percent = function percent() {
3772
+ return Schema.number().step(.01).min(0).max(1).role("slider");
3773
+ };
3774
+ Schema.date = function date() {
3775
+ return Schema.union([Schema.is(Date), Schema.transform(Schema.string().role("datetime"), (value, options) => {
3776
+ const date = new Date(value);
3777
+ if (isNaN(+date)) throw new ValidationError(`invalid date "${value}"`, options);
3778
+ return date;
3779
+ }, true)]);
3780
+ };
3781
+ Schema.regExp = function regExp(flag = "") {
3782
+ return Schema.union([Schema.is(RegExp), Schema.transform(Schema.string().role("regexp", { flag }), (value, options) => {
3783
+ try {
3784
+ return new RegExp(value, flag);
3785
+ } catch (e) {
3786
+ throw new ValidationError(e.message, options);
3787
+ }
3788
+ }, true)]);
3789
+ };
3790
+ Schema.arrayBuffer = function arrayBuffer(encoding) {
3791
+ return Schema.union([
3792
+ Schema.is(ArrayBuffer),
3793
+ Schema.is(SharedArrayBuffer),
3794
+ Schema.transform(Schema.any(), (value, options) => {
3795
+ if (Binary.isSource(value)) return Binary.fromSource(value);
3796
+ throw new ValidationError(`expected ArrayBufferSource but got ${value}`, options);
3797
+ }, true),
3798
+ ...encoding ? [Schema.transform(Schema.string(), (value, options) => {
3799
+ try {
3800
+ return encoding === "base64" ? Binary.fromBase64(value) : Binary.fromHex(value);
3801
+ } catch (e) {
3802
+ throw new ValidationError(e.message, options);
3803
+ }
3804
+ }, true)] : []
3805
+ ]);
3806
+ };
3807
+ Schema.extend("lazy", (data, schema, options, strict) => {
3808
+ if (!schema.inner[kSchema]) {
3809
+ schema.inner = schema.builder();
3810
+ schema.inner.meta = {
3811
+ ...schema.meta,
3812
+ ...schema.inner.meta
3813
+ };
3814
+ validateVolatileSchema(schema.inner, options.path, true);
3815
+ }
3816
+ return Schema.resolve(data, schema.inner, options, strict);
3817
+ });
3818
+ Schema.extend("any", (data) => {
3819
+ return [data];
3820
+ });
3821
+ Schema.extend("never", (data, _, options) => {
3822
+ throw new ValidationError(`expected nullable but got ${data}`, options);
3823
+ });
3824
+ Schema.extend("const", (data, { value }, options) => {
3825
+ if (deepEqual(data, value)) return [value];
3826
+ throw new ValidationError(`expected ${value} but got ${data}`, options);
3827
+ });
3828
+ function checkWithinRange(data, meta, description, options, skipMin = false) {
3829
+ const { max = Infinity, min = -Infinity } = meta;
3830
+ if (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options);
3831
+ if (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options);
3832
+ }
3833
+ Schema.extend("string", (data, { meta }, options) => {
3834
+ if (typeof data !== "string") throw new ValidationError(`expected string but got ${data}`, options);
3835
+ if (meta.pattern) {
3836
+ const regexp = new RegExp(meta.pattern.source, meta.pattern.flags);
3837
+ if (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options);
3838
+ }
3839
+ checkWithinRange(data.length, meta, "string length", options);
3840
+ return [data];
3841
+ });
3842
+ function decimalShift(data, digits) {
3843
+ const str = data.toString();
3844
+ if (str.includes("e")) return data * Math.pow(10, digits);
3845
+ const index = str.indexOf(".");
3846
+ if (index === -1) return data * Math.pow(10, digits);
3847
+ const frac = str.slice(index + 1);
3848
+ const integer = str.slice(0, index);
3849
+ if (frac.length <= digits) return +(integer + frac.padEnd(digits, "0"));
3850
+ return +(integer + frac.slice(0, digits) + "." + frac.slice(digits));
3851
+ }
3852
+ function isMultipleOf(data, min, step) {
3853
+ step = Math.abs(step);
3854
+ if (!/^\d+\.\d+$/.test(step.toString())) return (data - min) % step === 0;
3855
+ const index = step.toString().indexOf(".");
3856
+ const digits = step.toString().slice(index + 1).length;
3857
+ return Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0;
3858
+ }
3859
+ Schema.extend("number", (data, { meta }, options) => {
3860
+ if (typeof data !== "number") throw new ValidationError(`expected number but got ${data}`, options);
3861
+ checkWithinRange(data, meta, "number", options);
3862
+ const { step } = meta;
3863
+ if (step && !isMultipleOf(data, meta.min ?? 0, step)) throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options);
3864
+ return [data];
3865
+ });
3866
+ Schema.extend("boolean", (data, _, options) => {
3867
+ if (typeof data === "boolean") return [data];
3868
+ throw new ValidationError(`expected boolean but got ${data}`, options);
3869
+ });
3870
+ Schema.extend("bitset", (data, { bits, meta }, options) => {
3871
+ let value = 0, keys = [];
3872
+ if (typeof data === "number") {
3873
+ value = data;
3874
+ for (const key in bits) if (data & bits[key]) keys.push(key);
3875
+ } else if (Array.isArray(data)) {
3876
+ keys = data;
3877
+ for (const key of keys) {
3878
+ if (typeof key !== "string") throw new ValidationError(`expected string but got ${key}`, options);
3879
+ if (key in bits) value |= bits[key];
3880
+ }
3881
+ } else throw new ValidationError(`expected number or array but got ${data}`, options);
3882
+ if (value === meta.default) return [value];
3883
+ return [value, keys];
3884
+ });
3885
+ Schema.extend("function", (data, _, options) => {
3886
+ if (typeof data === "function") return [data];
3887
+ throw new ValidationError(`expected function but got ${data}`, options);
3888
+ });
3889
+ Schema.extend("is", (data, { constructor }, options) => {
3890
+ if (typeof constructor === "function") {
3891
+ if (data instanceof constructor) return [data];
3892
+ throw new ValidationError(`expected ${constructor.name} but got ${data}`, options);
3893
+ } else {
3894
+ if (isNullable(data)) throw new ValidationError(`expected ${constructor} but got ${data}`, options);
3895
+ let prototype = Object.getPrototypeOf(data);
3896
+ while (prototype) {
3897
+ if (prototype.constructor?.name === constructor) return [data];
3898
+ prototype = Object.getPrototypeOf(prototype);
3899
+ }
3900
+ throw new ValidationError(`expected ${constructor} but got ${data}`, options);
3901
+ }
3902
+ });
3903
+ function property(data, key, schema, options) {
3904
+ try {
3905
+ const [value, adapted] = Schema.resolve(data[key], schema, {
3906
+ ...options,
3907
+ path: [...options.path || [], key]
3908
+ });
3909
+ if (adapted !== void 0) data[key] = adapted;
3910
+ return value;
3911
+ } catch (e) {
3912
+ if (!options?.autofix) throw e;
3913
+ delete data[key];
3914
+ return schema.meta.volatile ? createVolatile(schema.meta.default) : schema.meta.default;
3915
+ }
3916
+ }
3917
+ Schema.extend("array", (data, { inner, meta }, options) => {
3918
+ if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
3919
+ checkWithinRange(data.length, meta, "array length", options, !isNullable(inner.meta.default));
3920
+ return [data.map((_, index) => property(data, index, inner, options))];
3921
+ });
3922
+ Schema.extend("dict", (data, { inner, sKey }, options, strict) => {
3923
+ if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);
3924
+ const result = {};
3925
+ for (const key in data) {
3926
+ let rKey;
3927
+ try {
3928
+ rKey = Schema.resolve(key, sKey, options)[0];
3929
+ } catch (error) {
3930
+ if (strict) continue;
3931
+ throw error;
3932
+ }
3933
+ result[rKey] = property(data, key, inner, options);
3934
+ data[rKey] = data[key];
3935
+ if (key !== rKey) delete data[key];
3936
+ }
3937
+ return [result];
3938
+ });
3939
+ Schema.extend("tuple", (data, { list }, options, strict) => {
3940
+ if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options);
3941
+ const result = list.map((inner, index) => property(data, index, inner, options));
3942
+ if (strict) return [result];
3943
+ result.push(...data.slice(list.length));
3944
+ return [result];
3945
+ });
3946
+ function merge(result, data) {
3947
+ for (const key in data) {
3948
+ if (key in result) continue;
3949
+ result[key] = data[key];
3950
+ }
3951
+ }
3952
+ Schema.extend("object", (data, { dict }, options, strict) => {
3953
+ if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options);
3954
+ const result = {};
3955
+ for (const key in dict) {
3956
+ const value = property(data, key, dict[key], options);
3957
+ if (!isNullable(value) || key in data) result[key] = value;
3958
+ }
3959
+ if (!strict) merge(result, data);
3960
+ return [result];
3961
+ });
3962
+ Schema.extend("union", (data, { list, toString }, options, strict) => {
3963
+ const messages = [];
3964
+ for (const inner of list) try {
3965
+ return Schema.resolve(data, inner, options, strict);
3966
+ } catch (error) {
3967
+ messages.push(error);
3968
+ }
3969
+ throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
3970
+ });
3971
+ Schema.extend("intersect", (data, { list, toString }, options, strict) => {
3972
+ if (!list.length) return [data];
3973
+ let result;
3974
+ for (const inner of list) {
3975
+ const value = Schema.resolve(data, inner, options, true)[0];
3976
+ if (isNullable(value)) continue;
3977
+ if (isNullable(result)) result = value;
3978
+ else if (typeof result !== typeof value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
3979
+ else if (typeof value === "object") merge(result ??= {}, value);
3980
+ else if (result !== value) throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options);
3981
+ }
3982
+ if (!strict && isPlainObject(data)) merge(result, data);
3983
+ return [result];
3984
+ });
3985
+ Schema.extend("transform", (data, { inner, callback, preserve }, options) => {
3986
+ const [result, adapted = data] = Schema.resolve(data, inner, options, true);
3987
+ if (preserve) return [callback(result)];
3988
+ else return [callback(result), callback(adapted)];
3989
+ });
3990
+ const formatters = {};
3991
+ function defineMethod(name, keys, format) {
3992
+ formatters[name] = format;
3993
+ Object.assign(Schema, { [name](...args) {
3994
+ const schema = new Schema({ type: name });
3995
+ keys.forEach((key, index) => {
3996
+ switch (key) {
3997
+ case "sKey":
3998
+ schema.sKey = args[index] ?? Schema.string();
3999
+ break;
4000
+ case "inner":
4001
+ schema.inner = Schema.from(args[index]);
4002
+ break;
4003
+ case "list":
4004
+ schema.list = args[index].map(Schema.from);
4005
+ break;
4006
+ case "dict":
4007
+ schema.dict = mapValues(args[index], Schema.from);
4008
+ break;
4009
+ case "bits":
4010
+ schema.bits = {};
4011
+ for (const key in args[index]) {
4012
+ if (typeof args[index][key] !== "number") continue;
4013
+ schema.bits[key] = args[index][key];
4014
+ }
4015
+ break;
4016
+ case "callback": {
4017
+ const callback = schema.callback = args[index];
4018
+ callback["toJSON"] ||= () => callback.toString();
4019
+ break;
4020
+ }
4021
+ case "constructor": {
4022
+ const constructor = schema.constructor = args[index];
4023
+ if (typeof constructor === "function") constructor["toJSON"] ||= () => constructor["name"];
4024
+ break;
4025
+ }
4026
+ default: schema[key] = args[index];
4027
+ }
4028
+ });
4029
+ if (name === "object" || name === "dict") schema.meta.default = {};
4030
+ else if (name === "array" || name === "tuple") schema.meta.default = [];
4031
+ else if (name === "bitset") schema.meta.default = 0;
4032
+ return schema;
4033
+ } });
4034
+ }
4035
+ defineMethod("is", ["constructor"], ({ constructor }) => {
4036
+ if (typeof constructor === "function") return constructor.name;
4037
+ else return constructor;
4038
+ });
4039
+ defineMethod("any", [], () => "any");
4040
+ defineMethod("never", [], () => "never");
4041
+ defineMethod("const", ["value"], ({ value }) => typeof value === "string" ? JSON.stringify(value) : value);
4042
+ defineMethod("string", [], () => "string");
4043
+ defineMethod("number", [], () => "number");
4044
+ defineMethod("boolean", [], () => "boolean");
4045
+ defineMethod("bitset", ["bits"], () => "bitset");
4046
+ defineMethod("function", [], () => "function");
4047
+ defineMethod("array", ["inner"], ({ inner }) => `${inner.toString(true)}[]`);
4048
+ defineMethod("dict", ["inner", "sKey"], ({ inner, sKey }) => `{ [key: ${sKey.toString()}]: ${inner.toString()} }`);
4049
+ defineMethod("tuple", ["list"], ({ list }) => `[${list.map((inner) => inner.toString()).join(", ")}]`);
4050
+ defineMethod("object", ["dict"], ({ dict }) => {
4051
+ if (Object.keys(dict).length === 0) return "{}";
4052
+ return `{ ${Object.entries(dict).map(([key, inner]) => {
4053
+ return `${key}${inner.meta.required ? "" : "?"}: ${inner.toString()}`;
4054
+ }).join(", ")} }`;
4055
+ });
4056
+ defineMethod("union", ["list"], ({ list }, inline) => {
4057
+ const result = list.map(({ toString: format }) => format()).join(" | ");
4058
+ return inline ? `(${result})` : result;
4059
+ });
4060
+ defineMethod("intersect", ["list"], ({ list }) => {
4061
+ return `${list.map((inner) => inner.toString(true)).join(" & ")}`;
4062
+ });
4063
+ defineMethod("transform", [
4064
+ "inner",
4065
+ "callback",
4066
+ "preserve"
4067
+ ], ({ inner }, isInner) => inner.toString(isInner));
4068
+ //#endregion
4069
+ //#region lib/types/onboarding-config.js
4070
+ /** Public page-bootstrap options shared by the Host and Client halves. */
4071
+ /** Validate Host configuration and its public page-bootstrap payload. */
4072
+ const Config = Schema.object({ credentialOnboarding: Schema.boolean().default(true) });
4073
+ /** Page-global key carrying only the public onboarding options. */
4074
+ const ONBOARDING_CONFIG_GLOBAL = "__QILIN_MODELS_ONBOARDING__";
4075
+ //#endregion
2715
4076
  //#region lib/types/client/index.js
2716
4077
  /** Dictionary namespace owned by this plugin. */
2717
4078
  const NS = "settings.models";
@@ -2746,6 +4107,8 @@ window.__ModuleLoader__.load({
2746
4107
  * @param ctx - client root context.
2747
4108
  */
2748
4109
  function apply(ctx) {
4110
+ const payload = globalThis[ONBOARDING_CONFIG_GLOBAL];
4111
+ const configured = Config(payload === void 0 ? {} : payload);
2749
4112
  ctx.effect(() => ctx.locale.register(NS, {
2750
4113
  zh,
2751
4114
  en
@@ -2801,7 +4164,7 @@ window.__ModuleLoader__.load({
2801
4164
  }
2802
4165
  }
2803
4166
  }, ModelsSection));
2804
- ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
4167
+ if (configured.credentialOnboarding) ctx.slots.inject("settings.onboarding", () => ctx.slots.register({
2805
4168
  name: "settings.onboarding",
2806
4169
  id: "deepseek-official",
2807
4170
  order: 0,