dsh-codex-connect 0.1.0-alpha.4.21 → 0.1.0-alpha.4.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/INSTALL.md +15 -2
- package/README.i18n.yaml +2 -2
- package/README.md +41 -6
- package/compatibility.json +3 -2
- package/docs/README.zh.md +41 -6
- package/docs/design.i18n.yaml +2 -2
- package/docs/design.md +1 -1
- package/docs/design.zh.md +1 -1
- package/lib/bin.js +2 -2
- package/lib/client.js +957 -248
- package/lib/index.d.ts +39 -11
- package/lib/index.js +2 -2
- package/lib/{src-Cxq99TvF.js → src-kwF-uZCG.js} +229 -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,9 @@ 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"
|
|
869
1315
|
];
|
|
870
1316
|
function isHighlightKind(value) {
|
|
871
1317
|
return typeof value === "string" && HIGHLIGHT_KINDS.includes(value);
|
|
@@ -1255,7 +1701,7 @@ window.__ModuleLoader__.load({
|
|
|
1255
1701
|
gap: 16,
|
|
1256
1702
|
flexWrap: "wrap"
|
|
1257
1703
|
};
|
|
1258
|
-
const buttonStyle$
|
|
1704
|
+
const buttonStyle$2 = {
|
|
1259
1705
|
display: "inline-flex",
|
|
1260
1706
|
alignItems: "center",
|
|
1261
1707
|
justifyContent: "center",
|
|
@@ -1273,10 +1719,10 @@ window.__ModuleLoader__.load({
|
|
|
1273
1719
|
cursor: "pointer"
|
|
1274
1720
|
};
|
|
1275
1721
|
const primaryButtonStyle$1 = {
|
|
1276
|
-
...buttonStyle$
|
|
1277
|
-
borderColor: "var(--dsw-alias-
|
|
1278
|
-
background: "var(--dsw-alias-
|
|
1279
|
-
color: "
|
|
1722
|
+
...buttonStyle$2,
|
|
1723
|
+
borderColor: "var(--dsw-alias-button-primary-fill)",
|
|
1724
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
1725
|
+
color: "var(--dsw-alias-label-primary-foreground)"
|
|
1280
1726
|
};
|
|
1281
1727
|
const textButtonStyle = {
|
|
1282
1728
|
border: 0,
|
|
@@ -1370,7 +1816,9 @@ window.__ModuleLoader__.load({
|
|
|
1370
1816
|
"image-generation": "updateHighlightImageGeneration",
|
|
1371
1817
|
"oauth-history": "updateHighlightOauthHistory",
|
|
1372
1818
|
"model-visibility": "updateHighlightModelVisibility",
|
|
1373
|
-
"proxy-connection": "updateHighlightProxyConnection"
|
|
1819
|
+
"proxy-connection": "updateHighlightProxyConnection",
|
|
1820
|
+
"models-account": "updateHighlightModelsAccount",
|
|
1821
|
+
"context-budget": "updateHighlightContextBudget"
|
|
1374
1822
|
};
|
|
1375
1823
|
const compatibilityTitleKeys = {
|
|
1376
1824
|
compatible: "compatibilityCompatibleTitle",
|
|
@@ -1574,7 +2022,7 @@ window.__ModuleLoader__.load({
|
|
|
1574
2022
|
children: compatibilityWarning ? t("updateHeading") : available ? t("newVersionAvailable", { version: snapshot.latestVersion }) : t("updateHeading")
|
|
1575
2023
|
}), overlay ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1576
2024
|
type: "button",
|
|
1577
|
-
style: buttonStyle$
|
|
2025
|
+
style: buttonStyle$2,
|
|
1578
2026
|
"aria-label": t("dismissUpdate"),
|
|
1579
2027
|
onClick: () => {
|
|
1580
2028
|
if (noticeKey !== void 0) updater.dismiss(noticeKey);
|
|
@@ -1663,7 +2111,7 @@ window.__ModuleLoader__.load({
|
|
|
1663
2111
|
children: agentPrompt
|
|
1664
2112
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1665
2113
|
type: "button",
|
|
1666
|
-
style: buttonStyle$
|
|
2114
|
+
style: buttonStyle$2,
|
|
1667
2115
|
onClick: () => {
|
|
1668
2116
|
copy();
|
|
1669
2117
|
},
|
|
@@ -1726,7 +2174,7 @@ window.__ModuleLoader__.load({
|
|
|
1726
2174
|
},
|
|
1727
2175
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
1728
2176
|
type: "button",
|
|
1729
|
-
style: buttonStyle$
|
|
2177
|
+
style: buttonStyle$2,
|
|
1730
2178
|
disabled: snapshot.status === "checking",
|
|
1731
2179
|
onClick: () => {
|
|
1732
2180
|
updater.refresh(true);
|
|
@@ -1754,8 +2202,6 @@ window.__ModuleLoader__.load({
|
|
|
1754
2202
|
//#endregion
|
|
1755
2203
|
//#region src/client/OpenAICodexSettings.tsx
|
|
1756
2204
|
/** 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
2205
|
const pageStyle = {
|
|
1760
2206
|
display: "flex",
|
|
1761
2207
|
flexDirection: "column",
|
|
@@ -1811,7 +2257,7 @@ window.__ModuleLoader__.load({
|
|
|
1811
2257
|
fontWeight: 500,
|
|
1812
2258
|
color: "var(--dsw-alias-label-primary)"
|
|
1813
2259
|
};
|
|
1814
|
-
const buttonStyle = {
|
|
2260
|
+
const buttonStyle$1 = {
|
|
1815
2261
|
boxSizing: "border-box",
|
|
1816
2262
|
minHeight: 34,
|
|
1817
2263
|
padding: "6px 14px",
|
|
@@ -1824,10 +2270,10 @@ window.__ModuleLoader__.load({
|
|
|
1824
2270
|
cursor: "pointer"
|
|
1825
2271
|
};
|
|
1826
2272
|
const primaryButtonStyle = {
|
|
1827
|
-
...buttonStyle,
|
|
1828
|
-
borderColor: "var(--dsw-alias-
|
|
1829
|
-
background: "var(--dsw-alias-
|
|
1830
|
-
color: "
|
|
2273
|
+
...buttonStyle$1,
|
|
2274
|
+
borderColor: "var(--dsw-alias-button-primary-fill)",
|
|
2275
|
+
background: "var(--dsw-alias-button-primary-fill)",
|
|
2276
|
+
color: "var(--dsw-alias-label-primary-foreground)"
|
|
1831
2277
|
};
|
|
1832
2278
|
const errorStyle$1 = {
|
|
1833
2279
|
...bodyStyle,
|
|
@@ -1931,15 +2377,16 @@ window.__ModuleLoader__.load({
|
|
|
1931
2377
|
]
|
|
1932
2378
|
});
|
|
1933
2379
|
}
|
|
1934
|
-
|
|
2380
|
+
/** Quota rows shared by Models and Plugin settings. */
|
|
2381
|
+
function UsageLimits({ usage, quotaError, t, heading = true }) {
|
|
1935
2382
|
const hasData = usage.rateLimits.length > 0 || usage.credits !== void 0 || usage.individualLimit !== void 0;
|
|
1936
2383
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1937
2384
|
style: quotaListStyle,
|
|
1938
2385
|
children: [
|
|
1939
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
2386
|
+
heading ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("h3", {
|
|
1940
2387
|
style: quotaTitleStyle,
|
|
1941
2388
|
children: t("usageLimits")
|
|
1942
|
-
}),
|
|
2389
|
+
}) : null,
|
|
1943
2390
|
usage.rateLimits.map((limit) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1944
2391
|
style: quotaGroupStyle,
|
|
1945
2392
|
children: limit.windows.map((window) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QuotaBar, {
|
|
@@ -1973,6 +2420,7 @@ window.__ModuleLoader__.load({
|
|
|
1973
2420
|
]
|
|
1974
2421
|
});
|
|
1975
2422
|
}
|
|
2423
|
+
/** Account indicator colors shared by the compact row and expanded controls. */
|
|
1976
2424
|
function dotStyle(status) {
|
|
1977
2425
|
return {
|
|
1978
2426
|
width: 9,
|
|
@@ -1982,133 +2430,157 @@ window.__ModuleLoader__.load({
|
|
|
1982
2430
|
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
2431
|
};
|
|
1984
2432
|
}
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2433
|
+
/** Non-sensitive account state label for either settings presentation. */
|
|
2434
|
+
function accountStatusLabel(status, t) {
|
|
2435
|
+
return t({
|
|
2436
|
+
"signed-in": "signedIn",
|
|
2437
|
+
loading: "loadingAccount",
|
|
2438
|
+
"signing-in": "signingIn",
|
|
2439
|
+
"reauth-required": "reauthRequired",
|
|
2440
|
+
"remote-web-origin-not-trusted": "remoteOriginTitle",
|
|
2441
|
+
error: "requestFailed",
|
|
2442
|
+
"signed-out": "signedOut"
|
|
2443
|
+
}[status]);
|
|
2444
|
+
}
|
|
2445
|
+
/** Shared OAuth actions; Models uses shorter, task-oriented labels. */
|
|
2446
|
+
function AccountActions({ t, store, snapshot, compact = false }) {
|
|
2447
|
+
const { status, busy } = snapshot;
|
|
2448
|
+
if (status.status === "loading" || status.status === "remote-web-origin-not-trusted") return null;
|
|
2449
|
+
if (status.status === "signed-in") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2450
|
+
type: "button",
|
|
2451
|
+
style: buttonStyle$1,
|
|
2452
|
+
disabled: busy,
|
|
2453
|
+
onClick: () => {
|
|
2454
|
+
store.signOut();
|
|
2455
|
+
},
|
|
2456
|
+
children: busy ? t("working") : t("logout")
|
|
2457
|
+
});
|
|
2458
|
+
if (status.status === "signing-in") return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2459
|
+
style: rowStyle,
|
|
2460
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2461
|
+
type: "button",
|
|
2462
|
+
style: buttonStyle$1,
|
|
2463
|
+
disabled: busy,
|
|
2464
|
+
onClick: () => {
|
|
2465
|
+
store.signIn();
|
|
2466
|
+
},
|
|
2467
|
+
children: busy ? t("working") : t(compact ? "continueAuthorization" : "reopenAuthorization")
|
|
2468
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2469
|
+
type: "button",
|
|
2470
|
+
style: buttonStyle$1,
|
|
2471
|
+
disabled: busy,
|
|
2472
|
+
onClick: () => {
|
|
2473
|
+
store.cancel();
|
|
2474
|
+
},
|
|
2475
|
+
children: t("cancelSignIn")
|
|
2476
|
+
})]
|
|
2477
|
+
});
|
|
2478
|
+
const action = status.status === "error" || status.status === "reauth-required" ? t(compact ? "reauthorize" : "loginAgain") : t(compact ? "authorize" : "login");
|
|
2479
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2480
|
+
type: "button",
|
|
2481
|
+
style: primaryButtonStyle,
|
|
2482
|
+
disabled: busy,
|
|
2483
|
+
onClick: () => {
|
|
2484
|
+
store.signIn();
|
|
2485
|
+
},
|
|
2486
|
+
children: busy ? t("working") : action
|
|
1999
2487
|
});
|
|
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
2488
|
}
|
|
2007
|
-
/**
|
|
2008
|
-
function
|
|
2009
|
-
|
|
2010
|
-
const [status, setStatus] = (0, react.useState)({ status: "loading" });
|
|
2011
|
-
const [busy, setBusy] = (0, react.useState)(false);
|
|
2489
|
+
/** Recovery links, errors and trusted-origin guidance in either account entry. */
|
|
2490
|
+
function AccountFeedback({ t, snapshot }) {
|
|
2491
|
+
const { status, loginUrl } = snapshot;
|
|
2012
2492
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
2013
2493
|
const [copyFailed, setCopyFailed] = (0, react.useState)(false);
|
|
2014
|
-
const [loginUrl, setLoginUrl] = (0, react.useState)();
|
|
2015
|
-
const mounted = (0, react.useRef)(true);
|
|
2016
2494
|
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
2495
|
const copyTrustedOriginCommand = async () => {
|
|
2083
2496
|
setCopyFailed(false);
|
|
2084
2497
|
try {
|
|
2085
2498
|
if (navigator.clipboard?.writeText === void 0) throw new Error("clipboard unavailable");
|
|
2086
2499
|
await navigator.clipboard.writeText(trustedOriginCommand);
|
|
2087
|
-
|
|
2500
|
+
setCopied(true);
|
|
2088
2501
|
} 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);
|
|
2502
|
+
setCopyFailed(true);
|
|
2104
2503
|
}
|
|
2105
2504
|
};
|
|
2106
|
-
|
|
2505
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
2506
|
+
loginUrl === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2507
|
+
style: {
|
|
2508
|
+
display: "flex",
|
|
2509
|
+
flexDirection: "column",
|
|
2510
|
+
alignItems: "flex-start",
|
|
2511
|
+
gap: 10
|
|
2512
|
+
},
|
|
2513
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2514
|
+
style: bodyStyle,
|
|
2515
|
+
children: t("authorizationHelp")
|
|
2516
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
2517
|
+
href: loginUrl,
|
|
2518
|
+
target: "_blank",
|
|
2519
|
+
rel: "noopener noreferrer",
|
|
2520
|
+
style: {
|
|
2521
|
+
...primaryButtonStyle,
|
|
2522
|
+
display: "inline-flex",
|
|
2523
|
+
alignItems: "center",
|
|
2524
|
+
textDecoration: "none"
|
|
2525
|
+
},
|
|
2526
|
+
children: t("openLoginInBrowser")
|
|
2527
|
+
})]
|
|
2528
|
+
}),
|
|
2529
|
+
status.status === "error" || status.status === "reauth-required" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2530
|
+
style: errorStyle$1,
|
|
2531
|
+
children: status.message
|
|
2532
|
+
}) : null,
|
|
2533
|
+
status.status === "remote-web-origin-not-trusted" ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2534
|
+
style: {
|
|
2535
|
+
display: "flex",
|
|
2536
|
+
flexDirection: "column",
|
|
2537
|
+
gap: 10
|
|
2538
|
+
},
|
|
2539
|
+
children: [
|
|
2540
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2541
|
+
style: errorStyle$1,
|
|
2542
|
+
children: t("remoteOriginDescription")
|
|
2543
|
+
}),
|
|
2544
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2545
|
+
style: bodyStyle,
|
|
2546
|
+
children: t("remoteOriginCommandHelp")
|
|
2547
|
+
}),
|
|
2548
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("code", {
|
|
2549
|
+
style: commandStyle,
|
|
2550
|
+
children: trustedOriginCommand
|
|
2551
|
+
}),
|
|
2552
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2553
|
+
style: rowStyle,
|
|
2554
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2555
|
+
type: "button",
|
|
2556
|
+
style: buttonStyle$1,
|
|
2557
|
+
onClick: () => {
|
|
2558
|
+
copyTrustedOriginCommand();
|
|
2559
|
+
},
|
|
2560
|
+
children: copied ? t("remoteOriginCopied") : t("remoteOriginCopy")
|
|
2561
|
+
}), copyFailed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2562
|
+
style: errorStyle$1,
|
|
2563
|
+
children: t("remoteOriginCopyFailed")
|
|
2564
|
+
}) : null]
|
|
2565
|
+
})
|
|
2566
|
+
]
|
|
2567
|
+
}) : null
|
|
2568
|
+
] });
|
|
2569
|
+
}
|
|
2570
|
+
/** OpenAI Codex account status and OAuth actions. */
|
|
2571
|
+
function OpenAICodexSettings({ t, configScope, updater, account, embedded = false, accountOnly = false }) {
|
|
2572
|
+
if (t === void 0) throw new Error("OpenAI Codex settings requires its translation function");
|
|
2573
|
+
const [localAccount] = (0, react.useState)(() => new OpenAICodexAccountStore());
|
|
2574
|
+
const store = account ?? localAccount;
|
|
2575
|
+
const snapshot = (0, react.useSyncExternalStore)(store.subscribe, store.getSnapshot);
|
|
2576
|
+
const { status } = snapshot;
|
|
2577
|
+
const titleId = (0, react.useId)();
|
|
2578
|
+
const label = accountStatusLabel(status.status, t);
|
|
2107
2579
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2108
2580
|
style: embedded ? embeddedPageStyle : pageStyle,
|
|
2109
|
-
...embedded ? { "aria-label": t("title") } : { "aria-labelledby":
|
|
2581
|
+
...embedded ? { "aria-label": t("title") } : { "aria-labelledby": titleId },
|
|
2110
2582
|
children: [embedded ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
2111
|
-
id:
|
|
2583
|
+
id: titleId,
|
|
2112
2584
|
style: titleStyle,
|
|
2113
2585
|
children: t("title")
|
|
2114
2586
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
@@ -2120,7 +2592,7 @@ window.__ModuleLoader__.load({
|
|
|
2120
2592
|
})] }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2121
2593
|
style: embedded ? embeddedCardStyle : cardStyle$1,
|
|
2122
2594
|
children: [
|
|
2123
|
-
updater === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexUpdateSettings, {
|
|
2595
|
+
accountOnly || updater === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexUpdateSettings, {
|
|
2124
2596
|
t,
|
|
2125
2597
|
updater
|
|
2126
2598
|
}),
|
|
@@ -2137,92 +2609,25 @@ window.__ModuleLoader__.load({
|
|
|
2137
2609
|
"aria-hidden": "true",
|
|
2138
2610
|
style: dotStyle(status.status)
|
|
2139
2611
|
}), /* @__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")
|
|
2612
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountActions, {
|
|
2613
|
+
t,
|
|
2614
|
+
store,
|
|
2615
|
+
snapshot
|
|
2156
2616
|
})]
|
|
2157
2617
|
}),
|
|
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
|
-
})]
|
|
2618
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountFeedback, {
|
|
2619
|
+
t,
|
|
2620
|
+
snapshot
|
|
2180
2621
|
}),
|
|
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
2622
|
status.status === "signed-in" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageLimits, {
|
|
2221
2623
|
usage: status.usage,
|
|
2222
2624
|
...status.quotaError === void 0 ? {} : { quotaError: status.quotaError },
|
|
2223
2625
|
t
|
|
2224
2626
|
}) : null,
|
|
2225
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
2627
|
+
accountOnly ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2628
|
+
style: bodyStyle,
|
|
2629
|
+
children: t("modelsAccountHelp")
|
|
2630
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexConfiguration, {
|
|
2226
2631
|
t,
|
|
2227
2632
|
...configScope === void 0 ? {} : { scope: configScope }
|
|
2228
2633
|
})
|
|
@@ -2300,7 +2705,7 @@ window.__ModuleLoader__.load({
|
|
|
2300
2705
|
});
|
|
2301
2706
|
}
|
|
2302
2707
|
/** Render account management as one expandable Plugin configuration card. */
|
|
2303
|
-
function OpenAICodexPluginCard({ t, configScope, updater }) {
|
|
2708
|
+
function OpenAICodexPluginCard({ t, configScope, updater, account }) {
|
|
2304
2709
|
if (t === void 0) throw new Error("OpenAI Codex plugin card requires its translation function");
|
|
2305
2710
|
const [open, setOpen] = (0, react.useState)(false);
|
|
2306
2711
|
const title = t("title");
|
|
@@ -2331,6 +2736,7 @@ window.__ModuleLoader__.load({
|
|
|
2331
2736
|
style: cardBodyStyle,
|
|
2332
2737
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexSettings, {
|
|
2333
2738
|
t,
|
|
2739
|
+
...account === void 0 ? {} : { account },
|
|
2334
2740
|
...updater === void 0 ? {} : { updater },
|
|
2335
2741
|
embedded: true,
|
|
2336
2742
|
...configScope === void 0 ? {} : { configScope }
|
|
@@ -2761,8 +3167,24 @@ window.__ModuleLoader__.load({
|
|
|
2761
3167
|
/** English copy for the OpenAI Codex Plugin configuration card. */
|
|
2762
3168
|
const en = {
|
|
2763
3169
|
title: "Codex Connect",
|
|
3170
|
+
modelsProviderName: "Openai-Codex",
|
|
3171
|
+
modelsProviderSupport: "Powered by the Codex Connect plugin.",
|
|
2764
3172
|
intro: "Use your ChatGPT subscription in dsh, with optional GPT Image generation and no API key.",
|
|
2765
3173
|
accountHeading: "ChatGPT account",
|
|
3174
|
+
manageAccount: "Manage",
|
|
3175
|
+
authorize: "Authorize",
|
|
3176
|
+
continueAuthorization: "Continue authorization",
|
|
3177
|
+
reauthorize: "Reauthorize",
|
|
3178
|
+
viewQuota: "View quota",
|
|
3179
|
+
hideQuota: "Hide quota",
|
|
3180
|
+
moreSettings: "More settings",
|
|
3181
|
+
moreSettingsTitle: "Codex Connect settings",
|
|
3182
|
+
closeSettings: "Close",
|
|
3183
|
+
settingsSaveHint: "Save applies changes to both settings entries. Closing discards unsaved changes.",
|
|
3184
|
+
reopenAuthorization: "Reopen authorization",
|
|
3185
|
+
cancelSignIn: "Cancel sign-in",
|
|
3186
|
+
authorizationHelp: "You can reopen the authorization page or cancel and start again. Cancelling does not sign out an existing account.",
|
|
3187
|
+
modelsAccountHelp: "Proxy, model visibility, search and image options remain in Settings → Plugins → Codex Connect, or open them here:",
|
|
2766
3188
|
expand: "Expand settings",
|
|
2767
3189
|
collapse: "Collapse settings",
|
|
2768
3190
|
loadingAccount: "Loading account…",
|
|
@@ -2810,6 +3232,20 @@ window.__ModuleLoader__.load({
|
|
|
2810
3232
|
modelCatalogIntro: "Choose which Codex models appear in model selectors. Existing conversations can continue using a hidden model.",
|
|
2811
3233
|
modelCatalogLoading: "Loading available models…",
|
|
2812
3234
|
modelCatalogFailed: "Available models could not be loaded.",
|
|
3235
|
+
modelContext: "Context",
|
|
3236
|
+
contextDefault: "Catalog default",
|
|
3237
|
+
contextCustom: "Custom",
|
|
3238
|
+
contextAdjust: "Adjust",
|
|
3239
|
+
contextHide: "Hide adjustment",
|
|
3240
|
+
contextTokens: "Context length",
|
|
3241
|
+
contextReset: "Restore default",
|
|
3242
|
+
contextSlider: "Adjust context budget",
|
|
3243
|
+
contextMaximum: "Configuration limit",
|
|
3244
|
+
contextLimitSource: "Source: official Codex configuration catalog (2026-08-28)",
|
|
3245
|
+
contextLimitFallback: "No higher configuration limit confirmed; capped at the installed catalog default.",
|
|
3246
|
+
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.",
|
|
3247
|
+
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.",
|
|
3248
|
+
contextInvalid: "Enter a whole-number budget within the model’s configuration range, or choose Restore default.",
|
|
2813
3249
|
capabilitiesHeading: "Optional capabilities",
|
|
2814
3250
|
capabilitiesIntro: "Choose which extra Codex capabilities this dsh profile may register.",
|
|
2815
3251
|
networkHeading: "Network connection",
|
|
@@ -2945,6 +3381,8 @@ window.__ModuleLoader__.load({
|
|
|
2945
3381
|
updateHighlightOauthHistory: "Added safer session-history migration and a sign-in fallback when the account needs to reconnect.",
|
|
2946
3382
|
updateHighlightModelVisibility: "You can now choose which Codex models appear in model selectors.",
|
|
2947
3383
|
updateHighlightProxyConnection: "Added opt-in Codex proxy detection with explicit confirmation and a visible direct-connection fallback.",
|
|
3384
|
+
updateHighlightModelsAccount: "Added an Openai-Codex account card in Models settings for authorization, quota, and shared plugin settings.",
|
|
3385
|
+
updateHighlightContextBudget: "Added bounded per-model context budget controls while preserving each catalog default until you save an override.",
|
|
2948
3386
|
viewTechnicalDetails: "View technical details",
|
|
2949
3387
|
hideTechnicalDetails: "Hide technical details",
|
|
2950
3388
|
technicalDetailsHeading: "Technical changes",
|
|
@@ -2970,8 +3408,24 @@ window.__ModuleLoader__.load({
|
|
|
2970
3408
|
/** Chinese copy for the OpenAI Codex Plugin configuration card. */
|
|
2971
3409
|
const zh = {
|
|
2972
3410
|
title: "Codex Connect",
|
|
3411
|
+
modelsProviderName: "Openai-Codex",
|
|
3412
|
+
modelsProviderSupport: "由 Codex Connect 插件提供支持。",
|
|
2973
3413
|
intro: "使用 ChatGPT 订阅在 dsh 中调用模型,并可使用 GPT Image 生成图片,无需 API Key。",
|
|
2974
3414
|
accountHeading: "ChatGPT 账户",
|
|
3415
|
+
manageAccount: "管理",
|
|
3416
|
+
authorize: "授权",
|
|
3417
|
+
continueAuthorization: "继续授权",
|
|
3418
|
+
reauthorize: "重新授权",
|
|
3419
|
+
viewQuota: "查看额度",
|
|
3420
|
+
hideQuota: "收起额度",
|
|
3421
|
+
moreSettings: "更多设置",
|
|
3422
|
+
moreSettingsTitle: "Codex Connect 设置",
|
|
3423
|
+
closeSettings: "关闭",
|
|
3424
|
+
settingsSaveHint: "保存后两处设置同步生效;关闭将放弃未保存的修改。",
|
|
3425
|
+
reopenAuthorization: "重新打开授权",
|
|
3426
|
+
cancelSignIn: "取消登录",
|
|
3427
|
+
authorizationHelp: "可以重新打开授权页,或取消后重试。取消登录不会退出已有账户。",
|
|
3428
|
+
modelsAccountHelp: "代理、模型显示、搜索和图片选项仍可在“设置 → 插件 → Codex Connect”中管理,也可直接打开:",
|
|
2975
3429
|
expand: "展开设置",
|
|
2976
3430
|
collapse: "折叠设置",
|
|
2977
3431
|
loadingAccount: "正在加载账户信息…",
|
|
@@ -3019,6 +3473,20 @@ window.__ModuleLoader__.load({
|
|
|
3019
3473
|
modelCatalogIntro: "选择要在模型选择器中显示的 Codex 模型;隐藏模型后,已有会话仍可继续使用。",
|
|
3020
3474
|
modelCatalogLoading: "正在加载可用模型…",
|
|
3021
3475
|
modelCatalogFailed: "无法加载可用模型。",
|
|
3476
|
+
modelContext: "上下文",
|
|
3477
|
+
contextDefault: "目录默认",
|
|
3478
|
+
contextCustom: "自定义",
|
|
3479
|
+
contextAdjust: "调整",
|
|
3480
|
+
contextHide: "收起调整",
|
|
3481
|
+
contextTokens: "上下文长度",
|
|
3482
|
+
contextReset: "恢复默认",
|
|
3483
|
+
contextSlider: "调整上下文预算",
|
|
3484
|
+
contextMaximum: "配置上限",
|
|
3485
|
+
contextLimitSource: "依据:Codex 官方配置目录(2026-08-28)",
|
|
3486
|
+
contextLimitFallback: "尚未确认更高配置上限,暂以已安装目录的默认值为上限。",
|
|
3487
|
+
contextAboveDefault: "已超过目录默认值:请求可能消耗更多额度,或被当前账号、通道拒绝。本插件未对该范围进行容量实测。",
|
|
3488
|
+
contextWarning: "调整的是本地上下文预算,不会扩大服务端容量;设置过高可能导致请求失败。隐藏模型会保留其预算,修改在保存后生效。",
|
|
3489
|
+
contextInvalid: "请输入模型配置范围内的整数预算,或点击“恢复默认”。",
|
|
3022
3490
|
capabilitiesHeading: "可选能力",
|
|
3023
3491
|
capabilitiesIntro: "选择允许此 dsh profile 注册哪些额外的 Codex 能力。",
|
|
3024
3492
|
networkHeading: "网络连接",
|
|
@@ -3154,6 +3622,8 @@ window.__ModuleLoader__.load({
|
|
|
3154
3622
|
updateHighlightOauthHistory: "增加更安全的会话历史迁移,并在账号需要重新登录时提供备用登录路径。",
|
|
3155
3623
|
updateHighlightModelVisibility: "现在可以选择哪些 Codex 模型显示在模型选择菜单中。",
|
|
3156
3624
|
updateHighlightProxyConnection: "增加可选的 Codex 代理检测,启用前需要明确确认,并始终保留直连回退入口。",
|
|
3625
|
+
updateHighlightModelsAccount: "在模型设置中增加 Openai-Codex 账户卡,用于授权、查看额度和打开共享插件设置。",
|
|
3626
|
+
updateHighlightContextBudget: "增加有范围限制的逐模型上下文预算设置;保存覆盖值前继续使用各模型的目录默认值。",
|
|
3157
3627
|
viewTechnicalDetails: "查看完整技术说明",
|
|
3158
3628
|
hideTechnicalDetails: "收起技术说明",
|
|
3159
3629
|
technicalDetailsHeading: "技术变更",
|
|
@@ -3270,7 +3740,7 @@ window.__ModuleLoader__.load({
|
|
|
3270
3740
|
//#region src/client/CodexImageGallery.tsx
|
|
3271
3741
|
/** Self-contained result-image gallery for the tool-call view.
|
|
3272
3742
|
*
|
|
3273
|
-
* DSH
|
|
3743
|
+
* DSH keeps the attachment package's React atoms behind its
|
|
3274
3744
|
* conversation slots. A tool-call view cannot render those slots, so this
|
|
3275
3745
|
* gallery owns only the durable-image presentation it needs and receives all
|
|
3276
3746
|
* stateful work through props.
|
|
@@ -3441,7 +3911,6 @@ window.__ModuleLoader__.load({
|
|
|
3441
3911
|
open: true,
|
|
3442
3912
|
onClose,
|
|
3443
3913
|
title: labels.dialog,
|
|
3444
|
-
closeLabel: labels.close,
|
|
3445
3914
|
headless: true,
|
|
3446
3915
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
3447
3916
|
ref: lightbox,
|
|
@@ -4340,7 +4809,232 @@ window.__ModuleLoader__.load({
|
|
|
4340
4809
|
}
|
|
4341
4810
|
//#endregion
|
|
4342
4811
|
//#region src/version.ts
|
|
4343
|
-
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.
|
|
4812
|
+
const CODEX_CONNECT_VERSION = "0.1.0-alpha.4.22";
|
|
4813
|
+
//#endregion
|
|
4814
|
+
//#region src/client/OpenAICodexModelsCard.tsx
|
|
4815
|
+
/** Compact Models account entry with quota disclosure and shared configuration. */
|
|
4816
|
+
const buttonStyle = {
|
|
4817
|
+
padding: "6px 14px",
|
|
4818
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4819
|
+
borderRadius: 999,
|
|
4820
|
+
background: "transparent",
|
|
4821
|
+
color: "inherit",
|
|
4822
|
+
font: "inherit",
|
|
4823
|
+
fontSize: 14,
|
|
4824
|
+
cursor: "pointer"
|
|
4825
|
+
};
|
|
4826
|
+
const secondaryStyle = {
|
|
4827
|
+
fontSize: 12,
|
|
4828
|
+
lineHeight: "18px",
|
|
4829
|
+
color: "var(--dsw-alias-label-secondary)"
|
|
4830
|
+
};
|
|
4831
|
+
/** Native modality contains keyboard focus and restores it to More settings on close. */
|
|
4832
|
+
function ConfigurationDialog({ t, configScope, onClose }) {
|
|
4833
|
+
const dialog = (0, react.useRef)(null);
|
|
4834
|
+
const titleId = (0, react.useId)();
|
|
4835
|
+
(0, react.useEffect)(() => {
|
|
4836
|
+
const element = dialog.current;
|
|
4837
|
+
element?.showModal();
|
|
4838
|
+
return () => {
|
|
4839
|
+
element?.close();
|
|
4840
|
+
};
|
|
4841
|
+
}, []);
|
|
4842
|
+
const close = () => {
|
|
4843
|
+
dialog.current?.close();
|
|
4844
|
+
onClose();
|
|
4845
|
+
};
|
|
4846
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dialog", {
|
|
4847
|
+
ref: dialog,
|
|
4848
|
+
"aria-labelledby": titleId,
|
|
4849
|
+
onCancel: (event) => {
|
|
4850
|
+
event.preventDefault();
|
|
4851
|
+
close();
|
|
4852
|
+
},
|
|
4853
|
+
onKeyDown: (event) => {
|
|
4854
|
+
if (event.key !== "Escape") return;
|
|
4855
|
+
event.stopPropagation();
|
|
4856
|
+
event.preventDefault();
|
|
4857
|
+
close();
|
|
4858
|
+
},
|
|
4859
|
+
style: {
|
|
4860
|
+
boxSizing: "border-box",
|
|
4861
|
+
width: "min(720px, calc(100vw - 32px))",
|
|
4862
|
+
maxHeight: "calc(100dvh - 32px)",
|
|
4863
|
+
overflowY: "auto",
|
|
4864
|
+
padding: 20,
|
|
4865
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4866
|
+
borderRadius: 12,
|
|
4867
|
+
background: "var(--dsw-alias-bg-layer-1, white)",
|
|
4868
|
+
color: "var(--dsw-alias-label-primary)",
|
|
4869
|
+
margin: "auto"
|
|
4870
|
+
},
|
|
4871
|
+
children: [
|
|
4872
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4873
|
+
style: {
|
|
4874
|
+
display: "flex",
|
|
4875
|
+
alignItems: "center",
|
|
4876
|
+
justifyContent: "space-between",
|
|
4877
|
+
gap: 12
|
|
4878
|
+
},
|
|
4879
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", {
|
|
4880
|
+
id: titleId,
|
|
4881
|
+
style: {
|
|
4882
|
+
margin: 0,
|
|
4883
|
+
fontSize: 18
|
|
4884
|
+
},
|
|
4885
|
+
children: t("moreSettingsTitle")
|
|
4886
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4887
|
+
type: "button",
|
|
4888
|
+
style: buttonStyle,
|
|
4889
|
+
onClick: close,
|
|
4890
|
+
children: t("closeSettings")
|
|
4891
|
+
})]
|
|
4892
|
+
}),
|
|
4893
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
4894
|
+
style: secondaryStyle,
|
|
4895
|
+
children: t("settingsSaveHint")
|
|
4896
|
+
}),
|
|
4897
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(OpenAICodexConfiguration, {
|
|
4898
|
+
t,
|
|
4899
|
+
...configScope === void 0 ? {} : { scope: configScope }
|
|
4900
|
+
})
|
|
4901
|
+
]
|
|
4902
|
+
});
|
|
4903
|
+
}
|
|
4904
|
+
function OpenAICodexModelsCard({ t, account, configScope }) {
|
|
4905
|
+
const [expanded, setExpanded] = (0, react.useState)(false);
|
|
4906
|
+
const [settingsOpen, setSettingsOpen] = (0, react.useState)(false);
|
|
4907
|
+
const detailsId = (0, react.useId)();
|
|
4908
|
+
const snapshot = (0, react.useSyncExternalStore)(account.subscribe, account.getSnapshot);
|
|
4909
|
+
const { status } = snapshot;
|
|
4910
|
+
const label = accountStatusLabel(status.status, t);
|
|
4911
|
+
(0, react.useEffect)(() => {
|
|
4912
|
+
if (status.status !== "signed-in") setExpanded(false);
|
|
4913
|
+
}, [status.status]);
|
|
4914
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4915
|
+
style: {
|
|
4916
|
+
border: "1px solid var(--dsw-alias-border-l2)",
|
|
4917
|
+
borderRadius: 12,
|
|
4918
|
+
padding: "12px 14px",
|
|
4919
|
+
color: "var(--dsw-alias-label-primary)"
|
|
4920
|
+
},
|
|
4921
|
+
children: [
|
|
4922
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4923
|
+
style: {
|
|
4924
|
+
display: "flex",
|
|
4925
|
+
alignItems: "center",
|
|
4926
|
+
flexWrap: "wrap",
|
|
4927
|
+
gap: 10
|
|
4928
|
+
},
|
|
4929
|
+
children: [
|
|
4930
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4931
|
+
style: {
|
|
4932
|
+
fontSize: 14,
|
|
4933
|
+
lineHeight: "22px",
|
|
4934
|
+
fontWeight: 500
|
|
4935
|
+
},
|
|
4936
|
+
children: t("modelsProviderName")
|
|
4937
|
+
}),
|
|
4938
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4939
|
+
"aria-hidden": "true",
|
|
4940
|
+
style: {
|
|
4941
|
+
...dotStyle(status.status),
|
|
4942
|
+
width: 8,
|
|
4943
|
+
height: 8
|
|
4944
|
+
}
|
|
4945
|
+
}),
|
|
4946
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4947
|
+
role: "status",
|
|
4948
|
+
style: {
|
|
4949
|
+
...secondaryStyle,
|
|
4950
|
+
flex: 1
|
|
4951
|
+
},
|
|
4952
|
+
children: label
|
|
4953
|
+
}),
|
|
4954
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4955
|
+
style: {
|
|
4956
|
+
display: "flex",
|
|
4957
|
+
flexWrap: "wrap",
|
|
4958
|
+
gap: 8,
|
|
4959
|
+
marginLeft: "auto"
|
|
4960
|
+
},
|
|
4961
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountActions, {
|
|
4962
|
+
t,
|
|
4963
|
+
store: account,
|
|
4964
|
+
snapshot,
|
|
4965
|
+
compact: true
|
|
4966
|
+
}), status.status === "signed-in" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4967
|
+
type: "button",
|
|
4968
|
+
"aria-expanded": expanded,
|
|
4969
|
+
"aria-controls": detailsId,
|
|
4970
|
+
onClick: () => {
|
|
4971
|
+
setExpanded(!expanded);
|
|
4972
|
+
},
|
|
4973
|
+
style: buttonStyle,
|
|
4974
|
+
children: t(expanded ? "hideQuota" : "viewQuota")
|
|
4975
|
+
})]
|
|
4976
|
+
})
|
|
4977
|
+
]
|
|
4978
|
+
}),
|
|
4979
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4980
|
+
style: {
|
|
4981
|
+
...secondaryStyle,
|
|
4982
|
+
marginTop: 4
|
|
4983
|
+
},
|
|
4984
|
+
children: t("modelsProviderSupport")
|
|
4985
|
+
}),
|
|
4986
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountFeedback, {
|
|
4987
|
+
t,
|
|
4988
|
+
snapshot
|
|
4989
|
+
}),
|
|
4990
|
+
expanded && status.status === "signed-in" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4991
|
+
id: detailsId,
|
|
4992
|
+
style: {
|
|
4993
|
+
borderTop: "1px solid var(--dsw-alias-border-l2)",
|
|
4994
|
+
marginTop: 12,
|
|
4995
|
+
paddingTop: 12
|
|
4996
|
+
},
|
|
4997
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageLimits, {
|
|
4998
|
+
t,
|
|
4999
|
+
usage: status.usage,
|
|
5000
|
+
heading: false,
|
|
5001
|
+
...status.quotaError === void 0 ? {} : { quotaError: status.quotaError }
|
|
5002
|
+
})
|
|
5003
|
+
}),
|
|
5004
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5005
|
+
style: {
|
|
5006
|
+
...secondaryStyle,
|
|
5007
|
+
marginTop: 12
|
|
5008
|
+
},
|
|
5009
|
+
children: [
|
|
5010
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("modelsAccountHelp") }),
|
|
5011
|
+
" ",
|
|
5012
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5013
|
+
type: "button",
|
|
5014
|
+
onClick: () => {
|
|
5015
|
+
setSettingsOpen(true);
|
|
5016
|
+
},
|
|
5017
|
+
style: {
|
|
5018
|
+
...buttonStyle,
|
|
5019
|
+
padding: 0,
|
|
5020
|
+
border: 0,
|
|
5021
|
+
fontSize: "inherit",
|
|
5022
|
+
textDecoration: "underline"
|
|
5023
|
+
},
|
|
5024
|
+
children: t("moreSettings")
|
|
5025
|
+
})
|
|
5026
|
+
]
|
|
5027
|
+
}),
|
|
5028
|
+
settingsOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ConfigurationDialog, {
|
|
5029
|
+
t,
|
|
5030
|
+
...configScope === void 0 ? {} : { configScope },
|
|
5031
|
+
onClose: () => {
|
|
5032
|
+
setSettingsOpen(false);
|
|
5033
|
+
}
|
|
5034
|
+
})
|
|
5035
|
+
]
|
|
5036
|
+
});
|
|
5037
|
+
}
|
|
4344
5038
|
//#endregion
|
|
4345
5039
|
//#region src/client/index.tsx
|
|
4346
5040
|
/** Stable browser-plugin name. */
|
|
@@ -4358,6 +5052,10 @@ window.__ModuleLoader__.load({
|
|
|
4358
5052
|
function apply(ctx) {
|
|
4359
5053
|
const namespace = "settings.openai-codex";
|
|
4360
5054
|
const updater = new OpenAICodexUpdateStore(CODEX_CONNECT_VERSION);
|
|
5055
|
+
const account = new OpenAICodexAccountStore();
|
|
5056
|
+
ctx.effect(() => () => {
|
|
5057
|
+
account.dispose();
|
|
5058
|
+
}, "dsh-codex-connect: account observation");
|
|
4361
5059
|
ctx.effect(() => {
|
|
4362
5060
|
updater.refresh();
|
|
4363
5061
|
return () => {
|
|
@@ -4379,9 +5077,20 @@ window.__ModuleLoader__.load({
|
|
|
4379
5077
|
inject: () => ({
|
|
4380
5078
|
t,
|
|
4381
5079
|
configScope,
|
|
4382
|
-
updater
|
|
5080
|
+
updater,
|
|
5081
|
+
account
|
|
4383
5082
|
})
|
|
4384
5083
|
}, OpenAICodexPluginCard));
|
|
5084
|
+
ctx.slots.inject("settings.models.footer", () => ctx.slots.register({
|
|
5085
|
+
name: "settings.models.footer",
|
|
5086
|
+
id: "dsh-codex-connect-account",
|
|
5087
|
+
order: 100,
|
|
5088
|
+
inject: () => ({
|
|
5089
|
+
t,
|
|
5090
|
+
account,
|
|
5091
|
+
configScope
|
|
5092
|
+
})
|
|
5093
|
+
}, OpenAICodexModelsCard));
|
|
4385
5094
|
ctx.slots.inject("shell.overlay", () => ctx.slots.register({
|
|
4386
5095
|
name: "shell.overlay",
|
|
4387
5096
|
id: "dsh-codex-connect-update",
|