@goodandready/dsh-subscriptions 0.6.91 → 0.7.3
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/bin/dsh-subscriptions.mjs +65 -0
- package/lib/adapter-manager.js +3 -0
- package/lib/adapter.js +10 -2
- package/lib/alerts.js +54 -22
- package/lib/client.js +283 -9
- package/lib/coexistence.js +45 -0
- package/lib/config-schema.js +22 -0
- package/lib/index.js +24 -1
- package/lib/messages.js +1 -1
- package/lib/model-settings.js +49 -0
- package/lib/native-tools.js +220 -0
- package/lib/reset-clock.js +16 -6
- package/lib/route-report.js +28 -0
- package/lib/routes/status.js +88 -2
- package/lib/speed-mode.js +17 -0
- package/lib/stream-rotate.js +10 -2
- package/lib/subscriptions.js +1 -1
- package/lib/usage-export.js +52 -0
- package/lib/vault-sync.js +53 -15
- package/lib/vendor-pack.js +36 -0
- package/overlay.example.yml +8 -0
- package/package.json +33 -2
package/lib/client.js
CHANGED
|
@@ -40,7 +40,7 @@ window.__ModuleLoader__.load({
|
|
|
40
40
|
|
|
41
41
|
|
|
42
42
|
const CSS =
|
|
43
|
-
".dsub-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}.dsub-card:hover{border-color:var(--dsw-alias-label-dimmed)}.dsub-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.dsub-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.dsub-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.dsub-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dsub-description{color:var(--dsw-alias-label-secondary);font-size:13px}.dsub-chev{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.dsub-chevOpen{transform:rotate(180deg)}.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:12px}.dsub-block{margin-top:10px}.dsub-group{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;padding:0 14px}.dsub-group[open]{padding-bottom:6px}.dsub-groupHead{cursor:pointer;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);padding:10px 0;list-style:none}.dsub-groupHead::-webkit-details-marker{display:none}.dsub-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:8px}.dsub-grow{flex:1 1 180px;min-width:140px}.dsub-helpBox{margin-top:8px;padding:12px 14px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);font-size:12px;line-height:1.6}.dsub-helpHead{display:flex;align-items:center;justify-content:space-between;font-weight:600;margin-bottom:8px;color:var(--dsw-alias-brand-primary)}.dsub-helpStep{margin-bottom:6px;color:var(--dsw-alias-label-primary)}.dsub-btnActive{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border-color:var(--dsw-alias-brand-primary)}.dsub-h{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary)}.dsub-sub{font-size:12px;color:var(--dsw-alias-label-secondary)}.dsub-dim{font-size:11.5px;color:var(--dsw-alias-label-tertiary)}.dsub-mini{appearance:none;font:inherit;font-size:12px;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:3px 8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}.dsub-mini:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}.dsub-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}.dsub-bad{font-size:12px;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;word-break:break-word;max-width:100%}.dsub-hint{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.dsub-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 12px;font-size:12.5px;font-weight:500;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}.dsub-btn:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}.dsub-inp{height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;min-width:180px}.dsub-inp:focus{outline:none;border-color:var(--dsw-alias-brand-primary)}.dsub-box{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;margin-top:8px;background:var(--dsw-alias-bg-layer-2)}.dsub-cooldown{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-bg-layer-1);font-size:11px;font-weight:600}.dsub-bar{position:relative;height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden;flex:1;min-width:80px}.dsub-barFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary);transition:width .2s}.dsub-barWarn .dsub-barFill{background:var(--dsw-alias-state-warn-primary)}.dsub-barFull .dsub-barFill{background:var(--dsw-alias-state-error-primary)}.dsub-barRow{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--dsw-alias-label-secondary)}.dsub-manual{display:flex;flex-direction:column;gap:6px;margin-top:4px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2)}.dsub-verify{font-size:12px;color:var(--dsw-alias-state-warn-primary)}.dsub-verify a{color:var(--dsw-alias-brand-primary)}.dsub-pill{display:inline-flex;align-items:center;gap:7px;height:28px;padding:0 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600;cursor:pointer;box-shadow:0 1px 3px color-mix(in srgb,black 15%,transparent),inset 0 1px 0 color-mix(in srgb,white 6%,transparent);transition:all .16s ease;user-select:none}.dsub-pill:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary);transform:translateY(-1px);box-shadow:0 3px 8px color-mix(in srgb,black 25%,transparent),inset 0 1px 0 color-mix(in srgb,white 10%,transparent)}.dsub-pill:active{transform:translateY(0)}.dsub-pillTag{padding:1px 5px;border-radius:4px;font-size:10.5px;font-weight:700;letter-spacing:.02em;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}.dsub-led{width:7px;height:7px;border-radius:50%;flex:none;transition:all .2s ease}.dsub-ledOk{background:var(--dsw-alias-state-success-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-success-primary) 70%,transparent)}.dsub-ledWarn{background:var(--dsw-alias-state-warn-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-warn-primary) 70%,transparent)}.dsub-ledBad{background:var(--dsw-alias-state-error-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-error-primary) 70%,transparent)}.dsub-ledOff{background:var(--dsw-alias-label-tertiary)}.dsub-toast-container{position:fixed;top:16px;right:16px;z-index:10030;display:flex;flex-direction:column;gap:8px;pointer-events:none}.dsub-toast{pointer-events:auto;min-width:280px;max-width:400px;padding:10px 14px;border-radius:10px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 24px color-mix(in srgb,black 40%,transparent);display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12px;line-height:1.4;animation:dsubFadeIn .2s ease-out}.dsub-toast-warn{border-color:var(--dsw-alias-state-warn-primary)}.dsub-toast-bad{border-color:var(--dsw-alias-state-error-primary)}.dsub-toast-ok{border-color:var(--dsw-alias-state-success-primary)}.dsub-toast-close{background:none;border:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:14px;padding:0 2px}.dsub-toast-close:hover{color:var(--dsw-alias-label-primary)}.dsub-modalWrap{position:fixed;inset:0;z-index:10020;display:grid;place-items:center;background:color-mix(in srgb,black 65%,transparent);backdrop-filter:blur(10px);animation:dsubFadeIn .16s ease-out}.dsub-modal{width:min(520px,94vw);max-height:min(85vh,720px);overflow-y:auto;border:1px solid var(--dsw-alias-border-l1);border-radius:16px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);box-shadow:0 24px 64px color-mix(in srgb,black 60%,transparent),0 0 0 1px color-mix(in srgb,white 7%,transparent);padding:20px;animation:dsubScaleIn .18s cubic-bezier(.16,1,.3,1)}@keyframes dsubFadeIn{from{opacity:0}to{opacity:1}}@keyframes dsubScaleIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.dsub-modalHead{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:14px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsub-modalTitleWrap{display:flex;align-items:center;gap:10px}.dsub-modalIcon{width:30px;height:30px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);display:grid;place-items:center;color:var(--dsw-alias-brand-primary);font-size:14px}.dsub-modalBadge{font-size:11px;font-weight:600;padding:2px 7px;border-radius:10px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}.dsub-heroCard{margin-top:14px;padding:14px 16px;border-radius:12px;background:linear-gradient(135deg,var(--dsw-alias-bg-layer-2) 0%,var(--dsw-alias-bg-layer-3) 100%);border:1px solid var(--dsw-alias-border-l1);box-shadow:inset 0 1px 0 color-mix(in srgb,white 5%,transparent)}.dsub-heroHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}.dsub-heroTitle{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}.dsub-heroModel{font-size:11.5px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace}.dsub-select{appearance:none;height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 24px 0 8px;font-size:12px;cursor:pointer}.dsub-details{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 12px;background:var(--dsw-alias-bg-layer-2)}.dsub-summary{cursor:pointer;font-weight:600;font-size:12.5px;color:var(--dsw-alias-label-secondary);user-select:none}.dsub-summary:hover{color:var(--dsw-alias-label-primary)}.dsub-header-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding:8px 0 12px;margin-bottom:8px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsub-badge{font-size:12px;padding:3px 10px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);display:inline-flex;align-items:center;gap:5px;font-weight:500}.dsub-badge-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent)}.dsub-badge-warn{border-color:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 10%,transparent)}.dsub-badge-bad{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}.dsub-badge-neutral{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.dsub-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px;margin-top:12px}.dsub-section-title{font-size:14.5px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}.dsub-section-desc{font-size:12px;color:var(--dsw-alias-label-secondary);margin-top:-4px;line-height:1.4}.dsub-grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}.dsub-stat-box{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:3px}.dsub-stat-val{font-size:16.5px;font-weight:700;color:var(--dsw-alias-label-primary)}.dsub-stat-lbl{font-size:11.5px;color:var(--dsw-alias-label-secondary)}.dsub-chart-wrap{display:flex;align-items:flex-end;gap:3px;height:52px;padding:6px 0;margin-top:8px;border-bottom:1px solid var(--dsw-alias-border-l3)}.dsub-chart-bar{flex:1;background:var(--dsw-alias-brand-primary);border-radius:2px 2px 0 0;min-height:3px;transition:height .2s ease;opacity:0.85;cursor:pointer}.dsub-chart-bar:hover{opacity:1;background:var(--dsw-alias-state-success-primary)}.dsub-chart-labels{display:flex;justify-content:space-between;font-size:10px;color:var(--dsw-alias-label-secondary);margin-top:3px}.dsub-alert-ok{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent);color:var(--dsw-alias-state-success-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 25%,transparent)}.dsub-alert-bad{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 25%,transparent)}.dsub-btn-primary{background:var(--dsw-alias-label-primary) !important;color:var(--dsw-alias-bg-layer-3) !important;border-color:transparent !important;font-weight:600}.dsub-btn-primary:hover:not(:disabled){opacity:0.9}.dsub-model-grid{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.dsub-model-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:6px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-size:11.5px;color:var(--dsw-alias-label-primary)}.dsub-model-chip code{font-family:ui-monospace,monospace;font-weight:600}.dsub-model-tag{font-size:10px;padding:1px 4px;border-radius:3px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-weight:600}.dsub-trace-box{padding:8px 12px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);margin-top:8px;font-size:12px}.dsub-trace-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;border-bottom:1px solid var(--dsw-alias-border-l3)}.dsub-trace-row:last-child{border-bottom:none}.dsub-model-status-available{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent)}.dsub-model-status-degraded{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 12%,transparent)}.dsub-model-status-quarantined{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}.dsub-model-status-cooldown{color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent)}.dsub-model-status-exhausted{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}.dsub-model-status-unconfigured{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3)}.dsub-heroBars{display:flex;flex-direction:column;gap:8px;margin-top:10px}.dsub-barLabelRow{display:flex;justify-content:space-between;font-size:11.5px;color:var(--dsw-alias-label-secondary);margin-bottom:3px}.dsub-barTrack{height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-barFillGrad{height:100%;border-radius:3px;transition:width .3s ease}.dsub-panel-box{margin-top:10px;padding:12px 14px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:8px}.dsub-panel-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 5%,transparent)}.dsub-panel-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between}.dsub-panel-desc{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}.dsub-usage-grid{display:flex;flex-direction:column;gap:8px;margin-top:4px}.dsub-usage-card{display:flex;flex-direction:column;gap:5px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}.dsub-usage-head{display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:500;color:var(--dsw-alias-label-primary)}.dsub-usage-track{width:100%;height:8px;border-radius:999px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);overflow:hidden}.dsub-usage-fill{height:100%;border-radius:999px;transition:width .3s ease}.dsub-usage-meta{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--dsw-alias-label-secondary)}.dsub-tag-ok{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-tag-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-tag-bad{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-slot-meta-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2);font-size:12px}.dsub-ref-tag{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}.dsub-ref-tag code{padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-family:ui-monospace,monospace;color:var(--dsw-alias-label-primary);font-size:11px}.dsub-speed-tag{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,transparent);padding:2px 8px;border-radius:6px;font-weight:500;border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 20%,transparent)}.dsub-btn-danger{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent)!important;color:var(--dsw-alias-state-error-primary)!important}.dsub-btn-danger:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)!important}.dsub-poolTitle{margin-top:16px;margin-bottom:8px;font-size:11.5px;font-weight:700;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.05em}.dsub-accountCard{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin-top:6px;transition:border-color .15s,background .15s}.dsub-accountCard:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary)}.dsub-brandBadge{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;font-size:12px;font-weight:700;flex-shrink:0}.dsub-brandCodex{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent)}.dsub-brandClaude{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}.dsub-brandGrok{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 30%,transparent)}.dsub-brandAgy{background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent)}.dsub-brandOllama{background:color-mix(in srgb,var(--dsw-alias-label-tertiary) 15%,transparent);color:var(--dsw-alias-label-secondary);border:1px solid color-mix(in srgb,var(--dsw-alias-label-tertiary) 30%,transparent)}.dsub-brandKimi{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}.dsub-brandGlm{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 30%,transparent)}.dsub-planBadge{display:inline-flex;align-items:center;padding:1px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent);margin-left:6px}.dsub-accInfo{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.dsub-accNameRow{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsub-accName{font-size:13px;font-weight:600}.dsub-accStatusTag{font-size:10.5px;font-weight:600;padding:1px 6px;border-radius:4px}.dsub-statusOk{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary)}.dsub-statusWarn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary)}.dsub-statusBad{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 15%,transparent);color:var(--dsw-alias-state-error-primary)}.dsub-statusOff{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-tertiary)}.dsub-modalFoot{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2)}.dsub-btnPrimary{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:600;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border:0;cursor:pointer;transition:opacity .15s}.dsub-btnPrimary:hover{opacity:.9}.dsub-btnSec{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:7px;font-size:11.5px;font-weight:500;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;text-decoration:none;transition:all .15s}.dsub-btnSec:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}.dsub-cq{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--dsw-alias-label-secondary);padding:0 6px}.dsub-cqBar{position:relative;width:40px;height:5px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-cqBarFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary)}.dsub-cqBarWarn .dsub-cqBarFill{background:var(--dsw-alias-state-warn-primary)}.dsub-cqBarFull .dsub-cqBarFill{background:var(--dsw-alias-state-error-primary)}.dsub-cqB{font-variant-numeric:tabular-nums;font-weight:600;color:var(--dsw-alias-label-primary)}.dsub-diag{font:11px/1.5 ui-monospace,SFMono-Regular,monospace;max-height:260px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}";
|
|
43
|
+
".dsub-card{list-style:none;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;transition:border-color .16s,background .16s}.dsub-card:hover{border-color:var(--dsw-alias-label-dimmed)}.dsub-cardOpen{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}.dsub-header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}.dsub-header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}.dsub-headText{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}.dsub-name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}.dsub-description{color:var(--dsw-alias-label-secondary);font-size:13px}.dsub-chev{color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}.dsub-chevOpen{transform:rotate(180deg)}.dsub-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:12px}.dsub-block{margin-top:10px}.dsub-group{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;padding:0 14px}.dsub-group[open]{padding-bottom:6px}.dsub-groupHead{cursor:pointer;font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);padding:10px 0;list-style:none}.dsub-groupHead::-webkit-details-marker{display:none}.dsub-row{display:flex;align-items:center;flex-wrap:wrap;gap:8px;margin-top:8px}.dsub-grow{flex:1 1 180px;min-width:140px}.dsub-helpBox{margin-top:8px;padding:12px 14px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l1);font-size:12px;line-height:1.6}.dsub-helpHead{display:flex;align-items:center;justify-content:space-between;font-weight:600;margin-bottom:8px;color:var(--dsw-alias-brand-primary)}.dsub-helpStep{margin-bottom:6px;color:var(--dsw-alias-label-primary)}.dsub-btnActive{background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border-color:var(--dsw-alias-brand-primary)}.dsub-h{font-size:13.5px;font-weight:600;color:var(--dsw-alias-label-primary)}.dsub-sub{font-size:12px;color:var(--dsw-alias-label-secondary)}.dsub-dim{font-size:11.5px;color:var(--dsw-alias-label-tertiary)}.dsub-mini{appearance:none;font:inherit;font-size:12px;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:6px;padding:3px 8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}.dsub-mini:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}.dsub-ok{font-size:12px;color:var(--dsw-alias-state-success-primary)}.dsub-bad{font-size:12px;color:var(--dsw-alias-state-error-primary);overflow-wrap:anywhere;word-break:break-word;max-width:100%}.dsub-hint{overflow-wrap:anywhere;word-break:break-word;max-width:100%}.dsub-btn{appearance:none;font:inherit;cursor:pointer;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:5px 12px;font-size:12.5px;font-weight:500;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);transition:all .15s}.dsub-btn:hover{background:var(--dsw-alias-bg-layer-1);border-color:var(--dsw-alias-label-dimmed)}.dsub-inp{height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 8px;font-size:12px;min-width:180px}.dsub-inp:focus{outline:none;border-color:var(--dsw-alias-brand-primary)}.dsub-box{border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;margin-top:8px;background:var(--dsw-alias-bg-layer-2)}.dsub-cooldown{display:inline-block;padding:2px 6px;border-radius:4px;background:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-bg-layer-1);font-size:11px;font-weight:600}.dsub-bar{position:relative;height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden;flex:1;min-width:80px}.dsub-barFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary);transition:width .2s}.dsub-barWarn .dsub-barFill{background:var(--dsw-alias-state-warn-primary)}.dsub-barFull .dsub-barFill{background:var(--dsw-alias-state-error-primary)}.dsub-barRow{display:flex;align-items:center;gap:8px;font-size:12px;color:var(--dsw-alias-label-secondary)}.dsub-manual{display:flex;flex-direction:column;gap:6px;margin-top:4px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2)}.dsub-verify{font-size:12px;color:var(--dsw-alias-state-warn-primary)}.dsub-verify a{color:var(--dsw-alias-brand-primary)}.dsub-pill{display:inline-flex;align-items:center;gap:7px;height:28px;padding:0 11px;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:12px;font-weight:600;cursor:pointer;box-shadow:0 1px 3px color-mix(in srgb,black 15%,transparent),inset 0 1px 0 color-mix(in srgb,white 6%,transparent);transition:all .16s ease;user-select:none}.dsub-pill:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary);transform:translateY(-1px);box-shadow:0 3px 8px color-mix(in srgb,black 25%,transparent),inset 0 1px 0 color-mix(in srgb,white 10%,transparent)}.dsub-pill:active{transform:translateY(0)}.dsub-pillTag{padding:1px 5px;border-radius:4px;font-size:10.5px;font-weight:700;letter-spacing:.02em;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}.dsub-led{width:7px;height:7px;border-radius:50%;flex:none;transition:all .2s ease}.dsub-ledOk{background:var(--dsw-alias-state-success-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-success-primary) 70%,transparent)}.dsub-ledWarn{background:var(--dsw-alias-state-warn-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-warn-primary) 70%,transparent)}.dsub-ledBad{background:var(--dsw-alias-state-error-primary);box-shadow:0 0 6px color-mix(in srgb,var(--dsw-alias-state-error-primary) 70%,transparent)}.dsub-ledOff{background:var(--dsw-alias-label-tertiary)}.dsub-toast-container{position:fixed;top:16px;right:16px;z-index:10030;display:flex;flex-direction:column;gap:8px;pointer-events:none}.dsub-toast{pointer-events:auto;min-width:280px;max-width:400px;padding:10px 14px;border-radius:10px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border:1px solid var(--dsw-alias-border-l1);box-shadow:0 8px 24px color-mix(in srgb,black 40%,transparent);display:flex;align-items:center;justify-content:space-between;gap:10px;font-size:12px;line-height:1.4;animation:dsubFadeIn .2s ease-out}.dsub-toast-warn{border-color:var(--dsw-alias-state-warn-primary)}.dsub-toast-bad{border-color:var(--dsw-alias-state-error-primary)}.dsub-toast-ok{border-color:var(--dsw-alias-state-success-primary)}.dsub-toast-close{background:none;border:none;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:14px;padding:0 2px}.dsub-toast-close:hover{color:var(--dsw-alias-label-primary)}.dsub-modalWrap{position:fixed;inset:0;z-index:10020;display:grid;place-items:center;background:color-mix(in srgb,black 65%,transparent);backdrop-filter:blur(10px);animation:dsubFadeIn .16s ease-out}.dsub-modal{width:min(520px,94vw);max-height:min(85vh,720px);overflow-y:auto;border:1px solid var(--dsw-alias-border-l1);border-radius:16px;background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);box-shadow:0 24px 64px color-mix(in srgb,black 60%,transparent),0 0 0 1px color-mix(in srgb,white 7%,transparent);padding:20px;animation:dsubScaleIn .18s cubic-bezier(.16,1,.3,1)}@keyframes dsubFadeIn{from{opacity:0}to{opacity:1}}@keyframes dsubScaleIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}.dsub-modalHead{display:flex;align-items:center;justify-content:space-between;gap:12px;padding-bottom:14px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsub-modalTitleWrap{display:flex;align-items:center;gap:10px}.dsub-modalIcon{width:30px;height:30px;border-radius:8px;background:var(--dsw-alias-bg-layer-1);display:grid;place-items:center;color:var(--dsw-alias-brand-primary);font-size:14px}.dsub-modalBadge{font-size:11px;font-weight:600;padding:2px 7px;border-radius:10px;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary)}.dsub-heroCard{margin-top:14px;padding:14px 16px;border-radius:12px;background:linear-gradient(135deg,var(--dsw-alias-bg-layer-2) 0%,var(--dsw-alias-bg-layer-3) 100%);border:1px solid var(--dsw-alias-border-l1);box-shadow:inset 0 1px 0 color-mix(in srgb,white 5%,transparent)}.dsub-heroHead{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}.dsub-heroTitle{font-size:14px;font-weight:700;display:flex;align-items:center;gap:6px}.dsub-heroModel{font-size:11.5px;color:var(--dsw-alias-label-secondary);font-family:ui-monospace,monospace}.dsub-select{appearance:none;height:30px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-primary);border-radius:6px;padding:0 24px 0 8px;font-size:12px;cursor:pointer}.dsub-details{margin-top:12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:8px 12px;background:var(--dsw-alias-bg-layer-2)}.dsub-summary{cursor:pointer;font-weight:600;font-size:12.5px;color:var(--dsw-alias-label-secondary);user-select:none}.dsub-summary:hover{color:var(--dsw-alias-label-primary)}.dsub-header-bar{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:8px;padding:8px 0 12px;margin-bottom:8px;border-bottom:1px solid var(--dsw-alias-border-l2)}.dsub-badge{font-size:12px;padding:3px 10px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);display:inline-flex;align-items:center;gap:5px;font-weight:500}.dsub-badge-ok{border-color:var(--dsw-alias-state-success-primary);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent)}.dsub-badge-warn{border-color:var(--dsw-alias-state-warn-primary);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 10%,transparent)}.dsub-badge-bad{border-color:var(--dsw-alias-state-error-primary);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent)}.dsub-badge-neutral{border-color:var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-2)}.dsub-section-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:10px;margin-top:12px}.dsub-section-title{font-size:14.5px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between;gap:8px}.dsub-section-desc{font-size:12px;color:var(--dsw-alias-label-secondary);margin-top:-4px;line-height:1.4}.dsub-grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:10px}.dsub-stat-box{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:3px}.dsub-stat-val{font-size:16.5px;font-weight:700;color:var(--dsw-alias-label-primary)}.dsub-stat-lbl{font-size:11.5px;color:var(--dsw-alias-label-secondary)}.dsub-chart-wrap{display:flex;align-items:flex-end;gap:3px;height:52px;padding:6px 0;margin-top:8px;border-bottom:1px solid var(--dsw-alias-border-l3)}.dsub-chart-bar{flex:1;background:var(--dsw-alias-brand-primary);border-radius:2px 2px 0 0;min-height:3px;transition:height .2s ease;opacity:0.85;cursor:pointer}.dsub-chart-bar:hover{opacity:1;background:var(--dsw-alias-state-success-primary)}.dsub-chart-labels{display:flex;justify-content:space-between;font-size:10px;color:var(--dsw-alias-label-secondary);margin-top:3px}.dsub-alert-ok{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 10%,transparent);color:var(--dsw-alias-state-success-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 25%,transparent)}.dsub-alert-bad{padding:8px 12px;border-radius:8px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 10%,transparent);color:var(--dsw-alias-state-error-primary);font-size:12.5px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary) 25%,transparent)}.dsub-btn-primary{background:var(--dsw-alias-label-primary) !important;color:var(--dsw-alias-bg-layer-3) !important;border-color:transparent !important;font-weight:600}.dsub-btn-primary:hover:not(:disabled){opacity:0.9}.dsub-model-grid{display:flex;flex-wrap:wrap;gap:6px;margin-top:6px}.dsub-model-chip{display:inline-flex;align-items:center;gap:6px;padding:3px 8px;border-radius:6px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-size:11.5px;color:var(--dsw-alias-label-primary)}.dsub-model-chip code{font-family:ui-monospace,monospace;font-weight:600}.dsub-model-tag{font-size:10px;padding:1px 4px;border-radius:3px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary);font-weight:600}.dsub-trace-box{padding:8px 12px;border-radius:8px;background:var(--dsw-alias-bg-layer-2);border:1px solid var(--dsw-alias-border-l2);margin-top:8px;font-size:12px}.dsub-trace-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:4px 0;border-bottom:1px solid var(--dsw-alias-border-l3)}.dsub-trace-row:last-child{border-bottom:none}.dsub-model-status-available{color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 12%,transparent)}.dsub-model-status-degraded{color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 12%,transparent)}.dsub-model-status-quarantined{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}.dsub-model-status-cooldown{color:var(--dsw-alias-state-business-primary);background:color-mix(in srgb,var(--dsw-alias-state-business-primary) 12%,transparent)}.dsub-model-status-exhausted{color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)}.dsub-model-status-unconfigured{color:var(--dsw-alias-label-tertiary);background:var(--dsw-alias-bg-layer-3)}.dsub-heroBars{display:flex;flex-direction:column;gap:8px;margin-top:10px}.dsub-barLabelRow{display:flex;justify-content:space-between;font-size:11.5px;color:var(--dsw-alias-label-secondary);margin-bottom:3px}.dsub-barTrack{height:6px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-barFillGrad{height:100%;border-radius:3px;transition:width .3s ease}.dsub-panel-box{margin-top:10px;padding:12px 14px;border-radius:10px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);display:flex;flex-direction:column;gap:8px}.dsub-panel-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 5%,transparent)}.dsub-panel-title{font-size:13px;font-weight:600;color:var(--dsw-alias-label-primary);display:flex;align-items:center;justify-content:space-between}.dsub-panel-desc{font-size:12px;color:var(--dsw-alias-label-secondary);line-height:1.4}.dsub-usage-grid{display:flex;flex-direction:column;gap:8px;margin-top:4px}.dsub-usage-card{display:flex;flex-direction:column;gap:5px;padding:8px 10px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-1)}.dsub-usage-head{display:flex;justify-content:space-between;align-items:center;font-size:12px;font-weight:500;color:var(--dsw-alias-label-primary)}.dsub-usage-track{width:100%;height:8px;border-radius:999px;background:var(--dsw-alias-bg-layer-3);border:1px solid var(--dsw-alias-border-l2);overflow:hidden}.dsub-usage-fill{height:100%;border-radius:999px;transition:width .3s ease}.dsub-usage-meta{display:flex;justify-content:space-between;align-items:center;font-size:11px;color:var(--dsw-alias-label-secondary)}.dsub-tag-ok{border-color:color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent);color:var(--dsw-alias-state-success-primary);background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-tag-warn{border-color:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 40%,transparent);color:var(--dsw-alias-state-warn-primary);background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-tag-bad{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent);color:var(--dsw-alias-state-error-primary);background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 8%,transparent);padding:1px 7px;border-radius:999px;font-size:11px;font-weight:600;border-style:solid;border-width:1px}.dsub-slot-meta-row{display:flex;flex-wrap:wrap;align-items:center;gap:10px;margin-top:12px;padding-top:10px;border-top:1px solid var(--dsw-alias-border-l2);font-size:12px}.dsub-ref-tag{display:inline-flex;align-items:center;gap:5px;font-size:11.5px;color:var(--dsw-alias-label-secondary)}.dsub-ref-tag code{padding:2px 6px;border-radius:4px;background:var(--dsw-alias-bg-layer-1);border:1px solid var(--dsw-alias-border-l2);font-family:ui-monospace,monospace;color:var(--dsw-alias-label-primary);font-size:11px}.dsub-speed-tag{display:inline-flex;align-items:center;gap:4px;font-size:11.5px;color:var(--dsw-alias-brand-primary);background:color-mix(in srgb,var(--dsw-alias-brand-primary) 8%,transparent);padding:2px 8px;border-radius:6px;font-weight:500;border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 20%,transparent)}.dsub-btn-danger{border-color:color-mix(in srgb,var(--dsw-alias-state-error-primary) 40%,transparent)!important;color:var(--dsw-alias-state-error-primary)!important}.dsub-btn-danger:hover:not(:disabled){background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 12%,transparent)!important}.dsub-poolTitle{margin-top:16px;margin-bottom:8px;font-size:11.5px;font-weight:700;color:var(--dsw-alias-label-secondary);text-transform:uppercase;letter-spacing:.05em}.dsub-accountCard{display:flex;align-items:center;gap:12px;padding:10px 14px;border:1px solid var(--dsw-alias-border-l2);border-radius:10px;background:var(--dsw-alias-bg-layer-2);margin-top:6px;transition:border-color .15s,background .15s}.dsub-accountCard:hover{background:var(--dsw-alias-bg-layer-3);border-color:var(--dsw-alias-label-tertiary)}.dsub-brandBadge{width:32px;height:32px;border-radius:8px;display:grid;place-items:center;font-size:12px;font-weight:700;flex-shrink:0}.dsub-brandCodex{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-success-primary) 30%,transparent)}.dsub-brandClaude{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}.dsub-brandGrok{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 30%,transparent)}.dsub-brandAgy{background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent)}.dsub-brandOllama{background:color-mix(in srgb,var(--dsw-alias-label-tertiary) 15%,transparent);color:var(--dsw-alias-label-secondary);border:1px solid color-mix(in srgb,var(--dsw-alias-label-tertiary) 30%,transparent)}.dsub-brandKimi{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary) 30%,transparent)}.dsub-brandGlm{background:color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 15%,transparent);color:var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary));border:1px solid color-mix(in srgb,var(--dsw-alias-state-business-primary,var(--dsw-alias-brand-primary)) 30%,transparent)}.dsub-planBadge{display:inline-flex;align-items:center;padding:1px 6px;border-radius:4px;font-size:10px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;background:color-mix(in srgb,var(--dsw-alias-brand-primary) 15%,transparent);color:var(--dsw-alias-brand-primary);border:1px solid color-mix(in srgb,var(--dsw-alias-brand-primary) 30%,transparent);margin-left:6px}.dsub-accInfo{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}.dsub-accNameRow{display:flex;align-items:center;justify-content:space-between;gap:8px}.dsub-accName{font-size:13px;font-weight:600}.dsub-accStatusTag{font-size:10.5px;font-weight:600;padding:1px 6px;border-radius:4px}.dsub-statusOk{background:color-mix(in srgb,var(--dsw-alias-state-success-primary) 15%,transparent);color:var(--dsw-alias-state-success-primary)}.dsub-statusWarn{background:color-mix(in srgb,var(--dsw-alias-state-warn-primary) 15%,transparent);color:var(--dsw-alias-state-warn-primary)}.dsub-statusBad{background:color-mix(in srgb,var(--dsw-alias-state-error-primary) 15%,transparent);color:var(--dsw-alias-state-error-primary)}.dsub-statusOff{background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-tertiary)}.dsub-modalFoot{display:flex;align-items:center;justify-content:space-between;margin-top:16px;padding-top:12px;border-top:1px solid var(--dsw-alias-border-l2)}.dsub-btnPrimary{display:inline-flex;align-items:center;gap:6px;padding:6px 12px;border-radius:8px;font-size:12px;font-weight:600;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-label-primary-foreground);border:0;cursor:pointer;transition:opacity .15s}.dsub-btnPrimary:hover{opacity:.9}.dsub-btnSec{display:inline-flex;align-items:center;gap:5px;padding:5px 10px;border-radius:7px;font-size:11.5px;font-weight:500;background:var(--dsw-alias-bg-layer-1);color:var(--dsw-alias-label-secondary);border:1px solid var(--dsw-alias-border-l2);cursor:pointer;text-decoration:none;transition:all .15s}.dsub-btnSec:hover{background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-label-tertiary)}.dsub-cq{display:inline-flex;align-items:center;gap:6px;font-size:12px;color:var(--dsw-alias-label-secondary);padding:0 6px}.dsub-cqBar{position:relative;width:40px;height:5px;border-radius:3px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-cqBarFill{height:100%;border-radius:3px;background:var(--dsw-alias-state-success-primary)}.dsub-cqBarWarn .dsub-cqBarFill{background:var(--dsw-alias-state-warn-primary)}.dsub-cqBarFull .dsub-cqBarFill{background:var(--dsw-alias-state-error-primary)}.dsub-cqB{font-variant-numeric:tabular-nums;font-weight:600;color:var(--dsw-alias-label-primary)}.dsub-qw{position:fixed;z-index:10010;display:flex;align-items:center;gap:6px;height:30px;padding:0 10px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);box-shadow:0 4px 14px color-mix(in srgb,black 28%,transparent);cursor:grab;user-select:none;font-size:11.5px;font-weight:600;touch-action:none}.dsub-qw:active{cursor:grabbing}.dsub-qwDocked{right:16px !important;bottom:16px !important;cursor:default}.dsub-qwPct{font-variant-numeric:tabular-nums}.dsub-qwBar{width:28px;height:4px;border-radius:2px;background:var(--dsw-alias-bg-layer-1);overflow:hidden}.dsub-qwBarFill{height:100%;border-radius:2px;background:var(--dsw-alias-state-success-primary)}.dsub-qwWarn .dsub-qwBarFill{background:var(--dsw-alias-state-warn-primary)}.dsub-qwFull .dsub-qwBarFill{background:var(--dsw-alias-state-error-primary)}.dsub-diag{font:11px/1.5 ui-monospace,SFMono-Regular,monospace;max-height:260px;overflow:auto;white-space:pre-wrap;word-break:break-word;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;padding:10px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-secondary)}";
|
|
44
44
|
const cssId = 'dsh-subscriptions/settings.module.css'
|
|
45
45
|
if (typeof document !== 'undefined' && !document.querySelector('style[data-plugin-css="' + cssId + '"]')) {
|
|
46
46
|
const tag = document.createElement('style')
|
|
@@ -106,6 +106,10 @@ window.__ModuleLoader__.load({
|
|
|
106
106
|
"hideDeprecated": "Hide deprecated models",
|
|
107
107
|
"hideDeprecatedHint": "Hide older or superseded model variants from model dropdowns.",
|
|
108
108
|
"composerQuota": "Composer quota indicator",
|
|
109
|
+
"composerQuotaDisplay": "Status-bar quota scope",
|
|
110
|
+
"composerQuotaDisplayHint": "Show quota for the provider of the current model, or hide the status-bar pill.",
|
|
111
|
+
"composerQuotaDisplayCurrent": "Current model",
|
|
112
|
+
"composerQuotaDisplayHidden": "Hidden",
|
|
109
113
|
"composerQuotaHint": "Display subscription usage indicator directly in the composer toolbar.",
|
|
110
114
|
"composerQuotaOff": "Disabled",
|
|
111
115
|
"composerQuotaPercent": "Percentage",
|
|
@@ -255,11 +259,23 @@ window.__ModuleLoader__.load({
|
|
|
255
259
|
"verifyLink": "Open verification link",
|
|
256
260
|
"verifySuffix": " then reconnect.",
|
|
257
261
|
"addAccount": "+ Add account",
|
|
262
|
+
"slotAdvanced": "Advanced slot settings",
|
|
263
|
+
"providerGallery": "Add provider",
|
|
264
|
+
"providerGalleryHint": "Unconnected providers are hidden from the main list to keep the page focused.",
|
|
265
|
+
"vipOnly": "VIP only",
|
|
266
|
+
"vipOnlyHint": "Reserve this account for VIP-tagged requests.",
|
|
267
|
+
"isPro": "Pro",
|
|
268
|
+
"isProHint": "Treat this account as Pro for weighted priority.",
|
|
269
|
+
"tags": "Tags",
|
|
270
|
+
"tagsPlaceholder": "team, prod",
|
|
271
|
+
"weight": "Weight",
|
|
272
|
+
"maxQueueSizeSlot": "Queue",
|
|
258
273
|
"save": "Save",
|
|
259
274
|
"saved": "Saved",
|
|
260
275
|
"accountLabel": "Account",
|
|
261
276
|
"plan": "Plan",
|
|
262
277
|
"storedAs": "Stored as",
|
|
278
|
+
"slashFast": "Toggle Codex Speed (fast/standard)",
|
|
263
279
|
"slashLogin": "Login to a subscription provider",
|
|
264
280
|
"slashLogout": "Log out a subscription provider",
|
|
265
281
|
"forecast": "≈",
|
|
@@ -404,6 +420,10 @@ window.__ModuleLoader__.load({
|
|
|
404
420
|
"hideDeprecated": "隐藏已废弃的旧模型",
|
|
405
421
|
"hideDeprecatedHint": "在模型下拉列表中隐藏早期或已被替代的旧版模型。",
|
|
406
422
|
"composerQuota": "输入框额度指示器",
|
|
423
|
+
"composerQuotaDisplay": "状态栏额度范围",
|
|
424
|
+
"composerQuotaDisplayHint": "显示当前模型所属服务商的额度,或隐藏状态栏指示器。",
|
|
425
|
+
"composerQuotaDisplayCurrent": "当前模型",
|
|
426
|
+
"composerQuotaDisplayHidden": "隐藏",
|
|
407
427
|
"composerQuotaHint": "在聊天输入框工具栏直接显示当前订阅额度指示器。",
|
|
408
428
|
"composerQuotaOff": "已禁用",
|
|
409
429
|
"composerQuotaPercent": "百分比显示",
|
|
@@ -553,11 +573,23 @@ window.__ModuleLoader__.load({
|
|
|
553
573
|
"verifyLink": "打开验证链接",
|
|
554
574
|
"verifySuffix": ",完成后点击重新连接。",
|
|
555
575
|
"addAccount": "+ 添加账户",
|
|
576
|
+
"slotAdvanced": "账户高级设置",
|
|
577
|
+
"providerGallery": "添加服务商",
|
|
578
|
+
"providerGalleryHint": "未连接的服务商默认隐藏在列表中,保持页面聚焦。",
|
|
579
|
+
"vipOnly": "仅 VIP",
|
|
580
|
+
"vipOnlyHint": "将此账户保留给 VIP 请求。",
|
|
581
|
+
"isPro": "Pro",
|
|
582
|
+
"isProHint": "按 Pro 账户参与加权优先级。",
|
|
583
|
+
"tags": "标签",
|
|
584
|
+
"tagsPlaceholder": "team, prod",
|
|
585
|
+
"weight": "权重",
|
|
586
|
+
"maxQueueSizeSlot": "队列",
|
|
556
587
|
"save": "保存",
|
|
557
588
|
"saved": "已保存",
|
|
558
589
|
"accountLabel": "账户",
|
|
559
590
|
"plan": "套餐方案",
|
|
560
591
|
"storedAs": "存储标识",
|
|
592
|
+
"slashFast": "切换 Codex 加速模式(快速/标准)",
|
|
561
593
|
"slashLogin": "登录订阅服务商",
|
|
562
594
|
"slashLogout": "登出订阅服务商",
|
|
563
595
|
"forecast": "≈",
|
|
@@ -1785,6 +1817,31 @@ window.__ModuleLoader__.load({
|
|
|
1785
1817
|
),
|
|
1786
1818
|
h('details', { className: 'dsub-group', open: true },
|
|
1787
1819
|
h('summary', { className: 'dsub-groupHead' }, t('groupRotation')),
|
|
1820
|
+
h('div', { className: 'dsub-row' },
|
|
1821
|
+
h('span', { className: 'dsub-h' }, t('composerQuotaDisplay')),
|
|
1822
|
+
h('select', {
|
|
1823
|
+
className: 'dsub-select',
|
|
1824
|
+
value: draft.composerQuotaDisplay || 'current',
|
|
1825
|
+
onChange: (e) => setDraft((d) => Object.assign({}, d, { composerQuotaDisplay: e.target.value })),
|
|
1826
|
+
},
|
|
1827
|
+
h('option', { value: 'current' }, t('composerQuotaDisplayCurrent')),
|
|
1828
|
+
h('option', { value: 'hidden' }, t('composerQuotaDisplayHidden')),
|
|
1829
|
+
),
|
|
1830
|
+
),
|
|
1831
|
+
h('div', { className: 'dsub-sub' }, t('composerQuotaDisplayHint')), h('div', { className: 'dsub-row' },
|
|
1832
|
+
h('span', { className: 'dsub-h' }, 'Quota widget'),
|
|
1833
|
+
h('select', {
|
|
1834
|
+
className: 'dsub-select',
|
|
1835
|
+
value: draft.quotaWidget || 'docked',
|
|
1836
|
+
onChange: (e) => setDraft((d) => Object.assign({}, d, { quotaWidget: e.target.value })),
|
|
1837
|
+
},
|
|
1838
|
+
h('option', { value: 'off' }, 'Off'),
|
|
1839
|
+
h('option', { value: 'docked' }, 'Docked'),
|
|
1840
|
+
h('option', { value: 'floating' }, 'Floating (draggable)'),
|
|
1841
|
+
),
|
|
1842
|
+
),
|
|
1843
|
+
h('div', { className: 'dsub-sub' }, 'Floating capsule can be dragged; docked stays bottom-right.'),
|
|
1844
|
+
|
|
1788
1845
|
h('div', { className: 'dsub-row' },
|
|
1789
1846
|
h('span', { className: 'dsub-h' }, t('composerQuota')),
|
|
1790
1847
|
h('select', {
|
|
@@ -2347,7 +2404,17 @@ window.__ModuleLoader__.load({
|
|
|
2347
2404
|
)
|
|
2348
2405
|
) : null,
|
|
2349
2406
|
),
|
|
2350
|
-
|
|
2407
|
+
(function(){
|
|
2408
|
+
const configuredSlot = (slot) => {
|
|
2409
|
+
const account = accountOf(slot.provider, slot.index)
|
|
2410
|
+
return !!((account && (account.configured || account.hasToken))
|
|
2411
|
+
|| slot.label || slot.proxyUrl || slot.expiresAt
|
|
2412
|
+
|| (Array.isArray(slot.tags) && slot.tags.length) || slot.vipOnly || slot.isPro || slot.weight)
|
|
2413
|
+
}
|
|
2414
|
+
const visibleNames = names.filter((prov) => slots.some((slot) => slot.provider === prov.id && configuredSlot(slot)))
|
|
2415
|
+
const hiddenNames = names.filter((prov) => visibleNames.indexOf(prov) < 0)
|
|
2416
|
+
return h(React.Fragment, null,
|
|
2417
|
+
visibleNames.map((prov) => {
|
|
2351
2418
|
const rows = slots
|
|
2352
2419
|
.map((slot, i) => ({ slot: slot, i: i }))
|
|
2353
2420
|
.filter((row) => row.slot.provider === prov.id)
|
|
@@ -2637,6 +2704,59 @@ window.__ModuleLoader__.load({
|
|
|
2637
2704
|
},
|
|
2638
2705
|
})
|
|
2639
2706
|
),
|
|
2707
|
+
h('details', { className: 'dsub-details' },
|
|
2708
|
+
h('summary', { className: 'dsub-summary' }, t('slotAdvanced')),
|
|
2709
|
+
h('div', { className: 'dsub-row' },
|
|
2710
|
+
h('label', { className: 'dsub-ref-tag', title: t('vipOnlyHint') },
|
|
2711
|
+
h('input', {
|
|
2712
|
+
type: 'checkbox',
|
|
2713
|
+
checked: !!row.slot.vipOnly,
|
|
2714
|
+
onChange: (e) => updateSlot(row.slot.provider, row.slot.index, { vipOnly: e.target.checked }),
|
|
2715
|
+
}),
|
|
2716
|
+
' ' + t('vipOnly')
|
|
2717
|
+
),
|
|
2718
|
+
h('label', { className: 'dsub-ref-tag', title: t('isProHint') },
|
|
2719
|
+
h('input', {
|
|
2720
|
+
type: 'checkbox',
|
|
2721
|
+
checked: !!row.slot.isPro,
|
|
2722
|
+
onChange: (e) => updateSlot(row.slot.provider, row.slot.index, { isPro: e.target.checked }),
|
|
2723
|
+
}),
|
|
2724
|
+
' ' + t('isPro')
|
|
2725
|
+
),
|
|
2726
|
+
),
|
|
2727
|
+
h('div', { className: 'dsub-row' },
|
|
2728
|
+
h('span', { className: 'dsub-ref-tag' }, t('tags')),
|
|
2729
|
+
h('input', {
|
|
2730
|
+
className: 'dsub-inp',
|
|
2731
|
+
style: { width: '160px', minWidth: '160px' },
|
|
2732
|
+
value: (Array.isArray(row.slot.tags) ? row.slot.tags : []).join(','),
|
|
2733
|
+
placeholder: t('tagsPlaceholder'),
|
|
2734
|
+
onChange: (e) => updateSlot(row.slot.provider, row.slot.index, {
|
|
2735
|
+
tags: e.target.value.split(',').map((value) => value.trim()).filter(Boolean),
|
|
2736
|
+
}),
|
|
2737
|
+
}),
|
|
2738
|
+
h('span', { className: 'dsub-ref-tag' }, t('weight')),
|
|
2739
|
+
h('input', {
|
|
2740
|
+
type: 'number', min: 0, max: 100,
|
|
2741
|
+
style: { width: '52px', padding: '1px 4px', fontSize: '11px', textAlign: 'center' },
|
|
2742
|
+
value: row.slot.weight !== undefined ? row.slot.weight : 0,
|
|
2743
|
+
onChange: (e) => {
|
|
2744
|
+
const value = parseInt(e.target.value, 10)
|
|
2745
|
+
updateSlot(row.slot.provider, row.slot.index, { weight: isNaN(value) ? 0 : Math.max(0, value) })
|
|
2746
|
+
},
|
|
2747
|
+
}),
|
|
2748
|
+
h('span', { className: 'dsub-ref-tag' }, t('maxQueueSizeSlot')),
|
|
2749
|
+
h('input', {
|
|
2750
|
+
type: 'number', min: 0, max: 1000,
|
|
2751
|
+
style: { width: '58px', padding: '1px 4px', fontSize: '11px', textAlign: 'center' },
|
|
2752
|
+
value: row.slot.maxQueueSize !== undefined ? row.slot.maxQueueSize : 0,
|
|
2753
|
+
onChange: (e) => {
|
|
2754
|
+
const value = parseInt(e.target.value, 10)
|
|
2755
|
+
updateSlot(row.slot.provider, row.slot.index, { maxQueueSize: isNaN(value) ? 0 : Math.max(0, value) })
|
|
2756
|
+
},
|
|
2757
|
+
}),
|
|
2758
|
+
),
|
|
2759
|
+
),
|
|
2640
2760
|
),
|
|
2641
2761
|
(function(){
|
|
2642
2762
|
var r = proxyRes[key]
|
|
@@ -2917,6 +3037,20 @@ window.__ModuleLoader__.load({
|
|
|
2917
3037
|
}, t('addAccount')),
|
|
2918
3038
|
)
|
|
2919
3039
|
}),
|
|
3040
|
+
hiddenNames.length ? h('details', { className: 'dsub-group', open: visibleNames.length === 0 },
|
|
3041
|
+
h('summary', { className: 'dsub-groupHead' }, '➕ ' + t('providerGallery')),
|
|
3042
|
+
h('div', { className: 'dsub-sub' }, t('providerGalleryHint')),
|
|
3043
|
+
h('div', { className: 'dsub-model-grid' },
|
|
3044
|
+
hiddenNames.map((prov) => h('button', {
|
|
3045
|
+
key: prov.id,
|
|
3046
|
+
type: 'button',
|
|
3047
|
+
className: 'dsub-mini',
|
|
3048
|
+
onClick: () => addSlot(prov.id),
|
|
3049
|
+
}, prov.name))
|
|
3050
|
+
)
|
|
3051
|
+
) : null
|
|
3052
|
+
)
|
|
3053
|
+
})(),
|
|
2920
3054
|
h('div', { className: 'dsub-foot' },
|
|
2921
3055
|
h('button', {
|
|
2922
3056
|
type: 'button', className: 'dsub-save',
|
|
@@ -3103,10 +3237,29 @@ window.__ModuleLoader__.load({
|
|
|
3103
3237
|
labels: (data && data.labels) || {},
|
|
3104
3238
|
expiryNotifyDays: (data && data.expiryNotifyDays) || 7,
|
|
3105
3239
|
composerQuota: (data && data.composerQuota) || 'off',
|
|
3240
|
+
composerQuotaDisplay: (data && data.composerQuotaDisplay) || 'current',
|
|
3241
|
+
quotaWidget: (data && data.quotaWidget) || 'docked',
|
|
3106
3242
|
active: (data && data.active) || null,
|
|
3107
3243
|
error: null,
|
|
3108
3244
|
}
|
|
3109
|
-
} catch { return { logged: [], usage: 0, expiresAt: {}, labels: {}, expiryNotifyDays: 7, fastMode: false, composerQuota: 'off', active: null, error: 'status unavailable' } }
|
|
3245
|
+
} catch { return { logged: [], usage: 0, expiresAt: {}, labels: {}, expiryNotifyDays: 7, fastMode: false, composerQuota: 'off', composerQuotaDisplay: 'current', active: null, error: 'status unavailable' } }
|
|
3246
|
+
}
|
|
3247
|
+
|
|
3248
|
+
function currentModelProvider(props) {
|
|
3249
|
+
let session = null
|
|
3250
|
+
try {
|
|
3251
|
+
const ctx = typeof window !== 'undefined' ? window.__dshCtx : null
|
|
3252
|
+
session = (props && (props.session || props.conversation))
|
|
3253
|
+
|| (ctx && ctx.sessions && (ctx.sessions.current || ctx.sessions.active
|
|
3254
|
+
|| (typeof ctx.sessions.getCurrent === 'function' && ctx.sessions.getCurrent())))
|
|
3255
|
+
|| null
|
|
3256
|
+
} catch { /* sessions service is optional */ }
|
|
3257
|
+
const model = session && (session.model || session.modelId
|
|
3258
|
+
|| (session.header && session.header.model) || (session.state && session.state.model))
|
|
3259
|
+
if (!model) return null
|
|
3260
|
+
if (typeof model === 'object') return model.provider || null
|
|
3261
|
+
const text = String(model)
|
|
3262
|
+
return text.includes('/') ? text.split('/')[0] : null
|
|
3110
3263
|
}
|
|
3111
3264
|
|
|
3112
3265
|
function ComposerQuota(props) {
|
|
@@ -3120,11 +3273,22 @@ window.__ModuleLoader__.load({
|
|
|
3120
3273
|
fetch('/dsh-subscriptions/analytics', { cache: 'no-store' })
|
|
3121
3274
|
.then((res) => res.json())
|
|
3122
3275
|
.catch(() => ({})),
|
|
3123
|
-
]).then(([r, analyticsPayload]) => {
|
|
3276
|
+
]).then(async ([r, analyticsPayload]) => {
|
|
3124
3277
|
if (!alive) return
|
|
3125
3278
|
const mode = r.composerQuota || 'off'
|
|
3126
|
-
const
|
|
3127
|
-
|
|
3279
|
+
const current = currentModelProvider(props)
|
|
3280
|
+
let a = r.active
|
|
3281
|
+
if (current && (!a || a.provider !== current)) {
|
|
3282
|
+
const cfg = await fetch('/dsh-subscriptions/config', { cache: 'no-store' })
|
|
3283
|
+
.then((res) => res.json())
|
|
3284
|
+
.catch(() => null)
|
|
3285
|
+
const rows = (cfg && cfg.accounts) || []
|
|
3286
|
+
a = rows.find((row) => row && row.provider === current && row.usagePercent != null)
|
|
3287
|
+
|| rows.find((row) => row && row.provider === current)
|
|
3288
|
+
|| null
|
|
3289
|
+
}
|
|
3290
|
+
const hidden = r.composerQuotaDisplay === 'hidden'
|
|
3291
|
+
if (mode !== 'off' && !hidden && a && a.provider && a.provider !== 'ollama' && a.usagePercent != null) {
|
|
3128
3292
|
const remaining = Math.max(0, 100 - a.usagePercent)
|
|
3129
3293
|
const forecast = (analyticsPayload && analyticsPayload.analytics && analyticsPayload.analytics.forecast) || []
|
|
3130
3294
|
const row = forecast.find((f) => f.provider === a.provider && (!f.ref || !a.ref || f.ref === a.ref))
|
|
@@ -3134,9 +3298,9 @@ window.__ModuleLoader__.load({
|
|
|
3134
3298
|
? { status: 'idle' }
|
|
3135
3299
|
: { status: 'forecast', runwaySeconds: Math.max(0, Number(row.hoursToExhaustion) * 3600) }
|
|
3136
3300
|
}
|
|
3137
|
-
setState({ mode, active: a, remaining, est })
|
|
3301
|
+
setState({ mode, active: a, remaining, est, hidden })
|
|
3138
3302
|
} else {
|
|
3139
|
-
setState({ mode, active: a, remaining: null, est: null })
|
|
3303
|
+
setState({ mode, active: a, remaining: null, est: null, hidden })
|
|
3140
3304
|
}
|
|
3141
3305
|
}).catch(() => {})
|
|
3142
3306
|
}
|
|
@@ -3144,7 +3308,7 @@ window.__ModuleLoader__.load({
|
|
|
3144
3308
|
const id = setInterval(pull, 60 * 1000)
|
|
3145
3309
|
return () => { alive = false; clearInterval(id) }
|
|
3146
3310
|
}, [])
|
|
3147
|
-
if (state.mode === 'off' || !state.active || state.remaining == null) return null
|
|
3311
|
+
if (state.mode === 'off' || state.hidden || !state.active || state.remaining == null) return null
|
|
3148
3312
|
const cls = state.remaining <= 10 ? ' dsub-cqBarFull' : (state.remaining <= 30 ? ' dsub-cqBarWarn' : '')
|
|
3149
3313
|
var value = null
|
|
3150
3314
|
if (state.mode === 'percent') {
|
|
@@ -3489,6 +3653,87 @@ window.__ModuleLoader__.load({
|
|
|
3489
3653
|
)
|
|
3490
3654
|
}
|
|
3491
3655
|
|
|
3656
|
+
// #688: floating/docked quota capsule. Draggable unless docked; opens settings.
|
|
3657
|
+
function QuotaCapsule(props) {
|
|
3658
|
+
const t = (props && props.t) || ((k) => k)
|
|
3659
|
+
const [state, setState] = React.useState({ mode: 'off', active: null, remaining: null })
|
|
3660
|
+
const [pos, setPos] = React.useState({ right: 16, bottom: 16 })
|
|
3661
|
+
const drag = React.useRef(null)
|
|
3662
|
+
const suppressClick = React.useRef(false)
|
|
3663
|
+
React.useEffect(() => {
|
|
3664
|
+
let alive = true
|
|
3665
|
+
const pull = () => {
|
|
3666
|
+
refreshLoggedIn().then(async (r) => {
|
|
3667
|
+
if (!alive) return
|
|
3668
|
+
const mode = r.quotaWidget || 'docked'
|
|
3669
|
+
if (mode === 'off') { setState({ mode, active: null, remaining: null }); return }
|
|
3670
|
+
let a = r.active
|
|
3671
|
+
const current = currentModelProvider(props)
|
|
3672
|
+
if (current && (!a || a.provider !== current)) {
|
|
3673
|
+
const cfg = await fetch('/dsh-subscriptions/config', { cache: 'no-store' }).then((res) => res.json()).catch(() => null)
|
|
3674
|
+
const rows = (cfg && cfg.accounts) || []
|
|
3675
|
+
a = rows.find((row) => row && row.provider === current && row.usagePercent != null) || null
|
|
3676
|
+
}
|
|
3677
|
+
if (!a || a.provider === 'ollama' || a.usagePercent == null) { setState({ mode, active: null, remaining: null }); return }
|
|
3678
|
+
setState({ mode, active: a, remaining: Math.max(0, 100 - a.usagePercent) })
|
|
3679
|
+
}).catch(() => {})
|
|
3680
|
+
}
|
|
3681
|
+
pull()
|
|
3682
|
+
const id = setInterval(pull, 60 * 1000)
|
|
3683
|
+
return () => { alive = false; clearInterval(id) }
|
|
3684
|
+
}, [])
|
|
3685
|
+
if (state.mode === 'off' || !state.active || state.remaining == null) return null
|
|
3686
|
+
const docked = state.mode !== 'floating'
|
|
3687
|
+
const tone = state.remaining <= 10 ? ' dsub-qwFull' : (state.remaining <= 30 ? ' dsub-qwWarn' : '')
|
|
3688
|
+
const openSettings = () => {
|
|
3689
|
+
const clientCtx = props.ctx || window.__dshCtx
|
|
3690
|
+
try {
|
|
3691
|
+
const nav = (clientCtx && clientCtx.pluginNavigation) || (window.__dshCtx && window.__dshCtx.pluginNavigation)
|
|
3692
|
+
if (nav && typeof nav.openBundle === 'function') nav.openBundle(PKG)
|
|
3693
|
+
} catch { /* bestEffort */ }
|
|
3694
|
+
try {
|
|
3695
|
+
const layout = (clientCtx && clientCtx.layout) || (window.__dshCtx && window.__dshCtx.layout)
|
|
3696
|
+
if (layout && typeof layout.selectPanel === 'function') layout.selectPanel('plugins')
|
|
3697
|
+
} catch { /* bestEffort */ }
|
|
3698
|
+
}
|
|
3699
|
+
const onPointerDown = (e) => {
|
|
3700
|
+
if (docked) return
|
|
3701
|
+
drag.current = { x: e.clientX, y: e.clientY, right: pos.right, bottom: pos.bottom, moved: false }
|
|
3702
|
+
try { e.currentTarget.setPointerCapture(e.pointerId) } catch { /* optional */ }
|
|
3703
|
+
}
|
|
3704
|
+
const onPointerMove = (e) => {
|
|
3705
|
+
const d = drag.current
|
|
3706
|
+
if (!d) return
|
|
3707
|
+
const dx = e.clientX - d.x
|
|
3708
|
+
const dy = e.clientY - d.y
|
|
3709
|
+
if (Math.abs(dx) + Math.abs(dy) > 3) { d.moved = true; suppressClick.current = true }
|
|
3710
|
+
setPos({
|
|
3711
|
+
right: Math.max(4, Math.min(window.innerWidth - 40, d.right - dx)),
|
|
3712
|
+
bottom: Math.max(4, Math.min(window.innerHeight - 40, d.bottom - dy)),
|
|
3713
|
+
})
|
|
3714
|
+
}
|
|
3715
|
+
const onPointerUp = () => { drag.current = null }
|
|
3716
|
+
return h('div', {
|
|
3717
|
+
className: 'dsub-qw' + (docked ? ' dsub-qwDocked' : '') + tone,
|
|
3718
|
+
style: { right: pos.right + 'px', bottom: pos.bottom + 'px' },
|
|
3719
|
+
role: 'button',
|
|
3720
|
+
tabIndex: 0,
|
|
3721
|
+
title: (state.active.provider || 'subscription') + ' · ' + Math.round(state.remaining) + '% ' + t('subsFree'),
|
|
3722
|
+
'aria-label': 'Subscription quota ' + Math.round(state.remaining) + '%',
|
|
3723
|
+
onPointerDown,
|
|
3724
|
+
onPointerMove,
|
|
3725
|
+
onPointerUp,
|
|
3726
|
+
onPointerCancel: onPointerUp,
|
|
3727
|
+
onClick: () => { if (suppressClick.current) { suppressClick.current = false; return } openSettings() },
|
|
3728
|
+
onKeyDown: (e) => { if (e.key === 'Enter' || e.key === ' ') openSettings() },
|
|
3729
|
+
},
|
|
3730
|
+
h('span', { className: 'dsub-led ' + ledClass(state.active.usagePercent) }),
|
|
3731
|
+
h('span', { className: 'dsub-qwBrand' }, brandBadge(state.active.provider).icon + ' ' + String(state.active.provider || '').toUpperCase()),
|
|
3732
|
+
h('span', { className: 'dsub-qwBar' }, h('span', { className: 'dsub-qwBarFill', style: { width: state.remaining + '%', display: 'block' } })),
|
|
3733
|
+
h('span', { className: 'dsub-qwPct' }, Math.round(state.remaining) + '%'),
|
|
3734
|
+
)
|
|
3735
|
+
}
|
|
3736
|
+
|
|
3492
3737
|
function registerSubsPill(ctx) {
|
|
3493
3738
|
ctx.effect(() => {
|
|
3494
3739
|
ctx.slots.inject('conversation.session.header.actions', () =>
|
|
@@ -3521,6 +3766,22 @@ window.__ModuleLoader__.load({
|
|
|
3521
3766
|
}, 'dsh-subscriptions: composer quota')
|
|
3522
3767
|
}
|
|
3523
3768
|
|
|
3769
|
+
function registerQuotaCapsule(ctx) {
|
|
3770
|
+
ctx.effect(() => {
|
|
3771
|
+
ctx.slots.inject('conversation.session.header.utilities', () =>
|
|
3772
|
+
ctx.slots.register(
|
|
3773
|
+
{
|
|
3774
|
+
name: 'conversation.session.header.utilities',
|
|
3775
|
+
id: 'dsh-subscriptions-quota-capsule',
|
|
3776
|
+
order: 30,
|
|
3777
|
+
locale: NS,
|
|
3778
|
+
},
|
|
3779
|
+
() => h(ErrorBoundary, null, h(QuotaCapsule, { t, ctx })),
|
|
3780
|
+
),
|
|
3781
|
+
)
|
|
3782
|
+
}, 'dsh-subscriptions: quota capsule')
|
|
3783
|
+
}
|
|
3784
|
+
|
|
3524
3785
|
function registerSlashCommands(ctx) {
|
|
3525
3786
|
ctx.effect(() => {
|
|
3526
3787
|
const triggers = ctx.get('inputTriggers')
|
|
@@ -3555,6 +3816,7 @@ window.__ModuleLoader__.load({
|
|
|
3555
3816
|
const line = (line) => line.trim()
|
|
3556
3817
|
const sources = [
|
|
3557
3818
|
{ name: 'login', description: t('slashLogin') },
|
|
3819
|
+
{ name: 'fast', description: t('slashFast') },
|
|
3558
3820
|
{ name: 'logout', description: t('slashLogout') },
|
|
3559
3821
|
]
|
|
3560
3822
|
const disposers = sources.map((src) =>
|
|
@@ -3579,6 +3841,17 @@ window.__ModuleLoader__.load({
|
|
|
3579
3841
|
return refreshLoggedIn().then((logged) =>
|
|
3580
3842
|
({ text: 'Connected: ' + (logged.length ? logged.join(', ') : 'none') }))
|
|
3581
3843
|
}
|
|
3844
|
+
if (src.name === 'fast') {
|
|
3845
|
+
const mode = /\bstandard\b|\boff\b/.test(t2) ? 'standard' : 'fast'
|
|
3846
|
+
const sid = (_session && (_session.id || _session.sessionId || (_session.header && _session.header.id))) || 'default'
|
|
3847
|
+
return fetch('/dsh-subscriptions/speed', {
|
|
3848
|
+
method: 'POST',
|
|
3849
|
+
headers: { 'Content-Type': 'application/json' },
|
|
3850
|
+
body: JSON.stringify({ sessionId: sid, mode }),
|
|
3851
|
+
}).then((r) => r.json()).then((d) => ({
|
|
3852
|
+
text: (d && d.mode === 'fast' ? 'Codex Speed: fast' : 'Codex Speed: standard'),
|
|
3853
|
+
})).catch((e) => ({ text: 'Codex Speed: ' + String(e && e.message || e) }))
|
|
3854
|
+
}
|
|
3582
3855
|
run(src.name, t2)
|
|
3583
3856
|
return Promise.resolve('handled')
|
|
3584
3857
|
},
|
|
@@ -3607,6 +3880,7 @@ window.__ModuleLoader__.load({
|
|
|
3607
3880
|
registerSettings(ctx)
|
|
3608
3881
|
registerSubsPill(ctx)
|
|
3609
3882
|
registerComposerQuota(ctx)
|
|
3883
|
+
registerQuotaCapsule(ctx)
|
|
3610
3884
|
registerSlashCommands(ctx)
|
|
3611
3885
|
}
|
|
3612
3886
|
return module.exports
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import path from 'node:path'
|
|
3
|
+
import os from 'node:os'
|
|
4
|
+
|
|
5
|
+
export const CONFLICTING_PLUGINS = Object.freeze([
|
|
6
|
+
'dsh-plugin-subscriptions',
|
|
7
|
+
'dsh-super-subscriptions',
|
|
8
|
+
'dsh-agy-link',
|
|
9
|
+
'dsh-codex-connect',
|
|
10
|
+
'dsh-key-rotation',
|
|
11
|
+
'@goodandready/dsh-key-rotation',
|
|
12
|
+
])
|
|
13
|
+
|
|
14
|
+
let activeConflicts = []
|
|
15
|
+
|
|
16
|
+
export function detectConflicts({ dependencies = [], loaded = [] } = {}) {
|
|
17
|
+
const names = new Set([...(dependencies || []), ...(loaded || [])].filter(Boolean).map(String))
|
|
18
|
+
return CONFLICTING_PLUGINS.filter((name) => names.has(name))
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function setActiveConflicts(conflicts) {
|
|
22
|
+
activeConflicts = Array.isArray(conflicts) ? conflicts.slice() : []
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function getActiveConflicts() {
|
|
26
|
+
return activeConflicts.slice()
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function readProfilePluginNames(profileDir = process.env.DSH_PROFILE_DIR) {
|
|
30
|
+
const candidates = []
|
|
31
|
+
if (profileDir) candidates.push(profileDir)
|
|
32
|
+
try { candidates.push(process.cwd()) } catch { /* ignore cwd errors */ }
|
|
33
|
+
const home = process.env.DSH_HOME || path.join(os.homedir(), '.dsh')
|
|
34
|
+
const profile = process.env.DSH_PROFILE
|
|
35
|
+
if (profile) candidates.push(path.join(home, 'profiles', profile))
|
|
36
|
+
for (const dir of candidates) {
|
|
37
|
+
try {
|
|
38
|
+
const pkg = JSON.parse(readFileSync(path.join(dir, 'package.json'), 'utf8'))
|
|
39
|
+
const deps = Object.keys(pkg.dependencies || {})
|
|
40
|
+
const bundles = (pkg.dsh && pkg.dsh.profile && pkg.dsh.profile.bundles) || []
|
|
41
|
+
return [...deps, ...bundles].filter(Boolean)
|
|
42
|
+
} catch { /* try next candidate */ }
|
|
43
|
+
}
|
|
44
|
+
return []
|
|
45
|
+
}
|
package/lib/config-schema.js
CHANGED
|
@@ -78,6 +78,16 @@ export const Config = z.object({
|
|
|
78
78
|
.description('#91 Ollama model used for the fallback (for example qwen2.5-coder). Empty = first model from /api/tags.'),
|
|
79
79
|
hideDeprecatedModels: z.boolean().volatile().default(false)
|
|
80
80
|
.description('#94 Hide test/preview/beta/legacy model ids from the native model picker.'),
|
|
81
|
+
modelDisplayNames: z.array(z.object({ provider: z.string(), id: z.string(), name: z.string() })).volatile().default([])
|
|
82
|
+
.description('#681 Per-model display names shown in the native model picker.'),
|
|
83
|
+
hiddenModels: z.array(z.object({ provider: z.string(), id: z.string() })).volatile().default([])
|
|
84
|
+
.description('#681 Per-model visibility switches for the native model picker.'),
|
|
85
|
+
modelContextWindows: z.array(z.object({ provider: z.string(), id: z.string(), contextWindow: z.number() })).volatile().default([])
|
|
86
|
+
.description('#681 Per-model context-window override.'),
|
|
87
|
+
modelReasoningDefaults: z.array(z.object({ provider: z.string(), id: z.string(), effort: z.string() })).volatile().default([])
|
|
88
|
+
.description('#681 Per-model default reasoning effort.'),
|
|
89
|
+
modelPlans: z.array(z.object({ provider: z.string(), id: z.string(), minPlan: z.string(), plan: z.string() })).volatile().default([])
|
|
90
|
+
.description('#690 Minimum subscription plan per model, shown in the picker metadata.'),
|
|
81
91
|
codexClientId: z.string().volatile().default(''),
|
|
82
92
|
codexVerbosity: z.string().volatile().default('')
|
|
83
93
|
.description('#93 Response verbosity for Codex reasoning models: low, medium or high. Empty = protocol default.'),
|
|
@@ -85,6 +95,14 @@ export const Config = z.object({
|
|
|
85
95
|
.description('#92 Fast Mode for Codex: sends service_tier priority (1.5x speed billing tier) with every request.'),
|
|
86
96
|
composerQuota: z.string().volatile().default('off')
|
|
87
97
|
.description('#84 Composer quota indicator mode: off, percent, bar or forecast (predictive runway from a sliding window).'),
|
|
98
|
+
composerQuotaDisplay: z.string().volatile().default('current')
|
|
99
|
+
.description('#682 Status-bar quota scope: current (model provider) or hidden.'),
|
|
100
|
+
quotaWidget: z.string().volatile().default('docked')
|
|
101
|
+
.description('#688 Quota widget placement: off, floating (draggable) or docked.'),
|
|
102
|
+
rateLimitWait: z.boolean().volatile().default(true)
|
|
103
|
+
.description('#684 Report the disclosed reset to dsh-llm-retry instead of parking the account on a guess.'),
|
|
104
|
+
rateLimitMaxWaitMs: z.number().volatile().default(21600000)
|
|
105
|
+
.description('#684 Maximum reset wait reported to dsh-llm-retry (default 6h).'),
|
|
88
106
|
codexRedirectUri: z.string().volatile().default(''),
|
|
89
107
|
codexBaseUrl: z.string().volatile().default(''),
|
|
90
108
|
codexClientVersion: z.string().volatile().default('')
|
|
@@ -162,6 +180,8 @@ export const Config = z.object({
|
|
|
162
180
|
.description('#562 Remote storage backend: webdav, gist, or s3.'),
|
|
163
181
|
vaultSyncPassphrase: z.string().role('secret').default('')
|
|
164
182
|
.description('#562 Passphrase used to encrypt/decrypt the remote vault archive.'),
|
|
183
|
+
vaultSyncProviders: z.array(z.string()).volatile().default([])
|
|
184
|
+
.description('#691 Optional provider allowlist for selective vault sync. Empty means all providers.'),
|
|
165
185
|
vaultSyncIntervalHours: z.number().volatile().default(24)
|
|
166
186
|
.description('#562 Automated periodic sync interval in hours (0 disables periodic pull).'),
|
|
167
187
|
vaultSyncAutoPush: z.boolean().volatile().default(true)
|
|
@@ -192,6 +212,8 @@ export const Config = z.object({
|
|
|
192
212
|
.description('#562 S3 Secret Access Key.'),
|
|
193
213
|
customVendors: z.array(z.any()).volatile().default([])
|
|
194
214
|
.description('Declarative OpenAI-Responses-compatible providers. See README.'),
|
|
215
|
+
providerPacks: z.array(z.any()).volatile().default([])
|
|
216
|
+
.description('#694 Data-only vendor packs registered through the provider SDK.'),
|
|
195
217
|
})
|
|
196
218
|
|
|
197
219
|
export function publicConfig(cfg) {
|