dsh-model-extension 1.3.1 → 1.3.3-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/client.js CHANGED
@@ -3,7 +3,7 @@ window.__ModuleLoader__.load({
3
3
  factory: (require) => {
4
4
  var module = { exports: {} };
5
5
  var exports = module.exports;
6
- var __extCss = ".PkL4gq_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}.PkL4gq_titleRow{align-items:center;gap:10px;display:flex}.PkL4gq_title{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}.PkL4gq_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}.PkL4gq_savedNotice{color:var(--dsw-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}.PkL4gq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}.PkL4gq_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}.PkL4gq_rowCard{border:.5px solid var(--dsw-alias-border-l4);border-radius:16px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}.PkL4gq_rowHead{align-items:center;gap:10px;display:flex}.PkL4gq_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}.PkL4gq_rowName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}.PkL4gq_rowTag{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:1px 6px;font-size:11px;line-height:16px}.PkL4gq_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}.PkL4gq_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}.PkL4gq_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}.PkL4gq_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}.PkL4gq_primaryButton,.PkL4gq_secondaryButton,.PkL4gq_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}.PkL4gq_primaryButton{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}.PkL4gq_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}.PkL4gq_secondaryButton,.PkL4gq_addButton{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary);background:0 0}.PkL4gq_secondaryButton:hover:not(:disabled),.PkL4gq_addButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.PkL4gq_secondaryButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}.PkL4gq_dangerButton{box-sizing:border-box;height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:18px;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}.PkL4gq_dangerButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.PkL4gq_rowActions .PkL4gq_secondaryButton,.PkL4gq_rowActions .PkL4gq_dangerButton{border-radius:14px;height:28px;padding:0 10px;font-size:12px;line-height:18px}.PkL4gq_primaryButton:disabled,.PkL4gq_secondaryButton:disabled,.PkL4gq_dangerButton:disabled,.PkL4gq_addButton:disabled,.PkL4gq_linkButton:disabled,.PkL4gq_addModelButton:disabled{opacity:.4;cursor:default}.PkL4gq_primaryButton:focus-visible,.PkL4gq_secondaryButton:focus-visible,.PkL4gq_dangerButton:focus-visible,.PkL4gq_addButton:focus-visible,.PkL4gq_linkButton:focus-visible,.PkL4gq_addModelButton:focus-visible,.PkL4gq_iconButton:focus-visible,.PkL4gq_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3);outline:none}.PkL4gq_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;display:flex}.PkL4gq_field{flex-direction:column;gap:6px;display:flex}.PkL4gq_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}.PkL4gq_linkButton{box-sizing:border-box;height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:14px;align-items:center;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.PkL4gq_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}.PkL4gq_advancedHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.PkL4gq_editorActions{justify-content:flex-end;gap:8px;display:flex}.PkL4gq_addBlock{flex-direction:column;gap:12px;display:flex}.PkL4gq_addActions{flex-wrap:wrap;gap:10px;display:flex}.PkL4gq_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}.PkL4gq_addCard{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}.PkL4gq_addCard .PkL4gq_editor,.PkL4gq_setupCard .PkL4gq_editor{background:0 0;padding:0}.PkL4gq_tabs{flex-direction:column;gap:12px;display:flex}.PkL4gq_tabBar{border-bottom:.5px solid var(--dsw-alias-border-l2);gap:4px;display:flex}.PkL4gq_tabButton{appearance:none;font:inherit;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:6px 12px 8px;font-size:13px;line-height:20px;position:relative}.PkL4gq_tabButton:hover{color:var(--dsw-alias-label-primary)}.PkL4gq_tabButton:disabled{opacity:.4;cursor:default}.PkL4gq_tabButtonActive{color:var(--dsw-alias-label-primary);font-weight:500}.PkL4gq_tabButtonActive:after{content:\"\";background:var(--dsw-alias-brand-primary);border-radius:2px;height:2px;position:absolute;bottom:-1px;left:10px;right:10px}.PkL4gq_tabPanel{flex-direction:column;gap:12px;display:flex}.PkL4gq_modelCatalog{flex-direction:column;gap:10px;display:flex}.PkL4gq_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}.PkL4gq_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}.PkL4gq_modelCatalogMeta,.PkL4gq_modelEmpty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}.PkL4gq_modelList{flex-direction:column;gap:8px;display:flex}.PkL4gq_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}.PkL4gq_modelEntry{border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;padding:6px}.PkL4gq_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto;align-items:center;gap:6px;display:grid}.PkL4gq_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.PkL4gq_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.PkL4gq_iconButton:disabled{cursor:default;opacity:.4}.PkL4gq_iconButtonDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.PkL4gq_modelAdvanced{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px;padding:8px 4px 2px;display:grid}.PkL4gq_modelField{flex-direction:column;gap:4px;display:flex}.PkL4gq_modelFieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.PkL4gq_modelEmpty{border:1px dashed var(--dsw-alias-border-l3);text-align:center;border-radius:8px;padding:12px}.PkL4gq_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;align-self:flex-start;align-items:center;gap:4px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}.PkL4gq_addModelButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.PkL4gq_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select.PkL4gq_input{cursor:pointer;max-width:240px}.PkL4gq_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}.PkL4gq_input::placeholder{color:var(--dsw-alias-label-dimmed)}.PkL4gq_input:disabled{opacity:.6;cursor:default}.PkL4gq_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}.PkL4gq_deleteDialog{width:min(480px,100%)}.PkL4gq_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}.PkL4gq_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}.PkL4gq_fetchDialog{max-width:520px}.PkL4gq_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}.PkL4gq_candidateSearch{flex:240px;min-width:0}.PkL4gq_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}.PkL4gq_candidate{border-radius:6px}.PkL4gq_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}.PkL4gq_candidateId{overflow-wrap:anywhere;flex:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}.PkL4gq_candidateEmpty{color:var(--dsw-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}[hidden]{display:none!important}.PkL4gq_extBlock{border:.5px solid var(--dsw-alias-border-l3);background:var(--dsw-alias-bg-layer-1);border-radius:10px;flex-direction:column;gap:10px;margin:8px 4px 2px;padding:10px;display:flex}.PkL4gq_extGroup{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:12px}.PkL4gq_extGroupFirst{border-top:none;padding-top:0}.PkL4gq_extCheck{cursor:pointer;align-items:flex-start;gap:8px;display:flex}.PkL4gq_extCheckLabel{color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px}.PkL4gq_extHint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.PkL4gq_extGated{flex-direction:column;gap:12px;padding-left:2px;display:flex}.PkL4gq_extField{flex-direction:column;gap:6px;display:flex}.PkL4gq_extLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.PkL4gq_extTable{border:.5px solid var(--dsw-alias-border-l4);border-radius:8px;overflow:hidden}.PkL4gq_extTHead{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-module-platform);grid-template-columns:64px minmax(0,1fr) minmax(0,1.2fr);font-size:12px;line-height:18px;display:grid}.PkL4gq_extTHead>div{padding:6px 10px}.PkL4gq_extTHead>div+div{border-left:.5px solid var(--dsw-alias-border-l2)}.PkL4gq_extTRow{border-top:.5px solid var(--dsw-alias-border-l2);grid-template-columns:64px minmax(0,1fr) minmax(0,1.2fr);align-items:center;display:grid}.PkL4gq_extTRow>div{padding:6px 10px;font-size:14px}.PkL4gq_extTRow>div+div{border-left:.5px solid var(--dsw-alias-border-l2)}.PkL4gq_extTRow input[type=text]{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px}.PkL4gq_extTRow input[type=text]:disabled{opacity:.6;cursor:default}.PkL4gq_extCheckbox{accent-color:var(--dsw-alias-brand-primary);flex:none;width:15px;height:15px}.PkL4gq_switchRow{cursor:pointer;align-items:center;gap:8px;font-size:14px;line-height:22px;display:flex}.PkL4gq_extTag{background:var(--dsw-static-deepseek-100);color:var(--dsw-static-deepseek-600);border:.5px solid #4176e659;border-radius:4px;flex:none;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px}.PkL4gq_modalMask{background:var(--dsw-alias-bg-mask-1);z-index:100;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}.PkL4gq_modal{background:var(--dsw-specific-menu);border-radius:16px;width:100%;padding:20px;box-shadow:0 12px 40px #0000002e}.PkL4gq_modalTitle{color:var(--dsw-alias-label-primary);margin-bottom:8px;font-size:16px;font-weight:500;line-height:24px}.PkL4gq_modalDesc{color:var(--dsw-alias-label-secondary);margin-bottom:16px;font-size:14px;line-height:22px}.PkL4gq_modalFoot{justify-content:flex-end;gap:8px;display:flex}.PkL4gq_quickWrap{flex-direction:column;gap:6px;display:flex;position:relative}.PkL4gq_quickList{z-index:20;background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);border:0;border-radius:8px;max-height:264px;margin-top:2px;padding:4px;position:absolute;top:100%;left:0;right:0;overflow-y:auto}.PkL4gq_quickItem{width:100%;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:6px;flex-direction:column;gap:1px;padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;display:flex}.PkL4gq_quickItemId{overflow-wrap:anywhere}.PkL4gq_quickItemApi{color:var(--dsw-alias-label-tertiary);letter-spacing:.2px;font-size:11px;line-height:14px}.PkL4gq_quickItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.PkL4gq_quickEmpty{color:var(--dsw-alias-label-tertiary);padding:6px 8px;font-size:12px;line-height:18px}@media (prefers-reduced-motion:reduce){.PkL4gq_customizedSummary:before{transition:none}}\n";
6
+ var __extCss = "._5ikCMa_section{max-width:720px;color:var(--dsw-alias-label-primary);flex-direction:column;gap:12px;display:flex}._5ikCMa_titleRow{align-items:center;gap:10px;display:flex}._5ikCMa_title{color:var(--dsw-alias-label-primary);margin:0;font-size:16px;font-weight:500;line-height:24px}._5ikCMa_intro{color:var(--dsw-alias-label-tertiary);margin:0;font-size:14px;line-height:22px}._5ikCMa_savedNotice{color:var(--dsw-alias-state-success-primary);margin:0;font-size:12px;line-height:18px}._5ikCMa_notice{color:var(--dsw-alias-state-warn-label);margin:0;font-size:12px;line-height:18px}._5ikCMa_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:12px;line-height:18px}._5ikCMa_rows{flex-direction:column;gap:8px;margin:12px 0 0;padding:0;list-style:none;display:flex}._5ikCMa_rowCard{border:.5px solid var(--dsw-alias-border-l4);border-radius:16px;flex-direction:column;gap:12px;padding:12px 14px;display:flex}._5ikCMa_rowHead{align-items:center;gap:10px;display:flex}._5ikCMa_rowIdentity{align-items:center;gap:6px;min-width:0;display:inline-flex}._5ikCMa_rowName{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px}._5ikCMa_rowTag{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-secondary);border-radius:4px;flex:none;padding:1px 6px;font-size:11px;line-height:16px}._5ikCMa_credentialDot{box-sizing:border-box;border-radius:50%;flex:none;width:8px;height:8px;display:inline-block}._5ikCMa_credentialDotConfigured{background:var(--dsw-alias-state-success-primary)}._5ikCMa_credentialDotMissing{background:var(--dsw-alias-state-error-primary)}._5ikCMa_rowActions{align-items:center;gap:4px;margin-left:auto;display:inline-flex}._5ikCMa_primaryButton,._5ikCMa_secondaryButton,._5ikCMa_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}._5ikCMa_primaryButton{background:var(--dsw-alias-button-primary-fill);color:var(--dsw-alias-label-primary-foreground)}._5ikCMa_primaryButton:hover:not(:disabled){background:var(--dsw-alias-button-primary-hover)}._5ikCMa_secondaryButton,._5ikCMa_addButton{border:.5px solid var(--dsw-alias-border-l3);color:var(--dsw-alias-label-primary);background:0 0}._5ikCMa_secondaryButton:hover:not(:disabled),._5ikCMa_addButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._5ikCMa_secondaryButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-solid)}._5ikCMa_dangerButton{box-sizing:border-box;height:36px;color:var(--dsw-alias-state-error-primary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:18px;justify-content:center;align-items:center;padding:0 14px;font-size:14px;line-height:22px;display:inline-flex}._5ikCMa_dangerButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}._5ikCMa_rowActions ._5ikCMa_secondaryButton,._5ikCMa_rowActions ._5ikCMa_dangerButton{border-radius:14px;height:28px;padding:0 10px;font-size:12px;line-height:18px}._5ikCMa_primaryButton:disabled,._5ikCMa_secondaryButton:disabled,._5ikCMa_dangerButton:disabled,._5ikCMa_addButton:disabled,._5ikCMa_linkButton:disabled,._5ikCMa_addModelButton:disabled{opacity:.4;cursor:default}._5ikCMa_primaryButton:focus-visible,._5ikCMa_secondaryButton:focus-visible,._5ikCMa_dangerButton:focus-visible,._5ikCMa_addButton:focus-visible,._5ikCMa_linkButton:focus-visible,._5ikCMa_addModelButton:focus-visible,._5ikCMa_iconButton:focus-visible,._5ikCMa_dragHandle:focus-visible,._5ikCMa_customizedSummary:focus-visible{box-shadow:0 0 0 2px var(--dsw-alias-border-l3);outline:none}._5ikCMa_editor{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;display:flex}._5ikCMa_field{flex-direction:column;gap:6px;display:flex}._5ikCMa_fieldLabel{color:var(--dsw-alias-label-secondary);align-items:center;gap:10px;font-size:12px;font-weight:500;line-height:18px;display:inline-flex}._5ikCMa_linkButton{box-sizing:border-box;height:28px;color:var(--dsw-alias-label-tertiary);font:inherit;cursor:pointer;background:0 0;border:none;border-radius:14px;align-items:center;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}._5ikCMa_linkButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-secondary)}._5ikCMa_advancedHint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}._5ikCMa_helpButton{border:.5px solid var(--dsw-alias-border-l3);corner-shape:round;width:16px;height:16px;color:var(--dsw-alias-label-tertiary);font:inherit;text-align:center;cursor:help;background:0 0;border-radius:50%;padding:0;font-size:11px;line-height:15px}._5ikCMa_helpButton:hover,._5ikCMa_helpButton:focus-visible{color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}._5ikCMa_editorActions{justify-content:flex-end;gap:8px;display:flex}._5ikCMa_addBlock{flex-direction:column;gap:12px;display:flex}._5ikCMa_addActions{flex-wrap:wrap;gap:10px;display:flex}._5ikCMa_addButton{border:1px dashed var(--dsw-alias-border-l3);border-radius:16px;flex:1 1 0;gap:6px;min-width:180px;height:44px}._5ikCMa_addCard{background:var(--dsw-alias-bg-module-platform);border-radius:12px;flex-direction:column;gap:14px;padding:14px 16px;list-style:none;display:flex}._5ikCMa_addCard ._5ikCMa_editor,._5ikCMa_setupCard ._5ikCMa_editor{background:0 0;padding:0}._5ikCMa_tabs{flex-direction:column;gap:12px;display:flex}._5ikCMa_tabBar{border-bottom:.5px solid var(--dsw-alias-border-l2);gap:4px;display:flex}._5ikCMa_tabButton{appearance:none;font:inherit;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;padding:6px 12px 8px;font-size:13px;line-height:20px;position:relative}._5ikCMa_tabButton:hover{color:var(--dsw-alias-label-primary)}._5ikCMa_tabButton:disabled{opacity:.4;cursor:default}._5ikCMa_tabButtonActive{color:var(--dsw-alias-label-primary);font-weight:500}._5ikCMa_tabButtonActive:after{content:\"\";background:var(--dsw-alias-brand-primary);border-radius:2px;height:2px;position:absolute;bottom:-1px;left:10px;right:10px}._5ikCMa_tabPanel{flex-direction:column;gap:12px;display:flex}._5ikCMa_modelCatalog{flex-direction:column;gap:10px;display:flex}._5ikCMa_modelCatalogHeading{flex-direction:column;gap:2px;display:flex}._5ikCMa_modelCatalogTitle{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:500;line-height:18px}._5ikCMa_modelCatalogMeta,._5ikCMa_modelEmpty{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:18px}._5ikCMa_modelList{flex-direction:column;gap:8px;display:flex}._5ikCMa_modelListHead{justify-content:space-between;align-items:flex-start;gap:12px;display:flex}._5ikCMa_modelEntry{border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;padding:6px}._5ikCMa_modelRow{grid-template-columns:minmax(0,1.4fr) minmax(0,1fr) auto auto auto;align-items:center;gap:6px;display:grid;position:relative}._5ikCMa_modelEntryDragging{border:.5px solid var(--dsw-alias-border-l4);opacity:.5;border-radius:10px;padding:6px}._5ikCMa_dragHandle{box-sizing:border-box;width:24px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:grab;touch-action:none;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}._5ikCMa_dragHandle:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._5ikCMa_dragHandle:active:not(:disabled){cursor:grabbing}._5ikCMa_dragHandle:disabled{cursor:default;opacity:.4}._5ikCMa_modelDropLine{background:var(--dsw-alias-brand-primary);pointer-events:none;border-radius:2px;height:2px;position:absolute;left:0;right:0}._5ikCMa_modelDropLine[data-edge=before]{top:-5px}._5ikCMa_modelDropLine[data-edge=after]{bottom:-5px}._5ikCMa_iconButton{box-sizing:border-box;width:28px;height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}._5ikCMa_iconButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}._5ikCMa_iconButton:disabled{cursor:default;opacity:.4}._5ikCMa_iconButtonDanger:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}._5ikCMa_modelAdvanced{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px;padding:8px 4px 2px;display:grid}._5ikCMa_capacityRow{grid-template-columns:repeat(auto-fit,minmax(160px,1fr));gap:8px;padding:0 4px;display:grid}._5ikCMa_modelField{flex-direction:column;gap:4px;display:flex}._5ikCMa_modelFieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._5ikCMa_modelEmpty{border:1px dashed var(--dsw-alias-border-l3);text-align:center;border-radius:8px;padding:12px}._5ikCMa_addModelButton{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l3);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;background:0 0;border-radius:14px;align-self:flex-start;align-items:center;gap:4px;padding:0 10px;font-size:12px;line-height:18px;display:inline-flex}._5ikCMa_addModelButton:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}._5ikCMa_input{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px;line-height:22px}select._5ikCMa_input{cursor:pointer;max-width:240px}._5ikCMa_input:focus{border-color:var(--dsw-alias-brand-primary);outline:none}._5ikCMa_input::placeholder{color:var(--dsw-alias-label-dimmed)}._5ikCMa_input:disabled{opacity:.6;cursor:default}._5ikCMa_keyInput{position:relative}._5ikCMa_keyInputFilled{padding-right:40px}._5ikCMa_keyToggle{border-radius:var(--dsw-radius-md);width:32px;color:var(--dsw-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}._5ikCMa_keyToggle:hover:not(:disabled){color:var(--dsw-alias-label-primary)}._5ikCMa_keyToggle:focus-visible{outline:var(--dsw-focus-ring-width) solid var(--dsw-focus-ring-color,var(--dsw-alias-state-business-primary));outline-offset:-2px}._5ikCMa_keyToggle:disabled{opacity:.6;cursor:default}._5ikCMa_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}._5ikCMa_deleteDialog{width:min(480px,100%)}._5ikCMa_deleteConfirm:not(:disabled){border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary)}._5ikCMa_deleteConfirm:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger)}._5ikCMa_fetchDialog{max-width:520px}._5ikCMa_candidateToolbar{align-items:center;gap:8px;margin-bottom:6px;display:flex}._5ikCMa_candidateSearch{flex:240px;min-width:0}._5ikCMa_candidateList{flex-direction:column;gap:2px;max-height:320px;margin:0;padding:0;list-style:none;display:flex;overflow-y:auto}._5ikCMa_candidate{border-radius:6px}._5ikCMa_candidateLabel{cursor:pointer;align-items:center;gap:8px;padding:6px 8px;display:flex}._5ikCMa_candidateId{overflow-wrap:anywhere;flex:auto;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px}._5ikCMa_candidateEmpty{color:var(--dsw-alias-label-secondary);text-align:center;margin:24px 0;font-size:13px;line-height:20px}[hidden]{display:none!important}._5ikCMa_extBlock{border:.5px solid var(--dsw-alias-border-l3);background:var(--dsw-alias-bg-layer-1);border-radius:10px;flex-direction:column;gap:10px;margin:8px 4px 2px;padding:10px;display:flex}._5ikCMa_extGroup{border-top:.5px solid var(--dsw-alias-border-l2);padding-top:12px}._5ikCMa_extGroupFirst{border-top:none;padding-top:0}._5ikCMa_extCheck{cursor:pointer;align-items:flex-start;gap:8px;display:flex}._5ikCMa_extCheckLabel{color:var(--dsw-alias-label-primary);font-size:14px;line-height:22px}._5ikCMa_extHint{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._5ikCMa_extGated{flex-direction:column;gap:12px;padding-left:2px;display:flex}._5ikCMa_extField{flex-direction:column;gap:6px;display:flex}._5ikCMa_extLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}._5ikCMa_extTable{border:.5px solid var(--dsw-alias-border-l4);border-radius:8px;overflow:hidden}._5ikCMa_extTHead{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-module-platform);grid-template-columns:64px minmax(0,1fr) minmax(0,1.2fr);font-size:12px;line-height:18px;display:grid}._5ikCMa_extTHead>div{padding:6px 10px}._5ikCMa_extTHead>div+div{border-left:.5px solid var(--dsw-alias-border-l2)}._5ikCMa_extTRow{border-top:.5px solid var(--dsw-alias-border-l2);grid-template-columns:64px minmax(0,1fr) minmax(0,1.2fr);align-items:center;display:grid}._5ikCMa_extTRow>div{padding:6px 10px;font-size:14px}._5ikCMa_extTRow>div+div{border-left:.5px solid var(--dsw-alias-border-l2)}._5ikCMa_extTRow input[type=text]{box-sizing:border-box;border:.5px solid var(--dsw-alias-border-l4);width:100%;height:32px;font:inherit;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 10px;font-size:14px}._5ikCMa_extTRow input[type=text]:disabled{opacity:.6;cursor:default}._5ikCMa_extCheckbox{accent-color:var(--dsw-alias-brand-primary);flex:none;width:15px;height:15px}._5ikCMa_switchRow{cursor:pointer;align-items:center;gap:8px;font-size:14px;line-height:22px;display:flex}._5ikCMa_extTag{background:var(--dsw-static-deepseek-100);color:var(--dsw-static-deepseek-600);border:.5px solid #4176e659;border-radius:4px;flex:none;padding:1px 6px;font-size:11px;font-weight:500;line-height:16px}._5ikCMa_modalMask{background:var(--dsw-alias-bg-mask-1);z-index:100;justify-content:center;align-items:center;padding:24px;display:flex;position:fixed;inset:0}._5ikCMa_modal{background:var(--dsw-specific-menu);border-radius:16px;width:100%;padding:20px;box-shadow:0 12px 40px #0000002e}._5ikCMa_modalTitle{color:var(--dsw-alias-label-primary);margin-bottom:8px;font-size:16px;font-weight:500;line-height:24px}._5ikCMa_modalDesc{color:var(--dsw-alias-label-secondary);margin-bottom:16px;font-size:14px;line-height:22px}._5ikCMa_modalFoot{justify-content:flex-end;gap:8px;display:flex}._5ikCMa_quickWrap{flex-direction:column;gap:6px;display:flex;position:relative}._5ikCMa_quickList{z-index:20;background:var(--dsw-specific-menu);backdrop-filter:var(--dsw-menu-backdrop-filter);--dsw-elevation-stroke-color:var(--dsw-alias-border-l1);box-shadow:var(--dsw-elevation-prominent);border:0;border-radius:8px;max-height:264px;margin-top:2px;padding:4px;position:absolute;top:100%;left:0;right:0;overflow-y:auto}._5ikCMa_quickItem{width:100%;color:var(--dsw-alias-label-primary);text-align:left;cursor:pointer;background:0 0;border:none;border-radius:6px;flex-direction:column;gap:1px;padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:13px;display:flex}._5ikCMa_quickItemId{overflow-wrap:anywhere}._5ikCMa_quickItemApi{color:var(--dsw-alias-label-tertiary);letter-spacing:.2px;font-size:11px;line-height:14px}._5ikCMa_quickItem:hover{background:var(--dsw-alias-interactive-bg-hover)}._5ikCMa_quickEmpty{color:var(--dsw-alias-label-tertiary);padding:6px 8px;font-size:12px;line-height:18px}@media (prefers-reduced-motion:reduce){._5ikCMa_customizedSummary:before{transition:none}}\n";
7
7
  if (typeof document !== 'undefined' && document.querySelector('style[data-plugin-css="dsh-model-extension"]') === null) {
8
8
  var __tag = document.createElement('style');
9
9
  __tag.dataset.plugin = "dsh-model-extension";
@@ -38,6 +38,9 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
38
38
  settingsPath: [...entry.settingsPath],
39
39
  active: active.has(entry.provider),
40
40
  ...entry.declared === void 0 ? {} : { declared: entry.declared },
41
+ ...entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: entry.defaultBaseURL },
42
+ ...entry.baseURLEnv === void 0 ? {} : { baseURLEnv: entry.baseURLEnv },
43
+ ...entry.nativeAuth === void 0 ? {} : { nativeAuth: entry.nativeAuth },
41
44
  ...entry.error === void 0 ? {} : { error: entry.error }
42
45
  }));
43
46
  for (const provider of registered) {
@@ -105,6 +108,8 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
105
108
  });
106
109
  /** Latest load wins; an older response never overwrites a newer one. */
107
110
  generation = 0;
111
+ /** Callers follow the current refresh's outcome, including callers whose read was superseded. */
112
+ pendingLoads = /* @__PURE__ */ new Set();
108
113
  /**
109
114
  * @param ctx - the page plugin's context, whose `remote.llm` and
110
115
  * `remote.credentials` namespaces carry the directory and credential reads.
@@ -121,11 +126,28 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
121
126
  * settings answer in parallel, then one batched credential describe over
122
127
  * every referenced ref. Provider failure or absence of an initial settings
123
128
  * answer keeps the last good rows and surfaces an error; a failed settings
124
- * refresh reuses the mirror's held view.
125
- * @returns nothing; the snapshot carries the outcome.
129
+ * refresh reuses the mirror's held view. Concurrent callers resolve only
130
+ * after the current refresh publishes its ready or error snapshot.
131
+ * @returns resolution after the current snapshot is published.
132
+ * @throws the current read's unexpected rejection; superseded rejections are ignored.
126
133
  */
127
- async load() {
134
+ load() {
135
+ const pending = Promise.withResolvers();
136
+ this.pendingLoads.add(pending);
128
137
  const generation = ++this.generation;
138
+ this.read(generation).then(() => {
139
+ this.settleLoads(generation, (load) => {
140
+ load.resolve();
141
+ });
142
+ }, (error) => {
143
+ this.settleLoads(generation, (load) => {
144
+ load.reject(error);
145
+ });
146
+ });
147
+ return pending.promise;
148
+ }
149
+ /** Publish one joined answer; stale answers leave the current refresh in charge. */
150
+ async read(generation) {
129
151
  this.store.update((s) => {
130
152
  s.status = "loading";
131
153
  s.error = null;
@@ -135,17 +157,20 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
135
157
  this.ctx.remote.llm.listConfigurableProviders(),
136
158
  this.describeFace.ensure()
137
159
  ]);
160
+ if (generation !== this.generation) return;
138
161
  if (!registered.ok) {
139
- this.failLoad(generation, registered.error.message);
162
+ this.failLoad(registered.error.message);
140
163
  return;
141
164
  }
142
165
  if (!declared.ok) {
143
- this.failLoad(generation, declared.error.message);
166
+ this.failLoad(declared.error.message);
144
167
  return;
145
168
  }
146
169
  const mirrored = this.describeFace.getSnapshot();
147
170
  if (mirrored.view === void 0) {
148
- this.failLoad(generation, mirrored.error ?? "settings are unavailable in this browser");
171
+ /* v8 ignore next -- SettingsDescribeFace.ensure settles with a view or the read's error */
172
+ if (mirrored.error === null) throw new Error("settings describe settled with neither a view nor an error");
173
+ this.failLoad(mirrored.error);
149
174
  return;
150
175
  }
151
176
  const providers = joinProviderDirectory(registered.value, declared.value);
@@ -166,13 +191,16 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
166
191
  const catalog = await this.ctx.remote.session.modelCatalog();
167
192
  for (const row of rows) if (row.entry.provider === "deepseek-account") row.accountAvailable = catalog.ok && catalog.value.groups.some((group) => group.id === "deepseek-account" && group.models.length > 0);
168
193
  }
169
- const refs = [...new Set(rows.filter((row) => row.entry.provider !== "deepseek-account").map((row) => row.apiKeyEnv ?? deriveKeyRef(row.entry.provider)))];
170
- let credentials = {};
194
+ const refs = [...new Set(rows.filter((row) => row.entry.provider !== "deepseek-account").flatMap((row) => row.apiKeyEnv === void 0 ? [deriveKeyRef(row.entry.provider), ...row.entry.nativeAuth?.env ?? []] : [row.apiKeyEnv]))];
195
+ const credentials = {};
171
196
  let credentialError = null;
172
- if (refs.length > 0) {
173
- const response = await this.ctx.remote.credentials.describe(refs);
174
- if (response.ok) credentials = response.value;
175
- else credentialError = response.error.message;
197
+ for (let index = 0; index < refs.length; index += 64) {
198
+ const response = await this.ctx.remote.credentials.describe(refs.slice(index, index + 64));
199
+ if (response.ok) Object.assign(credentials, response.value);
200
+ else {
201
+ credentialError = response.error.message;
202
+ break;
203
+ }
176
204
  }
177
205
  if (generation !== this.generation) return;
178
206
  this.store.update((s) => {
@@ -187,15 +215,25 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
187
215
  return {
188
216
  ...row,
189
217
  ...named === void 0 ? {} : { credential: named },
190
- ...derived === void 0 ? {} : { derivedCredential: derived }
218
+ ...derived === void 0 ? {} : { derivedCredential: derived },
219
+ ...credentialError === null ? { credentialChecks: Object.fromEntries((row.apiKeyEnv === void 0 ? row.entry.nativeAuth?.env ?? [] : [row.apiKeyEnv]).flatMap((ref) => {
220
+ const info = credentials[ref];
221
+ return info === void 0 ? [] : [[ref, info]];
222
+ })) } : {}
191
223
  };
192
224
  });
193
225
  s.namespaces = namespaces;
194
226
  });
195
227
  }
196
- /** Publish one load's failure text, unless a newer load already took over. */
197
- failLoad(generation, message) {
228
+ /** Settle callers only while this read still owns the current refresh. */
229
+ settleLoads(generation, settle) {
198
230
  if (generation !== this.generation) return;
231
+ const pending = [...this.pendingLoads];
232
+ this.pendingLoads.clear();
233
+ for (const load of pending) settle(load);
234
+ }
235
+ /** Publish the current joined read's failure text. */
236
+ failLoad(message) {
199
237
  this.store.update((s) => {
200
238
  s.status = "error";
201
239
  s.error = message;
@@ -629,8 +667,16 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
629
667
  retry: "Retry",
630
668
  keyInput: "API key",
631
669
  keyPlaceholder: "Enter your API key",
632
- keyPlaceholderNative: "Enter an API key, or leave blank to use environment authentication",
633
- keyStored: "Configured — enter a new value to replace",
670
+ keyPlaceholderFallback: "Leave blank to use env as auth ({hint})",
671
+ keyPlaceholderSaved: "Leave blank to use saved credentials",
672
+ keyFallbackMissing: "Env var not detected. Enter an API key, or configure {hint} in your env.",
673
+ keyFallbackDetected: "Env var detected. ({hint})",
674
+ keyFallbackDetectedHidden: "Env var detected.",
675
+ keyFallbackUnchecked: "Environment credential status has not been confirmed.",
676
+ keyHelp: "Saved credentials are used first. Environment fallbacks shown here, in order: {env}. Sources are launch environment, $cwd/.env, then $DSH_HOME/.env.",
677
+ authHelp: "Authentication details",
678
+ keyReveal: "Show secret",
679
+ keyHide: "Hide secret",
634
680
  keyEnvLocked: "Provided by the launch environment (read-only)",
635
681
  customized: "Customized settings",
636
682
  baseUrl: "Base URL",
@@ -742,8 +788,16 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
742
788
  retry: "重试",
743
789
  keyInput: "API 密钥",
744
790
  keyPlaceholder: "输入 API 密钥",
745
- keyPlaceholderNative: "输入 API 密钥,或留空使用环境认证",
746
- keyStored: "已配置——输入新值可替换",
791
+ keyPlaceholderFallback: "留空使用环境认证({hint})",
792
+ keyPlaceholderSaved: "留空使用已保存凭据",
793
+ keyFallbackMissing: "未检测到环境变量。请填写 API 密钥,或设置环境变量 {hint}。",
794
+ keyFallbackDetected: "已检测到环境变量({hint})",
795
+ keyFallbackDetectedHidden: "已检测到环境变量",
796
+ keyFallbackUnchecked: "环境凭据状态尚未确认",
797
+ keyHelp: "优先使用已保存的凭据。此处显示的环境后备按以下顺序排列:{env}。来源依次为启动环境、$cwd/.env、$DSH_HOME/.env。",
798
+ authHelp: "认证说明",
799
+ keyReveal: "显示密钥",
800
+ keyHide: "隐藏密钥",
747
801
  keyEnvLocked: "由启动环境提供(只读)",
748
802
  customized: "自定义设置",
749
803
  baseUrl: "API 地址",
@@ -1011,6 +1065,163 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
1011
1065
  }
1012
1066
  }
1013
1067
  //#endregion
1068
+ //#region src/client/models-plus/models-plus.module.css
1069
+ var models_plus_module_default = {
1070
+ "addActions": "_5ikCMa_addActions",
1071
+ "addBlock": "_5ikCMa_addBlock",
1072
+ "addButton": "_5ikCMa_addButton",
1073
+ "addCard": "_5ikCMa_addCard",
1074
+ "addModelButton": "_5ikCMa_addModelButton",
1075
+ "advancedHint": "_5ikCMa_advancedHint",
1076
+ "candidate": "_5ikCMa_candidate",
1077
+ "candidateEmpty": "_5ikCMa_candidateEmpty",
1078
+ "candidateId": "_5ikCMa_candidateId",
1079
+ "candidateLabel": "_5ikCMa_candidateLabel",
1080
+ "candidateList": "_5ikCMa_candidateList",
1081
+ "candidateSearch": "_5ikCMa_candidateSearch",
1082
+ "candidateToolbar": "_5ikCMa_candidateToolbar",
1083
+ "capacityRow": "_5ikCMa_capacityRow",
1084
+ "credentialDot": "_5ikCMa_credentialDot",
1085
+ "credentialDotConfigured": "_5ikCMa_credentialDotConfigured",
1086
+ "credentialDotMissing": "_5ikCMa_credentialDotMissing",
1087
+ "customizedSummary": "_5ikCMa_customizedSummary",
1088
+ "dangerButton": "_5ikCMa_dangerButton",
1089
+ "deleteConfirm": "_5ikCMa_deleteConfirm",
1090
+ "deleteDialog": "_5ikCMa_deleteDialog",
1091
+ "dragHandle": "_5ikCMa_dragHandle",
1092
+ "editor": "_5ikCMa_editor",
1093
+ "editorActions": "_5ikCMa_editorActions",
1094
+ "error": "_5ikCMa_error",
1095
+ "extBlock": "_5ikCMa_extBlock",
1096
+ "extCheck": "_5ikCMa_extCheck",
1097
+ "extCheckbox": "_5ikCMa_extCheckbox",
1098
+ "extCheckLabel": "_5ikCMa_extCheckLabel",
1099
+ "extField": "_5ikCMa_extField",
1100
+ "extGated": "_5ikCMa_extGated",
1101
+ "extGroup": "_5ikCMa_extGroup",
1102
+ "extGroupFirst": "_5ikCMa_extGroupFirst",
1103
+ "extHint": "_5ikCMa_extHint",
1104
+ "extLabel": "_5ikCMa_extLabel",
1105
+ "extTable": "_5ikCMa_extTable",
1106
+ "extTag": "_5ikCMa_extTag",
1107
+ "extTHead": "_5ikCMa_extTHead",
1108
+ "extTRow": "_5ikCMa_extTRow",
1109
+ "fetchDialog": "_5ikCMa_fetchDialog",
1110
+ "field": "_5ikCMa_field",
1111
+ "fieldLabel": "_5ikCMa_fieldLabel",
1112
+ "helpButton": "_5ikCMa_helpButton",
1113
+ "iconButton": "_5ikCMa_iconButton",
1114
+ "iconButtonDanger": "_5ikCMa_iconButtonDanger",
1115
+ "input": "_5ikCMa_input",
1116
+ "intro": "_5ikCMa_intro",
1117
+ "keyInput": "_5ikCMa_keyInput",
1118
+ "keyInputFilled": "_5ikCMa_keyInputFilled",
1119
+ "keyToggle": "_5ikCMa_keyToggle",
1120
+ "linkButton": "_5ikCMa_linkButton",
1121
+ "modal": "_5ikCMa_modal",
1122
+ "modalDesc": "_5ikCMa_modalDesc",
1123
+ "modalFoot": "_5ikCMa_modalFoot",
1124
+ "modalMask": "_5ikCMa_modalMask",
1125
+ "modalTitle": "_5ikCMa_modalTitle",
1126
+ "modelAdvanced": "_5ikCMa_modelAdvanced",
1127
+ "modelCatalog": "_5ikCMa_modelCatalog",
1128
+ "modelCatalogHeading": "_5ikCMa_modelCatalogHeading",
1129
+ "modelCatalogMeta": "_5ikCMa_modelCatalogMeta",
1130
+ "modelCatalogTitle": "_5ikCMa_modelCatalogTitle",
1131
+ "modelDropLine": "_5ikCMa_modelDropLine",
1132
+ "modelEmpty": "_5ikCMa_modelEmpty",
1133
+ "modelEntry": "_5ikCMa_modelEntry",
1134
+ "modelEntryDragging": "_5ikCMa_modelEntryDragging",
1135
+ "modelField": "_5ikCMa_modelField",
1136
+ "modelFieldLabel": "_5ikCMa_modelFieldLabel",
1137
+ "modelList": "_5ikCMa_modelList",
1138
+ "modelListHead": "_5ikCMa_modelListHead",
1139
+ "modelRow": "_5ikCMa_modelRow",
1140
+ "notice": "_5ikCMa_notice",
1141
+ "primaryButton": "_5ikCMa_primaryButton",
1142
+ "quickEmpty": "_5ikCMa_quickEmpty",
1143
+ "quickItem": "_5ikCMa_quickItem",
1144
+ "quickItemApi": "_5ikCMa_quickItemApi",
1145
+ "quickItemId": "_5ikCMa_quickItemId",
1146
+ "quickList": "_5ikCMa_quickList",
1147
+ "quickWrap": "_5ikCMa_quickWrap",
1148
+ "rowActions": "_5ikCMa_rowActions",
1149
+ "rowCard": "_5ikCMa_rowCard",
1150
+ "rowHead": "_5ikCMa_rowHead",
1151
+ "rowIdentity": "_5ikCMa_rowIdentity",
1152
+ "rowName": "_5ikCMa_rowName",
1153
+ "rows": "_5ikCMa_rows",
1154
+ "rowTag": "_5ikCMa_rowTag",
1155
+ "savedNotice": "_5ikCMa_savedNotice",
1156
+ "secondaryButton": "_5ikCMa_secondaryButton",
1157
+ "section": "_5ikCMa_section",
1158
+ "selectInput": "_5ikCMa_selectInput",
1159
+ "setupCard": "_5ikCMa_setupCard",
1160
+ "switchRow": "_5ikCMa_switchRow",
1161
+ "tabBar": "_5ikCMa_tabBar",
1162
+ "tabButton": "_5ikCMa_tabButton",
1163
+ "tabButtonActive": "_5ikCMa_tabButtonActive",
1164
+ "tabPanel": "_5ikCMa_tabPanel",
1165
+ "tabs": "_5ikCMa_tabs",
1166
+ "title": "_5ikCMa_title",
1167
+ "titleRow": "_5ikCMa_titleRow"
1168
+ };
1169
+ //#endregion
1170
+ //#region src/client/models-plus/ApiKeyInput.tsx
1171
+ /**
1172
+ * Write-only credential input with the same reveal behavior as masked
1173
+ * conversation text (mirrors the host ApiKeyInput @ 0.2.1-alpha.4).
1174
+ * A different value starts masked again, so a revealed secret never survives
1175
+ * an edit; `new-password` keeps a password manager from filling a derived
1176
+ * reference name into the field.
1177
+ */
1178
+ 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";
1179
+ 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`;
1180
+ const EYE_OFF_PATH = `${EYE_CONTOUR}M2.5 2.5L13.5 13.5`;
1181
+ /**
1182
+ * Reveal only a nonempty draft; a different value starts masked, as in the host field.
1183
+ * @param props - current draft, input attributes, and translated control labels.
1184
+ * @returns a password input with an optional reveal button.
1185
+ */
1186
+ function ApiKeyInput({ value, t, ...props }) {
1187
+ const [revealedValue, setRevealedValue] = (0, react.useState)();
1188
+ const revealed = value.length > 0 && revealedValue === value;
1189
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1190
+ className: models_plus_module_default["keyInput"],
1191
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
1192
+ ...props,
1193
+ className: `${models_plus_module_default["input"]} ${value.length > 0 ? models_plus_module_default["keyInputFilled"] : ""}`,
1194
+ type: revealed ? "text" : "password",
1195
+ autoComplete: "new-password",
1196
+ value,
1197
+ onChange: (event) => {
1198
+ setRevealedValue(void 0);
1199
+ props.onChange?.(event);
1200
+ }
1201
+ }), value.length === 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
1202
+ type: "button",
1203
+ className: models_plus_module_default["keyToggle"],
1204
+ "aria-label": t(revealed ? "keyHide" : "keyReveal"),
1205
+ "aria-pressed": revealed,
1206
+ disabled: props.disabled,
1207
+ onClick: () => {
1208
+ setRevealedValue(revealed ? void 0 : value);
1209
+ },
1210
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
1211
+ width: "16",
1212
+ height: "16",
1213
+ viewBox: "0 0 16 16",
1214
+ fill: "none",
1215
+ stroke: "currentColor",
1216
+ strokeWidth: 1.3,
1217
+ strokeLinecap: "round",
1218
+ "aria-hidden": "true",
1219
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: revealed ? EYE_OFF_PATH : EYE_PATH })
1220
+ })
1221
+ })]
1222
+ });
1223
+ }
1224
+ //#endregion
1014
1225
  //#region src/client/models-plus/presets.ts
1015
1226
  /**
1016
1227
  * Draft defaults for a NEW model row (added by hand or adopted from a fetch),
@@ -1167,99 +1378,6 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
1167
1378
  return next;
1168
1379
  }
1169
1380
  //#endregion
1170
- //#region src/client/models-plus/models-plus.module.css
1171
- var models_plus_module_default = {
1172
- "addActions": "PkL4gq_addActions",
1173
- "addBlock": "PkL4gq_addBlock",
1174
- "addButton": "PkL4gq_addButton",
1175
- "addCard": "PkL4gq_addCard",
1176
- "addModelButton": "PkL4gq_addModelButton",
1177
- "advancedHint": "PkL4gq_advancedHint",
1178
- "candidate": "PkL4gq_candidate",
1179
- "candidateEmpty": "PkL4gq_candidateEmpty",
1180
- "candidateId": "PkL4gq_candidateId",
1181
- "candidateLabel": "PkL4gq_candidateLabel",
1182
- "candidateList": "PkL4gq_candidateList",
1183
- "candidateSearch": "PkL4gq_candidateSearch",
1184
- "candidateToolbar": "PkL4gq_candidateToolbar",
1185
- "credentialDot": "PkL4gq_credentialDot",
1186
- "credentialDotConfigured": "PkL4gq_credentialDotConfigured",
1187
- "credentialDotMissing": "PkL4gq_credentialDotMissing",
1188
- "customizedSummary": "PkL4gq_customizedSummary",
1189
- "dangerButton": "PkL4gq_dangerButton",
1190
- "deleteConfirm": "PkL4gq_deleteConfirm",
1191
- "deleteDialog": "PkL4gq_deleteDialog",
1192
- "editor": "PkL4gq_editor",
1193
- "editorActions": "PkL4gq_editorActions",
1194
- "error": "PkL4gq_error",
1195
- "extBlock": "PkL4gq_extBlock",
1196
- "extCheck": "PkL4gq_extCheck",
1197
- "extCheckbox": "PkL4gq_extCheckbox",
1198
- "extCheckLabel": "PkL4gq_extCheckLabel",
1199
- "extField": "PkL4gq_extField",
1200
- "extGated": "PkL4gq_extGated",
1201
- "extGroup": "PkL4gq_extGroup",
1202
- "extGroupFirst": "PkL4gq_extGroupFirst",
1203
- "extHint": "PkL4gq_extHint",
1204
- "extLabel": "PkL4gq_extLabel",
1205
- "extTable": "PkL4gq_extTable",
1206
- "extTag": "PkL4gq_extTag",
1207
- "extTHead": "PkL4gq_extTHead",
1208
- "extTRow": "PkL4gq_extTRow",
1209
- "fetchDialog": "PkL4gq_fetchDialog",
1210
- "field": "PkL4gq_field",
1211
- "fieldLabel": "PkL4gq_fieldLabel",
1212
- "iconButton": "PkL4gq_iconButton",
1213
- "iconButtonDanger": "PkL4gq_iconButtonDanger",
1214
- "input": "PkL4gq_input",
1215
- "intro": "PkL4gq_intro",
1216
- "linkButton": "PkL4gq_linkButton",
1217
- "modal": "PkL4gq_modal",
1218
- "modalDesc": "PkL4gq_modalDesc",
1219
- "modalFoot": "PkL4gq_modalFoot",
1220
- "modalMask": "PkL4gq_modalMask",
1221
- "modalTitle": "PkL4gq_modalTitle",
1222
- "modelAdvanced": "PkL4gq_modelAdvanced",
1223
- "modelCatalog": "PkL4gq_modelCatalog",
1224
- "modelCatalogHeading": "PkL4gq_modelCatalogHeading",
1225
- "modelCatalogMeta": "PkL4gq_modelCatalogMeta",
1226
- "modelCatalogTitle": "PkL4gq_modelCatalogTitle",
1227
- "modelEmpty": "PkL4gq_modelEmpty",
1228
- "modelEntry": "PkL4gq_modelEntry",
1229
- "modelField": "PkL4gq_modelField",
1230
- "modelFieldLabel": "PkL4gq_modelFieldLabel",
1231
- "modelList": "PkL4gq_modelList",
1232
- "modelListHead": "PkL4gq_modelListHead",
1233
- "modelRow": "PkL4gq_modelRow",
1234
- "primaryButton": "PkL4gq_primaryButton",
1235
- "quickEmpty": "PkL4gq_quickEmpty",
1236
- "quickItem": "PkL4gq_quickItem",
1237
- "quickItemApi": "PkL4gq_quickItemApi",
1238
- "quickItemId": "PkL4gq_quickItemId",
1239
- "quickList": "PkL4gq_quickList",
1240
- "quickWrap": "PkL4gq_quickWrap",
1241
- "rowActions": "PkL4gq_rowActions",
1242
- "rowCard": "PkL4gq_rowCard",
1243
- "rowHead": "PkL4gq_rowHead",
1244
- "rowIdentity": "PkL4gq_rowIdentity",
1245
- "rowName": "PkL4gq_rowName",
1246
- "rows": "PkL4gq_rows",
1247
- "rowTag": "PkL4gq_rowTag",
1248
- "savedNotice": "PkL4gq_savedNotice",
1249
- "secondaryButton": "PkL4gq_secondaryButton",
1250
- "section": "PkL4gq_section",
1251
- "selectInput": "PkL4gq_selectInput",
1252
- "setupCard": "PkL4gq_setupCard",
1253
- "switchRow": "PkL4gq_switchRow",
1254
- "tabBar": "PkL4gq_tabBar",
1255
- "tabButton": "PkL4gq_tabButton",
1256
- "tabButtonActive": "PkL4gq_tabButtonActive",
1257
- "tabPanel": "PkL4gq_tabPanel",
1258
- "tabs": "PkL4gq_tabs",
1259
- "title": "PkL4gq_title",
1260
- "titleRow": "PkL4gq_titleRow"
1261
- };
1262
- //#endregion
1263
1381
  //#region src/client/models-plus/QuickLoad.tsx
1264
1382
  /**
1265
1383
  * Quick-load: source → provider → model id, three narrowing steps.
@@ -1785,8 +1903,7 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
1785
1903
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1786
1904
  className: models_plus_module_default["extGroup"],
1787
1905
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1788
- className: models_plus_module_default["modelField"],
1789
- style: { padding: "0 4px" },
1906
+ className: models_plus_module_default["capacityRow"],
1790
1907
  children: [capacityField("contextWindow", "上下文窗口"), capacityField("maxTokens", "最大输出 token")]
1791
1908
  })
1792
1909
  }),
@@ -2077,6 +2194,110 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2077
2194
  return next;
2078
2195
  });
2079
2196
  };
2197
+ const [dragging, setDragging] = (0, react.useState)(void 0);
2198
+ const [dropAt, setDropAt] = (0, react.useState)(void 0);
2199
+ const [epoch, setEpoch] = (0, react.useState)(0);
2200
+ const draggingRef = (0, react.useRef)(void 0);
2201
+ const dropAtRef = (0, react.useRef)(void 0);
2202
+ /**
2203
+ * Where a drop lands once the dragged row is out of the way.
2204
+ *
2205
+ * The indicator names a GAP, not a row: `after` picks the gap above or below
2206
+ * the row under the pointer (its own midpoint, so the indicator says what a
2207
+ * release would do before the release), and the gap is counted in pre-move
2208
+ * positions. Removing the dragged row first shifts everything after it up by
2209
+ * one, so a gap beyond the drag's own slot has to come back by one to stay
2210
+ * the same slot.
2211
+ * @param from - the dragged row's position.
2212
+ * @param row - the row under the pointer.
2213
+ * @param after - whether the pointer sits past that row's midpoint.
2214
+ * @returns the insertion index for the post-removal array.
2215
+ */
2216
+ const dropIndex = (from, row, after) => {
2217
+ const gap = after ? row + 1 : row;
2218
+ return from < gap ? gap - 1 : gap;
2219
+ };
2220
+ /**
2221
+ * Carry the expanded-row set through a move: the dragged row keeps its own
2222
+ * panel, and every row it passed shifts one slot.
2223
+ * @param current - the expanded positions before the move.
2224
+ * @param from - the dragged row's position.
2225
+ * @param to - its position after the move.
2226
+ * @returns the same panels, addressed by their new positions.
2227
+ */
2228
+ const moveExpanded = (current, from, to) => {
2229
+ const next = /* @__PURE__ */ new Set();
2230
+ for (const at of current) if (at === from) next.add(to);
2231
+ else if (from < to ? at > from && at <= to : at >= to && at < from) next.add(at + (from < to ? -1 : 1));
2232
+ else next.add(at);
2233
+ return next;
2234
+ };
2235
+ /**
2236
+ * Put one row at another position in the draft.
2237
+ * @param from - the row's current position.
2238
+ * @param to - the position it should end up at.
2239
+ */
2240
+ const moveRow = (from, to) => {
2241
+ if (from === to || from < 0 || to < 0 || from >= models.length || to >= models.length) return;
2242
+ const next = [...models];
2243
+ const [moved] = next.splice(from, 1);
2244
+ if (moved === void 0) return;
2245
+ next.splice(to, 0, moved);
2246
+ onChange(next);
2247
+ setExpanded((current) => moveExpanded(current, from, to));
2248
+ setEpoch((value) => value + 1);
2249
+ };
2250
+ /** @param index - the row the pointer took hold of. */
2251
+ const beginDrag = (index) => {
2252
+ draggingRef.current = index;
2253
+ dropAtRef.current = void 0;
2254
+ setDragging(index);
2255
+ setDropAt(void 0);
2256
+ };
2257
+ /**
2258
+ * Follow the pointer: keep the drop gap live so a release is predictable.
2259
+ * @param event - the dragover on a row.
2260
+ * @param index - that row's position.
2261
+ */
2262
+ const trackDrag = (event, index) => {
2263
+ if (draggingRef.current === void 0) return;
2264
+ event.preventDefault();
2265
+ if (event.dataTransfer !== null) event.dataTransfer.dropEffect = "move";
2266
+ const box = event.currentTarget.getBoundingClientRect();
2267
+ const at = {
2268
+ row: index,
2269
+ after: event.clientY > box.top + box.height / 2
2270
+ };
2271
+ const current = dropAtRef.current;
2272
+ if (current !== void 0 && current.row === at.row && current.after === at.after) return;
2273
+ dropAtRef.current = at;
2274
+ setDropAt(at);
2275
+ };
2276
+ /** Commit the drop, or abandon it when the drag never named a gap. */
2277
+ const endDrag = () => {
2278
+ const from = draggingRef.current;
2279
+ const at = dropAtRef.current;
2280
+ draggingRef.current = void 0;
2281
+ dropAtRef.current = void 0;
2282
+ setDragging(void 0);
2283
+ setDropAt(void 0);
2284
+ if (from === void 0 || at === void 0) return;
2285
+ moveRow(from, dropIndex(from, at.row, at.after));
2286
+ };
2287
+ /**
2288
+ * Reorder from the keyboard.
2289
+ *
2290
+ * The handle is a button, so the move has to be reachable without a pointer.
2291
+ * Alt + Arrow is the conventional "move this thing" chord, and it leaves the
2292
+ * bare arrow keys to their normal page duty.
2293
+ * @param event - the key event on the handle.
2294
+ * @param index - this row's position.
2295
+ */
2296
+ const handleHandleKey = (event, index) => {
2297
+ if (!event.altKey || event.key !== "ArrowUp" && event.key !== "ArrowDown") return;
2298
+ event.preventDefault();
2299
+ moveRow(index, index + (event.key === "ArrowUp" ? -1 : 1));
2300
+ };
2080
2301
  const fetchModels = async () => {
2081
2302
  setBusy(true);
2082
2303
  setFailure(void 0);
@@ -2176,9 +2397,16 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2176
2397
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2177
2398
  className: models_plus_module_default["modelList"],
2178
2399
  children: models.map((model, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2179
- className: models_plus_module_default["modelEntry"],
2400
+ className: dragging === index ? `${models_plus_module_default["modelEntry"]} ${models_plus_module_default["modelEntryDragging"]}` : models_plus_module_default["modelEntry"],
2180
2401
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2181
2402
  className: models_plus_module_default["modelRow"],
2403
+ onDragOver: (event) => {
2404
+ trackDrag(event, index);
2405
+ },
2406
+ onDrop: (event) => {
2407
+ event.preventDefault();
2408
+ endDrag();
2409
+ },
2182
2410
  children: [
2183
2411
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2184
2412
  className: models_plus_module_default["input"],
@@ -2253,7 +2481,42 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2253
2481
  strokeLinejoin: "round"
2254
2482
  })
2255
2483
  })
2256
- })
2484
+ }),
2485
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2486
+ type: "button",
2487
+ className: models_plus_module_default["dragHandle"],
2488
+ "aria-label": `拖动以调整模型顺序 ${String(index + 1)}`,
2489
+ title: "拖动以调整顺序(也可用 Alt + ↑/↓)",
2490
+ disabled: disabled || models.length < 2,
2491
+ draggable: disabled !== true,
2492
+ onDragStart: (event) => {
2493
+ event.dataTransfer.effectAllowed = "move";
2494
+ event.dataTransfer.setData("text/plain", textOf(model, "id"));
2495
+ beginDrag(index);
2496
+ },
2497
+ onDragEnd: endDrag,
2498
+ onKeyDown: (event) => {
2499
+ handleHandleKey(event, index);
2500
+ },
2501
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
2502
+ width: "14",
2503
+ height: "14",
2504
+ viewBox: "0 0 16 16",
2505
+ fill: "none",
2506
+ "aria-hidden": "true",
2507
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
2508
+ d: "M5.5 4h.01M5.5 8h.01M5.5 12h.01M10.5 4h.01M10.5 8h.01M10.5 12h.01",
2509
+ stroke: "currentColor",
2510
+ strokeWidth: "1.6",
2511
+ strokeLinecap: "round"
2512
+ })
2513
+ })
2514
+ }),
2515
+ dropAt !== void 0 && dropAt.row === index ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
2516
+ className: models_plus_module_default["modelDropLine"],
2517
+ "data-edge": dropAt.after ? "after" : "before",
2518
+ "aria-hidden": "true"
2519
+ }) : null
2257
2520
  ]
2258
2521
  }), expanded.has(index) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ModelEntryPanel, {
2259
2522
  model,
@@ -2263,7 +2526,7 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2263
2526
  onChange(models.map((row, at) => at === index ? next : row));
2264
2527
  }
2265
2528
  }) : null]
2266
- }, String(index)))
2529
+ }, epoch + ":" + String(index)))
2267
2530
  }),
2268
2531
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
2269
2532
  type: "button",
@@ -2404,6 +2667,56 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2404
2667
  return typeof named === "string" && named.length > 0 ? named : deriveKeyRef(provider);
2405
2668
  }
2406
2669
  /**
2670
+ * Judge the credential field the way the official card does: a profile's named
2671
+ * reference decides alone, the directory's native variables stand in only when
2672
+ * the profile names none, endpoint variables are not credentials, and oauth
2673
+ * references stay out of the display without changing what the adapter reads.
2674
+ *
2675
+ * Kept free of the translation table so the judgement can be asserted directly.
2676
+ * @param input - resolved profile facts plus the batch described credential state.
2677
+ * @returns the copy keys and state facts the field renders from.
2678
+ */
2679
+ function credentialView(input) {
2680
+ const native = input.namedRef === void 0 ? input.nativeAuth : void 0;
2681
+ const authRefs = input.namedRef === void 0 ? (native?.env ?? []).filter((ref) => !input.baseURLEnv.includes(ref)) : [input.namedRef];
2682
+ const visibleRefs = authRefs.filter((ref) => !ref.toLowerCase().includes("oauth"));
2683
+ const keyHint = visibleRefs[0];
2684
+ const checked = authRefs.map((ref) => [ref, input.credentialChecks?.[ref] ?? (ref === input.namedRef ? input.credential : void 0)]);
2685
+ const detected = checked.find(([, info]) => info?.configured === true);
2686
+ const detectedRef = detected?.[0];
2687
+ const detectedVisible = detectedRef !== void 0 && visibleRefs.includes(detectedRef) ? detectedRef : void 0;
2688
+ const missingRefs = checked.length > 0 && checked.every(([, info]) => info?.configured === false);
2689
+ const savedCredential = detected?.[1]?.source === "file";
2690
+ const locked = input.credential?.writable === false;
2691
+ const hint = locked || input.keyDraft.length > 0 || savedCredential || keyHint === void 0 ? void 0 : detectedRef === void 0 ? missingRefs ? {
2692
+ key: "keyFallbackMissing",
2693
+ tone: "notice"
2694
+ } : {
2695
+ key: "keyFallbackUnchecked",
2696
+ tone: "advancedHint"
2697
+ } : detectedVisible === void 0 ? {
2698
+ key: "keyFallbackDetectedHidden",
2699
+ tone: "advancedHint"
2700
+ } : {
2701
+ key: "keyFallbackDetected",
2702
+ tone: "savedNotice"
2703
+ };
2704
+ return {
2705
+ visibleRefs,
2706
+ keyHint,
2707
+ placeholderKey: locked ? "keyEnvLocked" : keyHint === void 0 ? "keyPlaceholder" : savedCredential ? "keyPlaceholderSaved" : "keyPlaceholderFallback",
2708
+ placeholderHint: keyHint,
2709
+ ...hint === void 0 ? {} : {
2710
+ hintKey: hint.key,
2711
+ hintRef: detectedVisible ?? keyHint,
2712
+ hintTone: hint.tone
2713
+ },
2714
+ ...visibleRefs.length === 0 ? {} : { helpRefs: visibleRefs },
2715
+ keyless: native !== void 0 && native.env.length === 0 && native.oauth,
2716
+ locked
2717
+ };
2718
+ }
2719
+ /**
2407
2720
  * Render one existing provider's editing card.
2408
2721
  * @param props - the addressed profile plus wire faces.
2409
2722
  * @returns the editor card.
@@ -2413,7 +2726,6 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2413
2726
  const [draft, setDraft] = (0, react.useState)(() => draftAt(schema, namespace, settingsPath));
2414
2727
  const [tab, setTab] = (0, react.useState)("provider");
2415
2728
  const [keyDraft, setKeyDraft] = (0, react.useState)("");
2416
- const [keyState, setKeyState] = (0, react.useState)(void 0);
2417
2729
  const [busy, setBusy] = (0, react.useState)(false);
2418
2730
  const [failure, setFailure] = (0, react.useState)(void 0);
2419
2731
  const [committedOriginal, setCommittedOriginal] = (0, react.useState)(() => schema.getPath(namespace.user, settingsPath));
@@ -2450,22 +2762,6 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2450
2762
  stale = true;
2451
2763
  };
2452
2764
  }, [layout]);
2453
- (0, react.useEffect)(() => {
2454
- if (accountProvider) return;
2455
- let stale = false;
2456
- setKeyState(void 0);
2457
- operations.describeCredential(keyRef).then((described) => {
2458
- if (stale) return;
2459
- setKeyState(described);
2460
- });
2461
- return () => {
2462
- stale = true;
2463
- };
2464
- }, [
2465
- operations,
2466
- keyRef,
2467
- accountProvider
2468
- ]);
2469
2765
  const stringAt = (source, key) => {
2470
2766
  const value = schema.getPath(source, [key]);
2471
2767
  return typeof value === "string" && value.trim().length > 0 ? value : void 0;
@@ -2575,8 +2871,32 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2575
2871
  const models = modelDrafts(modelsOverridden ? customModels : inheritedModels());
2576
2872
  const defaultContextWindow = schema.getPath(fallback, ["defaultContextWindow"]);
2577
2873
  const defaultMaxTokens = schema.getPath(fallback, ["maxTokens"]);
2578
- const keyPlaceholder = keyState?.writable === false ? "由启动环境提供(只读)" : keyState?.configured === true ? "已配置——输入新值可替换" : layout === "pi-ai" && props.declared === true ? "输入 API 密钥,或留空使用环境认证" : "输入 API 密钥";
2579
- const keyLocked = keyState?.writable === false;
2874
+ const view = credentialView({
2875
+ namedRef: stringAt(fallback, "apiKeyEnv"),
2876
+ nativeAuth: props.nativeAuth,
2877
+ baseURLEnv: props.baseURLEnv ?? [],
2878
+ keyDraft,
2879
+ credential: props.credential,
2880
+ credentialChecks: props.credentialChecks
2881
+ });
2882
+ const keyLocked = view.locked;
2883
+ const credentialHint = view.hintKey === void 0 ? void 0 : props.t(view.hintKey).replace("{hint}", () => view.hintRef ?? "");
2884
+ const keyHelp = view.helpRefs === void 0 ? void 0 : props.t("keyHelp").replace("{env}", () => (view.helpRefs ?? []).join(" / "));
2885
+ const authHelp = keyHelp === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
2886
+ label: keyHelp,
2887
+ side: "right",
2888
+ delayMs: 0,
2889
+ focusDelayMs: 0,
2890
+ portal: true,
2891
+ openOnClick: true,
2892
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
2893
+ type: "button",
2894
+ className: models_plus_module_default["helpButton"],
2895
+ "aria-label": props.t("authHelp"),
2896
+ children: "?"
2897
+ })
2898
+ });
2899
+ const keyPlaceholder = props.t(view.placeholderKey).replace("{hint}", () => view.placeholderHint ?? "");
2580
2900
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2581
2901
  className: models_plus_module_default["editor"],
2582
2902
  children: [
@@ -2653,28 +2973,33 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2653
2973
  }
2654
2974
  })]
2655
2975
  }) : null,
2656
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2976
+ view.keyless ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2657
2977
  className: models_plus_module_default["field"],
2658
2978
  children: [
2659
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
2979
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
2660
2980
  className: models_plus_module_default["fieldLabel"],
2661
- children: "API 密钥"
2981
+ children: [props.t("keyInput"), authHelp]
2662
2982
  }),
2663
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
2664
- className: models_plus_module_default["input"],
2665
- type: "password",
2666
- autoComplete: "off",
2983
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiKeyInput, {
2984
+ t: props.t,
2667
2985
  value: keyDraft,
2668
2986
  placeholder: keyPlaceholder,
2669
- "aria-label": "API 密钥",
2987
+ "aria-label": props.t("keyInput"),
2988
+ "aria-invalid": keyFailure !== void 0,
2989
+ "aria-describedby": credentialHint === void 0 ? void 0 : `${props.provider}-credential-hint`,
2670
2990
  disabled: disabled || keyLocked,
2671
2991
  onChange: (event) => {
2672
2992
  setKeyDraft(event.target.value);
2673
2993
  }
2674
2994
  }),
2995
+ credentialHint === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2996
+ id: `${props.provider}-credential-hint`,
2997
+ className: models_plus_module_default[view.hintTone ?? "advancedHint"],
2998
+ children: credentialHint
2999
+ }),
2675
3000
  keyFailure === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
2676
3001
  className: models_plus_module_default["error"],
2677
- children: keyFailure === "keyBlank" ? "请输入 API 密钥;留空则保持已存储的密钥。" : "此 API 密钥格式无效,请检查。"
3002
+ children: props.t(keyFailure)
2678
3003
  })
2679
3004
  ]
2680
3005
  }),
@@ -2994,17 +3319,16 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
2994
3319
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
2995
3320
  className: models_plus_module_default["field"],
2996
3321
  children: [
2997
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
3322
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
2998
3323
  className: models_plus_module_default["fieldLabel"],
2999
- children: "API 密钥"
3324
+ children: props.t("keyInput")
3000
3325
  }),
3001
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
3002
- className: models_plus_module_default["input"],
3003
- type: "password",
3004
- autoComplete: "off",
3326
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ApiKeyInput, {
3327
+ t: props.t,
3005
3328
  value: keyDraft,
3006
- placeholder: "输入 API 密钥,或留空使用环境认证",
3007
- "aria-label": "API 密钥",
3329
+ placeholder: props.t("keyPlaceholder"),
3330
+ "aria-label": props.t("keyInput"),
3331
+ "aria-invalid": keyFailure !== void 0,
3008
3332
  disabled,
3009
3333
  onChange: (event) => {
3010
3334
  setKeyDraft(event.target.value);
@@ -3012,7 +3336,7 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3012
3336
  }),
3013
3337
  keyFailure === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
3014
3338
  className: models_plus_module_default["error"],
3015
- children: keyFailure === "keyBlank" ? "请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。" : "此 API 密钥格式无效,请检查。"
3339
+ children: props.t(keyFailure === "keyBlank" ? "keyBlankNew" : "keyIllegalCharacters")
3016
3340
  })
3017
3341
  ]
3018
3342
  })
@@ -3034,7 +3358,7 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3034
3358
  api: protocol,
3035
3359
  ...keyValue.length === 0 ? {} : { apiKey: keyValue }
3036
3360
  },
3037
- probeBlocked: keyFailure === "keyBlank" ? "请输入 API 密钥;若该提供方以其他方式鉴权,可以留空。" : keyFailure,
3361
+ probeBlocked: keyFailure === void 0 ? void 0 : props.t(keyFailure === "keyBlank" ? "keyBlankNew" : "keyIllegalCharacters"),
3038
3362
  operations,
3039
3363
  disabled: profileDisabled,
3040
3364
  onChange: setModels
@@ -3097,7 +3421,10 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3097
3421
  settingsNs: row.entry.settingsNs,
3098
3422
  settingsPath: row.entry.settingsPath,
3099
3423
  ...credentialRef === void 0 ? {} : { credentialRef },
3100
- ...row.entry.declared === true ? { declared: true } : {}
3424
+ ...row.entry.declared === true ? { declared: true } : {},
3425
+ ...row.entry.defaultBaseURL === void 0 ? {} : { defaultBaseURL: row.entry.defaultBaseURL },
3426
+ ...row.entry.baseURLEnv === void 0 ? {} : { baseURLEnv: row.entry.baseURLEnv },
3427
+ ...row.entry.nativeAuth === void 0 ? {} : { nativeAuth: row.entry.nativeAuth }
3101
3428
  };
3102
3429
  }
3103
3430
  /**
@@ -3221,19 +3548,27 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3221
3548
  const addable = configurable.filter((row) => !row.configured);
3222
3549
  const addTarget = adding ? editing : void 0;
3223
3550
  const addNamespace = addTarget === void 0 ? void 0 : state.namespaces.get(addTarget.settingsNs);
3551
+ const addRow = addTarget === void 0 ? void 0 : state.rows.find((row) => row.entry.provider === addTarget.provider);
3224
3552
  const protocols = (() => {
3225
3553
  return protocolChoices(state.namespaces.get("llm-pi-ai"), schema);
3226
3554
  })();
3227
3555
  const renderEditor = (target, namespace, onClose) => {
3228
3556
  if (namespace === void 0) return null;
3557
+ const row = state.rows.find((candidate) => candidate.entry.provider === target.provider);
3229
3558
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderEditor, {
3230
3559
  provider: target.provider,
3231
3560
  displayName: target.displayName,
3232
3561
  settingsPath: target.settingsPath,
3233
3562
  ...target.declared === true ? { declared: true } : {},
3563
+ ...target.defaultBaseURL === void 0 ? {} : { defaultBaseURL: target.defaultBaseURL },
3564
+ ...target.baseURLEnv === void 0 ? {} : { baseURLEnv: target.baseURLEnv },
3565
+ ...target.nativeAuth === void 0 ? {} : { nativeAuth: target.nativeAuth },
3566
+ ...row?.credential === void 0 ? {} : { credential: row.credential },
3567
+ ...row?.credentialChecks === void 0 ? {} : { credentialChecks: row.credentialChecks },
3234
3568
  namespace,
3235
3569
  schema,
3236
3570
  operations,
3571
+ t,
3237
3572
  readOnly: !state.writable,
3238
3573
  onClose
3239
3574
  });
@@ -3383,10 +3718,16 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3383
3718
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ProviderEditor, {
3384
3719
  provider: addTarget.provider,
3385
3720
  displayName: addTarget.displayName,
3721
+ ...addRow?.credential === void 0 ? {} : { credential: addRow.credential },
3722
+ ...addRow?.credentialChecks === void 0 ? {} : { credentialChecks: addRow.credentialChecks },
3723
+ ...addTarget.defaultBaseURL === void 0 ? {} : { defaultBaseURL: addTarget.defaultBaseURL },
3724
+ ...addTarget.baseURLEnv === void 0 ? {} : { baseURLEnv: addTarget.baseURLEnv },
3725
+ ...addTarget.nativeAuth === void 0 ? {} : { nativeAuth: addTarget.nativeAuth },
3386
3726
  namespace: addNamespace,
3387
3727
  schema,
3388
3728
  settingsPath: addTarget.settingsPath,
3389
3729
  operations,
3730
+ t,
3390
3731
  readOnly: !state.writable,
3391
3732
  onClose: (changed) => {
3392
3733
  closeEditor(changed, addTarget);
@@ -3399,6 +3740,7 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3399
3740
  protocols,
3400
3741
  revision: state.namespaces.get("llm-pi-ai")?.revision ?? 0,
3401
3742
  operations,
3743
+ t,
3402
3744
  readOnly: !state.writable,
3403
3745
  onClose: (changed) => {
3404
3746
  setDeclaring(false);
@@ -3516,10 +3858,6 @@ if (typeof document !== 'undefined' && document.querySelector('style[data-plugin
3516
3858
  */
3517
3859
  function createModelsOperations(ctx) {
3518
3860
  return {
3519
- describeCredential: async (ref) => {
3520
- const response = await ctx.remote.credentials.describe([ref]);
3521
- return response.ok ? response.value[ref] : void 0;
3522
- },
3523
3861
  storeCredential: async (ref, value) => {
3524
3862
  const response = await ctx.remote.credentials.set(ref, value);
3525
3863
  return response.ok ? void 0 : response.error.message;