dsh-opencode-go 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.en.md +152 -0
- package/README.md +62 -41
- package/docs/verification.md +35 -0
- package/lib/client.js +348 -20
- package/lib/index.js +81 -15
- package/lib/types/adapter.d.ts +2 -3
- package/lib/types/client/locales.d.ts +15 -0
- package/lib/types/client/section-controller.d.ts +28 -2
- package/lib/types/client/settings.d.ts +18 -0
- package/lib/types/client/staged-form.d.ts +11 -1
- package/lib/types/config.d.ts +29 -5
- package/lib/types/index.d.ts +10 -6
- package/package.json +27 -23
package/lib/client.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
window.__ModuleLoader__.load({ id: "dsh-opencode-go", factory: (require) => { var module = { exports: {} }; var exports = module.exports;
|
|
2
2
|
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
3
4
|
var __defProp = Object.defineProperty;
|
|
4
5
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
6
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __export = (target, all) => {
|
|
8
10
|
for (var name in all)
|
|
@@ -16,6 +18,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
16
18
|
}
|
|
17
19
|
return to;
|
|
18
20
|
};
|
|
21
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
22
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
23
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
24
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
25
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
26
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
27
|
+
mod
|
|
28
|
+
));
|
|
19
29
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
30
|
|
|
21
31
|
// src/client/index.ts
|
|
@@ -30,6 +40,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
30
40
|
// src/client/Section.tsx
|
|
31
41
|
var import_react = require("react");
|
|
32
42
|
var import_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
43
|
+
var primitives = __toESM(require("@deepseek-ai/dsh-client-ui-primitives"), 1);
|
|
33
44
|
|
|
34
45
|
// plugin-css:/Users/tanglei/Desktop/dsh-opencode-go/src/client/Section.module.css
|
|
35
46
|
var id = "dsh-opencode-go/Section.module.css";
|
|
@@ -37,14 +48,16 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id) + "]")
|
|
|
37
48
|
const style = document.createElement("style");
|
|
38
49
|
style.dataset.plugin = "dsh-opencode-go";
|
|
39
50
|
style.dataset.pluginCss = id;
|
|
40
|
-
style.textContent = ".BtKYva_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.BtKYva_field+.BtKYva_field{border-top:.5px solid var(--dsw-alias-border-l2)}.BtKYva_head{align-items:center;gap:8px;display:flex}.BtKYva_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.BtKYva_badges{align-items:center;gap:8px;display:inline-flex}.BtKYva_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}.BtKYva_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.BtKYva_reset:disabled{cursor:default}.BtKYva_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}.BtKYva_input:focus-visible{border-color:var(--dsw-alias-brand-primary)
|
|
51
|
+
style.textContent = ".BtKYva_field{flex-direction:column;gap:6px;padding:12px 0;display:flex}.BtKYva_field+.BtKYva_field{border-top:.5px solid var(--dsw-alias-border-l2)}.BtKYva_head{align-items:center;gap:8px;display:flex}.BtKYva_label{min-width:0;color:var(--dsw-alias-label-primary);flex:1;font-size:13px;font-weight:500;line-height:1.5}.BtKYva_badges{align-items:center;gap:8px;display:inline-flex}.BtKYva_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}.BtKYva_reset:hover:not(:disabled){color:var(--dsw-alias-label-primary)}.BtKYva_reset:disabled{cursor:default}.BtKYva_reset:focus-visible,.BtKYva_disclosure:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:3px}.BtKYva_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}.BtKYva_input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px;border-color:var(--dsw-alias-brand-primary)}.BtKYva_input:disabled{color:var(--dsw-alias-label-tertiary);cursor:default}.BtKYva_inputInvalid{border-color:var(--dsw-alias-label-error);}.BtKYva_invalid{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}.BtKYva_hint{color:var(--dsw-alias-label-tertiary);margin:0;font-size:12px;line-height:1.5}.BtKYva_intro{color:var(--dsw-alias-label-secondary);margin:0 0 8px;font-size:13px;line-height:1.5}.BtKYva_disclosure{font:inherit;text-align:left;cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;margin:0;padding:0;display:flex}.BtKYva_disclosure:hover .BtKYva_label{color:var(--dsw-alias-brand-primary)}.BtKYva_chevron,.BtKYva_chevronOpen{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none}.BtKYva_chevron{transform:rotate(-90deg)}.BtKYva_advanced{flex-direction:column;gap:4px;padding:4px 0 0 22px;display:flex}.BtKYva_advanced .BtKYva_field+.BtKYva_field{border-top:none}.BtKYva_chips{flex-wrap:wrap;gap:6px;display:flex}.BtKYva_limitsEditor{flex-direction:column;gap:10px;padding-top:4px;display:flex}.BtKYva_limitsToolbar{grid-template-columns:minmax(0,1fr) auto;align-items:end;gap:6px 10px;display:grid}.BtKYva_limitsFilterLabel{color:var(--dsw-alias-label-secondary);grid-column:1/-1;font-size:12px;font-weight:500;line-height:1.5}.BtKYva_limitsSummary{color:var(--dsw-alias-label-tertiary);white-space:nowrap;padding-bottom:8px;font-size:12px;line-height:1.5}.BtKYva_limitsScroll{overscroll-behavior-x:contain;border:.5px solid var(--dsw-alias-border-l4);border-radius:10px;overflow-x:auto}.BtKYva_limitsTable{border-collapse:collapse;table-layout:fixed;width:100%;min-width:620px}.BtKYva_limitsTable th,.BtKYva_limitsTable td{text-align:left;vertical-align:middle;padding:10px}.BtKYva_limitsTable thead th{letter-spacing:.02em;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-bg-layer-3);font-size:11px;font-weight:600}.BtKYva_limitsTable thead th:first-child{width:44%}.BtKYva_limitsTable thead th:nth-child(2),.BtKYva_limitsTable thead th:nth-child(3){width:22%}.BtKYva_limitsTable thead th:last-child{width:12%}.BtKYva_limitsTable tbody tr+tr{border-top:.5px solid var(--dsw-alias-border-l2)}.BtKYva_limitsTable tbody tr:hover{background:var(--dsw-alias-bg-layer-3)}.BtKYva_limitsTable .BtKYva_input{box-sizing:border-box;width:100%;min-width:112px}.BtKYva_limitsName{min-width:0;font-weight:400}.BtKYva_limitsId,.BtKYva_limitsModelId{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.BtKYva_limitsId{color:var(--dsw-alias-label-primary);font-size:13px;line-height:1.4}.BtKYva_limitsModelId{color:var(--dsw-alias-label-tertiary);margin-top:2px;font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px;line-height:1.4}.BtKYva_visuallyHidden{clip:rect(0, 0, 0, 0);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}@media (width<=560px){.BtKYva_limitsToolbar{grid-template-columns:1fr}.BtKYva_limitsSummary{padding-bottom:0}}.BtKYva_actions{align-items:center;gap:8px;padding-top:12px;display:flex}.BtKYva_failedNote{color:var(--dsw-alias-label-error);margin:0;font-size:12px;line-height:1.5}";
|
|
41
52
|
document.head.appendChild(style);
|
|
42
53
|
}
|
|
43
|
-
var Section_default = { "
|
|
54
|
+
var Section_default = { "limitsModelId": "BtKYva_limitsModelId", "advanced": "BtKYva_advanced", "input": "BtKYva_input", "limitsEditor": "BtKYva_limitsEditor", "hint": "BtKYva_hint", "limitsFilterLabel": "BtKYva_limitsFilterLabel", "disclosure": "BtKYva_disclosure", "chevron": "BtKYva_chevron", "actions": "BtKYva_actions", "inputInvalid": "BtKYva_inputInvalid", "intro": "BtKYva_intro", "limitsTable": "BtKYva_limitsTable", "limitsId": "BtKYva_limitsId", "failedNote": "BtKYva_failedNote", "label": "BtKYva_label", "reset": "BtKYva_reset", "invalid": "BtKYva_invalid", "limitsName": "BtKYva_limitsName", "visuallyHidden": "BtKYva_visuallyHidden", "head": "BtKYva_head", "field": "BtKYva_field", "chevronOpen": "BtKYva_chevronOpen", "chips": "BtKYva_chips", "limitsToolbar": "BtKYva_limitsToolbar", "limitsSummary": "BtKYva_limitsSummary", "limitsScroll": "BtKYva_limitsScroll", "badges": "BtKYva_badges" };
|
|
44
55
|
|
|
45
56
|
// src/client/Section.tsx
|
|
46
57
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
58
|
+
var ChevronDown = primitives.IconChevronDownOutlineRegular ?? primitives.IconChevronDownOutline14;
|
|
47
59
|
function ValueField(props) {
|
|
60
|
+
const hintId = `${props.id}-hint`;
|
|
48
61
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.field, children: [
|
|
49
62
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.head, children: [
|
|
50
63
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: Section_default.label, htmlFor: props.id, children: props.label }),
|
|
@@ -66,8 +79,11 @@ function ValueField(props) {
|
|
|
66
79
|
"input",
|
|
67
80
|
{
|
|
68
81
|
id: props.id,
|
|
82
|
+
name: props.id,
|
|
83
|
+
autoComplete: "off",
|
|
84
|
+
"aria-describedby": hintId,
|
|
69
85
|
className: props.field.invalid ? Section_default.inputInvalid : Section_default.input,
|
|
70
|
-
type: "text",
|
|
86
|
+
type: props.numeric === true ? "number" : "text",
|
|
71
87
|
...props.numeric === true ? { inputMode: "numeric" } : {},
|
|
72
88
|
...props.field.invalid ? { "aria-invalid": true } : {},
|
|
73
89
|
value: props.field.text,
|
|
@@ -77,19 +93,171 @@ function ValueField(props) {
|
|
|
77
93
|
}
|
|
78
94
|
}
|
|
79
95
|
),
|
|
80
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: props.field.invalid ? Section_default.invalid : Section_default.hint, children: props.field.invalid ? props.invalidLabel : props.hint })
|
|
96
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: hintId, className: props.field.invalid ? Section_default.invalid : Section_default.hint, children: props.field.invalid ? props.invalidLabel : props.hint })
|
|
81
97
|
] });
|
|
82
98
|
}
|
|
83
99
|
function ModelsBody({ models, t }) {
|
|
84
100
|
if (models.status === "failed") {
|
|
85
101
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
86
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.failedNote, children: t("modelsFailed") }),
|
|
102
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.failedNote, role: "alert", children: t("modelsFailed") }),
|
|
87
103
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: models.message })
|
|
88
104
|
] });
|
|
89
105
|
}
|
|
90
|
-
if (models.status !== "ready") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: t("modelsLoading") });
|
|
106
|
+
if (models.status !== "ready") return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, role: "status", "aria-live": "polite", children: t("modelsLoading") });
|
|
91
107
|
if (models.count === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: t("modelsEmpty") });
|
|
92
|
-
return
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
function LimitsTable({ models, draft, t, disabled, onEdit }) {
|
|
111
|
+
const [query, setQuery] = (0, import_react.useState)("");
|
|
112
|
+
const known = new Map((models.status === "ready" ? models.entries : []).map((model) => [model.id, model]));
|
|
113
|
+
for (const [id3, limit] of Object.entries(draft)) {
|
|
114
|
+
if (hasCapacityOverride(limit) && !known.has(id3)) known.set(id3, { id: id3 });
|
|
115
|
+
}
|
|
116
|
+
if (known.size === 0) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: t("limitsEmpty") });
|
|
117
|
+
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
118
|
+
const entries = [...known.values()].filter((model) => {
|
|
119
|
+
if (normalizedQuery === "") return true;
|
|
120
|
+
return `${model.name ?? ""} ${model.id}`.toLocaleLowerCase().includes(normalizedQuery);
|
|
121
|
+
});
|
|
122
|
+
const customizedCount = Object.values(draft).filter(hasCapacityOverride).length;
|
|
123
|
+
const write = (id3, field, value) => {
|
|
124
|
+
const current = draft[id3] === null ? { contextWindow: null, maxTokens: null } : draft[id3] ?? {};
|
|
125
|
+
const merged = { ...current };
|
|
126
|
+
merged[field] = value ?? null;
|
|
127
|
+
const next = { ...draft, [id3]: merged };
|
|
128
|
+
onEdit(next);
|
|
129
|
+
};
|
|
130
|
+
const clearModel = (id3) => {
|
|
131
|
+
const next = { ...draft };
|
|
132
|
+
next[id3] = null;
|
|
133
|
+
onEdit(next);
|
|
134
|
+
};
|
|
135
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.limitsEditor, children: [
|
|
136
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.limitsToolbar, children: [
|
|
137
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: Section_default.limitsFilterLabel, htmlFor: "opencode-go-model-filter", children: t("limitsFilterLabel") }),
|
|
138
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
139
|
+
"input",
|
|
140
|
+
{
|
|
141
|
+
id: "opencode-go-model-filter",
|
|
142
|
+
className: Section_default.input,
|
|
143
|
+
type: "search",
|
|
144
|
+
name: "model-filter",
|
|
145
|
+
autoComplete: "off",
|
|
146
|
+
spellCheck: false,
|
|
147
|
+
placeholder: t("limitsFilterPlaceholder"),
|
|
148
|
+
value: query,
|
|
149
|
+
onChange: (event) => {
|
|
150
|
+
setQuery(event.target.value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
),
|
|
154
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Section_default.limitsSummary, role: "status", "aria-live": "polite", children: t("limitsSummary", { count: customizedCount }) })
|
|
155
|
+
] }),
|
|
156
|
+
entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: t("limitsNoMatches", { query }) }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: Section_default.limitsScroll, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("table", { className: Section_default.limitsTable, children: [
|
|
157
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("caption", { className: Section_default.visuallyHidden, children: t("limitsLabel") }),
|
|
158
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
159
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: t("limitsModel") }),
|
|
160
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: t("limitsContext") }),
|
|
161
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: t("limitsOutput") }),
|
|
162
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Section_default.visuallyHidden, children: t("limitsResetModel") }) })
|
|
163
|
+
] }) }),
|
|
164
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: entries.map((model) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
165
|
+
LimitRow,
|
|
166
|
+
{
|
|
167
|
+
model,
|
|
168
|
+
limit: draft[model.id],
|
|
169
|
+
disabled,
|
|
170
|
+
t,
|
|
171
|
+
onChange: write,
|
|
172
|
+
onReset: clearModel
|
|
173
|
+
},
|
|
174
|
+
model.id
|
|
175
|
+
)) })
|
|
176
|
+
] }) }),
|
|
177
|
+
customizedCount > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: Section_default.reset, disabled, onClick: () => {
|
|
178
|
+
onEdit(Object.fromEntries(Object.keys(draft).map((id3) => [id3, null])));
|
|
179
|
+
}, children: t("limitsResetAll") }) : null
|
|
180
|
+
] });
|
|
181
|
+
}
|
|
182
|
+
function LimitRow({ model, limit, disabled, t, onChange, onReset }) {
|
|
183
|
+
const name = model.name ?? model.id;
|
|
184
|
+
const contextId = `opencode-go-context-${inputKey(model.id)}`;
|
|
185
|
+
const outputId = `opencode-go-output-${inputKey(model.id)}`;
|
|
186
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("tr", { children: [
|
|
187
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("th", { scope: "row", className: Section_default.limitsName, children: [
|
|
188
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Section_default.limitsId, translate: "no", children: name }),
|
|
189
|
+
model.name !== void 0 && model.name !== model.id ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: Section_default.limitsModelId, translate: "no", children: model.id }) : null,
|
|
190
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Section_default.hint, children: t("limitsAdvertised", { context: capacityLabel(model.contextWindow), output: capacityLabel(model.maxTokens) }) })
|
|
191
|
+
] }),
|
|
192
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
193
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: Section_default.visuallyHidden, htmlFor: contextId, children: t("limitsContextLabel", { name }) }),
|
|
194
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
195
|
+
"input",
|
|
196
|
+
{
|
|
197
|
+
id: contextId,
|
|
198
|
+
className: Section_default.input,
|
|
199
|
+
type: "number",
|
|
200
|
+
name: contextId,
|
|
201
|
+
autoComplete: "off",
|
|
202
|
+
inputMode: "numeric",
|
|
203
|
+
min: 1,
|
|
204
|
+
step: 1,
|
|
205
|
+
value: limit?.contextWindow ?? "",
|
|
206
|
+
disabled,
|
|
207
|
+
onChange: (event) => {
|
|
208
|
+
const text = event.target.value.trim();
|
|
209
|
+
if (text === "") onChange(model.id, "contextWindow", void 0);
|
|
210
|
+
else {
|
|
211
|
+
const value = positiveInteger(text);
|
|
212
|
+
if (value !== void 0) onChange(model.id, "contextWindow", value);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
)
|
|
217
|
+
] }),
|
|
218
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("td", { children: [
|
|
219
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("label", { className: Section_default.visuallyHidden, htmlFor: outputId, children: t("limitsOutputLabel", { name }) }),
|
|
220
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
221
|
+
"input",
|
|
222
|
+
{
|
|
223
|
+
id: outputId,
|
|
224
|
+
className: Section_default.input,
|
|
225
|
+
type: "number",
|
|
226
|
+
name: outputId,
|
|
227
|
+
autoComplete: "off",
|
|
228
|
+
inputMode: "numeric",
|
|
229
|
+
min: 1,
|
|
230
|
+
step: 1,
|
|
231
|
+
value: limit?.maxTokens ?? "",
|
|
232
|
+
disabled,
|
|
233
|
+
onChange: (event) => {
|
|
234
|
+
const text = event.target.value.trim();
|
|
235
|
+
if (text === "") onChange(model.id, "maxTokens", void 0);
|
|
236
|
+
else {
|
|
237
|
+
const value = positiveInteger(text);
|
|
238
|
+
if (value !== void 0) onChange(model.id, "maxTokens", value);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
)
|
|
243
|
+
] }),
|
|
244
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { children: hasCapacityOverride(limit) ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", className: Section_default.reset, disabled, onClick: () => {
|
|
245
|
+
onReset(model.id);
|
|
246
|
+
}, children: t("limitsResetModel") }) : null })
|
|
247
|
+
] });
|
|
248
|
+
}
|
|
249
|
+
function hasCapacityOverride(limit) {
|
|
250
|
+
return limit?.contextWindow != null || limit?.maxTokens != null;
|
|
251
|
+
}
|
|
252
|
+
function positiveInteger(value) {
|
|
253
|
+
const parsed = Number(value);
|
|
254
|
+
return Number.isSafeInteger(parsed) && parsed > 0 ? parsed : void 0;
|
|
255
|
+
}
|
|
256
|
+
function capacityLabel(value) {
|
|
257
|
+
return value === void 0 ? "\u2014" : String(value);
|
|
258
|
+
}
|
|
259
|
+
function inputKey(value) {
|
|
260
|
+
return encodeURIComponent(value);
|
|
93
261
|
}
|
|
94
262
|
function OpencodeGoSection(props) {
|
|
95
263
|
const { useOpencodeGo, edit, resetField, save, discard, loadModels, setEnabled, t } = props;
|
|
@@ -111,6 +279,7 @@ function OpencodeGoSection(props) {
|
|
|
111
279
|
function Loaded(props) {
|
|
112
280
|
const { t, state, loadModels } = props;
|
|
113
281
|
const [advanced, setAdvanced] = (0, import_react.useState)(false);
|
|
282
|
+
const [limitsOpen, setLimitsOpen] = (0, import_react.useState)(false);
|
|
114
283
|
(0, import_react.useEffect)(() => {
|
|
115
284
|
if (state.available && state.models.status === "idle") loadModels();
|
|
116
285
|
}, [state.available, state.models.status, loadModels]);
|
|
@@ -125,6 +294,7 @@ function Loaded(props) {
|
|
|
125
294
|
disabled
|
|
126
295
|
};
|
|
127
296
|
const advancedOverridden = state.apiKeyEnv.overridden || state.baseURL.overridden || state.refreshMinutes.overridden || state.streamIdleTimeoutMs.overridden || state.maxRequestImageBytes.overridden || state.requestImagePixelBudget.overridden || state.requestImageMaxBytes.overridden;
|
|
297
|
+
const customizedModels = Object.values(state.modelLimitDraft).filter(hasCapacityOverride).length;
|
|
128
298
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { children: [
|
|
129
299
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.intro, children: t("intro") }),
|
|
130
300
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.field, children: [
|
|
@@ -151,9 +321,11 @@ function Loaded(props) {
|
|
|
151
321
|
"input",
|
|
152
322
|
{
|
|
153
323
|
id: "opencode-go-key",
|
|
324
|
+
name: "api-key",
|
|
154
325
|
className: Section_default.input,
|
|
155
326
|
type: "password",
|
|
156
327
|
autoComplete: "off",
|
|
328
|
+
"aria-describedby": "opencode-go-key-hint",
|
|
157
329
|
value: state.apiKey.text,
|
|
158
330
|
disabled: !state.apiKeyWritable,
|
|
159
331
|
onChange: (event) => {
|
|
@@ -161,7 +333,7 @@ function Loaded(props) {
|
|
|
161
333
|
}
|
|
162
334
|
}
|
|
163
335
|
),
|
|
164
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: state.apiKeyWritable ? t("keyHint") : t("keyNotWritable") })
|
|
336
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { id: "opencode-go-key-hint", className: Section_default.hint, children: state.apiKeyWritable ? t("keyHint") : t("keyNotWritable") })
|
|
165
337
|
] }),
|
|
166
338
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.field, children: [
|
|
167
339
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.head, children: [
|
|
@@ -182,6 +354,38 @@ function Loaded(props) {
|
|
|
182
354
|
] }),
|
|
183
355
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ModelsBody, { models: state.models, t })
|
|
184
356
|
] }),
|
|
357
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.field, children: [
|
|
358
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
359
|
+
"button",
|
|
360
|
+
{
|
|
361
|
+
type: "button",
|
|
362
|
+
className: Section_default.disclosure,
|
|
363
|
+
"aria-expanded": limitsOpen,
|
|
364
|
+
"aria-controls": "opencode-go-model-limits",
|
|
365
|
+
onClick: () => {
|
|
366
|
+
setLimitsOpen(!limitsOpen);
|
|
367
|
+
},
|
|
368
|
+
children: [
|
|
369
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { "aria-hidden": "true", className: limitsOpen ? Section_default.chevronOpen : Section_default.chevron }),
|
|
370
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Section_default.label, children: t("limitsLabel") }),
|
|
371
|
+
customizedModels > 0 ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tag, { tone: "neutral", children: t("limitsSummary", { count: customizedModels }) }) : null
|
|
372
|
+
]
|
|
373
|
+
}
|
|
374
|
+
),
|
|
375
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: Section_default.hint, children: t("limitsHint") }),
|
|
376
|
+
limitsOpen ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { id: "opencode-go-model-limits", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
377
|
+
LimitsTable,
|
|
378
|
+
{
|
|
379
|
+
models: state.models,
|
|
380
|
+
draft: state.modelLimitDraft,
|
|
381
|
+
t,
|
|
382
|
+
disabled,
|
|
383
|
+
onEdit: (next) => {
|
|
384
|
+
props.edit("modelLimits", JSON.stringify(next));
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
) }) : null
|
|
388
|
+
] }),
|
|
185
389
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: Section_default.field, children: [
|
|
186
390
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
187
391
|
"button",
|
|
@@ -194,7 +398,7 @@ function Loaded(props) {
|
|
|
194
398
|
setAdvanced(!advanced);
|
|
195
399
|
},
|
|
196
400
|
children: [
|
|
197
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
401
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ChevronDown, { className: advanced ? Section_default.chevronOpen : Section_default.chevron }),
|
|
198
402
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: Section_default.label, children: t("advancedLabel") }),
|
|
199
403
|
advancedOverridden ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tag, { tone: "neutral", children: t("overridden") }) : null
|
|
200
404
|
]
|
|
@@ -365,6 +569,21 @@ function textField(field) {
|
|
|
365
569
|
}
|
|
366
570
|
};
|
|
367
571
|
}
|
|
572
|
+
function jsonField(field) {
|
|
573
|
+
return {
|
|
574
|
+
field,
|
|
575
|
+
format: (value) => value === void 0 || value === null ? "" : JSON.stringify(value, void 0, 2),
|
|
576
|
+
parse: (text) => {
|
|
577
|
+
const trimmed = text.trim();
|
|
578
|
+
if (trimmed === "") return { kind: "clear" };
|
|
579
|
+
try {
|
|
580
|
+
return { kind: "set", value: JSON.parse(trimmed) };
|
|
581
|
+
} catch {
|
|
582
|
+
return void 0;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
};
|
|
586
|
+
}
|
|
368
587
|
var StagedForm = class {
|
|
369
588
|
/**
|
|
370
589
|
* @param scope - the bound settings scope for this page's namespace.
|
|
@@ -375,7 +594,7 @@ var StagedForm = class {
|
|
|
375
594
|
this.scope = scope;
|
|
376
595
|
this.specs = new Map(specs.map((spec) => [spec.field, spec]));
|
|
377
596
|
this.secretSpecs = new Map(secrets.map((spec) => [spec.field, spec]));
|
|
378
|
-
scope.subscribe(() => {
|
|
597
|
+
this.unsubscribe = scope.subscribe(() => {
|
|
379
598
|
this.publish();
|
|
380
599
|
});
|
|
381
600
|
}
|
|
@@ -383,8 +602,14 @@ var StagedForm = class {
|
|
|
383
602
|
secretSpecs;
|
|
384
603
|
staged = /* @__PURE__ */ new Map();
|
|
385
604
|
listeners = /* @__PURE__ */ new Set();
|
|
605
|
+
unsubscribe;
|
|
386
606
|
saving = false;
|
|
387
607
|
failed = false;
|
|
608
|
+
/** Shared 0.1.7 forms outlive individual settings pages. */
|
|
609
|
+
dispose() {
|
|
610
|
+
this.unsubscribe();
|
|
611
|
+
this.listeners.clear();
|
|
612
|
+
}
|
|
388
613
|
/**
|
|
389
614
|
* Publish a projection of this form, rebuilt whenever the scope or a draft changes.
|
|
390
615
|
* @param project - build the page state from the form's current reads.
|
|
@@ -515,7 +740,7 @@ var StagedForm = class {
|
|
|
515
740
|
}
|
|
516
741
|
async store(field, value) {
|
|
517
742
|
await this.scope.set(field, value);
|
|
518
|
-
return this.userLayer()?.[field]
|
|
743
|
+
return sameJsonValue(this.userLayer()?.[field], value);
|
|
519
744
|
}
|
|
520
745
|
stage(field, edit) {
|
|
521
746
|
this.staged.set(field, edit);
|
|
@@ -547,6 +772,19 @@ var StagedForm = class {
|
|
|
547
772
|
for (const listener of this.listeners) listener();
|
|
548
773
|
}
|
|
549
774
|
};
|
|
775
|
+
function sameJsonValue(left, right) {
|
|
776
|
+
if (Object.is(left, right)) return true;
|
|
777
|
+
if (left === null || right === null || typeof left !== "object" || typeof right !== "object") return false;
|
|
778
|
+
if (Array.isArray(left) || Array.isArray(right)) {
|
|
779
|
+
if (!Array.isArray(left) || !Array.isArray(right) || left.length !== right.length) return false;
|
|
780
|
+
return left.every((value, index) => sameJsonValue(value, right[index]));
|
|
781
|
+
}
|
|
782
|
+
const leftRecord = left;
|
|
783
|
+
const rightRecord = right;
|
|
784
|
+
const leftKeys = Object.keys(leftRecord);
|
|
785
|
+
const rightKeys = Object.keys(rightRecord);
|
|
786
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => Object.hasOwn(rightRecord, key) && sameJsonValue(leftRecord[key], rightRecord[key]));
|
|
787
|
+
}
|
|
550
788
|
|
|
551
789
|
// src/client/section-controller.ts
|
|
552
790
|
var OPENCODE_GO_NS = "llm-opencode-go";
|
|
@@ -574,12 +812,13 @@ var OpencodeGoSectionController = class {
|
|
|
574
812
|
numberField("streamIdleTimeoutMs"),
|
|
575
813
|
numberField("maxRequestImageBytes"),
|
|
576
814
|
numberField("requestImagePixelBudget"),
|
|
577
|
-
numberField("requestImageMaxBytes")
|
|
815
|
+
numberField("requestImageMaxBytes"),
|
|
816
|
+
jsonField("modelLimits")
|
|
578
817
|
],
|
|
579
818
|
[{ field: API_KEY_FIELD, write: (text) => this.writeKey(text) }]
|
|
580
819
|
);
|
|
581
820
|
this.store = this.form.bind(() => this.projection());
|
|
582
|
-
scope.subscribe(() => {
|
|
821
|
+
this.unsubscribe = scope.subscribe(() => {
|
|
583
822
|
void this.readCredential();
|
|
584
823
|
});
|
|
585
824
|
void this.readCredential();
|
|
@@ -590,6 +829,13 @@ var OpencodeGoSectionController = class {
|
|
|
590
829
|
models = { status: "idle" };
|
|
591
830
|
modelsRequest = 0;
|
|
592
831
|
face;
|
|
832
|
+
unsubscribe;
|
|
833
|
+
/** Release subscriptions without disposing the host's shared form. */
|
|
834
|
+
dispose() {
|
|
835
|
+
this.modelsRequest++;
|
|
836
|
+
this.unsubscribe();
|
|
837
|
+
this.form.dispose();
|
|
838
|
+
}
|
|
593
839
|
projection() {
|
|
594
840
|
return {
|
|
595
841
|
...this.form.shell(),
|
|
@@ -604,9 +850,28 @@ var OpencodeGoSectionController = class {
|
|
|
604
850
|
apiKey: this.form.field(API_KEY_FIELD),
|
|
605
851
|
apiKeyConfigured: this.credential.configured,
|
|
606
852
|
apiKeyWritable: this.credential.writable,
|
|
607
|
-
models: this.models
|
|
853
|
+
models: this.models,
|
|
854
|
+
modelLimits: this.form.field("modelLimits"),
|
|
855
|
+
modelLimitDraft: this.limitDraft()
|
|
608
856
|
};
|
|
609
857
|
}
|
|
858
|
+
/**
|
|
859
|
+
* Read the overrides as the page currently shows them. A staged JSON draft
|
|
860
|
+
* wins while it is valid; malformed text falls back to the last accepted
|
|
861
|
+
* settings value so the table never renders phantom rows.
|
|
862
|
+
*/
|
|
863
|
+
limitDraft() {
|
|
864
|
+
const staged = this.form.field("modelLimits");
|
|
865
|
+
if (staged.invalid) return modelLimitsOf(this.scope.getSnapshot().value?.modelLimits);
|
|
866
|
+
if (staged.overridden || this.form.shell().dirty) {
|
|
867
|
+
try {
|
|
868
|
+
return modelLimitsOf(JSON.parse(staged.text));
|
|
869
|
+
} catch {
|
|
870
|
+
return modelLimitsOf(this.scope.getSnapshot().value?.modelLimits);
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return modelLimitsOf(this.scope.getSnapshot().value?.modelLimits);
|
|
874
|
+
}
|
|
610
875
|
/**
|
|
611
876
|
* The adapter's effective switch state: the resolved section's value, over
|
|
612
877
|
* the Host's own default when the section carries none.
|
|
@@ -645,7 +910,8 @@ var OpencodeGoSectionController = class {
|
|
|
645
910
|
this.models = response.ok ? {
|
|
646
911
|
status: "ready",
|
|
647
912
|
count: response.value.length,
|
|
648
|
-
preview: response.value.map((model) => model.name ?? model.id)
|
|
913
|
+
preview: response.value.map((model) => model.name ?? model.id),
|
|
914
|
+
entries: response.value
|
|
649
915
|
} : { status: "failed", message: response.error.message };
|
|
650
916
|
this.store.set(this.projection());
|
|
651
917
|
}).catch((error) => {
|
|
@@ -723,6 +989,29 @@ var OpencodeGoSectionController = class {
|
|
|
723
989
|
return this.credential.configured;
|
|
724
990
|
}
|
|
725
991
|
};
|
|
992
|
+
function modelLimitsOf(value) {
|
|
993
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return {};
|
|
994
|
+
const limits = {};
|
|
995
|
+
for (const [id3, entry] of Object.entries(value)) {
|
|
996
|
+
if (entry === null) {
|
|
997
|
+
limits[id3] = null;
|
|
998
|
+
continue;
|
|
999
|
+
}
|
|
1000
|
+
if (typeof entry !== "object" || Array.isArray(entry)) continue;
|
|
1001
|
+
const fields = entry;
|
|
1002
|
+
const limit = {};
|
|
1003
|
+
if (fields.contextWindow === null) limit.contextWindow = null;
|
|
1004
|
+
if (fields.maxTokens === null) limit.maxTokens = null;
|
|
1005
|
+
if (typeof fields.contextWindow === "number" && Number.isSafeInteger(fields.contextWindow) && fields.contextWindow > 0) {
|
|
1006
|
+
limit.contextWindow = fields.contextWindow;
|
|
1007
|
+
}
|
|
1008
|
+
if (typeof fields.maxTokens === "number" && Number.isSafeInteger(fields.maxTokens) && fields.maxTokens > 0) {
|
|
1009
|
+
limit.maxTokens = fields.maxTokens;
|
|
1010
|
+
}
|
|
1011
|
+
if (limit.contextWindow !== void 0 || limit.maxTokens !== void 0) limits[id3] = limit;
|
|
1012
|
+
}
|
|
1013
|
+
return limits;
|
|
1014
|
+
}
|
|
726
1015
|
function refOf(snapshot) {
|
|
727
1016
|
const declared = snapshot.value?.apiKeyEnv;
|
|
728
1017
|
return declared !== void 0 && declared.length > 0 ? declared : DEFAULT_API_KEY_REF;
|
|
@@ -758,6 +1047,21 @@ var en = {
|
|
|
758
1047
|
modelsFailed: "Could not read the gateway model list.",
|
|
759
1048
|
modelsEmpty: "The gateway currently serves no model this adapter can route.",
|
|
760
1049
|
modelsCount: "{count} models",
|
|
1050
|
+
limitsLabel: "Model capacities",
|
|
1051
|
+
limitsHint: "Override the context window or max output for a model. Leave a field blank to use the catalog value.",
|
|
1052
|
+
limitsFilterLabel: "Find a model",
|
|
1053
|
+
limitsFilterPlaceholder: "Search by model name or id\u2026",
|
|
1054
|
+
limitsSummary: "{count} customized",
|
|
1055
|
+
limitsModel: "Model",
|
|
1056
|
+
limitsContext: "Context window",
|
|
1057
|
+
limitsOutput: "Max output",
|
|
1058
|
+
limitsAdvertised: "Catalog: {context} / {output}",
|
|
1059
|
+
limitsResetModel: "Use catalog",
|
|
1060
|
+
limitsResetAll: "Clear all overrides",
|
|
1061
|
+
limitsNoMatches: "No models match \u201C{query}\u201D. Try a different name or id.",
|
|
1062
|
+
limitsEmpty: "Read the model list first; capacities are edited per model the gateway serves.",
|
|
1063
|
+
limitsContextLabel: "Context window for {name}",
|
|
1064
|
+
limitsOutputLabel: "Max output for {name}",
|
|
761
1065
|
advancedLabel: "Advanced settings",
|
|
762
1066
|
advancedHint: "Credential name, gateway URL, and adapter tuning. The inherited values work as they are; change them only if you know you need to.",
|
|
763
1067
|
apiKeyEnvLabel: "Credential reference",
|
|
@@ -813,6 +1117,21 @@ var zh = {
|
|
|
813
1117
|
modelsFailed: "\u672A\u80FD\u8BFB\u53D6\u7F51\u5173\u6A21\u578B\u5217\u8868\u3002",
|
|
814
1118
|
modelsEmpty: "\u7F51\u5173\u5F53\u524D\u6CA1\u6709\u672C\u9002\u914D\u5668\u53EF\u8DEF\u7531\u7684\u6A21\u578B\u3002",
|
|
815
1119
|
modelsCount: "{count} \u4E2A\u6A21\u578B",
|
|
1120
|
+
limitsLabel: "\u6A21\u578B\u5BB9\u91CF",
|
|
1121
|
+
limitsHint: "\u4E3A\u6A21\u578B\u8986\u76D6\u4E0A\u4E0B\u6587\u7A97\u53E3\u6216\u6700\u5927\u8F93\u51FA\u3002\u7559\u7A7A\u7684\u5B57\u6BB5\u4F1A\u4F7F\u7528\u76EE\u5F55\u516C\u5E03\u7684\u5BB9\u91CF\u3002",
|
|
1122
|
+
limitsFilterLabel: "\u67E5\u627E\u6A21\u578B",
|
|
1123
|
+
limitsFilterPlaceholder: "\u6309\u6A21\u578B\u540D\u79F0\u6216 ID \u641C\u7D22\u2026",
|
|
1124
|
+
limitsSummary: "{count} \u4E2A\u5DF2\u81EA\u5B9A\u4E49",
|
|
1125
|
+
limitsModel: "\u6A21\u578B",
|
|
1126
|
+
limitsContext: "\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
1127
|
+
limitsOutput: "\u6700\u5927\u8F93\u51FA",
|
|
1128
|
+
limitsAdvertised: "\u76EE\u5F55\uFF1A{context} / {output}",
|
|
1129
|
+
limitsResetModel: "\u4F7F\u7528\u76EE\u5F55\u503C",
|
|
1130
|
+
limitsResetAll: "\u6E05\u9664\u5168\u90E8\u8986\u76D6",
|
|
1131
|
+
limitsNoMatches: "\u6CA1\u6709\u5339\u914D\u201C{query}\u201D\u7684\u6A21\u578B\u3002\u8BF7\u5C1D\u8BD5\u5176\u4ED6\u540D\u79F0\u6216 ID\u3002",
|
|
1132
|
+
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",
|
|
1133
|
+
limitsContextLabel: "{name} \u7684\u4E0A\u4E0B\u6587\u7A97\u53E3",
|
|
1134
|
+
limitsOutputLabel: "{name} \u7684\u6700\u5927\u8F93\u51FA",
|
|
816
1135
|
advancedLabel: "\u9AD8\u7EA7\u8BBE\u7F6E",
|
|
817
1136
|
advancedHint: "\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\u9664\u975E\u4F60\u660E\u786E\u77E5\u9053\u9700\u8981\u4FEE\u6539\uFF0C\u5426\u5219\u4E0D\u5FC5\u52A8\u8FD9\u91CC\u3002",
|
|
818
1137
|
apiKeyEnvLabel: "\u51ED\u8BC1\u5F15\u7528\u540D",
|
|
@@ -885,7 +1204,7 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id2) + "]"
|
|
|
885
1204
|
style.textContent = ".dmPm3q_root{min-width:0;display:inline-flex;position:relative}.dmPm3q_trigger{color:inherit;opacity:.75;font:inherit;cursor:pointer;white-space:nowrap;background:0 0;border:0;border-radius:6px;padding:4px 6px;font-size:12px}.dmPm3q_trigger:hover,.dmPm3q_trigger:focus-visible{opacity:1;background:color-mix(in srgb, currentColor 8%, transparent)}.dmPm3q_panel{z-index:100;border:1px solid color-mix(in srgb, currentColor 18%, transparent);width:280px;max-width:calc(100vw - 32px);color:var(--dsw-alias-label-primary,CanvasText);background:var(--dsw-specific-menu,Canvas);border-radius:12px;padding:16px;font-size:12px;position:absolute;bottom:calc(100% + 12px);right:0;box-shadow:0 8px 30px #0002}.dmPm3q_hint{opacity:.65;font-size:11px;line-height:1.6}.dmPm3q_window{margin-top:14px}.dmPm3q_row{justify-content:space-between;margin-bottom:5px;display:flex}.dmPm3q_window progress{accent-color:#39a878;width:100%;height:5px;margin-bottom:5px;display:block}.dmPm3q_window progress::-webkit-progress-bar{background:color-mix(in srgb, currentColor 15%, transparent);border-radius:4px}.dmPm3q_window progress::-webkit-progress-value{background:#39a878;border-radius:4px}.dmPm3q_window progress::-moz-progress-bar{background:#39a878;border-radius:4px}";
|
|
886
1205
|
document.head.appendChild(style);
|
|
887
1206
|
}
|
|
888
|
-
var UsagePill_default = { "
|
|
1207
|
+
var UsagePill_default = { "trigger": "dmPm3q_trigger", "panel": "dmPm3q_panel", "hint": "dmPm3q_hint", "window": "dmPm3q_window", "row": "dmPm3q_row", "root": "dmPm3q_root" };
|
|
889
1208
|
|
|
890
1209
|
// src/client/UsagePill.tsx
|
|
891
1210
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -1017,15 +1336,24 @@ function registerUsagePill(ctx) {
|
|
|
1017
1336
|
|
|
1018
1337
|
// src/client/index.ts
|
|
1019
1338
|
var NS = "settings.opencode-go";
|
|
1020
|
-
var inject = ["slots", "locale", "remote", "remote.credentials", "remote.llm"
|
|
1339
|
+
var inject = ["slots", "locale", "remote", "remote.credentials", "remote.llm"];
|
|
1021
1340
|
function apply(ctx) {
|
|
1022
1341
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "llm-opencode-go: copy dictionaries");
|
|
1023
1342
|
registerUsagePill(ctx);
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1343
|
+
ctx.inject(["configForms"], (child) => {
|
|
1344
|
+
const forms = child.get("configForms");
|
|
1345
|
+
mountSettings(child, forms.get("opencode-go"));
|
|
1027
1346
|
});
|
|
1347
|
+
ctx.inject(["settingsScope"], (child) => {
|
|
1348
|
+
mountSettings(child, child.settingsScope.bind({
|
|
1349
|
+
namespace: "llm-opencode-go",
|
|
1350
|
+
decode: (section) => typeof section === "object" && section !== null ? section : void 0
|
|
1351
|
+
}));
|
|
1352
|
+
});
|
|
1353
|
+
}
|
|
1354
|
+
function mountSettings(ctx, scope) {
|
|
1028
1355
|
const controller = new OpencodeGoSectionController(scope, ctx);
|
|
1356
|
+
ctx.effect(() => () => controller.dispose());
|
|
1029
1357
|
const t = ctx.locale.bind(NS);
|
|
1030
1358
|
const injected = () => ({ ...controller.inject(), t });
|
|
1031
1359
|
ctx.effect(() => {
|