dsh-codex-connect 0.1.0-alpha.4.21 → 0.1.0-alpha.4.23
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/INSTALL.md +15 -2
- package/README.i18n.yaml +2 -2
- package/README.md +62 -16
- package/compatibility.json +3 -2
- package/docs/README.zh.md +61 -13
- package/docs/design.i18n.yaml +2 -2
- package/docs/design.md +1 -1
- package/docs/design.zh.md +1 -1
- package/lib/bin.js +361 -15
- package/lib/client.js +962 -248
- package/lib/index.d.ts +39 -11
- package/lib/index.js +2 -2
- package/lib/{src-Cxq99TvF.js → src-ByKP_wn9.js} +230 -57
- package/package.json +81 -54
package/lib/client.js
CHANGED
|
@@ -36,10 +36,35 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
function isValidOpenAICodexProxyUrl(value) {
|
|
37
37
|
return normalizeOpenAICodexProxyUrl(value) !== void 0;
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Whether a value is a bounded per-model context-window override map. Keys
|
|
41
|
+
* are nonempty, unpadded model ids; values are positive safe integers or null
|
|
42
|
+
* to restore that model's catalog default. The Host also checks catalog
|
|
43
|
+
* membership and the model-specific configuration ceiling.
|
|
44
|
+
*/
|
|
45
|
+
function isValidOpenAICodexContextWindowOverrides(value) {
|
|
46
|
+
if (!isRecord$2(value)) return false;
|
|
47
|
+
const entries = Object.entries(value);
|
|
48
|
+
if (entries.length > 256) return false;
|
|
49
|
+
return entries.every(([modelId, window]) => modelId.length > 0 && modelId.trim() === modelId && (window === null || typeof window === "number" && Number.isSafeInteger(window) && window > 0));
|
|
50
|
+
}
|
|
51
|
+
/** Preserve per-model null masks until the Host has merged its settings layers. */
|
|
52
|
+
function parseOpenAICodexContextWindowOverrides(value) {
|
|
53
|
+
if (value === void 0 || value === null) return void 0;
|
|
54
|
+
if (!isValidOpenAICodexContextWindowOverrides(value)) throw new TypeError("OpenAI Codex contextWindowOverrides must contain at most 256 nonempty model ids with positive safe-integer token budgets or null resets");
|
|
55
|
+
return { ...value };
|
|
56
|
+
}
|
|
57
|
+
/** Resolve merged settings; whole-map or per-model null masks use catalog defaults. */
|
|
58
|
+
function resolveOpenAICodexContextWindowOverrides(value) {
|
|
59
|
+
const overrides = parseOpenAICodexContextWindowOverrides(value);
|
|
60
|
+
if (overrides === void 0) return void 0;
|
|
61
|
+
return Object.fromEntries(Object.entries(overrides).filter((entry) => entry[1] !== null));
|
|
62
|
+
}
|
|
39
63
|
Object.freeze({
|
|
40
64
|
models: void 0,
|
|
41
65
|
enableProxy: false,
|
|
42
66
|
proxyUrl: DEFAULT_OPENAI_CODEX_PROXY_URL,
|
|
67
|
+
contextWindowOverrides: void 0,
|
|
43
68
|
enableSearch: false,
|
|
44
69
|
enableImageTool: false,
|
|
45
70
|
enableImageGeneration: false,
|
|
@@ -57,6 +82,7 @@ window.__ModuleLoader__.load({
|
|
|
57
82
|
const models = value["models"];
|
|
58
83
|
const enableProxy = value["enableProxy"];
|
|
59
84
|
const proxyUrl = value["proxyUrl"];
|
|
85
|
+
const contextWindowOverrides = value["contextWindowOverrides"];
|
|
60
86
|
const enableSearch = value["enableSearch"];
|
|
61
87
|
const enableImageTool = value["enableImageTool"];
|
|
62
88
|
const enableImageGeneration = value["enableImageGeneration"];
|
|
@@ -67,16 +93,19 @@ window.__ModuleLoader__.load({
|
|
|
67
93
|
if (models !== void 0 && (!Array.isArray(models) || models.some((model) => typeof model !== "string"))) return void 0;
|
|
68
94
|
if (enableProxy !== void 0 && typeof enableProxy !== "boolean") return void 0;
|
|
69
95
|
if (proxyUrl !== void 0 && (typeof proxyUrl !== "string" || !isValidOpenAICodexProxyUrl(proxyUrl))) return void 0;
|
|
96
|
+
if (contextWindowOverrides !== void 0 && contextWindowOverrides !== null && !isValidOpenAICodexContextWindowOverrides(contextWindowOverrides)) return void 0;
|
|
70
97
|
if (typeof enableSearch !== "boolean" || typeof enableImageTool !== "boolean") return void 0;
|
|
71
98
|
if (enableImageGeneration !== void 0 && typeof enableImageGeneration !== "boolean") return void 0;
|
|
72
99
|
if (typeof searchModel !== "string" || searchModel.trim().length === 0) return void 0;
|
|
73
100
|
if (searchMode !== "cached" && searchMode !== "indexed" && searchMode !== "live") return void 0;
|
|
74
101
|
if (searchContextSize !== "low" && searchContextSize !== "medium" && searchContextSize !== "high") return void 0;
|
|
75
102
|
if (typeof searchMaxOutputTokens !== "number" || !Number.isInteger(searchMaxOutputTokens) || searchMaxOutputTokens < 1) return void 0;
|
|
103
|
+
const overrides = resolveOpenAICodexContextWindowOverrides(contextWindowOverrides);
|
|
76
104
|
return {
|
|
77
105
|
models: models === void 0 ? void 0 : [...new Set(models)],
|
|
78
106
|
enableProxy: enableProxy ?? false,
|
|
79
107
|
proxyUrl: proxyUrl === void 0 ? DEFAULT_OPENAI_CODEX_PROXY_URL : normalizeOpenAICodexProxyUrl(proxyUrl),
|
|
108
|
+
contextWindowOverrides: overrides === void 0 ? void 0 : Object.freeze(overrides),
|
|
80
109
|
enableSearch,
|
|
81
110
|
enableImageTool,
|
|
82
111
|
enableImageGeneration: enableImageGeneration ?? false,
|
|
@@ -95,11 +124,202 @@ window.__ModuleLoader__.load({
|
|
|
95
124
|
const OPENAI_CODEX_AUTH_LOGIN_PATH = "/plugins/dsh-openai-codex/auth/login";
|
|
96
125
|
/** Plugin-owned logout endpoint consumed by its browser half. */
|
|
97
126
|
const OPENAI_CODEX_AUTH_LOGOUT_PATH = "/plugins/dsh-openai-codex/auth/logout";
|
|
127
|
+
/** Cancel only the pending authorization; never delete a stored credential. */
|
|
128
|
+
const OPENAI_CODEX_AUTH_CANCEL_PATH = "/plugins/dsh-openai-codex/auth/cancel";
|
|
129
|
+
//#endregion
|
|
130
|
+
//#region src/client/account-store.ts
|
|
131
|
+
var AccountRequestError = class extends Error {};
|
|
132
|
+
async function request(path, method = "GET", signal) {
|
|
133
|
+
const response = await fetch(path, {
|
|
134
|
+
method,
|
|
135
|
+
headers: { accept: "application/json" },
|
|
136
|
+
credentials: "same-origin",
|
|
137
|
+
...signal === void 0 ? {} : { signal }
|
|
138
|
+
});
|
|
139
|
+
const value = await response.json().catch(() => void 0);
|
|
140
|
+
if (!response.ok) throw new AccountRequestError(typeof value === "object" && value !== null && "error" in value && typeof value.error === "string" ? value.error : `HTTP ${response.status}`);
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
/** One account state per browser-plugin instance; subscribers share requests and timers. */
|
|
144
|
+
var OpenAICodexAccountStore = class {
|
|
145
|
+
snapshot = {
|
|
146
|
+
status: { status: "loading" },
|
|
147
|
+
busy: false
|
|
148
|
+
};
|
|
149
|
+
listeners = /* @__PURE__ */ new Set();
|
|
150
|
+
controller;
|
|
151
|
+
timer;
|
|
152
|
+
disposed = false;
|
|
153
|
+
popup = null;
|
|
154
|
+
getSnapshot = () => this.snapshot;
|
|
155
|
+
subscribe = (listener) => {
|
|
156
|
+
if (this.disposed) return () => {};
|
|
157
|
+
this.listeners.add(listener);
|
|
158
|
+
if (this.listeners.size === 1) this.refresh();
|
|
159
|
+
return () => {
|
|
160
|
+
this.listeners.delete(listener);
|
|
161
|
+
if (this.listeners.size === 0) this.stopPolling();
|
|
162
|
+
};
|
|
163
|
+
};
|
|
164
|
+
publish(snapshot) {
|
|
165
|
+
if (this.disposed) return;
|
|
166
|
+
this.snapshot = snapshot;
|
|
167
|
+
for (const listener of this.listeners) listener();
|
|
168
|
+
}
|
|
169
|
+
failure(error) {
|
|
170
|
+
return error instanceof AccountRequestError && error.message === "remote-web-origin-not-trusted" ? { status: "remote-web-origin-not-trusted" } : {
|
|
171
|
+
status: "error",
|
|
172
|
+
message: error instanceof Error ? error.message : "Account request failed"
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
stopPolling() {
|
|
176
|
+
clearTimeout(this.timer);
|
|
177
|
+
this.timer = void 0;
|
|
178
|
+
this.controller?.abort();
|
|
179
|
+
this.controller = void 0;
|
|
180
|
+
}
|
|
181
|
+
schedule() {
|
|
182
|
+
clearTimeout(this.timer);
|
|
183
|
+
const interval = this.snapshot.status.status === "signing-in" ? 1e3 : this.snapshot.status.status === "signed-in" ? 6e4 : void 0;
|
|
184
|
+
if (!this.disposed && this.listeners.size > 0 && interval !== void 0) this.timer = setTimeout(() => {
|
|
185
|
+
this.refresh();
|
|
186
|
+
}, interval);
|
|
187
|
+
}
|
|
188
|
+
/** Refresh only while observed, without overlapping status reads or OAuth mutations. */
|
|
189
|
+
async refresh() {
|
|
190
|
+
if (this.disposed || this.snapshot.busy || this.controller !== void 0 || this.listeners.size === 0) return;
|
|
191
|
+
const controller = new AbortController();
|
|
192
|
+
this.controller = controller;
|
|
193
|
+
try {
|
|
194
|
+
const status = await request(OPENAI_CODEX_AUTH_STATUS_PATH, "GET", controller.signal);
|
|
195
|
+
if (!controller.signal.aborted) this.publish({
|
|
196
|
+
status,
|
|
197
|
+
busy: false,
|
|
198
|
+
...status.status === "signing-in" && this.snapshot.loginUrl !== void 0 ? { loginUrl: this.snapshot.loginUrl } : {}
|
|
199
|
+
});
|
|
200
|
+
} catch (error) {
|
|
201
|
+
if (!controller.signal.aborted) this.publish({
|
|
202
|
+
status: this.failure(error),
|
|
203
|
+
busy: false
|
|
204
|
+
});
|
|
205
|
+
} finally {
|
|
206
|
+
if (this.controller === controller) {
|
|
207
|
+
this.controller = void 0;
|
|
208
|
+
this.schedule();
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
/** Start or reopen the server-owned authorization from a user click, retaining popup permission. */
|
|
213
|
+
async signIn() {
|
|
214
|
+
if (this.disposed || this.snapshot.busy) return;
|
|
215
|
+
this.stopPolling();
|
|
216
|
+
const popup = window.open("about:blank", "_blank");
|
|
217
|
+
this.popup = popup;
|
|
218
|
+
if (popup !== null) popup.opener = null;
|
|
219
|
+
this.publish({
|
|
220
|
+
status: { status: "signing-in" },
|
|
221
|
+
busy: true
|
|
222
|
+
});
|
|
223
|
+
try {
|
|
224
|
+
const challenge = await request(OPENAI_CODEX_AUTH_LOGIN_PATH, "POST");
|
|
225
|
+
if (this.disposed) {
|
|
226
|
+
popup?.close();
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
if (popup !== null) popup.location.replace(challenge.url);
|
|
230
|
+
this.publish({
|
|
231
|
+
status: { status: "signing-in" },
|
|
232
|
+
busy: false,
|
|
233
|
+
loginUrl: challenge.url
|
|
234
|
+
});
|
|
235
|
+
} catch (error) {
|
|
236
|
+
popup?.close();
|
|
237
|
+
this.publish({
|
|
238
|
+
status: this.failure(error),
|
|
239
|
+
busy: false
|
|
240
|
+
});
|
|
241
|
+
if (error instanceof AccountRequestError && error.message === "OpenAI Codex sign-in cancelled") await this.refresh();
|
|
242
|
+
} finally {
|
|
243
|
+
if (this.popup === popup) this.popup = null;
|
|
244
|
+
this.schedule();
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
/** Cancel only the pending authorization, preserving an already signed-in account. */
|
|
248
|
+
async cancel() {
|
|
249
|
+
if (this.disposed || this.snapshot.busy) return;
|
|
250
|
+
this.stopPolling();
|
|
251
|
+
this.publish({
|
|
252
|
+
status: this.snapshot.status,
|
|
253
|
+
busy: true
|
|
254
|
+
});
|
|
255
|
+
try {
|
|
256
|
+
const status = await request(OPENAI_CODEX_AUTH_CANCEL_PATH, "POST");
|
|
257
|
+
this.publish({
|
|
258
|
+
status,
|
|
259
|
+
busy: false
|
|
260
|
+
});
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this.publish({
|
|
263
|
+
status: this.failure(error),
|
|
264
|
+
busy: false
|
|
265
|
+
});
|
|
266
|
+
} finally {
|
|
267
|
+
this.schedule();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
/** Sign out once for all mounted account views and invalidate older status reads. */
|
|
271
|
+
async signOut() {
|
|
272
|
+
if (this.disposed || this.snapshot.busy) return;
|
|
273
|
+
this.stopPolling();
|
|
274
|
+
this.publish({
|
|
275
|
+
status: this.snapshot.status,
|
|
276
|
+
busy: true
|
|
277
|
+
});
|
|
278
|
+
try {
|
|
279
|
+
await request(OPENAI_CODEX_AUTH_LOGOUT_PATH, "POST");
|
|
280
|
+
this.publish({
|
|
281
|
+
status: { status: "signed-out" },
|
|
282
|
+
busy: false
|
|
283
|
+
});
|
|
284
|
+
} catch (error) {
|
|
285
|
+
this.publish({
|
|
286
|
+
status: this.failure(error),
|
|
287
|
+
busy: false
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/** Stop local observation on plugin unload; do not log out the server account. */
|
|
292
|
+
dispose() {
|
|
293
|
+
this.disposed = true;
|
|
294
|
+
this.stopPolling();
|
|
295
|
+
this.popup?.close();
|
|
296
|
+
this.popup = null;
|
|
297
|
+
this.listeners.clear();
|
|
298
|
+
this.snapshot = {
|
|
299
|
+
status: { status: "loading" },
|
|
300
|
+
busy: false
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
};
|
|
98
304
|
//#endregion
|
|
99
305
|
//#region src/model-contract.ts
|
|
100
306
|
/** Node-free model catalog contract shared by the Host route and browser card. */
|
|
101
307
|
/** Same-origin endpoint exposing the complete Codex model catalog. */
|
|
102
308
|
const OPENAI_CODEX_MODEL_CATALOG_PATH = "/plugins/dsh-codex-connect/models";
|
|
309
|
+
/** Versioned official-client override policy, not a measured endpoint capacity. */
|
|
310
|
+
const OPENAI_CODEX_CONTEXT_LIMIT_SOURCE = "https://github.com/openai/codex/blob/7625343977154efed8c0dadba956374992a1580b/codex-rs/models-manager/models.json";
|
|
311
|
+
Object.freeze({
|
|
312
|
+
"gpt-5.6-sol": 872e3,
|
|
313
|
+
"gpt-5.6-terra": 872e3,
|
|
314
|
+
"gpt-5.6-luna": 872e3,
|
|
315
|
+
"gpt-5.4": 1e6,
|
|
316
|
+
"gpt-5.5": 272e3,
|
|
317
|
+
"gpt-5.4-mini": 272e3
|
|
318
|
+
});
|
|
319
|
+
/** Whether a proposed local token budget fits the model's configuration range. */
|
|
320
|
+
function isValidOpenAICodexContextBudget(value, maximum) {
|
|
321
|
+
return Number.isSafeInteger(value) && value > 0 && value <= maximum;
|
|
322
|
+
}
|
|
103
323
|
/** Validate the model catalog before it enters React state. */
|
|
104
324
|
function decodeOpenAICodexModelCatalog(value) {
|
|
105
325
|
if (!Array.isArray(value)) return void 0;
|
|
@@ -110,11 +330,18 @@ window.__ModuleLoader__.load({
|
|
|
110
330
|
const record = entry;
|
|
111
331
|
const id = record["id"];
|
|
112
332
|
const name = record["name"];
|
|
333
|
+
const contextWindow = record["contextWindow"];
|
|
334
|
+
const maxContextWindow = record["maxContextWindow"];
|
|
335
|
+
const contextLimitSource = record["contextLimitSource"];
|
|
113
336
|
if (typeof id !== "string" || id.length === 0 || typeof name !== "string" || name.length === 0 || ids.has(id)) return void 0;
|
|
337
|
+
if (typeof contextWindow !== "number" || typeof maxContextWindow !== "number" || !isValidOpenAICodexContextBudget(maxContextWindow, Number.MAX_SAFE_INTEGER) || !isValidOpenAICodexContextBudget(contextWindow, maxContextWindow) || contextLimitSource !== "codex-catalog" && contextLimitSource !== "catalog-default") return void 0;
|
|
114
338
|
ids.add(id);
|
|
115
339
|
catalog.push({
|
|
116
340
|
id,
|
|
117
|
-
name
|
|
341
|
+
name,
|
|
342
|
+
contextWindow,
|
|
343
|
+
maxContextWindow,
|
|
344
|
+
contextLimitSource
|
|
118
345
|
});
|
|
119
346
|
}
|
|
120
347
|
return catalog;
|
|
@@ -158,8 +385,8 @@ window.__ModuleLoader__.load({
|
|
|
158
385
|
border: 0
|
|
159
386
|
};
|
|
160
387
|
const modelListStyle = {
|
|
161
|
-
display: "
|
|
162
|
-
|
|
388
|
+
display: "flex",
|
|
389
|
+
flexDirection: "column",
|
|
163
390
|
gap: 10
|
|
164
391
|
};
|
|
165
392
|
const modelRowStyle = {
|
|
@@ -226,7 +453,7 @@ window.__ModuleLoader__.load({
|
|
|
226
453
|
display: "flex",
|
|
227
454
|
gap: 8
|
|
228
455
|
};
|
|
229
|
-
const buttonStyle$
|
|
456
|
+
const buttonStyle$3 = {
|
|
230
457
|
boxSizing: "border-box",
|
|
231
458
|
minHeight: 34,
|
|
232
459
|
padding: "6px 14px",
|
|
@@ -239,10 +466,10 @@ window.__ModuleLoader__.load({
|
|
|
239
466
|
cursor: "pointer"
|
|
240
467
|
};
|
|
241
468
|
const primaryButtonStyle$2 = {
|
|
242
|
-
...buttonStyle$
|
|
243
|
-
borderColor: "var(--dsw-alias-
|
|
244
|
-
background: "var(--dsw-alias-
|
|
245
|
-
color: "
|
|
469
|
+
...buttonStyle$3,
|
|
470
|
+
borderColor: "var(--dsw-alias-button-primary-fill)",
|
|
471
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
472
|
+
color: "var(--dsw-alias-label-primary-foreground)"
|
|
246
473
|
};
|
|
247
474
|
const errorStyle$2 = {
|
|
248
475
|
...bodyStyle$2,
|
|
@@ -263,6 +490,7 @@ window.__ModuleLoader__.load({
|
|
|
263
490
|
};
|
|
264
491
|
const CONFIG_FIELDS = [
|
|
265
492
|
"models",
|
|
493
|
+
"contextWindowOverrides",
|
|
266
494
|
"enableProxy",
|
|
267
495
|
"proxyUrl",
|
|
268
496
|
"enableSearch",
|
|
@@ -274,6 +502,11 @@ window.__ModuleLoader__.load({
|
|
|
274
502
|
"searchMaxOutputTokens"
|
|
275
503
|
];
|
|
276
504
|
function sameField(field, left, right) {
|
|
505
|
+
if (field === "contextWindowOverrides") {
|
|
506
|
+
const leftMap = left;
|
|
507
|
+
const rightMap = right;
|
|
508
|
+
return Object.keys(leftMap ?? {}).length === Object.keys(rightMap ?? {}).length && Object.entries(leftMap ?? {}).every(([id, value]) => rightMap?.[id] === value);
|
|
509
|
+
}
|
|
277
510
|
if (field !== "models") return left === right;
|
|
278
511
|
if (left === void 0 || right === void 0) return left === right;
|
|
279
512
|
return Array.isArray(left) && Array.isArray(right) && left.length === right.length && left.every((model, index) => model === right[index]);
|
|
@@ -292,6 +525,7 @@ window.__ModuleLoader__.load({
|
|
|
292
525
|
const [feedback, setFeedback] = (0, react.useState)("idle");
|
|
293
526
|
const [modelCatalog, setModelCatalog] = (0, react.useState)();
|
|
294
527
|
const [modelCatalogError, setModelCatalogError] = (0, react.useState)(false);
|
|
528
|
+
const [expandedModels, setExpandedModels] = (0, react.useState)({});
|
|
295
529
|
const [proxyDetection, setProxyDetection] = (0, react.useState)({ status: "idle" });
|
|
296
530
|
const [manualProxy, setManualProxy] = (0, react.useState)(false);
|
|
297
531
|
const [manualProbe, setManualProbe] = (0, react.useState)();
|
|
@@ -403,7 +637,11 @@ window.__ModuleLoader__.load({
|
|
|
403
637
|
const validModel = draft !== void 0 && draft.searchModel.trim().length > 0;
|
|
404
638
|
const validTokens = draft !== void 0 && Number.isInteger(draft.searchMaxOutputTokens) && draft.searchMaxOutputTokens > 0;
|
|
405
639
|
const validProxy = draft !== void 0 && isValidOpenAICodexProxyUrl(draft.proxyUrl);
|
|
406
|
-
const
|
|
640
|
+
const validContexts = draft !== void 0 && isValidOpenAICodexContextWindowOverrides(draft.contextWindowOverrides ?? {}) && Object.entries(draft.contextWindowOverrides ?? {}).every(([id, budget]) => {
|
|
641
|
+
const model = modelCatalog?.find((entry) => entry.id === id);
|
|
642
|
+
return model !== void 0 && isValidOpenAICodexContextBudget(budget, model.maxContextWindow);
|
|
643
|
+
});
|
|
644
|
+
const valid = validModel && validTokens && validProxy && validContexts;
|
|
407
645
|
const save = async () => {
|
|
408
646
|
if (scope === void 0 || draft === void 0 || !snapshot.writable || !valid) return;
|
|
409
647
|
const desired = {
|
|
@@ -416,7 +654,11 @@ window.__ModuleLoader__.load({
|
|
|
416
654
|
for (const field of CONFIG_FIELDS) {
|
|
417
655
|
const accepted = scope.getSnapshot().value;
|
|
418
656
|
if (accepted !== void 0 && sameField(field, accepted[field], desired[field])) continue;
|
|
419
|
-
|
|
657
|
+
const value = field === "contextWindowOverrides" ? {
|
|
658
|
+
...Object.fromEntries((modelCatalog ?? []).map((model) => [model.id, null])),
|
|
659
|
+
...desired.contextWindowOverrides
|
|
660
|
+
} : desired[field];
|
|
661
|
+
await scope.set(field, value);
|
|
420
662
|
const committed = scope.getSnapshot().value;
|
|
421
663
|
if (committed === void 0 || !sameField(field, committed[field], desired[field])) throw new Error(`Host refused ${field}`);
|
|
422
664
|
}
|
|
@@ -485,28 +727,230 @@ window.__ModuleLoader__.load({
|
|
|
485
727
|
"aria-label": t("modelCatalog"),
|
|
486
728
|
children: modelCatalog.map((model) => {
|
|
487
729
|
const selected = draft.models === void 0 || draft.models.includes(model.id);
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
730
|
+
const budget = draft.contextWindowOverrides?.[model.id];
|
|
731
|
+
const invalidBudget = budget !== void 0 && !isValidOpenAICodexContextBudget(budget, model.maxContextWindow);
|
|
732
|
+
const effectiveBudget = budget ?? model.contextWindow;
|
|
733
|
+
const changeBudget = (value) => {
|
|
734
|
+
update("contextWindowOverrides", {
|
|
735
|
+
...draft.contextWindowOverrides,
|
|
736
|
+
[model.id]: value
|
|
737
|
+
});
|
|
738
|
+
};
|
|
739
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
740
|
+
role: "group",
|
|
741
|
+
"aria-label": model.name,
|
|
742
|
+
style: {
|
|
743
|
+
minWidth: 0,
|
|
744
|
+
padding: "10px 0",
|
|
745
|
+
borderBottom: "1px solid var(--dsw-alias-border-l2)"
|
|
746
|
+
},
|
|
747
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
748
|
+
style: {
|
|
749
|
+
display: "flex",
|
|
750
|
+
alignItems: "center",
|
|
751
|
+
justifyContent: "space-between",
|
|
752
|
+
flexWrap: "wrap",
|
|
753
|
+
gap: 8
|
|
754
|
+
},
|
|
755
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
756
|
+
style: {
|
|
757
|
+
...modelRowStyle,
|
|
758
|
+
minWidth: 0,
|
|
759
|
+
overflowWrap: "anywhere"
|
|
760
|
+
},
|
|
761
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
762
|
+
type: "checkbox",
|
|
763
|
+
checked: selected,
|
|
764
|
+
onChange: (event) => {
|
|
765
|
+
const visible = new Set(draft.models ?? modelCatalog.map((entry) => entry.id));
|
|
766
|
+
if (event.currentTarget.checked) visible.add(model.id);
|
|
767
|
+
else visible.delete(model.id);
|
|
768
|
+
update("models", modelCatalog.filter((entry) => visible.has(entry.id)).map((entry) => entry.id));
|
|
769
|
+
}
|
|
770
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: model.name }), model.name === model.id ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
771
|
+
style: modelIdStyle,
|
|
772
|
+
children: [
|
|
773
|
+
" (",
|
|
774
|
+
model.id,
|
|
775
|
+
")"
|
|
776
|
+
]
|
|
777
|
+
})] })]
|
|
778
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
779
|
+
style: {
|
|
780
|
+
...buttonsStyle,
|
|
781
|
+
alignItems: "center",
|
|
782
|
+
flexWrap: "wrap"
|
|
783
|
+
},
|
|
784
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
785
|
+
style: bodyStyle$2,
|
|
786
|
+
children: [
|
|
787
|
+
t("modelContext"),
|
|
788
|
+
": ",
|
|
789
|
+
invalidBudget ? t("contextCustom") : `${effectiveBudget.toLocaleString()} tokens${budget === void 0 ? ` · ${t("contextDefault")}` : ""}`
|
|
790
|
+
]
|
|
791
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
792
|
+
type: "button",
|
|
793
|
+
style: buttonStyle$3,
|
|
794
|
+
"aria-expanded": expandedModels[model.id] === true,
|
|
795
|
+
onClick: () => {
|
|
796
|
+
setExpandedModels((current) => ({
|
|
797
|
+
...current,
|
|
798
|
+
[model.id]: !current[model.id]
|
|
799
|
+
}));
|
|
800
|
+
},
|
|
801
|
+
children: expandedModels[model.id] === true ? t("contextHide") : t("contextAdjust")
|
|
802
|
+
})]
|
|
803
|
+
})]
|
|
804
|
+
}), expandedModels[model.id] === true ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
805
|
+
role: "group",
|
|
806
|
+
"aria-label": t("contextTokens"),
|
|
807
|
+
style: {
|
|
808
|
+
display: "flex",
|
|
809
|
+
flexDirection: "column",
|
|
810
|
+
gap: 8,
|
|
811
|
+
marginTop: 12
|
|
812
|
+
},
|
|
501
813
|
children: [
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
814
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
815
|
+
style: {
|
|
816
|
+
display: "flex",
|
|
817
|
+
alignItems: "center",
|
|
818
|
+
justifyContent: "space-between",
|
|
819
|
+
gap: 12
|
|
820
|
+
},
|
|
821
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
822
|
+
style: labelStyle,
|
|
823
|
+
children: t("contextTokens")
|
|
824
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
825
|
+
type: "number",
|
|
826
|
+
min: 1,
|
|
827
|
+
step: 1,
|
|
828
|
+
max: model.maxContextWindow,
|
|
829
|
+
style: {
|
|
830
|
+
...controlStyle,
|
|
831
|
+
width: 112,
|
|
832
|
+
flexShrink: 0,
|
|
833
|
+
textAlign: "right",
|
|
834
|
+
fontVariantNumeric: "tabular-nums"
|
|
835
|
+
},
|
|
836
|
+
value: Number.isNaN(effectiveBudget) ? "" : effectiveBudget,
|
|
837
|
+
"aria-invalid": invalidBudget,
|
|
838
|
+
onChange: (event) => {
|
|
839
|
+
changeBudget(event.currentTarget.valueAsNumber);
|
|
840
|
+
}
|
|
841
|
+
})]
|
|
842
|
+
}),
|
|
843
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
844
|
+
style: {
|
|
845
|
+
...bodyStyle$2,
|
|
846
|
+
display: "flex",
|
|
847
|
+
alignItems: "center",
|
|
848
|
+
justifyContent: "space-between",
|
|
849
|
+
flexWrap: "wrap",
|
|
850
|
+
gap: 8
|
|
851
|
+
},
|
|
852
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
853
|
+
style: {
|
|
854
|
+
display: "inline-flex",
|
|
855
|
+
alignItems: "center",
|
|
856
|
+
gap: 6
|
|
857
|
+
},
|
|
858
|
+
children: [
|
|
859
|
+
model.contextLimitSource === "codex-catalog" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
860
|
+
href: OPENAI_CODEX_CONTEXT_LIMIT_SOURCE,
|
|
861
|
+
target: "_blank",
|
|
862
|
+
rel: "noopener noreferrer",
|
|
863
|
+
title: t("contextLimitSource"),
|
|
864
|
+
style: {
|
|
865
|
+
color: "inherit",
|
|
866
|
+
textDecorationStyle: "dotted",
|
|
867
|
+
textUnderlineOffset: 3
|
|
868
|
+
},
|
|
869
|
+
children: t("contextMaximum")
|
|
870
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
871
|
+
title: t("contextLimitFallback"),
|
|
872
|
+
children: t("contextMaximum")
|
|
873
|
+
}),
|
|
874
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
875
|
+
style: {
|
|
876
|
+
padding: "1px 6px",
|
|
877
|
+
borderRadius: 4,
|
|
878
|
+
background: "var(--dsw-alias-bg-layer-2, var(--dsw-alias-bg-layer-1))",
|
|
879
|
+
fontVariantNumeric: "tabular-nums"
|
|
880
|
+
},
|
|
881
|
+
children: model.maxContextWindow
|
|
882
|
+
}),
|
|
883
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "tokens" })
|
|
884
|
+
]
|
|
885
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
886
|
+
type: "button",
|
|
887
|
+
title: `${t("contextDefault")}: ${model.contextWindow.toLocaleString()} tokens`,
|
|
888
|
+
style: {
|
|
889
|
+
...bodyStyle$2,
|
|
890
|
+
padding: "2px 0",
|
|
891
|
+
border: 0,
|
|
892
|
+
background: "transparent",
|
|
893
|
+
font: "inherit",
|
|
894
|
+
fontSize: 12,
|
|
895
|
+
cursor: "pointer",
|
|
896
|
+
textDecoration: "underline",
|
|
897
|
+
textUnderlineOffset: 3
|
|
898
|
+
},
|
|
899
|
+
onClick: () => {
|
|
900
|
+
const overrides = { ...draft.contextWindowOverrides };
|
|
901
|
+
delete overrides[model.id];
|
|
902
|
+
update("contextWindowOverrides", overrides);
|
|
903
|
+
},
|
|
904
|
+
children: t("contextReset")
|
|
905
|
+
})]
|
|
906
|
+
}),
|
|
907
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
908
|
+
type: "range",
|
|
909
|
+
min: 1,
|
|
910
|
+
max: model.maxContextWindow,
|
|
911
|
+
step: 1,
|
|
912
|
+
"aria-label": t("contextSlider"),
|
|
913
|
+
"aria-valuetext": invalidBudget ? t("contextInvalid") : `${effectiveBudget.toLocaleString()} tokens`,
|
|
914
|
+
style: {
|
|
915
|
+
width: "100%",
|
|
916
|
+
height: 20,
|
|
917
|
+
margin: 0,
|
|
918
|
+
accentColor: "var(--dsw-alias-label-secondary)"
|
|
919
|
+
},
|
|
920
|
+
value: invalidBudget ? model.contextWindow : effectiveBudget,
|
|
921
|
+
onChange: (event) => {
|
|
922
|
+
changeBudget(event.currentTarget.valueAsNumber);
|
|
923
|
+
}
|
|
924
|
+
}),
|
|
925
|
+
budget !== void 0 && budget > model.contextWindow && !invalidBudget ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
926
|
+
style: bodyStyle$2,
|
|
927
|
+
role: "status",
|
|
928
|
+
children: t("contextAboveDefault")
|
|
929
|
+
}) : null,
|
|
930
|
+
invalidBudget ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
|
|
931
|
+
style: errorStyle$2,
|
|
932
|
+
role: "alert",
|
|
933
|
+
children: [
|
|
934
|
+
t("contextInvalid"),
|
|
935
|
+
" (1–",
|
|
936
|
+
model.maxContextWindow.toLocaleString(),
|
|
937
|
+
")"
|
|
938
|
+
]
|
|
939
|
+
}) : null
|
|
505
940
|
]
|
|
506
|
-
})
|
|
941
|
+
}) : null]
|
|
507
942
|
}, model.id);
|
|
508
943
|
})
|
|
509
944
|
}),
|
|
945
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
946
|
+
style: bodyStyle$2,
|
|
947
|
+
children: t("contextWarning")
|
|
948
|
+
}),
|
|
949
|
+
!validContexts ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
950
|
+
style: errorStyle$2,
|
|
951
|
+
role: "alert",
|
|
952
|
+
children: t("contextInvalid")
|
|
953
|
+
}) : null,
|
|
510
954
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
511
955
|
style: { paddingTop: 4 },
|
|
512
956
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
@@ -530,7 +974,7 @@ window.__ModuleLoader__.load({
|
|
|
530
974
|
children: [
|
|
531
975
|
!draft.enableProxy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
532
976
|
type: "button",
|
|
533
|
-
style: buttonStyle$
|
|
977
|
+
style: buttonStyle$3,
|
|
534
978
|
onClick: () => {
|
|
535
979
|
detectProxy();
|
|
536
980
|
},
|
|
@@ -539,7 +983,7 @@ window.__ModuleLoader__.load({
|
|
|
539
983
|
}) : null,
|
|
540
984
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
541
985
|
type: "button",
|
|
542
|
-
style: buttonStyle$
|
|
986
|
+
style: buttonStyle$3,
|
|
543
987
|
onClick: () => {
|
|
544
988
|
setManualProxy(true);
|
|
545
989
|
},
|
|
@@ -547,7 +991,7 @@ window.__ModuleLoader__.load({
|
|
|
547
991
|
}),
|
|
548
992
|
draft.enableProxy ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
549
993
|
type: "button",
|
|
550
|
-
style: buttonStyle$
|
|
994
|
+
style: buttonStyle$3,
|
|
551
995
|
onClick: () => {
|
|
552
996
|
update("enableProxy", false);
|
|
553
997
|
},
|
|
@@ -579,7 +1023,7 @@ window.__ModuleLoader__.load({
|
|
|
579
1023
|
}, candidate.proxyUrl)),
|
|
580
1024
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
581
1025
|
type: "button",
|
|
582
|
-
style: buttonStyle$
|
|
1026
|
+
style: buttonStyle$3,
|
|
583
1027
|
onClick: () => {
|
|
584
1028
|
setProxyDetection({ status: "idle" });
|
|
585
1029
|
},
|
|
@@ -613,7 +1057,7 @@ window.__ModuleLoader__.load({
|
|
|
613
1057
|
style: buttonsStyle,
|
|
614
1058
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
615
1059
|
type: "button",
|
|
616
|
-
style: buttonStyle$
|
|
1060
|
+
style: buttonStyle$3,
|
|
617
1061
|
disabled: !isValidOpenAICodexProxyUrl(draft.proxyUrl) || manualProbeBusy,
|
|
618
1062
|
onClick: () => {
|
|
619
1063
|
testManualProxy();
|
|
@@ -837,7 +1281,7 @@ window.__ModuleLoader__.load({
|
|
|
837
1281
|
style: buttonsStyle,
|
|
838
1282
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
839
1283
|
type: "button",
|
|
840
|
-
style: buttonStyle$
|
|
1284
|
+
style: buttonStyle$3,
|
|
841
1285
|
disabled: !dirty || busy,
|
|
842
1286
|
onClick: discard,
|
|
843
1287
|
children: t("discard")
|
|
@@ -865,7 +1309,10 @@ window.__ModuleLoader__.load({
|
|
|
865
1309
|
"image-generation",
|
|
866
1310
|
"oauth-history",
|
|
867
1311
|
"model-visibility",
|
|
868
|
-
"proxy-connection"
|
|
1312
|
+
"proxy-connection",
|
|
1313
|
+
"models-account",
|
|
1314
|
+
"context-budget",
|
|
1315
|
+
"auto-review-probe"
|
|
869
1316
|
];
|
|
870
1317
|
function isHighlightKind(value) {
|
|
871
1318
|
return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
|
|
@@ -1255,7 +1702,7 @@ window.__ModuleLoader__.load({
|
|
|
1255
1702
|
gap: 16,
|
|
1256
1703
|
flexWrap: "wrap"
|
|
1257
1704
|
};
|
|
1258
|
-
const buttonStyle$
|
|
1705
|
+
const buttonStyle$2 = {
|
|
1259
1706
|
display: "inline-flex",
|
|
1260
1707
|
alignItems: "center",
|
|
1261
1708
|
justifyContent: "center",
|
|
@@ -1273,10 +1720,10 @@ window.__ModuleLoader__.load({
|
|
|
1273
1720
|
cursor: "pointer"
|
|
1274
1721
|
};
|
|
1275
1722
|
const primaryButtonStyle$1 = {
|
|
1276
|
-
...buttonStyle$
|
|
1277
|
-
borderColor: "var(--dsw-alias-
|
|
1278
|
-
background: "var(--dsw-alias-
|
|
1279
|
-
color: "
|
|
1723
|
+
...buttonStyle$2,
|
|
1724
|
+
borderColor: "var(--dsw-alias-button-primary-fill)",
|
|
1725
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
1726
|
+
color: "var(--dsw-alias-label-primary-foreground)"
|
|
1280
1727
|
};
|
|
1281
1728
|
const textButtonStyle = {
|
|
1282
1729
|
border: 0,
|
|
@@ -1370,7 +1817,10 @@ window.__ModuleLoader__.load({
|
|
|
1370
1817
|
"image-generation": "updateHighlightImageGeneration",
|
|
1371
1818
|
"oauth-history": "updateHighlightOauthHistory",
|
|
1372
1819
|
"model-visibility": "updateHighlightModelVisibility",
|
|
1373
|
-
"proxy-connection": "updateHighlightProxyConnection"
|
|
1820
|
+
"proxy-connection": "updateHighlightProxyConnection",
|
|
1821
|
+
"models-account": "updateHighlightModelsAccount",
|
|
1822
|
+
"context-budget": "updateHighlightContextBudget",
|
|
1823
|
+
"auto-review-probe": "updateHighlightAutoReviewProbe"
|
|
1374
1824
|
};
|
|
1375
1825
|
const compatibilityTitleKeys = {
|
|
1376
1826
|
compatible: "compatibilityCompatibleTitle",
|
|
@@ -1574,7 +2024,7 @@ window.__ModuleLoader__.load({
|
|
|
1574
2024
|
children: compatibilityWarning ? t("updateHeading") : available ? t("newVersionAvailable", { version: snapshot.latestVersion }) : t("updateHeading")
|
|
1575
2025
|
}), overlay ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1576
2026
|
type: "button",
|
|
1577
|
-
style: buttonStyle$
|
|
2027
|
+
style: buttonStyle$2,
|
|
1578
2028
|
"aria-label": t("dismissUpdate"),
|
|
1579
2029
|
onClick: () => {
|
|
1580
2030
|
if (noticeKey !== void 0) updater.dismiss(noticeKey);
|
|
@@ -1663,7 +2113,7 @@ window.__ModuleLoader__.load({
|
|
|
1663
2113
|
children: agentPrompt
|
|
1664
2114
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1665
2115
|
type: "button",
|
|
1666
|
-
style: buttonStyle$
|
|
2116
|
+
style: buttonStyle$2,
|
|
1667
2117
|
onClick: () => {
|
|
1668
2118
|
copy();
|
|
1669
2119
|
},
|
|
@@ -1726,7 +2176,7 @@ window.__ModuleLoader__.load({
|
|
|
1726
2176
|
},
|
|
1727
2177
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1728
2178
|
type: "button",
|
|
1729
|
-
style: buttonStyle$
|
|
2179
|
+
style: buttonStyle$2,
|
|
1730
2180
|
disabled: snapshot.status === "checking",
|
|
1731
2181
|
onClick: () => {
|
|
1732
2182
|
updater.refresh(true);
|
|
@@ -1754,8 +2204,6 @@ window.__ModuleLoader__.load({
|
|
|
1754
2204
|
//#endregion
|
|
1755
2205
|
//#region src/client/OpenAICodexSettings.tsx
|
|
1756
2206
|
/** Plugin-owned OpenAI Codex account controls used inside Plugin configuration. */
|
|
1757
|
-
const POLL_INTERVAL_MS = 1e3;
|
|
1758
|
-
const USAGE_POLL_INTERVAL_MS$1 = 6e4;
|
|
1759
2207
|
const pageStyle = {
|
|
1760
2208
|
display: "flex",
|
|
1761
2209
|
flexDirection: "column",
|
|
@@ -1811,7 +2259,7 @@ window.__ModuleLoader__.load({
|
|
|
1811
2259
|
fontWeight: 500,
|
|
1812
2260
|
color: "var(--dsw-alias-label-primary)"
|
|
1813
2261
|
};
|
|
1814
|
-
const buttonStyle = {
|
|
2262
|
+
const buttonStyle$1 = {
|
|
1815
2263
|
boxSizing: "border-box",
|
|
1816
2264
|
minHeight: 34,
|
|
1817
2265
|
padding: "6px 14px",
|
|
@@ -1824,10 +2272,10 @@ window.__ModuleLoader__.load({
|
|
|
1824
2272
|
cursor: "pointer"
|
|
1825
2273
|
};
|
|
1826
2274
|
const primaryButtonStyle = {
|
|
1827
|
-
...buttonStyle,
|
|
1828
|
-
borderColor: "var(--dsw-alias-
|
|
1829
|
-
background: "var(--dsw-alias-
|
|
1830
|
-
color: "
|
|
2275
|
+
...buttonStyle$1,
|
|
2276
|
+
borderColor: "var(--dsw-alias-button-primary-fill)",
|
|
2277
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
2278
|
+
color: "var(--dsw-alias-label-primary-foreground)"
|
|
1831
2279
|
};
|
|
1832
2280
|
const errorStyle$1 = {
|
|
1833
2281
|
...bodyStyle,
|
|
@@ -1931,15 +2379,16 @@ window.__ModuleLoader__.load({
|
|
|
1931
2379
|
]
|
|
1932
2380
|
});
|
|
1933
2381
|
}
|
|
1934
|
-
|
|
2382
|
+
/** Quota rows shared by Models and Plugin settings. */
|
|
2383
|
+
function UsageLimits({ usage, quotaError, t, heading = true }) {
|
|
1935
2384
|
const hasData = usage.rateLimits.length > 0 || usage.credits !== void 0 || usage.individualLimit !== void 0;
|
|
1936
2385
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1937
2386
|
style: quotaListStyle,
|
|
1938
2387
|
children: [
|
|
1939
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2388
|
+
heading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
1940
2389
|
style: quotaTitleStyle,
|
|
1941
2390
|
children: t("usageLimits")
|
|
1942
|
-
}),
|
|
2391
|
+
}) : null,
|
|
1943
2392
|
usage.rateLimits.map((limit) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1944
2393
|
style: quotaGroupStyle,
|
|
1945
2394
|
children: limit.windows.map((window) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaBar, {
|
|
@@ -1973,6 +2422,7 @@ window.__ModuleLoader__.load({
|
|
|
1973
2422
|
]
|
|
1974
2423
|
});
|
|
1975
2424
|
}
|
|
2425
|
+
/** Account indicator colors shared by the compact row and expanded controls. */
|
|
1976
2426
|
function dotStyle(status) {
|
|
1977
2427
|
return {
|
|
1978
2428
|
width: 9,
|
|
@@ -1982,133 +2432,157 @@ window.__ModuleLoader__.load({
|
|
|
1982
2432
|
background: status === "signed-in" ? "var(--dsw-alias-state-success-primary, #22a06b)" : status === "error" || status === "reauth-required" || status === "remote-web-origin-not-trusted" ? "var(--dsw-alias-state-error-primary, #d92d20)" : status === "signing-in" || status === "loading" ? "var(--dsw-alias-brand-primary, #1677ff)" : "var(--dsw-alias-label-dimmed, #9aa0a6)"
|
|
1983
2433
|
};
|
|
1984
2434
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2435
|
+
/** Non-sensitive account state label for either settings presentation. */
|
|
2436
|
+
function accountStatusLabel(status, t) {
|
|
2437
|
+
return t({
|
|
2438
|
+
"signed-in": "signedIn",
|
|
2439
|
+
loading: "loadingAccount",
|
|
2440
|
+
"signing-in": "signingIn",
|
|
2441
|
+
"reauth-required": "reauthRequired",
|
|
2442
|
+
"remote-web-origin-not-trusted": "remoteOriginTitle",
|
|
2443
|
+
error: "requestFailed",
|
|
2444
|
+
"signed-out": "signedOut"
|
|
2445
|
+
}[status]);
|
|
2446
|
+
}
|
|
2447
|
+
/** Shared OAuth actions; Models uses shorter, task-oriented labels. */
|
|
2448
|
+
function AccountActions({ t, store, snapshot, compact = false }) {
|
|
2449
|
+
const { status, busy } = snapshot;
|
|
2450
|
+
if (status.status === "loading" || status.status === "remote-web-origin-not-trusted") return null;
|
|
2451
|
+
if (status.status === "signed-in") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2452
|
+
type: "button",
|
|
2453
|
+
style: buttonStyle$1,
|
|
2454
|
+
disabled: busy,
|
|
2455
|
+
onClick: () => {
|
|
2456
|
+
store.signOut();
|
|
2457
|
+
},
|
|
2458
|
+
children: busy ? t("working") : t("logout")
|
|
2459
|
+
});
|
|
2460
|
+
if (status.status === "signing-in") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2461
|
+
style: rowStyle,
|
|
2462
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2463
|
+
type: "button",
|
|
2464
|
+
style: buttonStyle$1,
|
|
2465
|
+
disabled: busy,
|
|
2466
|
+
onClick: () => {
|
|
2467
|
+
store.signIn();
|
|
2468
|
+
},
|
|
2469
|
+
children: busy ? t("working") : t(compact ? "continueAuthorization" : "reopenAuthorization")
|
|
2470
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2471
|
+
type: "button",
|
|
2472
|
+
style: buttonStyle$1,
|
|
2473
|
+
disabled: busy,
|
|
2474
|
+
onClick: () => {
|
|
2475
|
+
store.cancel();
|
|
2476
|
+
},
|
|
2477
|
+
children: t("cancelSignIn")
|
|
2478
|
+
})]
|
|
2479
|
+
});
|
|
2480
|
+
const action = status.status === "error" || status.status === "reauth-required" ? t(compact ? "reauthorize" : "loginAgain") : t(compact ? "authorize" : "login");
|
|
2481
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2482
|
+
type: "button",
|
|
2483
|
+
style: primaryButtonStyle,
|
|
2484
|
+
disabled: busy,
|
|
2485
|
+
onClick: () => {
|
|
2486
|
+
store.signIn();
|
|
2487
|
+
},
|
|
2488
|
+
children: busy ? t("working") : action
|
|
1999
2489
|
});
|
|
2000
|
-
const value = await response.json().catch(() => void 0);
|
|
2001
|
-
if (!response.ok) {
|
|
2002
|
-
const code = typeof value === "object" && value !== null && "error" in value && typeof value.error === "string" ? value.error : `HTTP ${response.status}`;
|
|
2003
|
-
throw new AccountRequestError(code, code);
|
|
2004
|
-
}
|
|
2005
|
-
return value;
|
|
2006
2490
|
}
|
|
2007
|
-
/**
|
|
2008
|
-
function
|
|
2009
|
-
|
|
2010
|
-
const [status, setStatus] = (0, react.useState)({ status: "loading" });
|
|
2011
|
-
const [busy, setBusy] = (0, react.useState)(false);
|
|
2491
|
+
/** Recovery links, errors and trusted-origin guidance in either account entry. */
|
|
2492
|
+
function AccountFeedback({ t, snapshot }) {
|
|
2493
|
+
const { status, loginUrl } = snapshot;
|
|
2012
2494
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
2013
2495
|
const [copyFailed, setCopyFailed] = (0, react.useState)(false);
|
|
2014
|
-
const [loginUrl, setLoginUrl] = (0, react.useState)();
|
|
2015
|
-
const mounted = (0, react.useRef)(true);
|
|
2016
2496
|
const trustedOriginCommand = `dsh plugin --profile web exec dsh-codex-connect trust-origin ${window.location.origin}`;
|
|
2017
|
-
(0, react.useEffect)(() => {
|
|
2018
|
-
mounted.current = true;
|
|
2019
|
-
return () => {
|
|
2020
|
-
mounted.current = false;
|
|
2021
|
-
};
|
|
2022
|
-
}, []);
|
|
2023
|
-
const refresh = (0, react.useCallback)(async (signal) => {
|
|
2024
|
-
try {
|
|
2025
|
-
const nextStatus = await jsonRequest(OPENAI_CODEX_AUTH_STATUS_PATH, "GET", signal);
|
|
2026
|
-
if (mounted.current && signal?.aborted !== true) setStatus(nextStatus);
|
|
2027
|
-
} catch (error) {
|
|
2028
|
-
if (mounted.current && signal?.aborted !== true) setStatus(error instanceof AccountRequestError && error.code === "remote-web-origin-not-trusted" ? { status: "remote-web-origin-not-trusted" } : {
|
|
2029
|
-
status: "error",
|
|
2030
|
-
message: error instanceof Error ? error.message : t("requestFailed")
|
|
2031
|
-
});
|
|
2032
|
-
}
|
|
2033
|
-
}, [t]);
|
|
2034
|
-
(0, react.useEffect)(() => {
|
|
2035
|
-
const controller = new AbortController();
|
|
2036
|
-
refresh(controller.signal);
|
|
2037
|
-
return () => {
|
|
2038
|
-
controller.abort();
|
|
2039
|
-
};
|
|
2040
|
-
}, [refresh]);
|
|
2041
|
-
(0, react.useEffect)(() => {
|
|
2042
|
-
const interval = status.status === "signing-in" ? POLL_INTERVAL_MS : status.status === "signed-in" ? USAGE_POLL_INTERVAL_MS$1 : void 0;
|
|
2043
|
-
if (interval === void 0) return;
|
|
2044
|
-
const controller = new AbortController();
|
|
2045
|
-
const timer = window.setInterval(() => {
|
|
2046
|
-
refresh(controller.signal);
|
|
2047
|
-
}, interval);
|
|
2048
|
-
return () => {
|
|
2049
|
-
window.clearInterval(timer);
|
|
2050
|
-
controller.abort();
|
|
2051
|
-
};
|
|
2052
|
-
}, [refresh, status.status]);
|
|
2053
|
-
(0, react.useEffect)(() => {
|
|
2054
|
-
if (status.status !== "signing-in") setLoginUrl(void 0);
|
|
2055
|
-
}, [status.status]);
|
|
2056
|
-
const signIn = async () => {
|
|
2057
|
-
const popup = window.open("about:blank", "_blank");
|
|
2058
|
-
if (popup !== null) popup.opener = null;
|
|
2059
|
-
setBusy(true);
|
|
2060
|
-
setStatus({ status: "signing-in" });
|
|
2061
|
-
try {
|
|
2062
|
-
const challenge = await jsonRequest(OPENAI_CODEX_AUTH_LOGIN_PATH, "POST");
|
|
2063
|
-
if (!mounted.current) {
|
|
2064
|
-
popup?.close();
|
|
2065
|
-
return;
|
|
2066
|
-
}
|
|
2067
|
-
if (popup !== null) {
|
|
2068
|
-
setLoginUrl(void 0);
|
|
2069
|
-
popup.location.replace(challenge.url);
|
|
2070
|
-
} else setLoginUrl(challenge.url);
|
|
2071
|
-
} catch (error) {
|
|
2072
|
-
popup?.close();
|
|
2073
|
-
setLoginUrl(void 0);
|
|
2074
|
-
if (mounted.current) setStatus(error instanceof AccountRequestError && error.code === "remote-web-origin-not-trusted" ? { status: "remote-web-origin-not-trusted" } : {
|
|
2075
|
-
status: "error",
|
|
2076
|
-
message: error instanceof Error ? error.message : t("requestFailed")
|
|
2077
|
-
});
|
|
2078
|
-
} finally {
|
|
2079
|
-
if (mounted.current) setBusy(false);
|
|
2080
|
-
}
|
|
2081
|
-
};
|
|
2082
2497
|
const copyTrustedOriginCommand = async () => {
|
|
2083
2498
|
setCopyFailed(false);
|
|
2084
2499
|
try {
|
|
2085
2500
|
if (navigator.clipboard?.writeText === void 0) throw new Error("clipboard unavailable");
|
|
2086
2501
|
await navigator.clipboard.writeText(trustedOriginCommand);
|
|
2087
|
-
|
|
2502
|
+
setCopied(true);
|
|
2088
2503
|
} catch {
|
|
2089
|
-
|
|
2090
|
-
}
|
|
2091
|
-
};
|
|
2092
|
-
const signOut = async () => {
|
|
2093
|
-
setBusy(true);
|
|
2094
|
-
try {
|
|
2095
|
-
await jsonRequest(OPENAI_CODEX_AUTH_LOGOUT_PATH, "POST");
|
|
2096
|
-
if (mounted.current) setStatus({ status: "signed-out" });
|
|
2097
|
-
} catch (error) {
|
|
2098
|
-
if (mounted.current) setStatus({
|
|
2099
|
-
status: "error",
|
|
2100
|
-
message: error instanceof Error ? error.message : t("requestFailed")
|
|
2101
|
-
});
|
|
2102
|
-
} finally {
|
|
2103
|
-
if (mounted.current) setBusy(false);
|
|
2504
|
+
setCopyFailed(true);
|
|
2104
2505
|
}
|
|
2105
2506
|
};
|
|
2106
|
-
|
|
2507
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2508
|
+
loginUrl === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2509
|
+
style: {
|
|
2510
|
+
display: "flex",
|
|
2511
|
+
flexDirection: "column",
|
|
2512
|
+
alignItems: "flex-start",
|
|
2513
|
+
gap: 10
|
|
2514
|
+
},
|
|
2515
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2516
|
+
style: bodyStyle,
|
|
2517
|
+
children: t("authorizationHelp")
|
|
2518
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2519
|
+
href: loginUrl,
|
|
2520
|
+
target: "_blank",
|
|
2521
|
+
rel: "noopener noreferrer",
|
|
2522
|
+
style: {
|
|
2523
|
+
...primaryButtonStyle,
|
|
2524
|
+
display: "inline-flex",
|
|
2525
|
+
alignItems: "center",
|
|
2526
|
+
textDecoration: "none"
|
|
2527
|
+
},
|
|
2528
|
+
children: t("openLoginInBrowser")
|
|
2529
|
+
})]
|
|
2530
|
+
}),
|
|
2531
|
+
status.status === "error" || status.status === "reauth-required" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2532
|
+
style: errorStyle$1,
|
|
2533
|
+
children: status.message
|
|
2534
|
+
}) : null,
|
|
2535
|
+
status.status === "remote-web-origin-not-trusted" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2536
|
+
style: {
|
|
2537
|
+
display: "flex",
|
|
2538
|
+
flexDirection: "column",
|
|
2539
|
+
gap: 10
|
|
2540
|
+
},
|
|
2541
|
+
children: [
|
|
2542
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2543
|
+
style: errorStyle$1,
|
|
2544
|
+
children: t("remoteOriginDescription")
|
|
2545
|
+
}),
|
|
2546
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2547
|
+
style: bodyStyle,
|
|
2548
|
+
children: t("remoteOriginCommandHelp")
|
|
2549
|
+
}),
|
|
2550
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
2551
|
+
style: commandStyle,
|
|
2552
|
+
children: trustedOriginCommand
|
|
2553
|
+
}),
|
|
2554
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2555
|
+
style: rowStyle,
|
|
2556
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2557
|
+
type: "button",
|
|
2558
|
+
style: buttonStyle$1,
|
|
2559
|
+
onClick: () => {
|
|
2560
|
+
copyTrustedOriginCommand();
|
|
2561
|
+
},
|
|
2562
|
+
children: copied ? t("remoteOriginCopied") : t("remoteOriginCopy")
|
|
2563
|
+
}), copyFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2564
|
+
style: errorStyle$1,
|
|
2565
|
+
children: t("remoteOriginCopyFailed")
|
|
2566
|
+
}) : null]
|
|
2567
|
+
})
|
|
2568
|
+
]
|
|
2569
|
+
}) : null
|
|
2570
|
+
] });
|
|
2571
|
+
}
|
|
2572
|
+
/** OpenAI Codex account status and OAuth actions. */
|
|
2573
|
+
function OpenAICodexSettings({ t, configScope, updater, account, embedded = false, accountOnly = false }) {
|
|
2574
|
+
if (t === void 0) throw new Error("OpenAI Codex settings requires its translation function");
|
|
2575
|
+
const [localAccount] = (0, react.useState)(() => new OpenAICodexAccountStore());
|
|
2576
|
+
const store = account ?? localAccount;
|
|
2577
|
+
const snapshot = (0, react.useSyncExternalStore)(store.subscribe, store.getSnapshot);
|
|
2578
|
+
const { status } = snapshot;
|
|
2579
|
+
const titleId = (0, react.useId)();
|
|
2580
|
+
const label = accountStatusLabel(status.status, t);
|
|
2107
2581
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2108
2582
|
style: embedded ? embeddedPageStyle : pageStyle,
|
|
2109
|
-
...embedded ? { "aria-label": t("title") } : { "aria-labelledby":
|
|
2583
|
+
...embedded ? { "aria-label": t("title") } : { "aria-labelledby": titleId },
|
|
2110
2584
|
children: [embedded ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
2111
|
-
id:
|
|
2585
|
+
id: titleId,
|
|
2112
2586
|
style: titleStyle,
|
|
2113
2587
|
children: t("title")
|
|
2114
2588
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -2120,7 +2594,7 @@ window.__ModuleLoader__.load({
|
|
|
2120
2594
|
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2121
2595
|
style: embedded ? embeddedCardStyle : cardStyle$1,
|
|
2122
2596
|
children: [
|
|
2123
|
-
updater === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexUpdateSettings, {
|
|
2597
|
+
accountOnly || updater === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexUpdateSettings, {
|
|
2124
2598
|
t,
|
|
2125
2599
|
updater
|
|
2126
2600
|
}),
|
|
@@ -2137,92 +2611,25 @@ window.__ModuleLoader__.load({
|
|
|
2137
2611
|
"aria-hidden": "true",
|
|
2138
2612
|
style: dotStyle(status.status)
|
|
2139
2613
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label })]
|
|
2140
|
-
}),
|
|
2141
|
-
|
|
2142
|
-
|
|
2143
|
-
|
|
2144
|
-
onClick: () => {
|
|
2145
|
-
signOut();
|
|
2146
|
-
},
|
|
2147
|
-
children: busy ? t("working") : t("logout")
|
|
2148
|
-
}) : status.status === "signing-in" && loginUrl !== void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2149
|
-
type: "button",
|
|
2150
|
-
style: primaryButtonStyle,
|
|
2151
|
-
disabled: busy,
|
|
2152
|
-
onClick: () => {
|
|
2153
|
-
signIn();
|
|
2154
|
-
},
|
|
2155
|
-
children: busy ? t("working") : status.status === "error" || status.status === "reauth-required" ? t("loginAgain") : t("login")
|
|
2614
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountActions, {
|
|
2615
|
+
t,
|
|
2616
|
+
store,
|
|
2617
|
+
snapshot
|
|
2156
2618
|
})]
|
|
2157
2619
|
}),
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
flexDirection: "column",
|
|
2162
|
-
alignItems: "flex-start",
|
|
2163
|
-
gap: 10
|
|
2164
|
-
},
|
|
2165
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2166
|
-
style: bodyStyle,
|
|
2167
|
-
children: t("popupBlockedFallback")
|
|
2168
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2169
|
-
href: loginUrl,
|
|
2170
|
-
target: "_blank",
|
|
2171
|
-
rel: "noopener noreferrer",
|
|
2172
|
-
style: {
|
|
2173
|
-
...primaryButtonStyle,
|
|
2174
|
-
display: "inline-flex",
|
|
2175
|
-
alignItems: "center",
|
|
2176
|
-
textDecoration: "none"
|
|
2177
|
-
},
|
|
2178
|
-
children: t("openLoginInBrowser")
|
|
2179
|
-
})]
|
|
2620
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountFeedback, {
|
|
2621
|
+
t,
|
|
2622
|
+
snapshot
|
|
2180
2623
|
}),
|
|
2181
|
-
status.status === "error" || status.status === "reauth-required" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2182
|
-
style: errorStyle$1,
|
|
2183
|
-
children: status.message
|
|
2184
|
-
}) : null,
|
|
2185
|
-
status.status === "remote-web-origin-not-trusted" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2186
|
-
style: {
|
|
2187
|
-
display: "flex",
|
|
2188
|
-
flexDirection: "column",
|
|
2189
|
-
gap: 10
|
|
2190
|
-
},
|
|
2191
|
-
children: [
|
|
2192
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2193
|
-
style: errorStyle$1,
|
|
2194
|
-
children: t("remoteOriginDescription")
|
|
2195
|
-
}),
|
|
2196
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2197
|
-
style: bodyStyle,
|
|
2198
|
-
children: t("remoteOriginCommandHelp")
|
|
2199
|
-
}),
|
|
2200
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
2201
|
-
style: commandStyle,
|
|
2202
|
-
children: trustedOriginCommand
|
|
2203
|
-
}),
|
|
2204
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2205
|
-
style: rowStyle,
|
|
2206
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2207
|
-
type: "button",
|
|
2208
|
-
style: buttonStyle,
|
|
2209
|
-
onClick: () => {
|
|
2210
|
-
copyTrustedOriginCommand();
|
|
2211
|
-
},
|
|
2212
|
-
children: copied ? t("remoteOriginCopied") : t("remoteOriginCopy")
|
|
2213
|
-
}), copyFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2214
|
-
style: errorStyle$1,
|
|
2215
|
-
children: t("remoteOriginCopyFailed")
|
|
2216
|
-
}) : null]
|
|
2217
|
-
})
|
|
2218
|
-
]
|
|
2219
|
-
}) : null,
|
|
2220
2624
|
status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageLimits, {
|
|
2221
2625
|
usage: status.usage,
|
|
2222
2626
|
...status.quotaError === void 0 ? {} : { quotaError: status.quotaError },
|
|
2223
2627
|
t
|
|
2224
2628
|
}) : null,
|
|
2225
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2629
|
+
accountOnly ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2630
|
+
style: bodyStyle,
|
|
2631
|
+
children: t("modelsAccountHelp")
|
|
2632
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexConfiguration, {
|
|
2226
2633
|
t,
|
|
2227
2634
|
...configScope === void 0 ? {} : { scope: configScope }
|
|
2228
2635
|
})
|
|
@@ -2300,7 +2707,7 @@ window.__ModuleLoader__.load({
|
|
|
2300
2707
|
});
|
|
2301
2708
|
}
|
|
2302
2709
|
/** Render account management as one expandable Plugin configuration card. */
|
|
2303
|
-
function OpenAICodexPluginCard({ t, configScope, updater }) {
|
|
2710
|
+
function OpenAICodexPluginCard({ t, configScope, updater, account }) {
|
|
2304
2711
|
if (t === void 0) throw new Error("OpenAI Codex plugin card requires its translation function");
|
|
2305
2712
|
const [open, setOpen] = (0, react.useState)(false);
|
|
2306
2713
|
const title = t("title");
|
|
@@ -2331,6 +2738,7 @@ window.__ModuleLoader__.load({
|
|
|
2331
2738
|
style: cardBodyStyle,
|
|
2332
2739
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexSettings, {
|
|
2333
2740
|
t,
|
|
2741
|
+
...account === void 0 ? {} : { account },
|
|
2334
2742
|
...updater === void 0 ? {} : { updater },
|
|
2335
2743
|
embedded: true,
|
|
2336
2744
|
...configScope === void 0 ? {} : { configScope }
|
|
@@ -2761,8 +3169,24 @@ window.__ModuleLoader__.load({
|
|
|
2761
3169
|
/** English copy for the OpenAI Codex Plugin configuration card. */
|
|
2762
3170
|
const en = {
|
|
2763
3171
|
title: "Codex Connect",
|
|
3172
|
+
modelsProviderName: "Openai-Codex",
|
|
3173
|
+
modelsProviderSupport: "Powered by the Codex Connect plugin.",
|
|
2764
3174
|
intro: "Use your ChatGPT subscription in dsh, with optional GPT Image generation and no API key.",
|
|
2765
3175
|
accountHeading: "ChatGPT account",
|
|
3176
|
+
manageAccount: "Manage",
|
|
3177
|
+
authorize: "Authorize",
|
|
3178
|
+
continueAuthorization: "Continue authorization",
|
|
3179
|
+
reauthorize: "Reauthorize",
|
|
3180
|
+
viewQuota: "View quota",
|
|
3181
|
+
hideQuota: "Hide quota",
|
|
3182
|
+
moreSettings: "More settings",
|
|
3183
|
+
moreSettingsTitle: "Codex Connect settings",
|
|
3184
|
+
closeSettings: "Close",
|
|
3185
|
+
settingsSaveHint: "Save applies changes to both settings entries. Closing discards unsaved changes.",
|
|
3186
|
+
reopenAuthorization: "Reopen authorization",
|
|
3187
|
+
cancelSignIn: "Cancel sign-in",
|
|
3188
|
+
authorizationHelp: "You can reopen the authorization page or cancel and start again. Cancelling does not sign out an existing account.",
|
|
3189
|
+
modelsAccountHelp: "Proxy, model visibility, search and image options remain in Settings → Plugins → Codex Connect, or open them here:",
|
|
2766
3190
|
expand: "Expand settings",
|
|
2767
3191
|
collapse: "Collapse settings",
|
|
2768
3192
|
loadingAccount: "Loading account…",
|
|
@@ -2810,6 +3234,20 @@ window.__ModuleLoader__.load({
|
|
|
2810
3234
|
modelCatalogIntro: "Choose which Codex models appear in model selectors. Existing conversations can continue using a hidden model.",
|
|
2811
3235
|
modelCatalogLoading: "Loading available models…",
|
|
2812
3236
|
modelCatalogFailed: "Available models could not be loaded.",
|
|
3237
|
+
modelContext: "Context",
|
|
3238
|
+
contextDefault: "Catalog default",
|
|
3239
|
+
contextCustom: "Custom",
|
|
3240
|
+
contextAdjust: "Adjust",
|
|
3241
|
+
contextHide: "Hide adjustment",
|
|
3242
|
+
contextTokens: "Context length",
|
|
3243
|
+
contextReset: "Restore default",
|
|
3244
|
+
contextSlider: "Adjust context budget",
|
|
3245
|
+
contextMaximum: "Configuration limit",
|
|
3246
|
+
contextLimitSource: "Source: official Codex configuration catalog (2026-08-28)",
|
|
3247
|
+
contextLimitFallback: "No higher configuration limit confirmed; capped at the installed catalog default.",
|
|
3248
|
+
contextAboveDefault: "Above the catalog default: larger requests may consume more quota or be rejected by your account or route. This plugin has not capacity-tested this range.",
|
|
3249
|
+
contextWarning: "Context overrides change client budgeting, not server capacity. An excessive value can cause requests to fail. Hiding a model keeps its budget. Changes apply after Save.",
|
|
3250
|
+
contextInvalid: "Enter a whole-number budget within the model’s configuration range, or choose Restore default.",
|
|
2813
3251
|
capabilitiesHeading: "Optional capabilities",
|
|
2814
3252
|
capabilitiesIntro: "Choose which extra Codex capabilities this dsh profile may register.",
|
|
2815
3253
|
networkHeading: "Network connection",
|
|
@@ -2945,6 +3383,9 @@ window.__ModuleLoader__.load({
|
|
|
2945
3383
|
updateHighlightOauthHistory: "Added safer session-history migration and a sign-in fallback when the account needs to reconnect.",
|
|
2946
3384
|
updateHighlightModelVisibility: "You can now choose which Codex models appear in model selectors.",
|
|
2947
3385
|
updateHighlightProxyConnection: "Added opt-in Codex proxy detection with explicit confirmation and a visible direct-connection fallback.",
|
|
3386
|
+
updateHighlightModelsAccount: "Added an Openai-Codex account card in Models settings for authorization, quota, and shared plugin settings.",
|
|
3387
|
+
updateHighlightContextBudget: "Added bounded per-model context budget controls while preserving each catalog default until you save an override.",
|
|
3388
|
+
updateHighlightAutoReviewProbe: "Added an explicit, synthetic probe for checking whether the hidden Codex approval reviewer is available without enabling it.",
|
|
2948
3389
|
viewTechnicalDetails: "View technical details",
|
|
2949
3390
|
hideTechnicalDetails: "Hide technical details",
|
|
2950
3391
|
technicalDetailsHeading: "Technical changes",
|
|
@@ -2970,8 +3411,24 @@ window.__ModuleLoader__.load({
|
|
|
2970
3411
|
/** Chinese copy for the OpenAI Codex Plugin configuration card. */
|
|
2971
3412
|
const zh = {
|
|
2972
3413
|
title: "Codex Connect",
|
|
3414
|
+
modelsProviderName: "Openai-Codex",
|
|
3415
|
+
modelsProviderSupport: "由 Codex Connect 插件提供支持。",
|
|
2973
3416
|
intro: "使用 ChatGPT 订阅在 dsh 中调用模型,并可使用 GPT Image 生成图片,无需 API Key。",
|
|
2974
3417
|
accountHeading: "ChatGPT 账户",
|
|
3418
|
+
manageAccount: "管理",
|
|
3419
|
+
authorize: "授权",
|
|
3420
|
+
continueAuthorization: "继续授权",
|
|
3421
|
+
reauthorize: "重新授权",
|
|
3422
|
+
viewQuota: "查看额度",
|
|
3423
|
+
hideQuota: "收起额度",
|
|
3424
|
+
moreSettings: "更多设置",
|
|
3425
|
+
moreSettingsTitle: "Codex Connect 设置",
|
|
3426
|
+
closeSettings: "关闭",
|
|
3427
|
+
settingsSaveHint: "保存后两处设置同步生效;关闭将放弃未保存的修改。",
|
|
3428
|
+
reopenAuthorization: "重新打开授权",
|
|
3429
|
+
cancelSignIn: "取消登录",
|
|
3430
|
+
authorizationHelp: "可以重新打开授权页,或取消后重试。取消登录不会退出已有账户。",
|
|
3431
|
+
modelsAccountHelp: "代理、模型显示、搜索和图片选项仍可在“设置 → 插件 → Codex Connect”中管理,也可直接打开:",
|
|
2975
3432
|
expand: "展开设置",
|
|
2976
3433
|
collapse: "折叠设置",
|
|
2977
3434
|
loadingAccount: "正在加载账户信息…",
|
|
@@ -3019,6 +3476,20 @@ window.__ModuleLoader__.load({
|
|
|
3019
3476
|
modelCatalogIntro: "选择要在模型选择器中显示的 Codex 模型;隐藏模型后,已有会话仍可继续使用。",
|
|
3020
3477
|
modelCatalogLoading: "正在加载可用模型…",
|
|
3021
3478
|
modelCatalogFailed: "无法加载可用模型。",
|
|
3479
|
+
modelContext: "上下文",
|
|
3480
|
+
contextDefault: "目录默认",
|
|
3481
|
+
contextCustom: "自定义",
|
|
3482
|
+
contextAdjust: "调整",
|
|
3483
|
+
contextHide: "收起调整",
|
|
3484
|
+
contextTokens: "上下文长度",
|
|
3485
|
+
contextReset: "恢复默认",
|
|
3486
|
+
contextSlider: "调整上下文预算",
|
|
3487
|
+
contextMaximum: "配置上限",
|
|
3488
|
+
contextLimitSource: "依据:Codex 官方配置目录(2026-08-28)",
|
|
3489
|
+
contextLimitFallback: "尚未确认更高配置上限,暂以已安装目录的默认值为上限。",
|
|
3490
|
+
contextAboveDefault: "已超过目录默认值:请求可能消耗更多额度,或被当前账号、通道拒绝。本插件未对该范围进行容量实测。",
|
|
3491
|
+
contextWarning: "调整的是本地上下文预算,不会扩大服务端容量;设置过高可能导致请求失败。隐藏模型会保留其预算,修改在保存后生效。",
|
|
3492
|
+
contextInvalid: "请输入模型配置范围内的整数预算,或点击“恢复默认”。",
|
|
3022
3493
|
capabilitiesHeading: "可选能力",
|
|
3023
3494
|
capabilitiesIntro: "选择允许此 dsh profile 注册哪些额外的 Codex 能力。",
|
|
3024
3495
|
networkHeading: "网络连接",
|
|
@@ -3154,6 +3625,9 @@ window.__ModuleLoader__.load({
|
|
|
3154
3625
|
updateHighlightOauthHistory: "增加更安全的会话历史迁移,并在账号需要重新登录时提供备用登录路径。",
|
|
3155
3626
|
updateHighlightModelVisibility: "现在可以选择哪些 Codex 模型显示在模型选择菜单中。",
|
|
3156
3627
|
updateHighlightProxyConnection: "增加可选的 Codex 代理检测,启用前需要明确确认,并始终保留直连回退入口。",
|
|
3628
|
+
updateHighlightModelsAccount: "在模型设置中增加 Openai-Codex 账户卡,用于授权、查看额度和打开共享插件设置。",
|
|
3629
|
+
updateHighlightContextBudget: "增加有范围限制的逐模型上下文预算设置;保存覆盖值前继续使用各模型的目录默认值。",
|
|
3630
|
+
updateHighlightAutoReviewProbe: "增加显式的合成探针,用于检查隐藏的 Codex 审批 reviewer 是否可用,但不会启用该能力。",
|
|
3157
3631
|
viewTechnicalDetails: "查看完整技术说明",
|
|
3158
3632
|
hideTechnicalDetails: "收起技术说明",
|
|
3159
3633
|
technicalDetailsHeading: "技术变更",
|
|
@@ -3270,7 +3744,7 @@ window.__ModuleLoader__.load({
|
|
|
3270
3744
|
//#region src/client/CodexImageGallery.tsx
|
|
3271
3745
|
/** Self-contained result-image gallery for the tool-call view.
|
|
3272
3746
|
*
|
|
3273
|
-
* DSH
|
|
3747
|
+
* DSH keeps the attachment package's React atoms behind its
|
|
3274
3748
|
* conversation slots. A tool-call view cannot render those slots, so this
|
|
3275
3749
|
* gallery owns only the durable-image presentation it needs and receives all
|
|
3276
3750
|
* stateful work through props.
|
|
@@ -3441,7 +3915,6 @@ window.__ModuleLoader__.load({
|
|
|
3441
3915
|
open: true,
|
|
3442
3916
|
onClose,
|
|
3443
3917
|
title: labels.dialog,
|
|
3444
|
-
closeLabel: labels.close,
|
|
3445
3918
|
headless: true,
|
|
3446
3919
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3447
3920
|
ref: lightbox,
|
|
@@ -4340,7 +4813,232 @@ window.__ModuleLoader__.load({
|
|
|
4340
4813
|
}
|
|
4341
4814
|
//#endregion
|
|
4342
4815
|
//#region src/version.ts
|
|
4343
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
4816
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.23";
|
|
4817
|
+
//#endregion
|
|
4818
|
+
//#region src/client/OpenAICodexModelsCard.tsx
|
|
4819
|
+
/** Compact Models account entry with quota disclosure and shared configuration. */
|
|
4820
|
+
const buttonStyle = {
|
|
4821
|
+
padding: "6px 14px",
|
|
4822
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4823
|
+
borderRadius: 999,
|
|
4824
|
+
background: "transparent",
|
|
4825
|
+
color: "inherit",
|
|
4826
|
+
font: "inherit",
|
|
4827
|
+
fontSize: 14,
|
|
4828
|
+
cursor: "pointer"
|
|
4829
|
+
};
|
|
4830
|
+
const secondaryStyle = {
|
|
4831
|
+
fontSize: 12,
|
|
4832
|
+
lineHeight: "18px",
|
|
4833
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
4834
|
+
};
|
|
4835
|
+
/** Native modality contains keyboard focus and restores it to More settings on close. */
|
|
4836
|
+
function ConfigurationDialog({ t, configScope, onClose }) {
|
|
4837
|
+
const dialog = (0, react.useRef)(null);
|
|
4838
|
+
const titleId = (0, react.useId)();
|
|
4839
|
+
(0, react.useEffect)(() => {
|
|
4840
|
+
const element = dialog.current;
|
|
4841
|
+
element?.showModal();
|
|
4842
|
+
return () => {
|
|
4843
|
+
element?.close();
|
|
4844
|
+
};
|
|
4845
|
+
}, []);
|
|
4846
|
+
const close = () => {
|
|
4847
|
+
dialog.current?.close();
|
|
4848
|
+
onClose();
|
|
4849
|
+
};
|
|
4850
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dialog", {
|
|
4851
|
+
ref: dialog,
|
|
4852
|
+
"aria-labelledby": titleId,
|
|
4853
|
+
onCancel: (event) => {
|
|
4854
|
+
event.preventDefault();
|
|
4855
|
+
close();
|
|
4856
|
+
},
|
|
4857
|
+
onKeyDown: (event) => {
|
|
4858
|
+
if (event.key !== "Escape") return;
|
|
4859
|
+
event.stopPropagation();
|
|
4860
|
+
event.preventDefault();
|
|
4861
|
+
close();
|
|
4862
|
+
},
|
|
4863
|
+
style: {
|
|
4864
|
+
boxSizing: "border-box",
|
|
4865
|
+
width: "min(720px, calc(100vw - 32px))",
|
|
4866
|
+
maxHeight: "calc(100dvh - 32px)",
|
|
4867
|
+
overflowY: "auto",
|
|
4868
|
+
padding: 20,
|
|
4869
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4870
|
+
borderRadius: 12,
|
|
4871
|
+
background: "var(--dsw-alias-bg-layer-1, white)",
|
|
4872
|
+
color: "var(--dsw-alias-label-primary)",
|
|
4873
|
+
margin: "auto"
|
|
4874
|
+
},
|
|
4875
|
+
children: [
|
|
4876
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4877
|
+
style: {
|
|
4878
|
+
display: "flex",
|
|
4879
|
+
alignItems: "center",
|
|
4880
|
+
justifyContent: "space-between",
|
|
4881
|
+
gap: 12
|
|
4882
|
+
},
|
|
4883
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
4884
|
+
id: titleId,
|
|
4885
|
+
style: {
|
|
4886
|
+
margin: 0,
|
|
4887
|
+
fontSize: 18
|
|
4888
|
+
},
|
|
4889
|
+
children: t("moreSettingsTitle")
|
|
4890
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4891
|
+
type: "button",
|
|
4892
|
+
style: buttonStyle,
|
|
4893
|
+
onClick: close,
|
|
4894
|
+
children: t("closeSettings")
|
|
4895
|
+
})]
|
|
4896
|
+
}),
|
|
4897
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4898
|
+
style: secondaryStyle,
|
|
4899
|
+
children: t("settingsSaveHint")
|
|
4900
|
+
}),
|
|
4901
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexConfiguration, {
|
|
4902
|
+
t,
|
|
4903
|
+
...configScope === void 0 ? {} : { scope: configScope }
|
|
4904
|
+
})
|
|
4905
|
+
]
|
|
4906
|
+
});
|
|
4907
|
+
}
|
|
4908
|
+
function OpenAICodexModelsCard({ t, account, configScope }) {
|
|
4909
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
4910
|
+
const [settingsOpen, setSettingsOpen] = (0, react.useState)(false);
|
|
4911
|
+
const detailsId = (0, react.useId)();
|
|
4912
|
+
const snapshot = (0, react.useSyncExternalStore)(account.subscribe, account.getSnapshot);
|
|
4913
|
+
const { status } = snapshot;
|
|
4914
|
+
const label = accountStatusLabel(status.status, t);
|
|
4915
|
+
(0, react.useEffect)(() => {
|
|
4916
|
+
if (status.status !== "signed-in") setExpanded(false);
|
|
4917
|
+
}, [status.status]);
|
|
4918
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4919
|
+
style: {
|
|
4920
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4921
|
+
borderRadius: 12,
|
|
4922
|
+
padding: "12px 14px",
|
|
4923
|
+
color: "var(--dsw-alias-label-primary)"
|
|
4924
|
+
},
|
|
4925
|
+
children: [
|
|
4926
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4927
|
+
style: {
|
|
4928
|
+
display: "flex",
|
|
4929
|
+
alignItems: "center",
|
|
4930
|
+
flexWrap: "wrap",
|
|
4931
|
+
gap: 10
|
|
4932
|
+
},
|
|
4933
|
+
children: [
|
|
4934
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4935
|
+
style: {
|
|
4936
|
+
fontSize: 14,
|
|
4937
|
+
lineHeight: "22px",
|
|
4938
|
+
fontWeight: 500
|
|
4939
|
+
},
|
|
4940
|
+
children: t("modelsProviderName")
|
|
4941
|
+
}),
|
|
4942
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4943
|
+
"aria-hidden": "true",
|
|
4944
|
+
style: {
|
|
4945
|
+
...dotStyle(status.status),
|
|
4946
|
+
width: 8,
|
|
4947
|
+
height: 8
|
|
4948
|
+
}
|
|
4949
|
+
}),
|
|
4950
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4951
|
+
role: "status",
|
|
4952
|
+
style: {
|
|
4953
|
+
...secondaryStyle,
|
|
4954
|
+
flex: 1
|
|
4955
|
+
},
|
|
4956
|
+
children: label
|
|
4957
|
+
}),
|
|
4958
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4959
|
+
style: {
|
|
4960
|
+
display: "flex",
|
|
4961
|
+
flexWrap: "wrap",
|
|
4962
|
+
gap: 8,
|
|
4963
|
+
marginLeft: "auto"
|
|
4964
|
+
},
|
|
4965
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountActions, {
|
|
4966
|
+
t,
|
|
4967
|
+
store: account,
|
|
4968
|
+
snapshot,
|
|
4969
|
+
compact: true
|
|
4970
|
+
}), status.status === "signed-in" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4971
|
+
type: "button",
|
|
4972
|
+
"aria-expanded": expanded,
|
|
4973
|
+
"aria-controls": detailsId,
|
|
4974
|
+
onClick: () => {
|
|
4975
|
+
setExpanded(!expanded);
|
|
4976
|
+
},
|
|
4977
|
+
style: buttonStyle,
|
|
4978
|
+
children: t(expanded ? "hideQuota" : "viewQuota")
|
|
4979
|
+
})]
|
|
4980
|
+
})
|
|
4981
|
+
]
|
|
4982
|
+
}),
|
|
4983
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4984
|
+
style: {
|
|
4985
|
+
...secondaryStyle,
|
|
4986
|
+
marginTop: 4
|
|
4987
|
+
},
|
|
4988
|
+
children: t("modelsProviderSupport")
|
|
4989
|
+
}),
|
|
4990
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountFeedback, {
|
|
4991
|
+
t,
|
|
4992
|
+
snapshot
|
|
4993
|
+
}),
|
|
4994
|
+
expanded && status.status === "signed-in" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4995
|
+
id: detailsId,
|
|
4996
|
+
style: {
|
|
4997
|
+
borderTop: "1px solid var(--dsw-alias-border-l2)",
|
|
4998
|
+
marginTop: 12,
|
|
4999
|
+
paddingTop: 12
|
|
5000
|
+
},
|
|
5001
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageLimits, {
|
|
5002
|
+
t,
|
|
5003
|
+
usage: status.usage,
|
|
5004
|
+
heading: false,
|
|
5005
|
+
...status.quotaError === void 0 ? {} : { quotaError: status.quotaError }
|
|
5006
|
+
})
|
|
5007
|
+
}),
|
|
5008
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5009
|
+
style: {
|
|
5010
|
+
...secondaryStyle,
|
|
5011
|
+
marginTop: 12
|
|
5012
|
+
},
|
|
5013
|
+
children: [
|
|
5014
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("modelsAccountHelp") }),
|
|
5015
|
+
" ",
|
|
5016
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5017
|
+
type: "button",
|
|
5018
|
+
onClick: () => {
|
|
5019
|
+
setSettingsOpen(true);
|
|
5020
|
+
},
|
|
5021
|
+
style: {
|
|
5022
|
+
...buttonStyle,
|
|
5023
|
+
padding: 0,
|
|
5024
|
+
border: 0,
|
|
5025
|
+
fontSize: "inherit",
|
|
5026
|
+
textDecoration: "underline"
|
|
5027
|
+
},
|
|
5028
|
+
children: t("moreSettings")
|
|
5029
|
+
})
|
|
5030
|
+
]
|
|
5031
|
+
}),
|
|
5032
|
+
settingsOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigurationDialog, {
|
|
5033
|
+
t,
|
|
5034
|
+
...configScope === void 0 ? {} : { configScope },
|
|
5035
|
+
onClose: () => {
|
|
5036
|
+
setSettingsOpen(false);
|
|
5037
|
+
}
|
|
5038
|
+
})
|
|
5039
|
+
]
|
|
5040
|
+
});
|
|
5041
|
+
}
|
|
4344
5042
|
//#endregion
|
|
4345
5043
|
//#region src/client/index.tsx
|
|
4346
5044
|
/** Stable browser-plugin name. */
|
|
@@ -4351,6 +5049,7 @@ window.__ModuleLoader__.load({
|
|
|
4351
5049
|
"locale",
|
|
4352
5050
|
"connection",
|
|
4353
5051
|
"remote",
|
|
5052
|
+
"remote.session",
|
|
4354
5053
|
"settingsScope",
|
|
4355
5054
|
"sessions"
|
|
4356
5055
|
];
|
|
@@ -4358,6 +5057,10 @@ window.__ModuleLoader__.load({
|
|
|
4358
5057
|
function apply(ctx) {
|
|
4359
5058
|
const namespace = "settings.openai-codex";
|
|
4360
5059
|
const updater = new OpenAICodexUpdateStore(CODEX_CONNECT_VERSION);
|
|
5060
|
+
const account = new OpenAICodexAccountStore();
|
|
5061
|
+
ctx.effect(() => () => {
|
|
5062
|
+
account.dispose();
|
|
5063
|
+
}, "dsh-codex-connect: account observation");
|
|
4361
5064
|
ctx.effect(() => {
|
|
4362
5065
|
updater.refresh();
|
|
4363
5066
|
return () => {
|
|
@@ -4379,9 +5082,20 @@ window.__ModuleLoader__.load({
|
|
|
4379
5082
|
inject: () => ({
|
|
4380
5083
|
t,
|
|
4381
5084
|
configScope,
|
|
4382
|
-
updater
|
|
5085
|
+
updater,
|
|
5086
|
+
account
|
|
4383
5087
|
})
|
|
4384
5088
|
}, OpenAICodexPluginCard));
|
|
5089
|
+
ctx.slots.inject("settings.models.footer", () => ctx.slots.register({
|
|
5090
|
+
name: "settings.models.footer",
|
|
5091
|
+
id: "dsh-codex-connect-account",
|
|
5092
|
+
order: 100,
|
|
5093
|
+
inject: () => ({
|
|
5094
|
+
t,
|
|
5095
|
+
account,
|
|
5096
|
+
configScope
|
|
5097
|
+
})
|
|
5098
|
+
}, OpenAICodexModelsCard));
|
|
4385
5099
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
4386
5100
|
name: "shell.overlay",
|
|
4387
5101
|
id: "dsh-codex-connect-update",
|