dsh-opencode-go 0.1.21 → 0.1.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +128 -167
- package/README.md +126 -158
- package/THIRD_PARTY_NOTICES.md +3 -1
- package/docs/development.md +56 -6
- package/docs/fork-review-2026-09-25.md +191 -0
- package/docs/independent-package.md +2 -2
- package/docs/verification.md +154 -0
- package/lib/build-info.json +8 -1
- package/lib/client.js +412 -262
- package/lib/index.js +6763 -428
- package/lib/types/account-manager.d.ts +23 -0
- package/lib/types/account-operations.d.ts +31 -0
- package/lib/types/account-policy.d.ts +16 -0
- package/lib/types/account-recovery.d.ts +2 -0
- package/lib/types/account-selection.d.ts +30 -0
- package/lib/types/account-service.d.ts +12 -0
- package/lib/types/accounts-contract.d.ts +38 -0
- package/lib/types/accounts.d.ts +5 -0
- package/lib/types/adapter.d.ts +30 -10
- package/lib/types/call-trace.d.ts +54 -0
- package/lib/types/catalog-manager.d.ts +20 -0
- package/lib/types/catalog.d.ts +5 -3
- package/lib/types/client/accounts-controller.d.ts +6 -17
- package/lib/types/client/host-compat.d.ts +7 -0
- package/lib/types/client/locales.d.ts +9 -0
- package/lib/types/client/section-controller.d.ts +11 -46
- package/lib/types/client/staged-form.d.ts +1 -3
- package/lib/types/client/usage.d.ts +1 -1
- package/lib/types/config-contract.d.ts +69 -0
- package/lib/types/config.d.ts +12 -53
- package/lib/types/conversion/context.d.ts +5 -1
- package/lib/types/conversion/image-pool.d.ts +24 -0
- package/lib/types/conversion/replay.d.ts +1 -1
- package/lib/types/conversion/stream.d.ts +1 -1
- package/lib/types/gateway-diagnostics.d.ts +22 -0
- package/lib/types/gateway-error.d.ts +2 -0
- package/lib/types/host-settings.d.ts +11 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/model-metadata.d.ts +3 -1
- package/lib/types/models-contract.d.ts +7 -0
- package/lib/types/protocol-contract.d.ts +5 -0
- package/lib/types/protocol-policy.d.ts +4 -0
- package/lib/types/reasoning.d.ts +36 -6
- package/lib/types/request-control.d.ts +2 -0
- package/lib/types/sdk-types.d.ts +1568 -0
- package/lib/types/settings-bridge.d.ts +22 -0
- package/lib/vendor-licenses.txt +103 -0
- package/package.json +6 -2
package/lib/client.js
CHANGED
|
@@ -82,6 +82,10 @@ function parseGoModels(value) {
|
|
|
82
82
|
for (const key of ["contextWindow", "maxTokens"]) {
|
|
83
83
|
if (typeof row[key] === "number" && Number.isSafeInteger(row[key]) && row[key] > 0) model[key] = row[key];
|
|
84
84
|
}
|
|
85
|
+
if (row.reasoningBudget !== null && typeof row.reasoningBudget === "object") {
|
|
86
|
+
const { min, max } = row.reasoningBudget;
|
|
87
|
+
if (typeof min === "number" && Number.isSafeInteger(min) && min > 0 && typeof max === "number" && Number.isSafeInteger(max) && max >= min) model.reasoningBudget = { min, max };
|
|
88
|
+
}
|
|
85
89
|
if (typeof row.deprecated === "boolean") model.deprecated = row.deprecated;
|
|
86
90
|
if (typeof row.configurationMissing === "boolean") model.configurationMissing = row.configurationMissing;
|
|
87
91
|
if (validReleaseDate(row.releaseDate)) model.releaseDate = row.releaseDate;
|
|
@@ -113,9 +117,11 @@ function parseSources(value) {
|
|
|
113
117
|
throw new Error("Invalid OpenCode Go catalog source timestamp");
|
|
114
118
|
}
|
|
115
119
|
if (source.error !== void 0 && typeof source.error !== "string") throw new Error("Invalid OpenCode Go catalog source error");
|
|
120
|
+
if (source.warning !== void 0 && typeof source.warning !== "string") throw new Error("Invalid OpenCode Go catalog source warning");
|
|
116
121
|
return {
|
|
117
122
|
...source.updatedAt === void 0 ? {} : { updatedAt: source.updatedAt },
|
|
118
|
-
...source.error === void 0 ? {} : { error: source.error }
|
|
123
|
+
...source.error === void 0 ? {} : { error: source.error },
|
|
124
|
+
...source.warning === void 0 ? {} : { warning: source.warning }
|
|
119
125
|
};
|
|
120
126
|
};
|
|
121
127
|
return { listing: parse(sources.listing), metadata: parse(sources.metadata) };
|
|
@@ -145,10 +151,10 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]")
|
|
|
145
151
|
const style = document.createElement("style");
|
|
146
152
|
style.dataset.plugin = "dsh-opencode-go";
|
|
147
153
|
style.dataset.pluginCss = id;
|
|
148
|
-
style.textContent = ".N807zW_accounts{gap:10px;margin:12px 0;display:grid}.N807zW_accountRow{border:.5px solid var(--dsw-alias-border-l2);border-radius:10px}.N807zW_accountRow[data-dragging=true]{opacity:.55}.N807zW_accountMain{grid-template-columns:16px 112px 92px minmax(0,1fr) 38px 106px 14px;align-items:center;gap:9px;padding:9px 11px;display:grid}.N807zW_accountHandle{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:grab;-webkit-user-drag:element;background:0 0;border:0;place-items:center;padding:0;display:grid}.N807zW_accountHandle:disabled{cursor:default;opacity:.5}.N807zW_accountHandle:focus-visible,.N807zW_accountToggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}.N807zW_accountName{white-space:nowrap;text-overflow:ellipsis;min-width:0;color:var(--dsw-alias-label-primary);font-size:12.5px;font-weight:600;overflow:hidden}.N807zW_accountState{min-width:0;color:var(--dsw-alias-label-tertiary);align-items:center;gap:5px;font-size:11.5px;display:inline-flex;overflow:hidden}.N807zW_accountDot{background:#39a878;border-radius:50%;flex:none;width:6px;height:6px}.N807zW_accountDot[data-off=true]{background:#d9a441}.N807zW_accountPercent{text-align:right;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);font-size:12.5px;font-weight:650}.N807zW_accountBar{background:#ffffff1a;border-radius:99px;height:12px;position:relative;overflow:hidden}.N807zW_accountBarFill{background:#39a878;border-radius:99px;position:absolute;inset:0 auto 0 0}.N807zW_accountBar[data-level=high] .N807zW_accountBarFill{background:#e0a100}.N807zW_accountBar[data-level=limited] .N807zW_accountBarFill{background:#e5484d}.N807zW_accountBarTick{background:#fff3;width:1px;position:absolute;top:0;bottom:0}.N807zW_accountReset{text-align:right;color:var(--dsw-alias-label-tertiary);font-size:11.5px}.N807zW_accountIdle{text-align:right;color:var(--dsw-alias-label-tertiary);grid-column:4/7;font-size:11.5px;line-height:1.5}.N807zW_accountToggle{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;place-items:center;padding:0;display:grid}.N807zW_accountProblems{align-items:baseline;gap:8px;padding:0 11px 9px 36px;display:flex}.N807zW_accountRetry{font:inherit;color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-size:11.5px;line-height:1.5}.N807zW_accountRetry:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.N807zW_accountHandle:active{cursor:grabbing}.N807zW_accountDetail{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:8px;padding:9px 11px 10px 36px;display:flex}.N807zW_accountDropLine{background:var(--dsw-alias-brand-primary);border-radius:2px;height:2px}.N807zW_accountUsage{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;font-size:12px;display:grid}.N807zW_accountUsage progress{accent-color:#39a878;width:100%;height:8px;margin:6px 0;display:block}.N807zW_accountUsage progress[data-level=high]{accent-color:#e0a100}.N807zW_accountUsage progress[data-level=limited]{accent-color:#e5484d}.N807zW_accountUsage .N807zW_hint{overflow-wrap:anywhere;display:block}.N807zW_accountActions{flex-wrap:wrap;gap:8px;margin-top:10px;display:flex}.N807zW_accountEditor{border:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-bg-layer-3) 25%, transparent);border-radius:10px;flex-direction:column;gap:8px;margin:0 11px 10px 36px;padding:10px 12px;display:flex}.N807zW_accountEditorHead{align-items:baseline;gap:6px;min-width:0;display:flex}.N807zW_accountEditorTitle{color:var(--dsw-alias-label-primary);flex:none;font-size:12.5px;font-weight:600;line-height:1.5}.N807zW_accountEditorFor{min-width:0;color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:11.5px;line-height:1.5}.N807zW_accountField{color:var(--dsw-alias-label-tertiary);flex-direction:column;gap:5px;font-size:11.5px;line-height:1.5;display:flex}.N807zW_accountEditorActions{align-items:center;gap:8px;margin-top:2px;display:flex}@media (width<=480px){.N807zW_accountUsage{grid-template-columns:1fr}}.N807zW_page{flex-direction:column;min-width:0;height:100%;min-height:0;display:flex;container-type:size}.N807zW_pageBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;padding:0 4px 16px 0;display:flex;overflow-y:auto}.N807zW_pageBody,.N807zW_modelList,.N807zW_modelDetails{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l3) transparent}.N807zW_pageBody::-webkit-scrollbar,.N807zW_modelList::-webkit-scrollbar,.N807zW_modelDetails::-webkit-scrollbar{width:8px;height:8px}.N807zW_pageBody::-webkit-scrollbar-track,.N807zW_modelList::-webkit-scrollbar-track,.N807zW_modelDetails::-webkit-scrollbar-track{background:0 0}.N807zW_pageBody::-webkit-scrollbar-thumb,.N807zW_modelList::-webkit-scrollbar-thumb,.N807zW_modelDetails::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);background-clip:content-box;border:2px solid #0000;border-radius:999px}.N807zW_pageBody:hover::-webkit-scrollbar-thumb,.N807zW_modelList:hover::-webkit-scrollbar-thumb,.N807zW_modelDetails:hover::-webkit-scrollbar-thumb{background:var(--dsw-alias-label-tertiary);background-clip:content-box}.N807zW_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.N807zW_field+.N807zW_field{border-top:.5px solid var(--dsw-alias-border-l2)}.N807zW_head{align-items:center;gap:8px;display:flex}.N807zW_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.N807zW_badges{align-items:center;gap:8px;display:inline-flex}.N807zW_trailing{flex:none;align-items:center;gap:8px;display:inline-flex}.N807zW_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.N807zW_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.N807zW_reset:disabled{cursor:default}.N807zW_reset:focus-visible,.N807zW_cardTrigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.N807zW_input{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.N807zW_input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px;border-color:var(--dsw-alias-brand-primary)}.N807zW_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.N807zW_inputInvalid{border-color:var(--dsw-alias-label-error);}.N807zW_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.N807zW_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}.N807zW_pageTop{flex-direction:column;gap:3px;padding:2px 0 12px;display:flex}.N807zW_title{color:var(--dsw-alias-label-primary);margin:0;font-size:15px;font-weight:600;line-height:1.4}.N807zW_intro{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:1.5}.N807zW_card,.N807zW_cardModels{border:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-bg-layer-3) 40%, transparent);border-radius:12px;padding:8px 0 10px}.N807zW_card{flex:none}.N807zW_card+.N807zW_card,.N807zW_card+.N807zW_cardModels,.N807zW_cardModels+.N807zW_card{margin-top:8px}.N807zW_cardModels{flex-direction:column;flex:1 0 auto;display:flex}.N807zW_cardFolded{flex:none}.N807zW_cardHead{align-items:center;gap:8px;min-height:24px;padding:0 14px;display:flex}.N807zW_cardTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13.5px;font-weight:600;line-height:1.5}.N807zW_cardSub{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11.5px;line-height:1.5}.N807zW_cardStamp{white-space:nowrap;color:var(--dsw-alias-label-tertiary);flex:none;font-size:11.5px;line-height:1.5}.N807zW_cardBody{flex-direction:column;gap:8px;padding:4px 14px 0;display:flex}.N807zW_cardBody>.N807zW_input{box-sizing:border-box;width:100%}.N807zW_cardModels>.N807zW_cardBody{flex:1 0 auto}.N807zW_cardNotes{flex-direction:column;gap:8px;padding:6px 14px 2px;display:flex}.N807zW_cardNotes:empty{display:none}.N807zW_cardDivider{border-top:.5px solid var(--dsw-alias-border-l2);margin:10px 14px}.N807zW_cardTrigger{width:100%;min-height:24px;font:inherit;text-align:left;color:inherit;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;margin:0;padding:0 14px;display:flex}.N807zW_cardTrigger:hover .N807zW_cardTitle{color:var(--dsw-alias-brand-primary)}.N807zW_cardHead>.N807zW_cardTrigger{padding:0}.N807zW_advancedGrid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px 18px;display:grid}.N807zW_advancedGrid .N807zW_field{padding:0}.N807zW_advancedGrid .N807zW_field+.N807zW_field{border-top:none}.N807zW_limitsEditor{flex-direction:column;flex:1 0 auto;gap:10px;padding-top:4px;display:flex}.N807zW_limitsFoot{border-top:.5px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;margin:2px -14px 0;padding:10px 14px 0;display:flex}.N807zW_limitsSummary{min-width:0;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:1;font-size:12px;line-height:1.5}.N807zW_modelMeta{align-items:baseline;gap:10px;display:flex}.N807zW_modelMeta .N807zW_limitsModelId{flex:1;min-width:0}.N807zW_releaseDate{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;font-size:11px;line-height:1.4}.N807zW_limitsModelId{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.4;display:block;overflow:hidden}.N807zW_visuallyHidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.N807zW_actions{border-top:.5px solid var(--dsw-alias-border-l2);flex-wrap:wrap;flex:none;align-items:center;gap:8px;padding:12px 0;display:flex}.N807zW_starLink{max-width:100%;color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;gap:7px;margin-left:auto;padding:6px 0;font-size:12px;line-height:1.5;text-decoration:none;display:inline-flex}.N807zW_starLink svg{flex:none}.N807zW_starLink:hover{color:var(--dsw-alias-brand-primary)}.N807zW_starLink:hover span{text-underline-offset:3px;text-decoration:underline}.N807zW_starLink:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.N807zW_failedNote{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.N807zW_slot{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.N807zW_slot svg{width:15px;height:15px}.N807zW_chevron,.N807zW_chevronOpen{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .15s}.N807zW_chevron{transform:rotate(-90deg)}.N807zW_filters{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.N807zW_filterAction{align-items:center;margin-left:auto;display:inline-flex}.N807zW_filter{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;padding:6px 9px;font-size:12px}.N807zW_filter[aria-pressed=true]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3)}.N807zW_filter span{color:var(--dsw-alias-label-tertiary);margin-left:4px}.N807zW_modelLayout{border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;flex:auto;grid-template-columns:minmax(0,45fr) minmax(0,55fr);min-height:260px;max-height:560px;display:grid;overflow:hidden}.N807zW_modelList{border-right:.5px solid var(--dsw-alias-border-l2);min-height:0;padding:4px 6px;overflow-y:auto}.N807zW_modelRow{align-items:center;gap:8px;padding-right:6px;display:flex}.N807zW_modelRow+.N807zW_modelRow{border-top:.5px solid var(--dsw-alias-border-l2)}.N807zW_modelRowSelected{background:var(--dsw-alias-bg-layer-3);border-top-color:#0000;border-radius:6px}.N807zW_modelRow>[role=switch]{flex-shrink:0}.N807zW_modelChoice{text-align:left;min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:1;align-items:baseline;padding:9px 3px 9px 6px;display:flex}.N807zW_modelRow:hover:not(.N807zW_modelRowSelected){background:color-mix(in srgb, var(--dsw-alias-bg-layer-3) 92%, var(--dsw-alias-label-primary));border-top-color:#0000;border-radius:6px}.N807zW_modelName{overflow-wrap:anywhere;flex-wrap:wrap;flex:0 auto;align-items:center;gap:5px;min-width:0;font-size:13px;display:flex}.N807zW_overrideDot{background:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;width:6px;height:6px}.N807zW_modelDetails{flex-direction:column;gap:10px;min-height:0;padding:14px;display:flex;overflow-y:auto}.N807zW_modelDetails h3{overflow-wrap:anywhere;margin:0;font-size:14px}.N807zW_modelHeading{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.N807zW_stats{flex-direction:column;gap:10px;display:flex}.N807zW_stat{flex-direction:column;gap:4px;display:flex}.N807zW_statLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}.N807zW_modelDetails .N807zW_input{box-sizing:border-box;width:100%;min-width:0;height:30px;padding:0 9px;font-size:12px}.N807zW_modalities{flex-wrap:wrap;gap:4px;display:flex}.N807zW_modality,.N807zW_modalityOff{border-radius:6px;padding:2px 7px;font-size:11px;line-height:1.5}.N807zW_modality{background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary)}.N807zW_modalityOff{border:.5px dashed var(--dsw-alias-border-l4);color:var(--dsw-alias-label-tertiary)}.N807zW_modelDetails .N807zW_reset{align-self:flex-start}.N807zW_paneFoot{color:var(--dsw-alias-label-tertiary);margin:auto 0 0;font-size:11px;line-height:1.5}.N807zW_newBadge{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:.5px solid var(--dsw-alias-border-l4);border-radius:4px;padding:2px 4px;font-size:9px}.N807zW_modelChoice:focus-visible,.N807zW_filter:focus-visible,.N807zW_cardTrigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}@container (width<=440px){.N807zW_advancedGrid{grid-template-columns:minmax(0,1fr)}.N807zW_modelLayout{flex:none;grid-template-columns:minmax(0,1fr);max-height:none}.N807zW_modelList{border-right:0;border-bottom:.5px solid var(--dsw-alias-border-l2);max-height:240px}.N807zW_modelDetails{max-height:460px}}@media (prefers-reduced-motion:reduce){.N807zW_chevron,.N807zW_chevronOpen{transition:none}}";
|
|
154
|
+
style.textContent = '.N807zW_accounts{gap:10px;margin:6px 0;padding:6px 0;display:grid}.N807zW_accountRow{border:.5px solid var(--dsw-alias-border-l2);border-radius:10px;position:relative}.N807zW_accountRow[data-dragging=true]{opacity:.55}.N807zW_accountMain{grid-template-columns:16px 112px 92px minmax(0,1fr) 38px 106px 14px;align-items:center;gap:9px;padding:9px 11px;display:grid}.N807zW_accountHandle{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);cursor:grab;-webkit-user-drag:element;background:0 0;border:0;place-items:center;padding:0;display:grid}.N807zW_accountHandle:disabled{cursor:default;opacity:.5}.N807zW_accountHandle:focus-visible,.N807zW_accountToggle:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px;border-radius:4px}.N807zW_accountName{white-space:nowrap;text-overflow:ellipsis;min-width:0;color:var(--dsw-alias-label-primary);font-size:12.5px;font-weight:600;overflow:hidden}.N807zW_accountState{min-width:0;color:var(--dsw-alias-label-tertiary);align-items:center;gap:5px;font-size:11.5px;display:inline-flex;overflow:hidden}.N807zW_accountDot{background:#39a878;border-radius:50%;flex:none;width:6px;height:6px}.N807zW_accountDot[data-off=true]{background:#d9a441}.N807zW_accountPercent{text-align:right;font-variant-numeric:tabular-nums;color:var(--dsw-alias-label-primary);font-size:12.5px;font-weight:650}.N807zW_accountBar{background:#ffffff1a;border-radius:99px;height:12px;position:relative;overflow:hidden}.N807zW_accountBarFill{background:#39a878;border-radius:99px;position:absolute;inset:0 auto 0 0}.N807zW_accountBar[data-level=high] .N807zW_accountBarFill{background:#e0a100}.N807zW_accountBar[data-level=limited] .N807zW_accountBarFill{background:#e5484d}.N807zW_accountBarTick{background:#fff3;width:1px;position:absolute;top:0;bottom:0}.N807zW_accountReset{text-align:right;color:var(--dsw-alias-label-tertiary);font-size:11.5px}.N807zW_accountIdle{text-align:right;color:var(--dsw-alias-label-tertiary);grid-column:4/7;font-size:11.5px;line-height:1.5}.N807zW_accountToggle{color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;place-items:center;padding:0;display:grid}.N807zW_accountProblems{align-items:baseline;gap:8px;padding:0 11px 9px 36px;display:flex}.N807zW_accountRetry{font:inherit;color:var(--dsw-alias-brand-primary);cursor:pointer;background:0 0;border:none;flex:none;padding:0;font-size:11.5px;line-height:1.5}.N807zW_accountRetry:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.N807zW_accountHandle:active{cursor:grabbing}.N807zW_accountDetail{border-top:.5px solid var(--dsw-alias-border-l2);flex-direction:column;gap:8px;padding:9px 11px 10px 36px;display:flex}.N807zW_accountRow:after{content:"";background:var(--dsw-alias-brand-primary);opacity:0;pointer-events:none;border-radius:2px;height:2px;position:absolute;left:0;right:0}.N807zW_accountRow[data-drop=before]:after{opacity:1;top:-6px}.N807zW_accountRow[data-drop=after]:after{opacity:1;bottom:-6px}.N807zW_accountUsage{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;font-size:12px;display:grid}.N807zW_accountUsage progress{accent-color:#39a878;width:100%;height:8px;margin:6px 0;display:block}.N807zW_accountUsage progress[data-level=high]{accent-color:#e0a100}.N807zW_accountUsage progress[data-level=limited]{accent-color:#e5484d}.N807zW_accountUsage .N807zW_hint{overflow-wrap:anywhere;display:block}.N807zW_accountActions{flex-wrap:wrap;gap:8px;margin-top:10px;display:flex}.N807zW_accountEditor{border:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-bg-layer-3) 25%, transparent);border-radius:10px;flex-direction:column;gap:8px;margin:0 11px 10px 36px;padding:10px 12px;display:flex}.N807zW_accountEditorHead{align-items:baseline;gap:6px;min-width:0;display:flex}.N807zW_accountEditorTitle{color:var(--dsw-alias-label-primary);flex:none;font-size:12.5px;font-weight:600;line-height:1.5}.N807zW_accountEditorFor{min-width:0;color:var(--dsw-alias-label-tertiary);overflow-wrap:anywhere;font-size:11.5px;line-height:1.5}.N807zW_accountField{color:var(--dsw-alias-label-tertiary);flex-direction:column;gap:5px;font-size:11.5px;line-height:1.5;display:flex}.N807zW_accountEditorActions{align-items:center;gap:8px;margin-top:2px;display:flex}@media (width<=480px){.N807zW_accountUsage{grid-template-columns:1fr}}.N807zW_page{flex-direction:column;min-width:0;height:100%;min-height:0;display:flex;container-type:size}.N807zW_pageBody{scrollbar-gutter:stable;flex-direction:column;flex:1;min-height:0;padding:0 4px 16px 0;display:flex;overflow-y:auto}.N807zW_pageBody,.N807zW_modelList,.N807zW_modelDetails{scrollbar-width:thin;scrollbar-color:var(--dsw-alias-border-l3) transparent}.N807zW_pageBody::-webkit-scrollbar,.N807zW_modelList::-webkit-scrollbar,.N807zW_modelDetails::-webkit-scrollbar{width:8px;height:8px}.N807zW_pageBody::-webkit-scrollbar-track,.N807zW_modelList::-webkit-scrollbar-track,.N807zW_modelDetails::-webkit-scrollbar-track{background:0 0}.N807zW_pageBody::-webkit-scrollbar-thumb,.N807zW_modelList::-webkit-scrollbar-thumb,.N807zW_modelDetails::-webkit-scrollbar-thumb{background:var(--dsw-alias-border-l3);background-clip:content-box;border:2px solid #0000;border-radius:999px}.N807zW_pageBody:hover::-webkit-scrollbar-thumb,.N807zW_modelList:hover::-webkit-scrollbar-thumb,.N807zW_modelDetails:hover::-webkit-scrollbar-thumb{background:var(--dsw-alias-label-tertiary);background-clip:content-box}.N807zW_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.N807zW_field+.N807zW_field{border-top:.5px solid var(--dsw-alias-border-l2)}.N807zW_head{align-items:center;gap:8px;display:flex}.N807zW_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.N807zW_badges{align-items:center;gap:8px;display:inline-flex}.N807zW_trailing{flex:none;align-items:center;gap:8px;display:inline-flex}.N807zW_reset{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:none;padding:0;font-size:12px;line-height:1.5}.N807zW_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.N807zW_reset:disabled{cursor:default}.N807zW_reset:focus-visible,.N807zW_cardTrigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.N807zW_input{border:.5px solid var(--dsw-alias-border-l4);background:var(--dsw-alias-bg-layer-3);height:34px;font:inherit;color:var(--dsw-alias-label-primary);border-radius:8px;padding:0 12px;font-size:13px;line-height:1.5}.N807zW_input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px;border-color:var(--dsw-alias-brand-primary)}.N807zW_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.N807zW_inputInvalid{border-color:var(--dsw-alias-label-error);}.N807zW_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.N807zW_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}.N807zW_pageTop{flex-direction:column;gap:3px;padding:2px 0 12px;display:flex}.N807zW_title{color:var(--dsw-alias-label-primary);margin:0;font-size:15px;font-weight:600;line-height:1.4}.N807zW_intro{color:var(--dsw-alias-label-secondary);margin:0;font-size:13px;line-height:1.5}.N807zW_card,.N807zW_cardModels{border:.5px solid var(--dsw-alias-border-l2);background:color-mix(in srgb, var(--dsw-alias-bg-layer-3) 40%, transparent);border-radius:12px;padding:8px 0 10px}.N807zW_card{flex:none}.N807zW_card+.N807zW_card,.N807zW_card+.N807zW_cardModels,.N807zW_cardModels+.N807zW_card{margin-top:8px}.N807zW_cardModels{flex-direction:column;flex:1 0 auto;display:flex}.N807zW_cardFolded{flex:none}.N807zW_cardHead{align-items:center;gap:8px;min-height:24px;padding:0 14px;display:flex}.N807zW_cardTitle{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13.5px;font-weight:600;line-height:1.5}.N807zW_cardSub{color:var(--dsw-alias-label-tertiary);flex:none;font-size:11.5px;line-height:1.5}.N807zW_cardStamp{white-space:nowrap;color:var(--dsw-alias-label-tertiary);flex:none;font-size:11.5px;line-height:1.5}.N807zW_cardBody{flex-direction:column;gap:8px;padding:4px 14px 0;display:flex}.N807zW_cardBody>.N807zW_input{box-sizing:border-box;width:100%}.N807zW_cardModels>.N807zW_cardBody{flex:1 0 auto}.N807zW_cardNotes{flex-direction:column;gap:8px;padding:6px 14px 2px;display:flex}.N807zW_cardNotes:empty{display:none}.N807zW_cardDivider{border-top:.5px solid var(--dsw-alias-border-l2);margin:10px 14px}.N807zW_cardTrigger{width:100%;min-height:24px;font:inherit;text-align:left;color:inherit;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;margin:0;padding:0 14px;display:flex}.N807zW_cardTrigger:hover .N807zW_cardTitle{color:var(--dsw-alias-brand-primary)}.N807zW_cardHead>.N807zW_cardTrigger{padding:0}.N807zW_advancedGrid{grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px 18px;display:grid}.N807zW_advancedGrid .N807zW_field{padding:0}.N807zW_advancedGrid .N807zW_field+.N807zW_field{border-top:none}.N807zW_limitsEditor{flex-direction:column;flex:1 0 auto;gap:10px;padding-top:4px;display:flex}.N807zW_limitsFoot{border-top:.5px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;margin:2px -14px 0;padding:10px 14px 0;display:flex}.N807zW_limitsSummary{min-width:0;color:var(--dsw-alias-label-tertiary);white-space:nowrap;flex:1;font-size:12px;line-height:1.5}.N807zW_modelMeta{align-items:baseline;gap:10px;display:flex}.N807zW_modelMeta .N807zW_limitsModelId{flex:1;min-width:0}.N807zW_releaseDate{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;flex:none;font-size:11px;line-height:1.4}.N807zW_limitsModelId{text-overflow:ellipsis;white-space:nowrap;color:var(--dsw-alias-label-tertiary);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.4;display:block;overflow:hidden}.N807zW_visuallyHidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.N807zW_actions{border-top:.5px solid var(--dsw-alias-border-l2);flex-wrap:wrap;flex:none;align-items:center;gap:8px;padding:12px 0;display:flex}.N807zW_starLink{max-width:100%;color:var(--dsw-alias-label-secondary);border-radius:4px;align-items:center;gap:7px;margin-left:auto;padding:6px 0;font-size:12px;line-height:1.5;text-decoration:none;display:inline-flex}.N807zW_starLink svg{flex:none}.N807zW_starLink:hover{color:var(--dsw-alias-brand-primary)}.N807zW_starLink:hover span{text-underline-offset:3px;text-decoration:underline}.N807zW_starLink:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.N807zW_failedNote{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.N807zW_slot{width:16px;height:16px;color:var(--dsw-alias-label-tertiary);flex:none;justify-content:center;align-items:center;display:inline-flex}.N807zW_slot svg{width:15px;height:15px}.N807zW_chevron,.N807zW_chevronOpen{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .15s}.N807zW_chevron{transform:rotate(-90deg)}.N807zW_filters{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.N807zW_filterAction{align-items:center;margin-left:auto;display:inline-flex}.N807zW_filter{font:inherit;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:6px;padding:6px 9px;font-size:12px}.N807zW_filter[aria-pressed=true]{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3)}.N807zW_filter span{color:var(--dsw-alias-label-tertiary);margin-left:4px}.N807zW_modelLayout{border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;flex:auto;grid-template-columns:minmax(0,45fr) minmax(0,55fr);min-height:260px;max-height:560px;display:grid;overflow:hidden}.N807zW_modelList{border-right:.5px solid var(--dsw-alias-border-l2);min-height:0;padding:4px 6px;overflow-y:auto}.N807zW_modelRow{align-items:center;gap:8px;padding-right:6px;display:flex}.N807zW_modelRow+.N807zW_modelRow{border-top:.5px solid var(--dsw-alias-border-l2)}.N807zW_modelRowSelected{background:var(--dsw-alias-bg-layer-3);border-top-color:#0000;border-radius:6px}.N807zW_modelRow>[role=switch]{flex-shrink:0}.N807zW_modelChoice{text-align:left;min-width:0;color:var(--dsw-alias-label-primary);cursor:pointer;background:0 0;border:0;border-radius:6px;flex:1;align-items:baseline;padding:9px 3px 9px 6px;display:flex}.N807zW_modelRow:hover:not(.N807zW_modelRowSelected){background:color-mix(in srgb, var(--dsw-alias-bg-layer-3) 92%, var(--dsw-alias-label-primary));border-top-color:#0000;border-radius:6px}.N807zW_modelName{overflow-wrap:anywhere;flex-wrap:wrap;flex:0 auto;align-items:center;gap:5px;min-width:0;font-size:13px;display:flex}.N807zW_overrideDot{background:var(--dsw-alias-brand-primary);border-radius:50%;flex:none;width:6px;height:6px}.N807zW_modelDetails{flex-direction:column;gap:10px;min-height:0;padding:14px;display:flex;overflow-y:auto}.N807zW_modelDetails h3{overflow-wrap:anywhere;margin:0;font-size:14px}.N807zW_modelHeading{flex-wrap:wrap;align-items:center;gap:6px;display:flex}.N807zW_stats{flex-direction:column;gap:10px;display:flex}.N807zW_stat{flex-direction:column;gap:4px;display:flex}.N807zW_statLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:1.5}.N807zW_budgetEditor{margin-top:12px;font-size:12px}.N807zW_budgetEditor summary{cursor:pointer}.N807zW_budgetInput{align-items:center;gap:8px;margin-top:4px;display:flex}.N807zW_budgetPresets{flex-wrap:wrap;gap:6px;margin-top:8px;display:flex}.N807zW_modelDetails .N807zW_input{box-sizing:border-box;width:100%;min-width:0;height:30px;padding:0 9px;font-size:12px}.N807zW_modalities{flex-wrap:wrap;gap:4px;display:flex}.N807zW_modality,.N807zW_modalityOff{border-radius:6px;padding:2px 7px;font-size:11px;line-height:1.5}.N807zW_modality{background:var(--dsw-alias-bg-layer-3);color:var(--dsw-alias-label-secondary)}.N807zW_modalityOff{border:.5px dashed var(--dsw-alias-border-l4);color:var(--dsw-alias-label-tertiary)}.N807zW_modelDetails .N807zW_reset{align-self:flex-start}.N807zW_paneFoot{color:var(--dsw-alias-label-tertiary);margin:auto 0 0;font-size:11px;line-height:1.5}.N807zW_newBadge{color:var(--dsw-alias-label-primary);background:var(--dsw-alias-bg-layer-3);border:.5px solid var(--dsw-alias-border-l4);border-radius:4px;padding:2px 4px;font-size:9px}.N807zW_modelChoice:focus-visible,.N807zW_filter:focus-visible,.N807zW_cardTrigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}@container (width<=440px){.N807zW_advancedGrid{grid-template-columns:minmax(0,1fr)}.N807zW_modelLayout{flex:none;grid-template-columns:minmax(0,1fr);max-height:none}.N807zW_modelList{border-right:0;border-bottom:.5px solid var(--dsw-alias-border-l2);max-height:240px}.N807zW_modelDetails{max-height:460px}}@media (prefers-reduced-motion:reduce){.N807zW_chevron,.N807zW_chevronOpen{transition:none}}';
|
|
149
155
|
document.head.appendChild(style);
|
|
150
156
|
}
|
|
151
|
-
var Section_default = { "accountActions": "N807zW_accountActions", "accountBar": "N807zW_accountBar", "accountBarFill": "N807zW_accountBarFill", "accountBarTick": "N807zW_accountBarTick", "accountDetail": "N807zW_accountDetail", "accountDot": "N807zW_accountDot", "
|
|
157
|
+
var Section_default = { "accountActions": "N807zW_accountActions", "accountBar": "N807zW_accountBar", "accountBarFill": "N807zW_accountBarFill", "accountBarTick": "N807zW_accountBarTick", "accountDetail": "N807zW_accountDetail", "accountDot": "N807zW_accountDot", "accountEditor": "N807zW_accountEditor", "accountEditorActions": "N807zW_accountEditorActions", "accountEditorFor": "N807zW_accountEditorFor", "accountEditorHead": "N807zW_accountEditorHead", "accountEditorTitle": "N807zW_accountEditorTitle", "accountField": "N807zW_accountField", "accountHandle": "N807zW_accountHandle", "accountIdle": "N807zW_accountIdle", "accountMain": "N807zW_accountMain", "accountName": "N807zW_accountName", "accountPercent": "N807zW_accountPercent", "accountProblems": "N807zW_accountProblems", "accountReset": "N807zW_accountReset", "accountRetry": "N807zW_accountRetry", "accountRow": "N807zW_accountRow", "accountState": "N807zW_accountState", "accountToggle": "N807zW_accountToggle", "accountUsage": "N807zW_accountUsage", "accounts": "N807zW_accounts", "actions": "N807zW_actions", "advancedGrid": "N807zW_advancedGrid", "badges": "N807zW_badges", "budgetEditor": "N807zW_budgetEditor", "budgetInput": "N807zW_budgetInput", "budgetPresets": "N807zW_budgetPresets", "card": "N807zW_card", "cardBody": "N807zW_cardBody", "cardDivider": "N807zW_cardDivider", "cardFolded": "N807zW_cardFolded", "cardHead": "N807zW_cardHead", "cardModels": "N807zW_cardModels", "cardNotes": "N807zW_cardNotes", "cardStamp": "N807zW_cardStamp", "cardSub": "N807zW_cardSub", "cardTitle": "N807zW_cardTitle", "cardTrigger": "N807zW_cardTrigger", "chevron": "N807zW_chevron", "chevronOpen": "N807zW_chevronOpen", "failedNote": "N807zW_failedNote", "field": "N807zW_field", "filter": "N807zW_filter", "filterAction": "N807zW_filterAction", "filters": "N807zW_filters", "head": "N807zW_head", "hint": "N807zW_hint", "input": "N807zW_input", "inputInvalid": "N807zW_inputInvalid N807zW_input", "intro": "N807zW_intro", "invalid": "N807zW_invalid", "label": "N807zW_label", "limitsEditor": "N807zW_limitsEditor", "limitsFoot": "N807zW_limitsFoot", "limitsModelId": "N807zW_limitsModelId", "limitsSummary": "N807zW_limitsSummary", "modalities": "N807zW_modalities", "modality": "N807zW_modality", "modalityOff": "N807zW_modalityOff", "modelChoice": "N807zW_modelChoice", "modelDetails": "N807zW_modelDetails", "modelHeading": "N807zW_modelHeading", "modelLayout": "N807zW_modelLayout", "modelList": "N807zW_modelList", "modelMeta": "N807zW_modelMeta", "modelName": "N807zW_modelName", "modelRow": "N807zW_modelRow", "modelRowSelected": "N807zW_modelRowSelected", "newBadge": "N807zW_newBadge", "overrideDot": "N807zW_overrideDot", "page": "N807zW_page", "pageBody": "N807zW_pageBody", "pageTop": "N807zW_pageTop", "paneFoot": "N807zW_paneFoot", "releaseDate": "N807zW_releaseDate", "reset": "N807zW_reset", "slot": "N807zW_slot", "starLink": "N807zW_starLink", "stat": "N807zW_stat", "statLabel": "N807zW_statLabel", "stats": "N807zW_stats", "title": "N807zW_title", "trailing": "N807zW_trailing", "visuallyHidden": "N807zW_visuallyHidden" };
|
|
152
158
|
|
|
153
159
|
// src/client/ModelEditor.tsx
|
|
154
160
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -160,7 +166,7 @@ var MODALITY_COPY = {
|
|
|
160
166
|
pdf: "modalityPdf"
|
|
161
167
|
};
|
|
162
168
|
function hasCapacityOverride(limit) {
|
|
163
|
-
return limit?.contextWindow != null || limit?.maxTokens != null;
|
|
169
|
+
return limit?.contextWindow != null || limit?.maxTokens != null || (limit?.thinkingBudgets?.length ?? 0) > 0;
|
|
164
170
|
}
|
|
165
171
|
function ModelEditor({ models, draft, modelVisibility, t, locale, disabled, visibilitySaving, filterAction, onEdit, onModelEnabled }) {
|
|
166
172
|
const [query, setQuery] = (0, import_react.useState)("");
|
|
@@ -189,7 +195,7 @@ function ModelEditor({ models, draft, modelVisibility, t, locale, disabled, visi
|
|
|
189
195
|
["deprecated", "filterDeprecated", all.filter((entry) => entry.deprecated).length]
|
|
190
196
|
];
|
|
191
197
|
const write = (id3, field, value) => {
|
|
192
|
-
const current = draft[id3] === null ? { contextWindow: null, maxTokens: null } : draft[id3] ?? {};
|
|
198
|
+
const current = draft[id3] === null ? { contextWindow: null, maxTokens: null, thinkingBudgets: null } : draft[id3] ?? {};
|
|
193
199
|
onEdit({ ...draft, [id3]: { ...current, [field]: value ?? null } });
|
|
194
200
|
};
|
|
195
201
|
const badges = (entry) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
@@ -291,6 +297,20 @@ function ModelEditor({ models, draft, modelVisibility, t, locale, disabled, visi
|
|
|
291
297
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(Modalities, { model, t })
|
|
292
298
|
] })
|
|
293
299
|
] }),
|
|
300
|
+
model.reasoningBudget ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
301
|
+
BudgetPresets,
|
|
302
|
+
{
|
|
303
|
+
model,
|
|
304
|
+
limit: draft[model.id],
|
|
305
|
+
t,
|
|
306
|
+
locale,
|
|
307
|
+
disabled,
|
|
308
|
+
onChange: (values) => {
|
|
309
|
+
write(model.id, "thinkingBudgets", values);
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
model.id
|
|
313
|
+
) : null,
|
|
294
314
|
hasCapacityOverride(draft[model.id]) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
295
315
|
"button",
|
|
296
316
|
{
|
|
@@ -374,6 +394,72 @@ function Capacity({ model, field, limit, disabled, t, locale, onChange }) {
|
|
|
374
394
|
] })
|
|
375
395
|
] });
|
|
376
396
|
}
|
|
397
|
+
function BudgetPresets({ model, limit, disabled, t, locale, onChange }) {
|
|
398
|
+
const [text, setText] = (0, import_react.useState)("");
|
|
399
|
+
const range = model.reasoningBudget;
|
|
400
|
+
const max = Math.min(range.max, (limit?.maxTokens ?? model.maxTokens ?? range.max + 1024) - 1024);
|
|
401
|
+
const values = limit?.thinkingBudgets ?? [];
|
|
402
|
+
const tokens = Number(text);
|
|
403
|
+
const valid = text.trim() !== "" && Number.isSafeInteger(tokens) && tokens >= range.min && tokens <= max;
|
|
404
|
+
const id3 = `opencode-go-thinking-budget-${encodeURIComponent(model.id)}`;
|
|
405
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("details", { className: Section_default.budgetEditor, children: [
|
|
406
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("summary", { children: t("thinkingBudgets") }),
|
|
407
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: t("thinkingBudgetsHint", { min: range.min.toLocaleString(locale), max: max.toLocaleString(locale) }) }),
|
|
408
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: Section_default.statLabel, htmlFor: id3, children: t("thinkingBudgetAddLabel", { name: model.name ?? model.id }) }),
|
|
409
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.budgetInput, children: [
|
|
410
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
411
|
+
"input",
|
|
412
|
+
{
|
|
413
|
+
id: id3,
|
|
414
|
+
className: Section_default.input,
|
|
415
|
+
type: "number",
|
|
416
|
+
step: 1,
|
|
417
|
+
min: range.min,
|
|
418
|
+
max,
|
|
419
|
+
inputMode: "numeric",
|
|
420
|
+
value: text,
|
|
421
|
+
placeholder: "4096",
|
|
422
|
+
disabled,
|
|
423
|
+
"aria-invalid": text !== "" && !valid,
|
|
424
|
+
onChange: (event) => {
|
|
425
|
+
setText(event.target.value);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
),
|
|
429
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
430
|
+
import_dsh_client_ui_primitives.Button,
|
|
431
|
+
{
|
|
432
|
+
variant: "outline",
|
|
433
|
+
size: "sm",
|
|
434
|
+
disabled: disabled || !valid || values.includes(tokens) || values.length >= 16,
|
|
435
|
+
onClick: () => {
|
|
436
|
+
onChange([...values, tokens].sort((a, b) => a - b));
|
|
437
|
+
setText("");
|
|
438
|
+
},
|
|
439
|
+
children: t("thinkingBudgetAdd")
|
|
440
|
+
}
|
|
441
|
+
)
|
|
442
|
+
] }),
|
|
443
|
+
values.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Section_default.budgetPresets, children: values.map((value) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
444
|
+
"button",
|
|
445
|
+
{
|
|
446
|
+
type: "button",
|
|
447
|
+
className: Section_default.filter,
|
|
448
|
+
disabled,
|
|
449
|
+
"aria-label": t("thinkingBudgetRemove", { value }),
|
|
450
|
+
onClick: () => {
|
|
451
|
+
const next = values.filter((tokens2) => tokens2 !== value);
|
|
452
|
+
onChange(next.length > 0 ? next : void 0);
|
|
453
|
+
},
|
|
454
|
+
children: [
|
|
455
|
+
value.toLocaleString(locale),
|
|
456
|
+
" tokens \xD7"
|
|
457
|
+
]
|
|
458
|
+
},
|
|
459
|
+
value
|
|
460
|
+
)) }) : null
|
|
461
|
+
] });
|
|
462
|
+
}
|
|
377
463
|
|
|
378
464
|
// src/client/AccountsCard.tsx
|
|
379
465
|
var import_react2 = require("react");
|
|
@@ -382,8 +468,8 @@ var import_dsh_client_ui_primitives2 = require("@deepseek-ai/dsh-client-ui-primi
|
|
|
382
468
|
|
|
383
469
|
// src/accounts.ts
|
|
384
470
|
var MAX_ACCOUNTS = 20;
|
|
385
|
-
var ACCOUNT_REF_PREFIX = "DSH_OPENCODE_GO_ACCOUNT_";
|
|
386
471
|
var DEFAULT_ACCOUNT_REF = "OPENCODE_API_KEY";
|
|
472
|
+
var ACCOUNT_REF_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
387
473
|
function accountRefOf(settings) {
|
|
388
474
|
return settings.apiKeyEnv || DEFAULT_ACCOUNT_REF;
|
|
389
475
|
}
|
|
@@ -431,6 +517,14 @@ function GripIcon() {
|
|
|
431
517
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "7.5", cy: "11.5", r: "1.3" })
|
|
432
518
|
] });
|
|
433
519
|
}
|
|
520
|
+
function slotAt(container, clientY) {
|
|
521
|
+
const rows = container.querySelectorAll("[data-account-row]");
|
|
522
|
+
for (let index = 0; index < rows.length; index++) {
|
|
523
|
+
const box = rows[index].getBoundingClientRect();
|
|
524
|
+
if (clientY < box.top + box.height / 2) return index;
|
|
525
|
+
}
|
|
526
|
+
return rows.length;
|
|
527
|
+
}
|
|
434
528
|
function AccountsCard({ state, actions, writable, t, locale }) {
|
|
435
529
|
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
436
530
|
const [details, setDetails] = (0, import_react2.useState)(null);
|
|
@@ -445,6 +539,13 @@ function AccountsCard({ state, actions, writable, t, locale }) {
|
|
|
445
539
|
const unreadable = state.entries.filter((entry) => entry.failed === true).length;
|
|
446
540
|
const preferred = state.entries.find((entry) => entry.apiKeyEnv === state.activeRef);
|
|
447
541
|
const reorderable = !disabled && total > 1;
|
|
542
|
+
const draggingFrom = dragging === null ? -1 : state.entries.findIndex((entry) => entry.apiKeyEnv === dragging);
|
|
543
|
+
const noopSlot = draggingFrom >= 0 && (dropAt === draggingFrom || dropAt === draggingFrom + 1);
|
|
544
|
+
const markAt = (index) => {
|
|
545
|
+
if (!reorderable || dropAt === null || noopSlot) return void 0;
|
|
546
|
+
if (dropAt === index) return "before";
|
|
547
|
+
return dropAt === total && index === total - 1 ? "after" : void 0;
|
|
548
|
+
};
|
|
448
549
|
const updatedAt = state.entries.reduce((latest, entry) => Math.max(latest, entry.updatedAt ?? 0), 0);
|
|
449
550
|
(0, import_react2.useEffect)(() => {
|
|
450
551
|
actions.loadAccounts();
|
|
@@ -468,6 +569,12 @@ function AccountsCard({ state, actions, writable, t, locale }) {
|
|
|
468
569
|
(0, import_react2.useEffect)(() => {
|
|
469
570
|
if (editor?.ref != null && !state.entries.some((entry) => entry.apiKeyEnv === editor.ref)) cancel();
|
|
470
571
|
}, [state.entries, editor]);
|
|
572
|
+
(0, import_react2.useEffect)(() => {
|
|
573
|
+
if (dragging !== null && !state.entries.some((entry) => entry.apiKeyEnv === dragging)) {
|
|
574
|
+
setDragging(null);
|
|
575
|
+
setDropAt(null);
|
|
576
|
+
}
|
|
577
|
+
}, [state.entries, dragging]);
|
|
471
578
|
const submit = async () => {
|
|
472
579
|
if (!editor) return;
|
|
473
580
|
const accepted = editor.kind === "add" ? await actions.addAccount(name, key) : editor.kind === "rename" ? await actions.renameAccount(editor.ref, name) : editor.kind === "key" ? await actions.replaceAccountKey(editor.ref, key) : await actions.removeAccount(editor.ref);
|
|
@@ -629,20 +736,48 @@ function AccountsCard({ state, actions, writable, t, locale }) {
|
|
|
629
736
|
state.blocked ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: Section_default.hint, children: t("accountsBlocked") }) : null,
|
|
630
737
|
state.failure ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: Section_default.failedNote, role: "alert", children: t(state.failure === "cleanup" ? "accountsCleanupFailed" : state.failure === "remove" ? "accountsRemoveKeyFailed" : state.failure === "read" ? "accountsReadFailed" : "accountsWriteFailed") }) : null,
|
|
631
738
|
!total ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: Section_default.hint, children: t("accountsEmpty") }) : null,
|
|
632
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
739
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
740
|
+
"div",
|
|
741
|
+
{
|
|
742
|
+
className: Section_default.accounts,
|
|
743
|
+
onDragEnter: (event) => {
|
|
744
|
+
if (reorderable && dragging !== null) event.preventDefault();
|
|
745
|
+
},
|
|
746
|
+
onDragOver: (event) => {
|
|
747
|
+
if (!reorderable || dragging === null) return;
|
|
748
|
+
event.preventDefault();
|
|
749
|
+
if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
|
|
750
|
+
setDropAt(slotAt(event.currentTarget, event.clientY));
|
|
751
|
+
},
|
|
752
|
+
onDrop: (event) => {
|
|
753
|
+
const source = dragging;
|
|
754
|
+
setDragging(null);
|
|
755
|
+
setDropAt(null);
|
|
756
|
+
if (source === null) return;
|
|
757
|
+
event.preventDefault();
|
|
758
|
+
const from = state.entries.findIndex((entry) => entry.apiKeyEnv === source);
|
|
759
|
+
if (from < 0) return;
|
|
760
|
+
const slot = Number.isFinite(event.clientY) ? slotAt(event.currentTarget, event.clientY) : dropAt;
|
|
761
|
+
if (slot === null) return;
|
|
762
|
+
const to = slot > from ? slot - 1 : slot;
|
|
763
|
+
if (to !== from) move(source, to);
|
|
764
|
+
},
|
|
765
|
+
onDragEnd: () => {
|
|
766
|
+
setDragging(null);
|
|
767
|
+
setDropAt(null);
|
|
768
|
+
},
|
|
769
|
+
children: state.entries.map((account, index) => {
|
|
770
|
+
const label = account.name || t("accountDefault");
|
|
771
|
+
const rolling = account.usage?.rolling;
|
|
772
|
+
const expanded = details === account.apiKeyEnv;
|
|
773
|
+
const panelId = `opencode-go-account-${index}`;
|
|
774
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
641
775
|
"div",
|
|
642
776
|
{
|
|
643
777
|
className: Section_default.accountRow,
|
|
644
778
|
"data-account-row": account.apiKeyEnv,
|
|
645
779
|
"data-dragging": dragging === account.apiKeyEnv ? "true" : void 0,
|
|
780
|
+
"data-drop": markAt(index),
|
|
646
781
|
onDragStart: (event) => {
|
|
647
782
|
if (!reorderable || event.target?.closest?.("[data-account-handle]") == null) {
|
|
648
783
|
event.preventDefault();
|
|
@@ -657,27 +792,6 @@ function AccountsCard({ state, actions, writable, t, locale }) {
|
|
|
657
792
|
}
|
|
658
793
|
setDragging(account.apiKeyEnv);
|
|
659
794
|
},
|
|
660
|
-
onDragOver: (event) => {
|
|
661
|
-
if (!reorderable || dragging === null || dragging === account.apiKeyEnv) return;
|
|
662
|
-
event.preventDefault();
|
|
663
|
-
if (event.dataTransfer) event.dataTransfer.dropEffect = "move";
|
|
664
|
-
const box = event.currentTarget.getBoundingClientRect();
|
|
665
|
-
setDropAt(event.clientY < box.top + box.height / 2 ? index : index + 1);
|
|
666
|
-
},
|
|
667
|
-
onDrop: (event) => {
|
|
668
|
-
const source = dragging;
|
|
669
|
-
const slot = dropAt;
|
|
670
|
-
setDragging(null);
|
|
671
|
-
setDropAt(null);
|
|
672
|
-
if (source === null || slot === null) return;
|
|
673
|
-
event.preventDefault();
|
|
674
|
-
const from = state.entries.findIndex((entry) => entry.apiKeyEnv === source);
|
|
675
|
-
if (from >= 0) move(source, slot > from ? slot - 1 : slot);
|
|
676
|
-
},
|
|
677
|
-
onDragEnd: () => {
|
|
678
|
-
setDragging(null);
|
|
679
|
-
setDropAt(null);
|
|
680
|
-
},
|
|
681
795
|
children: [
|
|
682
796
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: Section_default.accountMain, "data-account-main": "", children: [
|
|
683
797
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -763,11 +877,10 @@ function AccountsCard({ state, actions, writable, t, locale }) {
|
|
|
763
877
|
editor?.ref === account.apiKeyEnv ? editorForm(label) : null
|
|
764
878
|
]
|
|
765
879
|
}
|
|
766
|
-
)
|
|
767
|
-
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
] }),
|
|
880
|
+
) }, account.id);
|
|
881
|
+
})
|
|
882
|
+
}
|
|
883
|
+
),
|
|
771
884
|
editor ? editor.kind === "add" ? editorForm() : null : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
772
885
|
import_dsh_client_ui_primitives2.Button,
|
|
773
886
|
{
|
|
@@ -876,7 +989,11 @@ function ModelsBody({ models, t, locale }) {
|
|
|
876
989
|
status.error ? t("modelsSourceFailed") : t("modelsSourceCurrent"),
|
|
877
990
|
". ",
|
|
878
991
|
" ",
|
|
879
|
-
status.updatedAt === void 0 ? t("modelsSourceNeverFetched") : t("modelsSourceUpdated", { time: new Date(status.updatedAt).toLocaleString(locale) })
|
|
992
|
+
status.updatedAt === void 0 ? t("modelsSourceNeverFetched") : t("modelsSourceUpdated", { time: new Date(status.updatedAt).toLocaleString(locale) }),
|
|
993
|
+
status.warning ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
994
|
+
" ",
|
|
995
|
+
status.warning
|
|
996
|
+
] }) : null
|
|
880
997
|
] }, source);
|
|
881
998
|
}) : null;
|
|
882
999
|
if (models.status === "failed") {
|
|
@@ -894,9 +1011,12 @@ function ModelsBody({ models, t, locale }) {
|
|
|
894
1011
|
models.message ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: Section_default.hint, children: models.message }) : null,
|
|
895
1012
|
sourceStatus
|
|
896
1013
|
] });
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
1014
|
+
const warning = sources?.listing.warning ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: Section_default.failedNote, role: "alert", children: sources.listing.warning }) : null;
|
|
1015
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
|
|
1016
|
+
progress,
|
|
1017
|
+
warning,
|
|
1018
|
+
models.count === 0 ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: Section_default.hint, children: t("modelsEmpty") }) : null
|
|
1019
|
+
] });
|
|
900
1020
|
}
|
|
901
1021
|
function OpencodeGoSection(props) {
|
|
902
1022
|
const { useOpencodeGo, edit, resetField, save, discard, loadModels, setEnabled, setModelEnabled, t } = props;
|
|
@@ -958,7 +1078,7 @@ function Loaded(props) {
|
|
|
958
1078
|
resetLabel: t("reset"),
|
|
959
1079
|
disabled
|
|
960
1080
|
};
|
|
961
|
-
const advancedOverridden = state.usageDisplay.overridden || state.apiKeyEnv.overridden || state.baseURL.overridden || state.proxyURL.overridden || state.refreshMinutes.overridden || state.streamIdleTimeoutMs.overridden || state.maxImages.overridden || state.maxRequestImageBytes.overridden || state.requestImagePixelBudget.overridden || state.requestImageMaxBytes.overridden;
|
|
1081
|
+
const advancedOverridden = state.usageDisplay.overridden || state.protocolOverrides.overridden || state.apiKeyEnv.overridden || state.baseURL.overridden || state.proxyURL.overridden || state.refreshMinutes.overridden || state.streamIdleTimeoutMs.overridden || state.maxImages.overridden || state.maxRequestImageBytes.overridden || state.requestImagePixelBudget.overridden || state.requestImageMaxBytes.overridden;
|
|
962
1082
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Section_default.page, children: [
|
|
963
1083
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Section_default.pageBody, children: [
|
|
964
1084
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: Section_default.pageTop, children: [
|
|
@@ -1097,6 +1217,26 @@ function Loaded(props) {
|
|
|
1097
1217
|
}
|
|
1098
1218
|
}
|
|
1099
1219
|
),
|
|
1220
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1221
|
+
ValueField,
|
|
1222
|
+
{
|
|
1223
|
+
id: "opencode-go-protocol-overrides",
|
|
1224
|
+
label: t("protocolOverridesLabel"),
|
|
1225
|
+
hint: t("protocolOverridesHint"),
|
|
1226
|
+
field: state.protocolOverrides,
|
|
1227
|
+
options: [
|
|
1228
|
+
{ value: "auto", label: t("protocolOverridesAuto") },
|
|
1229
|
+
{ value: "openai-responses", label: t("protocolOverridesResponses") }
|
|
1230
|
+
],
|
|
1231
|
+
...fieldProps,
|
|
1232
|
+
onEdit: (text) => {
|
|
1233
|
+
props.edit("protocolOverrides", text);
|
|
1234
|
+
},
|
|
1235
|
+
onReset: () => {
|
|
1236
|
+
props.resetField("protocolOverrides");
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
),
|
|
1100
1240
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
1101
1241
|
ValueField,
|
|
1102
1242
|
{
|
|
@@ -1279,6 +1419,17 @@ function Loaded(props) {
|
|
|
1279
1419
|
// src/provider-identity.ts
|
|
1280
1420
|
var PROVIDER_ID = "dsh-opencode-go";
|
|
1281
1421
|
|
|
1422
|
+
// src/config-contract.ts
|
|
1423
|
+
var SETTINGS_NAMESPACE = "llm-opencode-go";
|
|
1424
|
+
var PROFILE_ENTRY_ID = "opencode-go";
|
|
1425
|
+
|
|
1426
|
+
// src/settings-bridge.ts
|
|
1427
|
+
function settingsWriteResult(verdict, committed) {
|
|
1428
|
+
if (verdict === true) return "applied";
|
|
1429
|
+
if (verdict === false) return "rejected";
|
|
1430
|
+
return committed() ? "applied" : "unknown";
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1282
1433
|
// src/proxy-url.ts
|
|
1283
1434
|
function assertProxyURL(raw) {
|
|
1284
1435
|
const value = raw?.trim() ?? "";
|
|
@@ -1304,19 +1455,33 @@ function assertProxyURL(raw) {
|
|
|
1304
1455
|
return url.href;
|
|
1305
1456
|
}
|
|
1306
1457
|
|
|
1458
|
+
// src/protocol-contract.ts
|
|
1459
|
+
var RESPONSES_OVERRIDE_MODEL = "deepseek-v4.1-flash";
|
|
1460
|
+
|
|
1461
|
+
// src/account-operations.ts
|
|
1462
|
+
function visibleAccountsOf(settings) {
|
|
1463
|
+
const entries = [...accountsOf(settings)];
|
|
1464
|
+
for (const operation of settings.accountOperations ?? []) {
|
|
1465
|
+
if (!entries.some((account) => account.apiKeyEnv === operation.account.apiKeyEnv)) entries.push(operation.account);
|
|
1466
|
+
}
|
|
1467
|
+
return entries;
|
|
1468
|
+
}
|
|
1469
|
+
|
|
1307
1470
|
// src/client/accounts-controller.ts
|
|
1308
|
-
function
|
|
1309
|
-
|
|
1310
|
-
const { name, code, message } = error;
|
|
1311
|
-
return /conflict/i.test(`${String(name ?? "")} ${String(code ?? "")} ${String(message ?? "")}`);
|
|
1471
|
+
function operationId() {
|
|
1472
|
+
return Array.from(crypto.getRandomValues(new Uint8Array(16)), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
1312
1473
|
}
|
|
1313
1474
|
var GoAccountsController = class {
|
|
1314
|
-
constructor(scope, ctx, readUsage, publish, blocked) {
|
|
1475
|
+
constructor(scope, ctx, readUsage, publish, blocked, execute = async (command) => {
|
|
1476
|
+
const response = await ctx.remote.opencodeGoAccounts.execute(command);
|
|
1477
|
+
return response.ok ? response.value : "unknown";
|
|
1478
|
+
}) {
|
|
1315
1479
|
this.scope = scope;
|
|
1316
1480
|
this.ctx = ctx;
|
|
1317
1481
|
this.readUsage = readUsage;
|
|
1318
1482
|
this.publish = publish;
|
|
1319
1483
|
this.blocked = blocked;
|
|
1484
|
+
this.execute = execute;
|
|
1320
1485
|
this.sync();
|
|
1321
1486
|
}
|
|
1322
1487
|
rows = /* @__PURE__ */ new Map();
|
|
@@ -1327,10 +1492,11 @@ var GoAccountsController = class {
|
|
|
1327
1492
|
identity = "";
|
|
1328
1493
|
loaded = false;
|
|
1329
1494
|
disposed = false;
|
|
1495
|
+
addition;
|
|
1330
1496
|
snapshot() {
|
|
1331
1497
|
const config = this.scope.getSnapshot().value ?? {};
|
|
1332
1498
|
return {
|
|
1333
|
-
entries:
|
|
1499
|
+
entries: visibleAccountsOf(config).map((account) => ({ ...this.rows.get(account.apiKeyEnv), ...account })),
|
|
1334
1500
|
activeRef: accountRefOf(config),
|
|
1335
1501
|
autoSwitch: config.autoSwitch === true,
|
|
1336
1502
|
busy: this.busy,
|
|
@@ -1342,7 +1508,7 @@ var GoAccountsController = class {
|
|
|
1342
1508
|
sync() {
|
|
1343
1509
|
const config = this.scope.getSnapshot().value ?? {};
|
|
1344
1510
|
const identity = JSON.stringify([
|
|
1345
|
-
|
|
1511
|
+
visibleAccountsOf(config).map((account) => [account.id, account.apiKeyEnv]).sort((left, right) => left[1] < right[1] ? -1 : left[1] > right[1] ? 1 : 0),
|
|
1346
1512
|
config.baseURL,
|
|
1347
1513
|
config.proxyURL
|
|
1348
1514
|
]);
|
|
@@ -1358,7 +1524,7 @@ var GoAccountsController = class {
|
|
|
1358
1524
|
this.epoch++;
|
|
1359
1525
|
}
|
|
1360
1526
|
invalidate(ref) {
|
|
1361
|
-
if (!
|
|
1527
|
+
if (!visibleAccountsOf(this.scope.getSnapshot().value ?? {}).some((account) => account.apiKeyEnv === ref)) return;
|
|
1362
1528
|
this.epoch++;
|
|
1363
1529
|
this.rows.delete(ref);
|
|
1364
1530
|
if (this.loaded) void this.refresh();
|
|
@@ -1366,7 +1532,7 @@ var GoAccountsController = class {
|
|
|
1366
1532
|
async refresh() {
|
|
1367
1533
|
this.loaded = true;
|
|
1368
1534
|
const epoch = ++this.epoch;
|
|
1369
|
-
const accounts = [...
|
|
1535
|
+
const accounts = [...visibleAccountsOf(this.scope.getSnapshot().value ?? {})];
|
|
1370
1536
|
this.refreshing = true;
|
|
1371
1537
|
this.publish();
|
|
1372
1538
|
try {
|
|
@@ -1434,155 +1600,36 @@ var GoAccountsController = class {
|
|
|
1434
1600
|
this.publish();
|
|
1435
1601
|
}
|
|
1436
1602
|
actions() {
|
|
1603
|
+
const command = (request) => this.execute(request).then((status) => status === "applied");
|
|
1437
1604
|
return {
|
|
1438
1605
|
loadAccounts: () => {
|
|
1439
1606
|
void this.refresh();
|
|
1440
1607
|
},
|
|
1441
|
-
addAccount: (name, key) => this.
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
return
|
|
1608
|
+
addAccount: (name, key) => this.run(async () => {
|
|
1609
|
+
if (!name.trim() || name.trim().length > 80 || !key.trim()) return false;
|
|
1610
|
+
const resumed = this.scope.getSnapshot().value?.accountOperations?.find((entry) => entry.kind === "add" && entry.account.name === name.trim());
|
|
1611
|
+
if (this.addition?.name !== name.trim()) this.addition = { name: name.trim(), id: resumed?.account.id ?? operationId() };
|
|
1612
|
+
const accepted = await command({ kind: "add", id: this.addition.id, name, key });
|
|
1613
|
+
if (accepted) this.addition = void 0;
|
|
1614
|
+
return accepted;
|
|
1448
1615
|
}),
|
|
1616
|
+
renameAccount: (ref, name) => this.run(() => command({ kind: "rename", ref, name })),
|
|
1617
|
+
removeAccount: (ref) => this.run(async () => {
|
|
1618
|
+
const accepted = await command({ kind: "remove", ref });
|
|
1619
|
+
if (!accepted) this.failure = "remove";
|
|
1620
|
+
return accepted;
|
|
1621
|
+
}),
|
|
1622
|
+
selectAccount: (ref) => this.run(() => command({ kind: "select", ref })),
|
|
1623
|
+
setAutoSwitch: (value) => this.run(() => command({ kind: "auto-switch", value })),
|
|
1449
1624
|
replaceAccountKey: (ref, key) => this.run(async () => {
|
|
1450
|
-
if (!key.trim() ||
|
|
1451
|
-
const
|
|
1452
|
-
if (
|
|
1453
|
-
|
|
1454
|
-
return true;
|
|
1625
|
+
if (!key.trim() || this.rows.get(ref)?.writable === false) return false;
|
|
1626
|
+
const accepted = await command({ kind: "replace-key", ref, key });
|
|
1627
|
+
if (accepted) this.invalidate(ref);
|
|
1628
|
+
return accepted;
|
|
1455
1629
|
}, false),
|
|
1456
|
-
moveAccount: (ref, toIndex) => this.move
|
|
1630
|
+
moveAccount: (ref, toIndex) => this.run(() => command({ kind: "move", ref, toIndex }))
|
|
1457
1631
|
};
|
|
1458
1632
|
}
|
|
1459
|
-
/**
|
|
1460
|
-
* Reorder the visible accounts and keep the preferred reference on the first row.
|
|
1461
|
-
* The adapter tries the preferred reference first and the rest in array order, so
|
|
1462
|
-
* one write is what makes top-to-bottom the real call order. A placeholder row the
|
|
1463
|
-
* settings never stored is materialized here, which its `legacy:` id admits.
|
|
1464
|
-
*/
|
|
1465
|
-
move(ref, toIndex) {
|
|
1466
|
-
return this.run(async () => {
|
|
1467
|
-
const snapshot = this.scope.getSnapshot();
|
|
1468
|
-
const entries = [...accountsOf(snapshot.value ?? {})];
|
|
1469
|
-
const from = entries.findIndex((account) => account.apiKeyEnv === ref);
|
|
1470
|
-
if (from < 0 || !Number.isInteger(toIndex) || toIndex < 0 || toIndex >= entries.length || toIndex === from) return false;
|
|
1471
|
-
const [moved] = entries.splice(from, 1);
|
|
1472
|
-
entries.splice(toIndex, 0, moved);
|
|
1473
|
-
await this.mutate([
|
|
1474
|
-
{ op: "set", path: ["accounts"], value: entries },
|
|
1475
|
-
{ op: "set", path: ["apiKeyEnv"], value: entries[0].apiKeyEnv }
|
|
1476
|
-
], snapshot.revision);
|
|
1477
|
-
const after = this.scope.getSnapshot().value;
|
|
1478
|
-
return after?.apiKeyEnv === entries[0].apiKeyEnv && after.accounts?.[toIndex]?.apiKeyEnv === ref;
|
|
1479
|
-
});
|
|
1480
|
-
}
|
|
1481
|
-
account(ref) {
|
|
1482
|
-
return accountsOf(this.scope.getSnapshot().value ?? {}).find((account) => account.apiKeyEnv === ref);
|
|
1483
|
-
}
|
|
1484
|
-
async mutate(ops, revision = this.scope.getSnapshot().revision) {
|
|
1485
|
-
await this.scope.mutate(ops, revision);
|
|
1486
|
-
}
|
|
1487
|
-
add(name, key) {
|
|
1488
|
-
return this.run(async () => {
|
|
1489
|
-
if (!name.trim() || name.trim().length > 80 || !key.trim()) return false;
|
|
1490
|
-
const id3 = Array.from(crypto.getRandomValues(new Uint8Array(16)), (byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
1491
|
-
const ref = ACCOUNT_REF_PREFIX + id3.replaceAll("-", "").toUpperCase();
|
|
1492
|
-
const account = { id: id3, name: name.trim(), apiKeyEnv: ref };
|
|
1493
|
-
const response = await this.ctx.remote.credentials.set(ref, key.trim());
|
|
1494
|
-
if (!response.ok) return false;
|
|
1495
|
-
for (let attempt = 0; attempt < 3; attempt++) {
|
|
1496
|
-
const snapshot = this.scope.getSnapshot();
|
|
1497
|
-
const existing = accountsOf(snapshot.value ?? {});
|
|
1498
|
-
if (existing.some((entry) => entry.id === id3)) return true;
|
|
1499
|
-
const configured = await this.configuredOf(existing.map((entry) => entry.apiKeyEnv));
|
|
1500
|
-
const accounts = existing.filter((entry) => !(snapshot.value?.accounts == null && !entry.name && configured.get(entry.apiKeyEnv) === false));
|
|
1501
|
-
if (accounts.length >= MAX_ACCOUNTS) break;
|
|
1502
|
-
const first = existing.length === 0 || existing.every((entry) => configured.get(entry.apiKeyEnv) === false);
|
|
1503
|
-
try {
|
|
1504
|
-
await this.mutate([
|
|
1505
|
-
{ op: "set", path: ["accounts"], value: [...accounts, account] },
|
|
1506
|
-
...first ? [{ op: "set", path: ["apiKeyEnv"], value: ref }] : []
|
|
1507
|
-
], snapshot.revision);
|
|
1508
|
-
} catch (error) {
|
|
1509
|
-
if (attempt < 2 && isSettingsConflict(error)) continue;
|
|
1510
|
-
return false;
|
|
1511
|
-
}
|
|
1512
|
-
if (this.scope.getSnapshot().value?.accounts?.some((entry) => entry.id === id3)) return true;
|
|
1513
|
-
break;
|
|
1514
|
-
}
|
|
1515
|
-
try {
|
|
1516
|
-
if (!(await this.ctx.remote.credentials.unset(ref)).ok) this.failure = "cleanup";
|
|
1517
|
-
} catch {
|
|
1518
|
-
this.failure = "cleanup";
|
|
1519
|
-
}
|
|
1520
|
-
return false;
|
|
1521
|
-
});
|
|
1522
|
-
}
|
|
1523
|
-
/** Loaded rows answer from cache; anything they do not know is described on
|
|
1524
|
-
* the spot, so a placeholder decision never races the page's first describe. */
|
|
1525
|
-
async configuredOf(refs) {
|
|
1526
|
-
const configured = /* @__PURE__ */ new Map();
|
|
1527
|
-
const unknown = refs.filter((ref) => {
|
|
1528
|
-
const known = this.rows.get(ref)?.configured;
|
|
1529
|
-
if (known === void 0) return true;
|
|
1530
|
-
configured.set(ref, known);
|
|
1531
|
-
return false;
|
|
1532
|
-
});
|
|
1533
|
-
if (unknown.length === 0) return configured;
|
|
1534
|
-
try {
|
|
1535
|
-
const described = await this.ctx.remote.credentials.describe(unknown);
|
|
1536
|
-
if (described.ok) for (const ref of unknown) configured.set(ref, described.value[ref]?.configured ?? false);
|
|
1537
|
-
} catch {
|
|
1538
|
-
}
|
|
1539
|
-
return configured;
|
|
1540
|
-
}
|
|
1541
|
-
rename(ref, name) {
|
|
1542
|
-
return this.run(async () => {
|
|
1543
|
-
if (!this.account(ref) || !name.trim() || name.trim().length > 80) return false;
|
|
1544
|
-
const accounts = accountsOf(this.scope.getSnapshot().value ?? {}).map((account) => account.apiKeyEnv === ref ? { ...account, name: name.trim() } : account);
|
|
1545
|
-
await this.mutate([{ op: "set", path: ["accounts"], value: accounts }]);
|
|
1546
|
-
return this.scope.getSnapshot().value?.accounts?.find((account) => account.apiKeyEnv === ref)?.name === name.trim();
|
|
1547
|
-
});
|
|
1548
|
-
}
|
|
1549
|
-
select(ref) {
|
|
1550
|
-
return this.run(async () => {
|
|
1551
|
-
if (!this.account(ref)) return false;
|
|
1552
|
-
await this.mutate([{ op: "set", path: ["apiKeyEnv"], value: ref }]);
|
|
1553
|
-
return accountRefOf(this.scope.getSnapshot().value ?? {}) === ref;
|
|
1554
|
-
});
|
|
1555
|
-
}
|
|
1556
|
-
remove(ref) {
|
|
1557
|
-
return this.run(async () => {
|
|
1558
|
-
if (!this.account(ref)) return false;
|
|
1559
|
-
if (ref.startsWith(ACCOUNT_REF_PREFIX)) {
|
|
1560
|
-
const described = await this.ctx.remote.credentials.describe([ref]).catch(() => void 0);
|
|
1561
|
-
if (!described?.ok || described.value[ref] === void 0) {
|
|
1562
|
-
this.failure = "remove";
|
|
1563
|
-
return false;
|
|
1564
|
-
}
|
|
1565
|
-
if (described.value[ref].configured === true) {
|
|
1566
|
-
let removed = false;
|
|
1567
|
-
try {
|
|
1568
|
-
removed = (await this.ctx.remote.credentials.unset(ref)).ok;
|
|
1569
|
-
} catch {
|
|
1570
|
-
}
|
|
1571
|
-
if (!removed) {
|
|
1572
|
-
this.failure = "remove";
|
|
1573
|
-
return false;
|
|
1574
|
-
}
|
|
1575
|
-
}
|
|
1576
|
-
}
|
|
1577
|
-
const config = this.scope.getSnapshot().value ?? {};
|
|
1578
|
-
const remaining = accountsOf(config).filter((account) => account.apiKeyEnv !== ref);
|
|
1579
|
-
await this.mutate([
|
|
1580
|
-
{ op: "set", path: ["accounts"], value: remaining },
|
|
1581
|
-
...accountRefOf(config) === ref && remaining.length ? [{ op: "set", path: ["apiKeyEnv"], value: remaining[0].apiKeyEnv }] : []
|
|
1582
|
-
]);
|
|
1583
|
-
return !this.account(ref);
|
|
1584
|
-
});
|
|
1585
|
-
}
|
|
1586
1633
|
async run(action, requiresSettings = true) {
|
|
1587
1634
|
if (this.busy || this.blocked() || requiresSettings && !this.scope.getSnapshot().writable) return false;
|
|
1588
1635
|
this.busy = true;
|
|
@@ -1701,7 +1748,7 @@ var StagedForm = class {
|
|
|
1701
1748
|
available: snapshot.status === "ready",
|
|
1702
1749
|
writable: snapshot.writable,
|
|
1703
1750
|
dirty: plan.length > 0,
|
|
1704
|
-
invalid: plan.some((item) => item.run === void 0),
|
|
1751
|
+
invalid: plan.some((item) => item.run === void 0 && item.write === void 0),
|
|
1705
1752
|
saving: this.saving,
|
|
1706
1753
|
failed: this.failed
|
|
1707
1754
|
};
|
|
@@ -1762,20 +1809,34 @@ var StagedForm = class {
|
|
|
1762
1809
|
*/
|
|
1763
1810
|
async save() {
|
|
1764
1811
|
const plan = this.plan();
|
|
1765
|
-
|
|
1766
|
-
|
|
1812
|
+
if (plan.length === 0 || this.saving || plan.some((item) => !item.write && !item.run)) return;
|
|
1813
|
+
const revision = this.snapshotOf().revision;
|
|
1767
1814
|
this.saving = true;
|
|
1768
1815
|
this.failed = false;
|
|
1769
1816
|
this.publish();
|
|
1770
1817
|
let landed = true;
|
|
1771
|
-
|
|
1818
|
+
const settings = plan.filter((item) => item.write !== void 0);
|
|
1819
|
+
const accept = (item) => {
|
|
1820
|
+
if (this.staged.get(item.field) === item.edit) this.staged.delete(item.field);
|
|
1821
|
+
};
|
|
1822
|
+
if (settings.length > 0) {
|
|
1823
|
+
const ops = settings.map(({ field, write }) => write.kind === "clear" ? { op: "unset", path: [field] } : { op: "set", path: [field], value: write.value });
|
|
1772
1824
|
try {
|
|
1773
|
-
|
|
1825
|
+
const accepted = await this.scope.mutate(ops, revision);
|
|
1826
|
+
landed = settingsWriteResult(accepted, () => settings.every((item) => item.write.kind === "clear" ? !this.stored(item.field) : sameJsonValue(this.userLayer()?.[item.field], item.write.value))) === "applied";
|
|
1827
|
+
if (landed) settings.forEach(accept);
|
|
1828
|
+
} catch {
|
|
1829
|
+
landed = false;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
if (landed) for (const item of plan.filter((item2) => item2.run !== void 0)) {
|
|
1833
|
+
try {
|
|
1834
|
+
if (await item.run()) accept(item);
|
|
1835
|
+
else landed = false;
|
|
1774
1836
|
} catch {
|
|
1775
1837
|
landed = false;
|
|
1776
1838
|
}
|
|
1777
1839
|
}
|
|
1778
|
-
if (landed) this.staged.clear();
|
|
1779
1840
|
this.saving = false;
|
|
1780
1841
|
this.failed = !landed;
|
|
1781
1842
|
this.publish();
|
|
@@ -1792,30 +1853,20 @@ var StagedForm = class {
|
|
|
1792
1853
|
const secret = this.secretSpecs.get(field);
|
|
1793
1854
|
if (secret !== void 0) {
|
|
1794
1855
|
const value = staged.text.trim();
|
|
1795
|
-
if (value !== "") plan.push({ field, run: () => secret.write(value) });
|
|
1856
|
+
if (value !== "") plan.push({ field, edit: staged, run: () => secret.write(value) });
|
|
1796
1857
|
continue;
|
|
1797
1858
|
}
|
|
1798
1859
|
const spec = this.spec(field);
|
|
1799
1860
|
if (staged.clear) {
|
|
1800
|
-
if (this.stored(field)) plan.push({ field,
|
|
1861
|
+
if (this.stored(field)) plan.push({ field, edit: staged, write: { kind: "clear" }, run: void 0 });
|
|
1801
1862
|
continue;
|
|
1802
1863
|
}
|
|
1803
1864
|
if (this.unchangedDraft(field, staged)) continue;
|
|
1804
1865
|
const write = spec.parse(staged.text);
|
|
1805
|
-
|
|
1806
|
-
else if (write.kind === "clear") plan.push({ field, run: () => this.clear(field) });
|
|
1807
|
-
else plan.push({ field, run: () => this.store(field, write.value) });
|
|
1866
|
+
plan.push({ field, edit: staged, write, run: void 0 });
|
|
1808
1867
|
}
|
|
1809
1868
|
return plan;
|
|
1810
1869
|
}
|
|
1811
|
-
async clear(field) {
|
|
1812
|
-
await this.scope.unset(field);
|
|
1813
|
-
return !this.stored(field);
|
|
1814
|
-
}
|
|
1815
|
-
async store(field, value) {
|
|
1816
|
-
await this.scope.set(field, value);
|
|
1817
|
-
return sameJsonValue(this.userLayer()?.[field], value);
|
|
1818
|
-
}
|
|
1819
1870
|
stage(field, edit) {
|
|
1820
1871
|
this.staged.set(field, edit);
|
|
1821
1872
|
this.failed = false;
|
|
@@ -1871,8 +1922,7 @@ function sameJsonValue(left, right) {
|
|
|
1871
1922
|
}
|
|
1872
1923
|
|
|
1873
1924
|
// src/client/section-controller.ts
|
|
1874
|
-
var OPENCODE_GO_NS =
|
|
1875
|
-
var DEFAULT_API_KEY_REF = "OPENCODE_API_KEY";
|
|
1925
|
+
var OPENCODE_GO_NS = SETTINGS_NAMESPACE;
|
|
1876
1926
|
var API_KEY_FIELD = "apiKey";
|
|
1877
1927
|
var OpencodeGoSectionController = class {
|
|
1878
1928
|
/**
|
|
@@ -1887,10 +1937,14 @@ var OpencodeGoSectionController = class {
|
|
|
1887
1937
|
const result = await ctx.remote.opencodeGoUsage.readAccount(ref);
|
|
1888
1938
|
if (!result.ok) throw result.error;
|
|
1889
1939
|
return result.value;
|
|
1940
|
+
}, executeAccountCommand = async (command) => {
|
|
1941
|
+
const result = await ctx.remote.opencodeGoAccounts.execute(command);
|
|
1942
|
+
return result.ok ? result.value : "unknown";
|
|
1890
1943
|
}) {
|
|
1891
1944
|
this.scope = scope;
|
|
1892
1945
|
this.ctx = ctx;
|
|
1893
1946
|
this.readModels = readModels;
|
|
1947
|
+
this.executeAccountCommand = executeAccountCommand;
|
|
1894
1948
|
this.form = new StagedForm(
|
|
1895
1949
|
scope,
|
|
1896
1950
|
[
|
|
@@ -1902,6 +1956,11 @@ var OpencodeGoSectionController = class {
|
|
|
1902
1956
|
format: (value) => typeof value === "string" ? value : DEFAULT_USAGE_DISPLAY,
|
|
1903
1957
|
parse: (text) => USAGE_DISPLAY_MODES.some((mode) => mode === text) ? { kind: "set", value: text } : void 0
|
|
1904
1958
|
},
|
|
1959
|
+
{
|
|
1960
|
+
field: "protocolOverrides",
|
|
1961
|
+
format: (value) => value?.[RESPONSES_OVERRIDE_MODEL] ?? "auto",
|
|
1962
|
+
parse: (text) => text === "auto" || text === "openai-responses" ? { kind: "set", value: { [RESPONSES_OVERRIDE_MODEL]: text === "auto" ? null : text } } : void 0
|
|
1963
|
+
},
|
|
1905
1964
|
textField("apiKeyEnv"),
|
|
1906
1965
|
textField("baseURL"),
|
|
1907
1966
|
{
|
|
@@ -1934,7 +1993,8 @@ var OpencodeGoSectionController = class {
|
|
|
1934
1993
|
() => {
|
|
1935
1994
|
this.store.set(this.projection());
|
|
1936
1995
|
},
|
|
1937
|
-
() => this.form.shell().saving || this.pickerSaving || Boolean(this.form.field(API_KEY_FIELD).text.trim())
|
|
1996
|
+
() => this.form.shell().saving || this.pickerSaving || Boolean(this.form.field(API_KEY_FIELD).text.trim()),
|
|
1997
|
+
this.executeAccountCommand
|
|
1938
1998
|
);
|
|
1939
1999
|
this.store.set(this.projection());
|
|
1940
2000
|
const networkIdentity = () => JSON.stringify([
|
|
@@ -1983,6 +2043,7 @@ var OpencodeGoSectionController = class {
|
|
|
1983
2043
|
accounts: this.accounts?.snapshot(),
|
|
1984
2044
|
enabled: this.enabled(),
|
|
1985
2045
|
usageDisplay: this.form.field("usageDisplay"),
|
|
2046
|
+
protocolOverrides: this.form.field("protocolOverrides"),
|
|
1986
2047
|
modelVisibility: this.scope.getSnapshot().value?.modelVisibility ?? {},
|
|
1987
2048
|
pickerSaving: this.pickerSaving,
|
|
1988
2049
|
pickerFailed: this.pickerFailed,
|
|
@@ -2058,8 +2119,8 @@ var OpencodeGoSectionController = class {
|
|
|
2058
2119
|
this.pickerFailed = false;
|
|
2059
2120
|
this.store.set(this.projection());
|
|
2060
2121
|
try {
|
|
2061
|
-
await this.scope.set(field, value);
|
|
2062
|
-
this.pickerFailed =
|
|
2122
|
+
const verdict = await this.scope.set(field, value);
|
|
2123
|
+
this.pickerFailed = settingsWriteResult(verdict, accepted) !== "applied";
|
|
2063
2124
|
} catch {
|
|
2064
2125
|
this.pickerFailed = true;
|
|
2065
2126
|
} finally {
|
|
@@ -2195,17 +2256,16 @@ var OpencodeGoSectionController = class {
|
|
|
2195
2256
|
return this.face;
|
|
2196
2257
|
}
|
|
2197
2258
|
/**
|
|
2198
|
-
*
|
|
2259
|
+
* Ask the account service to write the staged key, then refresh its display.
|
|
2199
2260
|
* @param value - the staged credential literal.
|
|
2200
|
-
* @returns whether the Host
|
|
2261
|
+
* @returns whether the Host confirmed the write.
|
|
2201
2262
|
*/
|
|
2202
2263
|
async writeKey(value) {
|
|
2203
2264
|
const ref = this.keyDraftRef ?? refOf(this.scope.getSnapshot());
|
|
2204
|
-
|
|
2205
|
-
if (!response.ok) return false;
|
|
2265
|
+
if (await this.executeAccountCommand({ kind: "replace-key", ref, key: value }) !== "applied") return false;
|
|
2206
2266
|
this.accounts?.invalidate(ref);
|
|
2207
2267
|
await this.readCredential();
|
|
2208
|
-
return
|
|
2268
|
+
return true;
|
|
2209
2269
|
}
|
|
2210
2270
|
};
|
|
2211
2271
|
function modelLimitsOf(value) {
|
|
@@ -2221,19 +2281,22 @@ function modelLimitsOf(value) {
|
|
|
2221
2281
|
const limit = {};
|
|
2222
2282
|
if (fields.contextWindow === null) limit.contextWindow = null;
|
|
2223
2283
|
if (fields.maxTokens === null) limit.maxTokens = null;
|
|
2284
|
+
if (fields.thinkingBudgets === null) limit.thinkingBudgets = null;
|
|
2285
|
+
if (Array.isArray(fields.thinkingBudgets) && fields.thinkingBudgets.length <= 16 && fields.thinkingBudgets.every((value2) => typeof value2 === "number" && Number.isSafeInteger(value2) && value2 > 0)) {
|
|
2286
|
+
limit.thinkingBudgets = fields.thinkingBudgets;
|
|
2287
|
+
}
|
|
2224
2288
|
if (typeof fields.contextWindow === "number" && Number.isSafeInteger(fields.contextWindow) && fields.contextWindow > 0) {
|
|
2225
2289
|
limit.contextWindow = fields.contextWindow;
|
|
2226
2290
|
}
|
|
2227
2291
|
if (typeof fields.maxTokens === "number" && Number.isSafeInteger(fields.maxTokens) && fields.maxTokens > 0) {
|
|
2228
2292
|
limit.maxTokens = fields.maxTokens;
|
|
2229
2293
|
}
|
|
2230
|
-
if (limit.contextWindow !== void 0 || limit.maxTokens !== void 0) limits[id3] = limit;
|
|
2294
|
+
if (limit.contextWindow !== void 0 || limit.maxTokens !== void 0 || limit.thinkingBudgets !== void 0) limits[id3] = limit;
|
|
2231
2295
|
}
|
|
2232
2296
|
return limits;
|
|
2233
2297
|
}
|
|
2234
2298
|
function refOf(snapshot) {
|
|
2235
|
-
|
|
2236
|
-
return declared !== void 0 && declared.length > 0 ? declared : DEFAULT_API_KEY_REF;
|
|
2299
|
+
return accountRefOf(snapshot.value ?? {});
|
|
2237
2300
|
}
|
|
2238
2301
|
|
|
2239
2302
|
// src/client/locales.ts
|
|
@@ -2252,22 +2315,22 @@ var en = {
|
|
|
2252
2315
|
accountRename: "Rename",
|
|
2253
2316
|
accountReplaceKey: "Replace key",
|
|
2254
2317
|
accountRemove: "Remove account",
|
|
2255
|
-
accountRemoveHint: "Remove \u201C{name}\u201D? If it is
|
|
2318
|
+
accountRemoveHint: "Remove \u201C{name}\u201D? If it is the current account, the next account takes over. Keys added here are deleted from the credential service; existing external references are kept.",
|
|
2256
2319
|
accountName: "Account name",
|
|
2257
2320
|
accountKeyHint: "The key is saved through the host credential service and is never returned to this page.",
|
|
2258
2321
|
accountConfirm: "Confirm",
|
|
2259
2322
|
accountCancel: "Cancel",
|
|
2260
2323
|
accountAutoSwitch: "Automatic fallback",
|
|
2261
|
-
accountAutoSwitchHint: "
|
|
2262
|
-
accountPreferredTag: "
|
|
2324
|
+
accountAutoSwitchHint: "When a quota runs out or a key is unusable, the other accounts are tried in the Settings page order before any content or tool call is emitted; once an account starts producing output, it becomes the current account.",
|
|
2325
|
+
accountPreferredTag: "Current",
|
|
2263
2326
|
accountSwitchAction: "Switch",
|
|
2264
2327
|
accountSwitchTitle: "Switch account",
|
|
2265
2328
|
accountSwitchBack: "Back to usage",
|
|
2266
2329
|
accountSwitchHint: "Later requests in this profile use this account. The consumption order stays on the Settings page.",
|
|
2267
2330
|
accountSwitchFailed: "Could not switch account. Please retry.",
|
|
2268
|
-
accountFallbackQuota: "The
|
|
2269
|
-
accountFallbackCredential: "The
|
|
2270
|
-
accountsSummary: "{count} accounts \xB7
|
|
2331
|
+
accountFallbackQuota: "The current account reached its quota; switched to",
|
|
2332
|
+
accountFallbackCredential: "The current key was unavailable or rejected; switched to",
|
|
2333
|
+
accountsSummary: "{count} accounts \xB7 Current {name}",
|
|
2271
2334
|
accountsSummaryEmpty: "No accounts yet",
|
|
2272
2335
|
accountsAvailability: "{ready}/{total} configured",
|
|
2273
2336
|
accountsAvailabilityFailed: "{ready}/{total} configured \xB7 {failed} unreadable",
|
|
@@ -2334,6 +2397,11 @@ var en = {
|
|
|
2334
2397
|
limitsModel: "Model",
|
|
2335
2398
|
limitsContext: "Context window",
|
|
2336
2399
|
limitsOutput: "Max output",
|
|
2400
|
+
thinkingBudgets: "Thinking budgets",
|
|
2401
|
+
thinkingBudgetsHint: "Add token budgets to the conversation picker, then Save. Range: {min}\u2013{max} tokens. Existing reasoning choices stay available; Default uses the service settings. The SDK may reduce a budget to leave room for the answer.",
|
|
2402
|
+
thinkingBudgetAddLabel: "New thinking budget for {name}",
|
|
2403
|
+
thinkingBudgetAdd: "Add",
|
|
2404
|
+
thinkingBudgetRemove: "Remove {value} token budget",
|
|
2337
2405
|
capacityDefault: "Default: {value} tokens",
|
|
2338
2406
|
capacityMissing: "API did not provide a value",
|
|
2339
2407
|
modalityLabel: "Input modalities",
|
|
@@ -2369,7 +2437,7 @@ var en = {
|
|
|
2369
2437
|
limitsEmpty: "Read the model list first; capacities are edited per model the gateway serves.",
|
|
2370
2438
|
limitsContextLabel: "Context window for {name}",
|
|
2371
2439
|
limitsOutputLabel: "Max output for {name}",
|
|
2372
|
-
advancedSummary: "Usage display \xB7 Credential name \xB7 Gateway URL \xB7 Refresh \xB7 Idle timeout \xB7 Image limits",
|
|
2440
|
+
advancedSummary: "Usage display \xB7 Protocol \xB7 Credential name \xB7 Gateway URL \xB7 Refresh \xB7 Idle timeout \xB7 Image limits",
|
|
2373
2441
|
advancedLabel: "Advanced settings",
|
|
2374
2442
|
advancedHint: "Usage display, credential name, gateway URL, and adapter tuning. The inherited values work as they are; change them only if you know you need to.",
|
|
2375
2443
|
usageDisplayLabel: "Usage display",
|
|
@@ -2377,6 +2445,10 @@ var en = {
|
|
|
2377
2445
|
usageDisplay_auto: "Auto (default)",
|
|
2378
2446
|
usageDisplay_always: "Always",
|
|
2379
2447
|
usageDisplay_off: "Off",
|
|
2448
|
+
protocolOverridesLabel: "DeepSeek V4.1 Flash protocol",
|
|
2449
|
+
protocolOverridesHint: "Auto follows the model catalog. Responses is experimental and applies only to DeepSeek V4.1 Flash; speed depends on the gateway. Save to apply to new requests. Choose Auto to restore catalog routing.",
|
|
2450
|
+
protocolOverridesAuto: "Auto (default)",
|
|
2451
|
+
protocolOverridesResponses: "Responses (experimental)",
|
|
2380
2452
|
apiKeyEnvLabel: "Credential reference",
|
|
2381
2453
|
apiKeyEnvHint: "The name the key is resolved from, addressed through the credentials service.",
|
|
2382
2454
|
baseURLLabel: "Gateway URL",
|
|
@@ -2421,22 +2493,22 @@ var zh = {
|
|
|
2421
2493
|
accountRename: "\u91CD\u547D\u540D",
|
|
2422
2494
|
accountReplaceKey: "\u66FF\u6362 Key",
|
|
2423
2495
|
accountRemove: "\u5220\u9664\u8D26\u53F7",
|
|
2424
|
-
accountRemoveHint: "\u5220\u9664\u201C{name}\u201D\uFF1F\u82E5\u5B83\u662F\u5F53\u524D\
|
|
2496
|
+
accountRemoveHint: "\u5220\u9664\u201C{name}\u201D\uFF1F\u82E5\u5B83\u662F\u5F53\u524D\u8D26\u53F7\uFF0C\u5C06\u4F7F\u7528\u4E0B\u4E00\u4E2A\u8D26\u53F7\u3002\u5728\u8FD9\u91CC\u6DFB\u52A0\u7684 Key \u4F1A\u4ECE\u51ED\u636E\u670D\u52A1\u5220\u9664\uFF1B\u5DF2\u6709\u5916\u90E8\u5F15\u7528\u4F1A\u4FDD\u7559\u3002",
|
|
2425
2497
|
accountName: "\u8D26\u53F7\u540D\u79F0",
|
|
2426
2498
|
accountKeyHint: "Key \u901A\u8FC7\u5BBF\u4E3B\u51ED\u636E\u670D\u52A1\u4FDD\u5B58\uFF0C\u9875\u9762\u4E0D\u4F1A\u56DE\u663E\u5DF2\u4FDD\u5B58\u7684\u5BC6\u94A5\u3002",
|
|
2427
2499
|
accountConfirm: "\u786E\u8BA4",
|
|
2428
2500
|
accountCancel: "\u53D6\u6D88",
|
|
2429
2501
|
accountAutoSwitch: "\u81EA\u52A8\u4F7F\u7528\u5907\u7528\u8D26\u53F7",
|
|
2430
|
-
accountAutoSwitchHint: "\
|
|
2431
|
-
accountPreferredTag: "\
|
|
2502
|
+
accountAutoSwitchHint: "\u989D\u5EA6\u8017\u5C3D\u6216 Key \u4E0D\u53EF\u7528\u65F6\uFF0C\u5728\u5C1A\u672A\u8F93\u51FA\u5185\u5BB9\u6216\u5DE5\u5177\u8C03\u7528\u524D\uFF0C\u6309\u8BBE\u7F6E\u9875\u7684\u8D26\u53F7\u987A\u5E8F\u5C1D\u8BD5\u5176\u4ED6\u8D26\u53F7\uFF1B\u4E00\u65E6\u67D0\u4E2A\u8D26\u53F7\u5F00\u59CB\u6B63\u5E38\u8F93\u51FA\uFF0C\u5F53\u524D\u8D26\u53F7\u5373\u5207\u6362\u4E3A\u5B83\u3002",
|
|
2503
|
+
accountPreferredTag: "\u5F53\u524D\u8D26\u53F7",
|
|
2432
2504
|
accountSwitchAction: "\u5207\u6362",
|
|
2433
2505
|
accountSwitchTitle: "\u5207\u6362\u8D26\u53F7",
|
|
2434
2506
|
accountSwitchBack: "\u8FD4\u56DE\u989D\u5EA6",
|
|
2435
2507
|
accountSwitchHint: "\u5207\u6362\u540E\uFF0C\u672C profile \u7684\u540E\u7EED\u8BF7\u6C42\u4F7F\u7528\u8BE5\u8D26\u53F7\uFF1B\u989D\u5EA6\u6D88\u8017\u987A\u5E8F\u5728\u8BBE\u7F6E\u9875\u8C03\u6574\u3002",
|
|
2436
2508
|
accountSwitchFailed: "\u8D26\u53F7\u5207\u6362\u672A\u751F\u6548\uFF0C\u8BF7\u91CD\u8BD5\u3002",
|
|
2437
|
-
accountFallbackQuota: "\
|
|
2438
|
-
accountFallbackCredential: "\
|
|
2439
|
-
accountsSummary: "{count} \u4E2A \xB7 \
|
|
2509
|
+
accountFallbackQuota: "\u5F53\u524D\u8D26\u53F7\u989D\u5EA6\u8017\u5C3D\uFF0C\u5DF2\u81EA\u52A8\u5207\u6362\u4E3A\uFF1A",
|
|
2510
|
+
accountFallbackCredential: "\u5F53\u524D Key \u4E0D\u53EF\u7528\u6216\u88AB\u62D2\u7EDD\uFF0C\u5DF2\u81EA\u52A8\u5207\u6362\u4E3A\uFF1A",
|
|
2511
|
+
accountsSummary: "{count} \u4E2A \xB7 \u5F53\u524D {name}",
|
|
2440
2512
|
accountsSummaryEmpty: "\u5C1A\u672A\u6DFB\u52A0\u8D26\u53F7",
|
|
2441
2513
|
accountsAvailability: "{ready}/{total} \u5DF2\u914D\u7F6E",
|
|
2442
2514
|
accountsAvailabilityFailed: "{ready}/{total} \u5DF2\u914D\u7F6E \xB7 {failed} \u4E2A\u8BFB\u53D6\u5931\u8D25",
|
|
@@ -2503,6 +2575,11 @@ var zh = {
|
|
|
2503
2575
|
limitsModel: "\u6A21\u578B",
|
|
2504
2576
|
limitsContext: "\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
2505
2577
|
limitsOutput: "\u6700\u5927\u8F93\u51FA",
|
|
2578
|
+
thinkingBudgets: "\u601D\u8003\u9884\u7B97",
|
|
2579
|
+
thinkingBudgetsHint: "\u6DFB\u52A0 token \u9884\u7B97\u5E76\u4FDD\u5B58\uFF0C\u5373\u53EF\u5728\u4F1A\u8BDD\u4E2D\u9009\u62E9\u3002\u8303\u56F4\uFF1A{min}\u2013{max} tokens\u3002\u4FDD\u7559\u539F\u6709\u601D\u8003\u9009\u9879\uFF1B\u201C\u9ED8\u8BA4\u201D\u4F7F\u7528\u670D\u52A1\u5546\u8BBE\u7F6E\u3002SDK \u4F1A\u6309\u5269\u4F59\u8F93\u51FA\u7A7A\u95F4\u7F29\u5C0F\u9884\u7B97\uFF0C\u4E3A\u56DE\u7B54\u7559\u51FA\u7A7A\u95F4\u3002",
|
|
2580
|
+
thinkingBudgetAddLabel: "\u4E3A {name} \u6DFB\u52A0\u601D\u8003\u9884\u7B97",
|
|
2581
|
+
thinkingBudgetAdd: "\u6DFB\u52A0",
|
|
2582
|
+
thinkingBudgetRemove: "\u79FB\u9664 {value} token \u9884\u7B97",
|
|
2506
2583
|
capacityDefault: "\u9ED8\u8BA4\uFF1A{value} tokens",
|
|
2507
2584
|
capacityMissing: "API \u672A\u63D0\u4F9B",
|
|
2508
2585
|
modalityLabel: "\u8F93\u5165\u6A21\u6001",
|
|
@@ -2538,7 +2615,7 @@ var zh = {
|
|
|
2538
2615
|
limitsEmpty: "\u8BF7\u5148\u8BFB\u53D6\u6A21\u578B\u5217\u8868\uFF1B\u5BB9\u91CF\u6309\u7F51\u5173\u63D0\u4F9B\u7684\u6A21\u578B\u9010\u4E2A\u7F16\u8F91\u3002",
|
|
2539
2616
|
limitsContextLabel: "{name} \u7684\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
2540
2617
|
limitsOutputLabel: "{name} \u7684\u6700\u5927\u8F93\u51FA",
|
|
2541
|
-
advancedSummary: "\u989D\u5EA6\u663E\u793A \xB7 \u51ED\u8BC1\u5F15\u7528\u540D \xB7 \u7F51\u5173\u5730\u5740 \xB7 \u76EE\u5F55\u5237\u65B0 \xB7 \u6D41\u7A7A\u95F2\u8D85\u65F6 \xB7 \u56FE\u7247 4 \u9879",
|
|
2618
|
+
advancedSummary: "\u989D\u5EA6\u663E\u793A \xB7 \u534F\u8BAE \xB7 \u51ED\u8BC1\u5F15\u7528\u540D \xB7 \u7F51\u5173\u5730\u5740 \xB7 \u76EE\u5F55\u5237\u65B0 \xB7 \u6D41\u7A7A\u95F2\u8D85\u65F6 \xB7 \u56FE\u7247 4 \u9879",
|
|
2542
2619
|
advancedLabel: "\u9AD8\u7EA7\u8BBE\u7F6E",
|
|
2543
2620
|
advancedHint: "\u989D\u5EA6\u663E\u793A\u3001\u51ED\u8BC1\u540D\u79F0\u3001\u7F51\u5173\u5730\u5740\u4E0E\u9002\u914D\u5668\u8C03\u4F18\u53C2\u6570\u3002\u7EE7\u627F\u6765\u7684\u53D6\u503C\u5373\u53EF\u6B63\u5E38\u4F7F\u7528\uFF0C\u6309\u9700\u4FEE\u6539\u3002",
|
|
2544
2621
|
usageDisplayLabel: "\u989D\u5EA6\u663E\u793A",
|
|
@@ -2546,6 +2623,10 @@ var zh = {
|
|
|
2546
2623
|
usageDisplay_auto: "\u81EA\u52A8\uFF08\u9ED8\u8BA4\uFF09",
|
|
2547
2624
|
usageDisplay_always: "\u5E38\u9A7B",
|
|
2548
2625
|
usageDisplay_off: "\u5173\u95ED",
|
|
2626
|
+
protocolOverridesLabel: "DeepSeek V4.1 Flash \u534F\u8BAE",
|
|
2627
|
+
protocolOverridesHint: "\u81EA\u52A8\u8DDF\u968F\u6A21\u578B\u76EE\u5F55\u3002Responses \u4E3A\u5B9E\u9A8C\u6027\u9009\u9879\uFF0C\u4EC5\u5F71\u54CD DeepSeek V4.1 Flash\uFF0C\u901F\u5EA6\u53D6\u51B3\u4E8E\u7F51\u5173\u3002\u4FDD\u5B58\u540E\u5BF9\u65B0\u8BF7\u6C42\u751F\u6548\uFF1B\u9009\u62E9\u81EA\u52A8\u53EF\u6062\u590D\u76EE\u5F55\u8DEF\u7531\u3002",
|
|
2628
|
+
protocolOverridesAuto: "\u81EA\u52A8\uFF08\u9ED8\u8BA4\uFF09",
|
|
2629
|
+
protocolOverridesResponses: "Responses\uFF08\u5B9E\u9A8C\u6027\uFF09",
|
|
2549
2630
|
apiKeyEnvLabel: "\u51ED\u8BC1\u5F15\u7528\u540D",
|
|
2550
2631
|
apiKeyEnvHint: "key \u89E3\u6790\u6240\u4F9D\u636E\u7684\u5F15\u7528\u540D\uFF0C\u7ECF\u51ED\u8BC1\u670D\u52A1\u5BFB\u5740\u3002",
|
|
2551
2632
|
baseURLLabel: "\u7F51\u5173\u5730\u5740",
|
|
@@ -2597,7 +2678,7 @@ function parseGoUsage(value) {
|
|
|
2597
2678
|
}
|
|
2598
2679
|
for (const key of ["rolling", "weekly", "monthly"]) {
|
|
2599
2680
|
const row = source[key];
|
|
2600
|
-
if (!row || row.status !== "ok" && row.status !== "rate-limited" || typeof row.percent !== "number" || !Number.isFinite(row.percent) || row.percent < 0 || typeof row.resetsAt !== "string" || !Number.isFinite(Date.parse(row.resetsAt))) {
|
|
2681
|
+
if (!row || row.status !== "ok" && row.status !== "rate-limited" || typeof row.percent !== "number" || !Number.isFinite(row.percent) || row.percent < 0 || row.percent > 100 || typeof row.resetsAt !== "string" || !Number.isFinite(Date.parse(row.resetsAt))) {
|
|
2601
2682
|
throw new Error("Invalid OpenCode Go usage response");
|
|
2602
2683
|
}
|
|
2603
2684
|
result[key] = { status: row.status, percent: row.percent, resetsAt: row.resetsAt };
|
|
@@ -2641,10 +2722,61 @@ var usageRemote = {
|
|
|
2641
2722
|
}]
|
|
2642
2723
|
};
|
|
2643
2724
|
|
|
2725
|
+
// src/accounts-contract.ts
|
|
2726
|
+
function parseAccountCommand(value) {
|
|
2727
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("Invalid account command");
|
|
2728
|
+
const row = value;
|
|
2729
|
+
const fields = {
|
|
2730
|
+
add: ["kind", "id", "name", "key"],
|
|
2731
|
+
remove: ["kind", "ref"],
|
|
2732
|
+
select: ["kind", "ref"],
|
|
2733
|
+
rename: ["kind", "ref", "name"],
|
|
2734
|
+
"replace-key": ["kind", "ref", "key"],
|
|
2735
|
+
move: ["kind", "ref", "toIndex"],
|
|
2736
|
+
"auto-switch": ["kind", "value"]
|
|
2737
|
+
};
|
|
2738
|
+
if (typeof row.kind !== "string" || !Object.hasOwn(fields, row.kind) || Object.keys(row).some((key) => !fields[row.kind].includes(key)) || fields[row.kind].some((key) => !Object.hasOwn(row, key))) throw new Error("Invalid account command");
|
|
2739
|
+
if ("ref" in row && (typeof row.ref !== "string" || !ACCOUNT_REF_PATTERN.test(row.ref))) throw new Error("Invalid account reference");
|
|
2740
|
+
if ("name" in row && (typeof row.name !== "string" || !row.name.trim() || row.name.trim().length > 80)) throw new Error("Invalid account name");
|
|
2741
|
+
if ("key" in row && (typeof row.key !== "string" || !row.key.trim())) throw new Error("Missing account credential");
|
|
2742
|
+
if (row.kind === "add" && (typeof row.id !== "string" || !/^[a-f0-9]{32}$/.test(row.id))) throw new Error("Invalid account operation ID");
|
|
2743
|
+
if (row.kind === "move" && (!Number.isInteger(row.toIndex) || row.toIndex < 0)) throw new Error("Invalid account position");
|
|
2744
|
+
if (row.kind === "auto-switch" && typeof row.value !== "boolean") throw new Error("Invalid account switch");
|
|
2745
|
+
return { ...row };
|
|
2746
|
+
}
|
|
2747
|
+
function parseResult(value) {
|
|
2748
|
+
if (value !== "applied" && value !== "rejected" && value !== "unknown") throw new Error("Invalid account command result");
|
|
2749
|
+
return value;
|
|
2750
|
+
}
|
|
2751
|
+
var commandCodec = {
|
|
2752
|
+
mode: "strict",
|
|
2753
|
+
typeSymbol: "dsh-opencode-go#AccountCommand",
|
|
2754
|
+
schema: { parse: parseAccountCommand },
|
|
2755
|
+
create: () => ({ parse: parseAccountCommand })
|
|
2756
|
+
};
|
|
2757
|
+
var resultCodec = {
|
|
2758
|
+
mode: "strict",
|
|
2759
|
+
typeSymbol: "dsh-opencode-go#AccountCommandResult",
|
|
2760
|
+
schema: { parse: parseResult },
|
|
2761
|
+
create: () => ({ parse: parseResult })
|
|
2762
|
+
};
|
|
2763
|
+
var accountsRemote = {
|
|
2764
|
+
package: "dsh-opencode-go",
|
|
2765
|
+
descriptors: [{
|
|
2766
|
+
id: "dsh-opencode-go#opencodeGoAccounts/execute",
|
|
2767
|
+
service: "opencodeGoAccounts",
|
|
2768
|
+
namespace: "opencodeGoAccounts",
|
|
2769
|
+
method: "execute",
|
|
2770
|
+
invocation: { kind: "direct" },
|
|
2771
|
+
parameters: [{ name: "command", wire: "command", source: "json", codec: commandCodec }],
|
|
2772
|
+
result: resultCodec
|
|
2773
|
+
}]
|
|
2774
|
+
};
|
|
2775
|
+
|
|
2644
2776
|
// src/remote-contract.ts
|
|
2645
2777
|
var goRemote = {
|
|
2646
2778
|
package: "dsh-opencode-go",
|
|
2647
|
-
descriptors: [...usageRemote.descriptors, ...modelsRemote.descriptors]
|
|
2779
|
+
descriptors: [...usageRemote.descriptors, ...modelsRemote.descriptors, ...accountsRemote.descriptors]
|
|
2648
2780
|
};
|
|
2649
2781
|
|
|
2650
2782
|
// src/client/UsagePill.tsx
|
|
@@ -3006,7 +3138,7 @@ function ActiveUsage({ readUsage, t, getLocale, accounts, activeRef, writable, s
|
|
|
3006
3138
|
|
|
3007
3139
|
// src/client/usage.ts
|
|
3008
3140
|
var import_dsh_client_store2 = require("@deepseek-ai/dsh-client-store");
|
|
3009
|
-
function registerUsagePill(ctx, settings) {
|
|
3141
|
+
function registerUsagePill(ctx, settings, selectAccount) {
|
|
3010
3142
|
ctx.inject(["modelDirectories", "sessions", "remote.session"], (scope) => {
|
|
3011
3143
|
scope.inject(["remote.opencodeGoUsage"], (ready) => {
|
|
3012
3144
|
const credentialChanges = (0, import_dsh_client_store2.createSnapshotStore)(0);
|
|
@@ -3032,12 +3164,7 @@ function registerUsagePill(ctx, settings) {
|
|
|
3032
3164
|
selectAccount: async (ref) => {
|
|
3033
3165
|
const snapshot = settings.getSnapshot();
|
|
3034
3166
|
if (!snapshot.writable || !accountsOf(snapshot.value ?? {}).some((account) => account.apiKeyEnv === ref)) return false;
|
|
3035
|
-
|
|
3036
|
-
await settings.mutate([{ op: "set", path: ["apiKeyEnv"], value: ref }], snapshot.revision);
|
|
3037
|
-
return accountRefOf(settings.getSnapshot().value ?? {}) === ref;
|
|
3038
|
-
} catch {
|
|
3039
|
-
return false;
|
|
3040
|
-
}
|
|
3167
|
+
return selectAccount ? selectAccount(ref).catch(() => false) : false;
|
|
3041
3168
|
},
|
|
3042
3169
|
readUsage,
|
|
3043
3170
|
getLocale: () => ready.locale.getLocale().active,
|
|
@@ -3048,6 +3175,37 @@ function registerUsagePill(ctx, settings) {
|
|
|
3048
3175
|
});
|
|
3049
3176
|
}
|
|
3050
3177
|
|
|
3178
|
+
// src/client/host-compat.ts
|
|
3179
|
+
function mountSettingsScopes(ctx, mount) {
|
|
3180
|
+
ctx.inject(["configForms", "remote.opencodeGoModels"], (child) => {
|
|
3181
|
+
const forms = child.get("configForms");
|
|
3182
|
+
mount(child, forms.get(PROFILE_ENTRY_ID));
|
|
3183
|
+
});
|
|
3184
|
+
ctx.inject(["settingsScope", "remote.opencodeGoModels"], (child) => {
|
|
3185
|
+
mount(child, child.settingsScope.bind({
|
|
3186
|
+
namespace: SETTINGS_NAMESPACE,
|
|
3187
|
+
decode: (section) => typeof section === "object" && section !== null ? section : void 0
|
|
3188
|
+
}));
|
|
3189
|
+
});
|
|
3190
|
+
}
|
|
3191
|
+
function accountCommands(ctx) {
|
|
3192
|
+
const unavailable = async () => "unknown";
|
|
3193
|
+
let execute = unavailable;
|
|
3194
|
+
ctx.inject(["remote.opencodeGoAccounts"], (ready) => {
|
|
3195
|
+
ready.effect(() => {
|
|
3196
|
+
const connected = async (command) => {
|
|
3197
|
+
const result = await ready.remote.opencodeGoAccounts.execute(command);
|
|
3198
|
+
return result.ok ? result.value : "unknown";
|
|
3199
|
+
};
|
|
3200
|
+
execute = connected;
|
|
3201
|
+
return () => {
|
|
3202
|
+
if (execute === connected) execute = unavailable;
|
|
3203
|
+
};
|
|
3204
|
+
});
|
|
3205
|
+
});
|
|
3206
|
+
return (command) => execute(command);
|
|
3207
|
+
}
|
|
3208
|
+
|
|
3051
3209
|
// src/client/index.ts
|
|
3052
3210
|
var NS = "settings.opencode-go";
|
|
3053
3211
|
var inject = ["slots", "locale", "remote", "remote.credentials", "remote.llm"];
|
|
@@ -3055,19 +3213,11 @@ function apply(ctx) {
|
|
|
3055
3213
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "llm-opencode-go: copy dictionaries");
|
|
3056
3214
|
const modelsReady = ctx.remote.$mount(goRemote);
|
|
3057
3215
|
ctx.effect(async () => await modelsReady);
|
|
3058
|
-
ctx
|
|
3059
|
-
const forms = child.get("configForms");
|
|
3060
|
-
mountSettings(child, forms.get("opencode-go"), modelsReady);
|
|
3061
|
-
});
|
|
3062
|
-
ctx.inject(["settingsScope", "remote.opencodeGoModels"], (child) => {
|
|
3063
|
-
mountSettings(child, child.settingsScope.bind({
|
|
3064
|
-
namespace: "llm-opencode-go",
|
|
3065
|
-
decode: (section) => typeof section === "object" && section !== null ? section : void 0
|
|
3066
|
-
}), modelsReady);
|
|
3067
|
-
});
|
|
3216
|
+
mountSettingsScopes(ctx, (child, scope) => mountSettings(child, scope, modelsReady));
|
|
3068
3217
|
}
|
|
3069
3218
|
function mountSettings(ctx, scope, modelsReady) {
|
|
3070
|
-
|
|
3219
|
+
const executeAccountCommand = accountCommands(ctx);
|
|
3220
|
+
registerUsagePill(ctx, scope, async (ref) => await executeAccountCommand({ kind: "select", ref }) === "applied");
|
|
3071
3221
|
let readAccount;
|
|
3072
3222
|
ctx.inject(["remote.opencodeGoUsage"], (ready) => {
|
|
3073
3223
|
readAccount = async (ref) => {
|
|
@@ -3083,7 +3233,7 @@ function mountSettings(ctx, scope, modelsReady) {
|
|
|
3083
3233
|
await modelsReady;
|
|
3084
3234
|
if (readAccount === void 0) throw new Error("OpenCode Go account usage is unavailable in this session");
|
|
3085
3235
|
return readAccount(ref);
|
|
3086
|
-
});
|
|
3236
|
+
}, executeAccountCommand);
|
|
3087
3237
|
ctx.effect(() => () => controller.dispose());
|
|
3088
3238
|
const t = ctx.locale.bind(NS);
|
|
3089
3239
|
const injected = () => ({ ...controller.inject(), t, getLocale: () => ctx.locale.getLocale().active });
|