@shuind/dsh-codex-harness 0.1.11 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -1
- package/lib/client.js +633 -0
- package/lib/index.js +40 -5
- package/lib/types/client/index.d.ts +40 -0
- package/lib/types/client/index.js +112 -0
- package/lib/types/context.d.ts +5 -0
- package/lib/types/context.js +5 -0
- package/lib/types/index.d.ts +20 -0
- package/lib/types/index.js +40 -4
- package/package.json +43 -1
package/README.md
CHANGED
|
@@ -16,11 +16,17 @@ DSH 的通用 `@deepseek-ai/dsh-llm-pi-ai` 继续负责用户配置的 provider
|
|
|
16
16
|
## 安装
|
|
17
17
|
|
|
18
18
|
```sh
|
|
19
|
-
dsh plugin --profile web add @shuind/dsh-codex-harness@0.1.
|
|
19
|
+
dsh plugin --profile web add @shuind/dsh-codex-harness@0.1.12
|
|
20
20
|
```
|
|
21
21
|
|
|
22
22
|
重启 Web,创建新会话,在模式菜单中选择 `Codex 模式`。
|
|
23
23
|
|
|
24
|
+
## Fast 与上下文大小
|
|
25
|
+
|
|
26
|
+
Codex 模式会在模型选择菜单中提供 `Fast` 控制。开启后,GPT Responses 请求会携带 `service_tier: "priority"`;它不是思考强度,也不会修改 `reasoning_effort`。该设置按 `codex` 设置命名空间保存,并作用于之后的请求。其他 preset 不会显示 Fast。
|
|
27
|
+
|
|
28
|
+
点击上下文使用量指示器可以展开上下文设置。上下文大小使用整数 K tokens,可通过滑块或数字输入设置,范围为 `1K` 到 `1000K`;恢复模型默认值会删除覆盖。设置值用于下一次请求;上方的上下文 meter 显示当前请求实际使用的容量,因此修改设置后要发送下一次请求,上方的分母才会更新。这个值同时用于上下文容量投影、token meter、compaction 判断和适配器的响应 token 统计,而不只是修改显示文本。实际使用前请确认中转站和模型支持所选容量。
|
|
29
|
+
|
|
24
30
|
## 中转站配置
|
|
25
31
|
|
|
26
32
|
请继续在 DSH 的 Models/`llm-pi-ai` 配置中填写你的 Responses 中转站地址、API key 和模型。例如 provider 下配置 `api: openai-responses`、`baseURL`、`apiKeyEnv`,并在 `models` 中填写中转站实际支持的 GPT 模型 id。Codex 模式不会替换这些配置。
|
package/lib/client.js
ADDED
|
@@ -0,0 +1,633 @@
|
|
|
1
|
+
window.__ModuleLoader__.load({
|
|
2
|
+
id: "@shuind/dsh-codex-harness",
|
|
3
|
+
factory: (require) => {
|
|
4
|
+
var module = { exports: {} };
|
|
5
|
+
var exports = module.exports;
|
|
6
|
+
Object.defineProperties(exports, {
|
|
7
|
+
__esModule: { value: true },
|
|
8
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
9
|
+
});
|
|
10
|
+
//#region \0rolldown/runtime.js
|
|
11
|
+
var __commonJSMin = (cb, mod) => () => (mod || (cb((mod = { exports: {} }).exports, mod), cb = null), mod.exports);
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react.production.min.js
|
|
14
|
+
/**
|
|
15
|
+
* @license React
|
|
16
|
+
* react.production.min.js
|
|
17
|
+
*
|
|
18
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
19
|
+
*
|
|
20
|
+
* This source code is licensed under the MIT license found in the
|
|
21
|
+
* LICENSE file in the root directory of this source tree.
|
|
22
|
+
*/
|
|
23
|
+
var require_react_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
24
|
+
var l = Symbol.for("react.element");
|
|
25
|
+
var n = Symbol.for("react.portal");
|
|
26
|
+
var p = Symbol.for("react.fragment");
|
|
27
|
+
var q = Symbol.for("react.strict_mode");
|
|
28
|
+
var r = Symbol.for("react.profiler");
|
|
29
|
+
var t = Symbol.for("react.provider");
|
|
30
|
+
var u = Symbol.for("react.context");
|
|
31
|
+
var v = Symbol.for("react.forward_ref");
|
|
32
|
+
var w = Symbol.for("react.suspense");
|
|
33
|
+
var x = Symbol.for("react.memo");
|
|
34
|
+
var y = Symbol.for("react.lazy");
|
|
35
|
+
var z = Symbol.iterator;
|
|
36
|
+
function A(a) {
|
|
37
|
+
if (null === a || "object" !== typeof a) return null;
|
|
38
|
+
a = z && a[z] || a["@@iterator"];
|
|
39
|
+
return "function" === typeof a ? a : null;
|
|
40
|
+
}
|
|
41
|
+
var B = {
|
|
42
|
+
isMounted: function() {
|
|
43
|
+
return !1;
|
|
44
|
+
},
|
|
45
|
+
enqueueForceUpdate: function() {},
|
|
46
|
+
enqueueReplaceState: function() {},
|
|
47
|
+
enqueueSetState: function() {}
|
|
48
|
+
};
|
|
49
|
+
var C = Object.assign;
|
|
50
|
+
var D = {};
|
|
51
|
+
function E(a, b, e) {
|
|
52
|
+
this.props = a;
|
|
53
|
+
this.context = b;
|
|
54
|
+
this.refs = D;
|
|
55
|
+
this.updater = e || B;
|
|
56
|
+
}
|
|
57
|
+
E.prototype.isReactComponent = {};
|
|
58
|
+
E.prototype.setState = function(a, b) {
|
|
59
|
+
if ("object" !== typeof a && "function" !== typeof a && null != a) throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");
|
|
60
|
+
this.updater.enqueueSetState(this, a, b, "setState");
|
|
61
|
+
};
|
|
62
|
+
E.prototype.forceUpdate = function(a) {
|
|
63
|
+
this.updater.enqueueForceUpdate(this, a, "forceUpdate");
|
|
64
|
+
};
|
|
65
|
+
function F() {}
|
|
66
|
+
F.prototype = E.prototype;
|
|
67
|
+
function G(a, b, e) {
|
|
68
|
+
this.props = a;
|
|
69
|
+
this.context = b;
|
|
70
|
+
this.refs = D;
|
|
71
|
+
this.updater = e || B;
|
|
72
|
+
}
|
|
73
|
+
var H = G.prototype = new F();
|
|
74
|
+
H.constructor = G;
|
|
75
|
+
C(H, E.prototype);
|
|
76
|
+
H.isPureReactComponent = !0;
|
|
77
|
+
var I = Array.isArray;
|
|
78
|
+
var J = Object.prototype.hasOwnProperty;
|
|
79
|
+
var K = { current: null };
|
|
80
|
+
var L = {
|
|
81
|
+
key: !0,
|
|
82
|
+
ref: !0,
|
|
83
|
+
__self: !0,
|
|
84
|
+
__source: !0
|
|
85
|
+
};
|
|
86
|
+
function M(a, b, e) {
|
|
87
|
+
var d, c = {}, k = null, h = null;
|
|
88
|
+
if (null != b) for (d in void 0 !== b.ref && (h = b.ref), void 0 !== b.key && (k = "" + b.key), b) J.call(b, d) && !L.hasOwnProperty(d) && (c[d] = b[d]);
|
|
89
|
+
var g = arguments.length - 2;
|
|
90
|
+
if (1 === g) c.children = e;
|
|
91
|
+
else if (1 < g) {
|
|
92
|
+
for (var f = Array(g), m = 0; m < g; m++) f[m] = arguments[m + 2];
|
|
93
|
+
c.children = f;
|
|
94
|
+
}
|
|
95
|
+
if (a && a.defaultProps) for (d in g = a.defaultProps, g) void 0 === c[d] && (c[d] = g[d]);
|
|
96
|
+
return {
|
|
97
|
+
$$typeof: l,
|
|
98
|
+
type: a,
|
|
99
|
+
key: k,
|
|
100
|
+
ref: h,
|
|
101
|
+
props: c,
|
|
102
|
+
_owner: K.current
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function N(a, b) {
|
|
106
|
+
return {
|
|
107
|
+
$$typeof: l,
|
|
108
|
+
type: a.type,
|
|
109
|
+
key: b,
|
|
110
|
+
ref: a.ref,
|
|
111
|
+
props: a.props,
|
|
112
|
+
_owner: a._owner
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function O(a) {
|
|
116
|
+
return "object" === typeof a && null !== a && a.$$typeof === l;
|
|
117
|
+
}
|
|
118
|
+
function escape(a) {
|
|
119
|
+
var b = {
|
|
120
|
+
"=": "=0",
|
|
121
|
+
":": "=2"
|
|
122
|
+
};
|
|
123
|
+
return "$" + a.replace(/[=:]/g, function(a) {
|
|
124
|
+
return b[a];
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
var P = /\/+/g;
|
|
128
|
+
function Q(a, b) {
|
|
129
|
+
return "object" === typeof a && null !== a && null != a.key ? escape("" + a.key) : b.toString(36);
|
|
130
|
+
}
|
|
131
|
+
function R(a, b, e, d, c) {
|
|
132
|
+
var k = typeof a;
|
|
133
|
+
if ("undefined" === k || "boolean" === k) a = null;
|
|
134
|
+
var h = !1;
|
|
135
|
+
if (null === a) h = !0;
|
|
136
|
+
else switch (k) {
|
|
137
|
+
case "string":
|
|
138
|
+
case "number":
|
|
139
|
+
h = !0;
|
|
140
|
+
break;
|
|
141
|
+
case "object": switch (a.$$typeof) {
|
|
142
|
+
case l:
|
|
143
|
+
case n: h = !0;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (h) return h = a, c = c(h), a = "" === d ? "." + Q(h, 0) : d, I(c) ? (e = "", null != a && (e = a.replace(P, "$&/") + "/"), R(c, b, e, "", function(a) {
|
|
147
|
+
return a;
|
|
148
|
+
})) : null != c && (O(c) && (c = N(c, e + (!c.key || h && h.key === c.key ? "" : ("" + c.key).replace(P, "$&/") + "/") + a)), b.push(c)), 1;
|
|
149
|
+
h = 0;
|
|
150
|
+
d = "" === d ? "." : d + ":";
|
|
151
|
+
if (I(a)) for (var g = 0; g < a.length; g++) {
|
|
152
|
+
k = a[g];
|
|
153
|
+
var f = d + Q(k, g);
|
|
154
|
+
h += R(k, b, e, f, c);
|
|
155
|
+
}
|
|
156
|
+
else if (f = A(a), "function" === typeof f) for (a = f.call(a), g = 0; !(k = a.next()).done;) k = k.value, f = d + Q(k, g++), h += R(k, b, e, f, c);
|
|
157
|
+
else if ("object" === k) throw b = String(a), Error("Objects are not valid as a React child (found: " + ("[object Object]" === b ? "object with keys {" + Object.keys(a).join(", ") + "}" : b) + "). If you meant to render a collection of children, use an array instead.");
|
|
158
|
+
return h;
|
|
159
|
+
}
|
|
160
|
+
function S(a, b, e) {
|
|
161
|
+
if (null == a) return a;
|
|
162
|
+
var d = [], c = 0;
|
|
163
|
+
R(a, d, "", "", function(a) {
|
|
164
|
+
return b.call(e, a, c++);
|
|
165
|
+
});
|
|
166
|
+
return d;
|
|
167
|
+
}
|
|
168
|
+
function T(a) {
|
|
169
|
+
if (-1 === a._status) {
|
|
170
|
+
var b = a._result;
|
|
171
|
+
b = b();
|
|
172
|
+
b.then(function(b) {
|
|
173
|
+
if (0 === a._status || -1 === a._status) a._status = 1, a._result = b;
|
|
174
|
+
}, function(b) {
|
|
175
|
+
if (0 === a._status || -1 === a._status) a._status = 2, a._result = b;
|
|
176
|
+
});
|
|
177
|
+
-1 === a._status && (a._status = 0, a._result = b);
|
|
178
|
+
}
|
|
179
|
+
if (1 === a._status) return a._result.default;
|
|
180
|
+
throw a._result;
|
|
181
|
+
}
|
|
182
|
+
var U = { current: null };
|
|
183
|
+
var V = { transition: null };
|
|
184
|
+
var W = {
|
|
185
|
+
ReactCurrentDispatcher: U,
|
|
186
|
+
ReactCurrentBatchConfig: V,
|
|
187
|
+
ReactCurrentOwner: K
|
|
188
|
+
};
|
|
189
|
+
function X() {
|
|
190
|
+
throw Error("act(...) is not supported in production builds of React.");
|
|
191
|
+
}
|
|
192
|
+
exports.Children = {
|
|
193
|
+
map: S,
|
|
194
|
+
forEach: function(a, b, e) {
|
|
195
|
+
S(a, function() {
|
|
196
|
+
b.apply(this, arguments);
|
|
197
|
+
}, e);
|
|
198
|
+
},
|
|
199
|
+
count: function(a) {
|
|
200
|
+
var b = 0;
|
|
201
|
+
S(a, function() {
|
|
202
|
+
b++;
|
|
203
|
+
});
|
|
204
|
+
return b;
|
|
205
|
+
},
|
|
206
|
+
toArray: function(a) {
|
|
207
|
+
return S(a, function(a) {
|
|
208
|
+
return a;
|
|
209
|
+
}) || [];
|
|
210
|
+
},
|
|
211
|
+
only: function(a) {
|
|
212
|
+
if (!O(a)) throw Error("React.Children.only expected to receive a single React element child.");
|
|
213
|
+
return a;
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
exports.Component = E;
|
|
217
|
+
exports.Fragment = p;
|
|
218
|
+
exports.Profiler = r;
|
|
219
|
+
exports.PureComponent = G;
|
|
220
|
+
exports.StrictMode = q;
|
|
221
|
+
exports.Suspense = w;
|
|
222
|
+
exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = W;
|
|
223
|
+
exports.act = X;
|
|
224
|
+
exports.cloneElement = function(a, b, e) {
|
|
225
|
+
if (null === a || void 0 === a) throw Error("React.cloneElement(...): The argument must be a React element, but you passed " + a + ".");
|
|
226
|
+
var d = C({}, a.props), c = a.key, k = a.ref, h = a._owner;
|
|
227
|
+
if (null != b) {
|
|
228
|
+
void 0 !== b.ref && (k = b.ref, h = K.current);
|
|
229
|
+
void 0 !== b.key && (c = "" + b.key);
|
|
230
|
+
if (a.type && a.type.defaultProps) var g = a.type.defaultProps;
|
|
231
|
+
for (f in b) J.call(b, f) && !L.hasOwnProperty(f) && (d[f] = void 0 === b[f] && void 0 !== g ? g[f] : b[f]);
|
|
232
|
+
}
|
|
233
|
+
var f = arguments.length - 2;
|
|
234
|
+
if (1 === f) d.children = e;
|
|
235
|
+
else if (1 < f) {
|
|
236
|
+
g = Array(f);
|
|
237
|
+
for (var m = 0; m < f; m++) g[m] = arguments[m + 2];
|
|
238
|
+
d.children = g;
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
$$typeof: l,
|
|
242
|
+
type: a.type,
|
|
243
|
+
key: c,
|
|
244
|
+
ref: k,
|
|
245
|
+
props: d,
|
|
246
|
+
_owner: h
|
|
247
|
+
};
|
|
248
|
+
};
|
|
249
|
+
exports.createContext = function(a) {
|
|
250
|
+
a = {
|
|
251
|
+
$$typeof: u,
|
|
252
|
+
_currentValue: a,
|
|
253
|
+
_currentValue2: a,
|
|
254
|
+
_threadCount: 0,
|
|
255
|
+
Provider: null,
|
|
256
|
+
Consumer: null,
|
|
257
|
+
_defaultValue: null,
|
|
258
|
+
_globalName: null
|
|
259
|
+
};
|
|
260
|
+
a.Provider = {
|
|
261
|
+
$$typeof: t,
|
|
262
|
+
_context: a
|
|
263
|
+
};
|
|
264
|
+
return a.Consumer = a;
|
|
265
|
+
};
|
|
266
|
+
exports.createElement = M;
|
|
267
|
+
exports.createFactory = function(a) {
|
|
268
|
+
var b = M.bind(null, a);
|
|
269
|
+
b.type = a;
|
|
270
|
+
return b;
|
|
271
|
+
};
|
|
272
|
+
exports.createRef = function() {
|
|
273
|
+
return { current: null };
|
|
274
|
+
};
|
|
275
|
+
exports.forwardRef = function(a) {
|
|
276
|
+
return {
|
|
277
|
+
$$typeof: v,
|
|
278
|
+
render: a
|
|
279
|
+
};
|
|
280
|
+
};
|
|
281
|
+
exports.isValidElement = O;
|
|
282
|
+
exports.lazy = function(a) {
|
|
283
|
+
return {
|
|
284
|
+
$$typeof: y,
|
|
285
|
+
_payload: {
|
|
286
|
+
_status: -1,
|
|
287
|
+
_result: a
|
|
288
|
+
},
|
|
289
|
+
_init: T
|
|
290
|
+
};
|
|
291
|
+
};
|
|
292
|
+
exports.memo = function(a, b) {
|
|
293
|
+
return {
|
|
294
|
+
$$typeof: x,
|
|
295
|
+
type: a,
|
|
296
|
+
compare: void 0 === b ? null : b
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
exports.startTransition = function(a) {
|
|
300
|
+
var b = V.transition;
|
|
301
|
+
V.transition = {};
|
|
302
|
+
try {
|
|
303
|
+
a();
|
|
304
|
+
} finally {
|
|
305
|
+
V.transition = b;
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
exports.unstable_act = X;
|
|
309
|
+
exports.useCallback = function(a, b) {
|
|
310
|
+
return U.current.useCallback(a, b);
|
|
311
|
+
};
|
|
312
|
+
exports.useContext = function(a) {
|
|
313
|
+
return U.current.useContext(a);
|
|
314
|
+
};
|
|
315
|
+
exports.useDebugValue = function() {};
|
|
316
|
+
exports.useDeferredValue = function(a) {
|
|
317
|
+
return U.current.useDeferredValue(a);
|
|
318
|
+
};
|
|
319
|
+
exports.useEffect = function(a, b) {
|
|
320
|
+
return U.current.useEffect(a, b);
|
|
321
|
+
};
|
|
322
|
+
exports.useId = function() {
|
|
323
|
+
return U.current.useId();
|
|
324
|
+
};
|
|
325
|
+
exports.useImperativeHandle = function(a, b, e) {
|
|
326
|
+
return U.current.useImperativeHandle(a, b, e);
|
|
327
|
+
};
|
|
328
|
+
exports.useInsertionEffect = function(a, b) {
|
|
329
|
+
return U.current.useInsertionEffect(a, b);
|
|
330
|
+
};
|
|
331
|
+
exports.useLayoutEffect = function(a, b) {
|
|
332
|
+
return U.current.useLayoutEffect(a, b);
|
|
333
|
+
};
|
|
334
|
+
exports.useMemo = function(a, b) {
|
|
335
|
+
return U.current.useMemo(a, b);
|
|
336
|
+
};
|
|
337
|
+
exports.useReducer = function(a, b, e) {
|
|
338
|
+
return U.current.useReducer(a, b, e);
|
|
339
|
+
};
|
|
340
|
+
exports.useRef = function(a) {
|
|
341
|
+
return U.current.useRef(a);
|
|
342
|
+
};
|
|
343
|
+
exports.useState = function(a) {
|
|
344
|
+
return U.current.useState(a);
|
|
345
|
+
};
|
|
346
|
+
exports.useSyncExternalStore = function(a, b, e) {
|
|
347
|
+
return U.current.useSyncExternalStore(a, b, e);
|
|
348
|
+
};
|
|
349
|
+
exports.useTransition = function() {
|
|
350
|
+
return U.current.useTransition();
|
|
351
|
+
};
|
|
352
|
+
exports.version = "18.3.1";
|
|
353
|
+
}));
|
|
354
|
+
//#endregion
|
|
355
|
+
//#region node_modules/.pnpm/react@18.3.1/node_modules/react/index.js
|
|
356
|
+
var require_react = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
357
|
+
module.exports = require_react_production_min();
|
|
358
|
+
}));
|
|
359
|
+
//#endregion
|
|
360
|
+
//#region node_modules/.pnpm/react@18.3.1/node_modules/react/cjs/react-jsx-runtime.production.min.js
|
|
361
|
+
/**
|
|
362
|
+
* @license React
|
|
363
|
+
* react-jsx-runtime.production.min.js
|
|
364
|
+
*
|
|
365
|
+
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
366
|
+
*
|
|
367
|
+
* This source code is licensed under the MIT license found in the
|
|
368
|
+
* LICENSE file in the root directory of this source tree.
|
|
369
|
+
*/
|
|
370
|
+
var require_react_jsx_runtime_production_min = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
371
|
+
var f = require_react();
|
|
372
|
+
var k = Symbol.for("react.element");
|
|
373
|
+
var m = Object.prototype.hasOwnProperty;
|
|
374
|
+
var n = f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner;
|
|
375
|
+
var p = {
|
|
376
|
+
key: !0,
|
|
377
|
+
ref: !0,
|
|
378
|
+
__self: !0,
|
|
379
|
+
__source: !0
|
|
380
|
+
};
|
|
381
|
+
function q(c, a, g) {
|
|
382
|
+
var b, d = {}, e = null, h = null;
|
|
383
|
+
void 0 !== g && (e = "" + g);
|
|
384
|
+
void 0 !== a.key && (e = "" + a.key);
|
|
385
|
+
void 0 !== a.ref && (h = a.ref);
|
|
386
|
+
for (b in a) m.call(a, b) && !p.hasOwnProperty(b) && (d[b] = a[b]);
|
|
387
|
+
if (c && c.defaultProps) for (b in a = c.defaultProps, a) void 0 === d[b] && (d[b] = a[b]);
|
|
388
|
+
return {
|
|
389
|
+
$$typeof: k,
|
|
390
|
+
type: c,
|
|
391
|
+
key: e,
|
|
392
|
+
ref: h,
|
|
393
|
+
props: d,
|
|
394
|
+
_owner: n.current
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
exports.jsx = q;
|
|
398
|
+
exports.jsxs = q;
|
|
399
|
+
}));
|
|
400
|
+
//#endregion
|
|
401
|
+
//#region lib/types/context.js
|
|
402
|
+
var import_jsx_runtime = (/* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
403
|
+
module.exports = require_react_jsx_runtime_production_min();
|
|
404
|
+
})))();
|
|
405
|
+
/** User-selectable Codex context controls use whole K-token units. */
|
|
406
|
+
const CODEX_CONTEXT_UNIT = 1e3;
|
|
407
|
+
const CODEX_CONTEXT_MAX = 1e6;
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region lib/types/client/index.js
|
|
410
|
+
const NS = "codex";
|
|
411
|
+
const SETTINGS_NAMESPACE = "codex";
|
|
412
|
+
const en = {
|
|
413
|
+
fast: "Fast mode",
|
|
414
|
+
fastOn: "Fast mode on (priority tier)",
|
|
415
|
+
fastOff: "Fast mode off",
|
|
416
|
+
fastStateOn: "On",
|
|
417
|
+
fastStateOff: "Off",
|
|
418
|
+
contextSize: "Context size",
|
|
419
|
+
contextSizeDescription: "Next request capacity in K tokens. The meter above is current.",
|
|
420
|
+
contextRestore: "Restore model default"
|
|
421
|
+
};
|
|
422
|
+
const zh = {
|
|
423
|
+
fast: "Fast",
|
|
424
|
+
fastOn: "Fast mode on (priority tier)",
|
|
425
|
+
fastOff: "Fast mode off",
|
|
426
|
+
fastStateOn: "开",
|
|
427
|
+
fastStateOff: "关",
|
|
428
|
+
contextSize: "上下文大小",
|
|
429
|
+
contextSizeDescription: "设置下次请求的上下文容量,单位为 K tokens;上方是当前请求。",
|
|
430
|
+
contextRestore: "恢复模型默认值"
|
|
431
|
+
};
|
|
432
|
+
function FastModeButton({ sessionId, useSessions, useSettings, setSetting, t }) {
|
|
433
|
+
const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
|
|
434
|
+
const snapshot = useSettings((state) => state);
|
|
435
|
+
const fast = snapshot.value?.fast ?? false;
|
|
436
|
+
if (agentPreset !== "codex") return null;
|
|
437
|
+
return (0, import_jsx_runtime.jsxs)("button", {
|
|
438
|
+
type: "button",
|
|
439
|
+
role: "menuitemcheckbox",
|
|
440
|
+
disabled: snapshot.writable === false,
|
|
441
|
+
"aria-pressed": fast,
|
|
442
|
+
"aria-label": fast ? t("fastOn") : t("fastOff"),
|
|
443
|
+
title: fast ? t("fastOn") : t("fastOff"),
|
|
444
|
+
onClick: () => {
|
|
445
|
+
setSetting("fast", !fast);
|
|
446
|
+
},
|
|
447
|
+
style: {
|
|
448
|
+
boxSizing: "border-box",
|
|
449
|
+
display: "flex",
|
|
450
|
+
alignItems: "center",
|
|
451
|
+
justifyContent: "space-between",
|
|
452
|
+
width: "100%",
|
|
453
|
+
height: 40,
|
|
454
|
+
border: 0,
|
|
455
|
+
borderRadius: 10,
|
|
456
|
+
padding: "0 10px",
|
|
457
|
+
color: fast ? "var(--dsw-static-blue-500)" : "var(--dsw-alias-label-secondary)",
|
|
458
|
+
background: fast ? "var(--dsw-alias-interactive-bg-selected)" : "transparent",
|
|
459
|
+
cursor: snapshot.writable === false ? "default" : "pointer",
|
|
460
|
+
font: "inherit",
|
|
461
|
+
fontSize: 14,
|
|
462
|
+
lineHeight: "22px",
|
|
463
|
+
fontWeight: fast ? 600 : 400,
|
|
464
|
+
textAlign: "left"
|
|
465
|
+
},
|
|
466
|
+
children: [(0, import_jsx_runtime.jsx)("span", { children: t("fast") }), (0, import_jsx_runtime.jsx)("span", {
|
|
467
|
+
style: {
|
|
468
|
+
color: "var(--dsw-alias-label-tertiary)",
|
|
469
|
+
fontSize: 12
|
|
470
|
+
},
|
|
471
|
+
children: fast ? t("fastStateOn") : t("fastStateOff")
|
|
472
|
+
})]
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
function ContextSizeControl({ contextWindow, useSettings, setSetting, unsetSetting, t }) {
|
|
476
|
+
const snapshot = useSettings((state) => state);
|
|
477
|
+
const configured = snapshot.value?.contextWindow;
|
|
478
|
+
const maxK = CODEX_CONTEXT_MAX / CODEX_CONTEXT_UNIT;
|
|
479
|
+
const valueK = Math.min(maxK, Math.max(1, Math.round((configured ?? contextWindow) / CODEX_CONTEXT_UNIT)));
|
|
480
|
+
const setValueK = (nextK) => {
|
|
481
|
+
if (!Number.isFinite(nextK)) return;
|
|
482
|
+
const normalized = Math.min(maxK, Math.max(1, Math.trunc(nextK))) * CODEX_CONTEXT_UNIT;
|
|
483
|
+
if (normalized === contextWindow) unsetSetting("contextWindow");
|
|
484
|
+
else setSetting("contextWindow", normalized);
|
|
485
|
+
};
|
|
486
|
+
return (0, import_jsx_runtime.jsxs)("div", {
|
|
487
|
+
style: {
|
|
488
|
+
marginTop: 10,
|
|
489
|
+
display: "grid",
|
|
490
|
+
gap: 5
|
|
491
|
+
},
|
|
492
|
+
children: [
|
|
493
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
494
|
+
style: {
|
|
495
|
+
display: "flex",
|
|
496
|
+
alignItems: "baseline",
|
|
497
|
+
justifyContent: "space-between",
|
|
498
|
+
gap: 12
|
|
499
|
+
},
|
|
500
|
+
children: [(0, import_jsx_runtime.jsx)("strong", {
|
|
501
|
+
style: {
|
|
502
|
+
color: "var(--dsw-alias-label-primary)",
|
|
503
|
+
fontSize: 12
|
|
504
|
+
},
|
|
505
|
+
children: t("contextSize")
|
|
506
|
+
}), (0, import_jsx_runtime.jsxs)("span", {
|
|
507
|
+
style: {
|
|
508
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
509
|
+
fontSize: 11
|
|
510
|
+
},
|
|
511
|
+
children: [valueK, "K"]
|
|
512
|
+
})]
|
|
513
|
+
}),
|
|
514
|
+
(0, import_jsx_runtime.jsx)("input", {
|
|
515
|
+
type: "range",
|
|
516
|
+
min: 1,
|
|
517
|
+
max: maxK,
|
|
518
|
+
step: 1,
|
|
519
|
+
value: valueK,
|
|
520
|
+
disabled: snapshot.writable === false,
|
|
521
|
+
"aria-label": t("contextSize"),
|
|
522
|
+
onChange: (event) => {
|
|
523
|
+
setValueK(Number(event.target.value));
|
|
524
|
+
}
|
|
525
|
+
}),
|
|
526
|
+
(0, import_jsx_runtime.jsxs)("div", {
|
|
527
|
+
style: {
|
|
528
|
+
display: "flex",
|
|
529
|
+
alignItems: "center",
|
|
530
|
+
gap: 7
|
|
531
|
+
},
|
|
532
|
+
children: [
|
|
533
|
+
(0, import_jsx_runtime.jsx)("input", {
|
|
534
|
+
type: "number",
|
|
535
|
+
min: 1,
|
|
536
|
+
max: maxK,
|
|
537
|
+
step: 1,
|
|
538
|
+
value: valueK,
|
|
539
|
+
disabled: snapshot.writable === false,
|
|
540
|
+
"aria-label": t("contextSize"),
|
|
541
|
+
onChange: (event) => {
|
|
542
|
+
setValueK(Number(event.target.value));
|
|
543
|
+
},
|
|
544
|
+
style: {
|
|
545
|
+
width: 76,
|
|
546
|
+
border: "1px solid var(--dsw-alias-border-primary)",
|
|
547
|
+
borderRadius: 5,
|
|
548
|
+
padding: "3px 5px",
|
|
549
|
+
color: "var(--dsw-alias-label-primary)",
|
|
550
|
+
background: "var(--dsw-alias-fill-primary)",
|
|
551
|
+
font: "inherit",
|
|
552
|
+
fontSize: 11
|
|
553
|
+
}
|
|
554
|
+
}),
|
|
555
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
556
|
+
style: {
|
|
557
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
558
|
+
fontSize: 11
|
|
559
|
+
},
|
|
560
|
+
children: "K"
|
|
561
|
+
}),
|
|
562
|
+
(0, import_jsx_runtime.jsx)("span", {
|
|
563
|
+
style: {
|
|
564
|
+
color: "var(--dsw-alias-label-secondary)",
|
|
565
|
+
fontSize: 11
|
|
566
|
+
},
|
|
567
|
+
children: t("contextSizeDescription")
|
|
568
|
+
})
|
|
569
|
+
]
|
|
570
|
+
}),
|
|
571
|
+
configured !== void 0 && (0, import_jsx_runtime.jsx)("button", {
|
|
572
|
+
type: "button",
|
|
573
|
+
onClick: () => {
|
|
574
|
+
unsetSetting("contextWindow");
|
|
575
|
+
},
|
|
576
|
+
style: {
|
|
577
|
+
justifySelf: "start",
|
|
578
|
+
border: 0,
|
|
579
|
+
padding: 0,
|
|
580
|
+
color: "var(--dsw-static-blue-500)",
|
|
581
|
+
background: "transparent",
|
|
582
|
+
cursor: "pointer",
|
|
583
|
+
font: "inherit",
|
|
584
|
+
fontSize: 11
|
|
585
|
+
},
|
|
586
|
+
children: t("contextRestore")
|
|
587
|
+
})
|
|
588
|
+
]
|
|
589
|
+
});
|
|
590
|
+
}
|
|
591
|
+
const inject = [
|
|
592
|
+
"slots",
|
|
593
|
+
"locale",
|
|
594
|
+
"settingsScope"
|
|
595
|
+
];
|
|
596
|
+
/** Mount Fast inside the model selector and context size inside the meter panel. */
|
|
597
|
+
function apply(ctx) {
|
|
598
|
+
ctx.effect(() => ctx.locale.register(NS, {
|
|
599
|
+
en,
|
|
600
|
+
zh
|
|
601
|
+
}), "codex client: dictionaries");
|
|
602
|
+
const settings = ctx.settingsScope.bind({ namespace: SETTINGS_NAMESPACE });
|
|
603
|
+
const injected = () => ({
|
|
604
|
+
hooks: { settings },
|
|
605
|
+
setSetting: (field, value) => settings.set(field, value),
|
|
606
|
+
unsetSetting: (field) => settings.unset(field)
|
|
607
|
+
});
|
|
608
|
+
ctx.slots.inject("conversation.input.model.settings", () => ctx.slots.register({
|
|
609
|
+
name: "conversation.input.model.settings",
|
|
610
|
+
id: "codex-fast",
|
|
611
|
+
order: 0,
|
|
612
|
+
locale: NS,
|
|
613
|
+
inject: injected
|
|
614
|
+
}, FastModeButton));
|
|
615
|
+
ctx.slots.inject("conversation.input.context.settings", () => ctx.slots.register({
|
|
616
|
+
name: "conversation.input.context.settings",
|
|
617
|
+
id: "codex-context-size",
|
|
618
|
+
order: 0,
|
|
619
|
+
locale: NS,
|
|
620
|
+
inject: injected
|
|
621
|
+
}, ContextSizeControl));
|
|
622
|
+
}
|
|
623
|
+
var client_default = {
|
|
624
|
+
inject,
|
|
625
|
+
apply
|
|
626
|
+
};
|
|
627
|
+
//#endregion
|
|
628
|
+
exports.apply = apply;
|
|
629
|
+
exports.default = client_default;
|
|
630
|
+
exports.inject = inject;
|
|
631
|
+
return module.exports;
|
|
632
|
+
}
|
|
633
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import z from "@deepseek-ai/schemastery";
|
|
2
|
-
import { settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
2
|
+
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
3
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
4
4
|
import { randomBytes } from "node:crypto";
|
|
5
5
|
import { resolve } from "node:path";
|
|
6
6
|
import { credentialRef } from "@deepseek-ai/dsh-credentials";
|
|
7
7
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
8
|
+
//#region lib/types/context.js
|
|
9
|
+
const CODEX_CONTEXT_MAX = 1e6;
|
|
8
10
|
String.raw`start: begin_patch hunk+ end_patch
|
|
9
11
|
begin_patch: "*** Begin Patch" LF
|
|
10
12
|
end_patch: "*** End Patch" LF?
|
|
@@ -714,7 +716,8 @@ const inject = [
|
|
|
714
716
|
"shell",
|
|
715
717
|
"fs",
|
|
716
718
|
"llm",
|
|
717
|
-
"credentials"
|
|
719
|
+
"credentials",
|
|
720
|
+
"settings"
|
|
718
721
|
];
|
|
719
722
|
/** Runtime configuration schema for the Codex tool bridge. */
|
|
720
723
|
const Config = z.object({
|
|
@@ -726,6 +729,13 @@ const Config = z.object({
|
|
|
726
729
|
remoteCompact: z.boolean().default(true)
|
|
727
730
|
});
|
|
728
731
|
const LLM_PI_AI_SETTINGS = settingsNamespace("llm-pi-ai");
|
|
732
|
+
/** Live Codex-only request controls shared by the Web controls and agent layer. */
|
|
733
|
+
const CODEX_SETTINGS_NAMESPACE = settingsNamespace("codex");
|
|
734
|
+
const CODEX_SETTINGS_SCHEMA = z.object({
|
|
735
|
+
fast: z.boolean().default(false),
|
|
736
|
+
contextWindow: z.number().step(1).min(1).max(CODEX_CONTEXT_MAX)
|
|
737
|
+
});
|
|
738
|
+
const CODEX_SETTINGS_ENTRY = { fast: false };
|
|
729
739
|
const GPT_REASONING_EFFORTS = {
|
|
730
740
|
low: "low",
|
|
731
741
|
medium: "medium",
|
|
@@ -809,6 +819,27 @@ function watchConfiguredGptModels(ctx) {
|
|
|
809
819
|
});
|
|
810
820
|
schedule();
|
|
811
821
|
}
|
|
822
|
+
/** Install the optional settings source used by the request waterfall. */
|
|
823
|
+
function installCodexSettings(ctx) {
|
|
824
|
+
let source = () => CODEX_SETTINGS_ENTRY;
|
|
825
|
+
installSettingsSection(ctx, CODEX_SETTINGS_NAMESPACE, CODEX_SETTINGS_SCHEMA, CODEX_SETTINGS_ENTRY, {
|
|
826
|
+
setSource: (current) => {
|
|
827
|
+
source = current;
|
|
828
|
+
},
|
|
829
|
+
onChange: () => {}
|
|
830
|
+
});
|
|
831
|
+
return { current: () => source() };
|
|
832
|
+
}
|
|
833
|
+
/** Apply the live Codex controls to one agent request without leaking them to other routes. */
|
|
834
|
+
function applyCodexRequestSettings(request, settings) {
|
|
835
|
+
const { contextWindow: _inheritedContextWindow, serviceTier: _inheritedServiceTier, ...withoutCodexControls } = request;
|
|
836
|
+
if (!isGptModel(request.model)) return withoutCodexControls;
|
|
837
|
+
return {
|
|
838
|
+
...withoutCodexControls,
|
|
839
|
+
...settings.contextWindow === void 0 ? {} : { contextWindow: settings.contextWindow },
|
|
840
|
+
...settings.fast ? { serviceTier: "priority" } : {}
|
|
841
|
+
};
|
|
842
|
+
}
|
|
812
843
|
const CODEX_BASE_PROMPT = String.raw`You are Codex, based on {{model}}. You are running as a coding agent in dsh Web on a user's computer.
|
|
813
844
|
|
|
814
845
|
## General
|
|
@@ -1221,15 +1252,19 @@ function apply(ctx, config = {}) {
|
|
|
1221
1252
|
};
|
|
1222
1253
|
if (ctx.fs.sandboxMode !== void 0 && ctx.get("sandboxPolicy") === void 0) throw new Error("codex: a sandboxing filesystem requires ctx.sandboxPolicy");
|
|
1223
1254
|
watchConfiguredGptModels(ctx);
|
|
1255
|
+
const codexSettings = installCodexSettings(ctx);
|
|
1256
|
+
ctx.on("agent/request", async (_payload, next) => {
|
|
1257
|
+
return applyCodexRequestSettings(await next(), codexSettings.current());
|
|
1258
|
+
});
|
|
1224
1259
|
if ((resolved.hostedWebSearch || resolved.remoteCompact) && typeof ctx.effect === "function") {
|
|
1225
1260
|
const disposeHostedWebSearch = installHostedWebSearch();
|
|
1226
1261
|
ctx.effect(() => disposeHostedWebSearch, "codex: Responses transport wrapper");
|
|
1227
1262
|
}
|
|
1228
|
-
if (resolved.hostedWebSearch || resolved.remoteCompact) ctx.on("llm/stream", (options, next) => {
|
|
1263
|
+
if (resolved.hostedWebSearch || resolved.remoteCompact) ctx.on("llm/stream", ((options, next) => {
|
|
1229
1264
|
if (resolved.remoteCompact && options.purpose === "compaction" && isGptModel(options.model)) return remoteCompactStream(ctx, options, next);
|
|
1230
1265
|
if ((resolved.hostedWebSearch || resolved.remoteCompact) && options.purpose === void 0 && isGptModel(options.model)) return hostedWebSearchStream(next);
|
|
1231
1266
|
return next();
|
|
1232
|
-
});
|
|
1267
|
+
}));
|
|
1233
1268
|
ctx.systemPrompt.section({
|
|
1234
1269
|
name: "codex:base",
|
|
1235
1270
|
order: 10,
|
|
@@ -1246,4 +1281,4 @@ var types_default = {
|
|
|
1246
1281
|
apply
|
|
1247
1282
|
};
|
|
1248
1283
|
//#endregion
|
|
1249
|
-
export { Config, apply, types_default as default, enrichCodexModel, inject, name };
|
|
1284
|
+
export { CODEX_SETTINGS_NAMESPACE, CODEX_SETTINGS_SCHEMA, Config, apply, applyCodexRequestSettings, types_default as default, enrichCodexModel, inject, name };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/** Browser controls for the Codex request settings mounted by the Host plugin. */
|
|
2
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
3
|
+
declare const en: {
|
|
4
|
+
readonly fast: "Fast mode";
|
|
5
|
+
readonly fastOn: "Fast mode on (priority tier)";
|
|
6
|
+
readonly fastOff: "Fast mode off";
|
|
7
|
+
readonly fastStateOn: "On";
|
|
8
|
+
readonly fastStateOff: "Off";
|
|
9
|
+
readonly contextSize: "Context size";
|
|
10
|
+
readonly contextSizeDescription: "Next request capacity in K tokens. The meter above is current.";
|
|
11
|
+
readonly contextRestore: "Restore model default";
|
|
12
|
+
};
|
|
13
|
+
type CodexKey = keyof typeof en;
|
|
14
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
15
|
+
interface LocaleNamespaceMap {
|
|
16
|
+
codex: CodexKey;
|
|
17
|
+
}
|
|
18
|
+
interface SlotMap {
|
|
19
|
+
'conversation.input.model.settings': {
|
|
20
|
+
kind: 'list';
|
|
21
|
+
scope: 'session';
|
|
22
|
+
};
|
|
23
|
+
'conversation.input.context.settings': {
|
|
24
|
+
kind: 'list';
|
|
25
|
+
scope: 'session';
|
|
26
|
+
owner: {
|
|
27
|
+
contextWindow: number;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
export declare const inject: string[];
|
|
33
|
+
/** Mount Fast inside the model selector and context size inside the meter panel. */
|
|
34
|
+
export declare function apply(ctx: Context): void;
|
|
35
|
+
declare const _default: {
|
|
36
|
+
inject: string[];
|
|
37
|
+
apply: typeof apply;
|
|
38
|
+
};
|
|
39
|
+
export default _default;
|
|
40
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CODEX_CONTEXT_MAX, CODEX_CONTEXT_UNIT, CODEX_PRESET_ID } from "../context.js";
|
|
3
|
+
const NS = 'codex';
|
|
4
|
+
const SETTINGS_NAMESPACE = 'codex';
|
|
5
|
+
const en = {
|
|
6
|
+
fast: 'Fast mode',
|
|
7
|
+
fastOn: 'Fast mode on (priority tier)',
|
|
8
|
+
fastOff: 'Fast mode off',
|
|
9
|
+
fastStateOn: 'On',
|
|
10
|
+
fastStateOff: 'Off',
|
|
11
|
+
contextSize: 'Context size',
|
|
12
|
+
contextSizeDescription: 'Next request capacity in K tokens. The meter above is current.',
|
|
13
|
+
contextRestore: 'Restore model default',
|
|
14
|
+
};
|
|
15
|
+
const zh = {
|
|
16
|
+
fast: 'Fast',
|
|
17
|
+
fastOn: 'Fast mode on (priority tier)',
|
|
18
|
+
fastOff: 'Fast mode off',
|
|
19
|
+
fastStateOn: '开',
|
|
20
|
+
fastStateOff: '关',
|
|
21
|
+
contextSize: '上下文大小',
|
|
22
|
+
contextSizeDescription: '设置下次请求的上下文容量,单位为 K tokens;上方是当前请求。',
|
|
23
|
+
contextRestore: '恢复模型默认值',
|
|
24
|
+
};
|
|
25
|
+
function FastModeButton({ sessionId, useSessions, useSettings, setSetting, t }) {
|
|
26
|
+
const agentPreset = useSessions(state => state.byId[sessionId]?.agentPreset);
|
|
27
|
+
const snapshot = useSettings(state => state);
|
|
28
|
+
const fast = snapshot.value?.fast ?? false;
|
|
29
|
+
if (agentPreset !== CODEX_PRESET_ID)
|
|
30
|
+
return null;
|
|
31
|
+
return (_jsxs("button", { type: "button", role: "menuitemcheckbox", disabled: snapshot.writable === false, "aria-pressed": fast, "aria-label": fast ? t('fastOn') : t('fastOff'), title: fast ? t('fastOn') : t('fastOff'), onClick: () => { void setSetting('fast', !fast); }, style: {
|
|
32
|
+
boxSizing: 'border-box',
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
justifyContent: 'space-between',
|
|
36
|
+
width: '100%',
|
|
37
|
+
height: 40,
|
|
38
|
+
border: 0,
|
|
39
|
+
borderRadius: 10,
|
|
40
|
+
padding: '0 10px',
|
|
41
|
+
color: fast ? 'var(--dsw-static-blue-500)' : 'var(--dsw-alias-label-secondary)',
|
|
42
|
+
background: fast ? 'var(--dsw-alias-interactive-bg-selected)' : 'transparent',
|
|
43
|
+
cursor: snapshot.writable === false ? 'default' : 'pointer',
|
|
44
|
+
font: 'inherit',
|
|
45
|
+
fontSize: 14,
|
|
46
|
+
lineHeight: '22px',
|
|
47
|
+
fontWeight: fast ? 600 : 400,
|
|
48
|
+
textAlign: 'left',
|
|
49
|
+
}, children: [_jsx("span", { children: t('fast') }), _jsx("span", { style: { color: 'var(--dsw-alias-label-tertiary)', fontSize: 12 }, children: fast ? t('fastStateOn') : t('fastStateOff') })] }));
|
|
50
|
+
}
|
|
51
|
+
function ContextSizeControl({ contextWindow, useSettings, setSetting, unsetSetting, t }) {
|
|
52
|
+
const snapshot = useSettings(state => state);
|
|
53
|
+
const configured = snapshot.value?.contextWindow;
|
|
54
|
+
const maxK = CODEX_CONTEXT_MAX / CODEX_CONTEXT_UNIT;
|
|
55
|
+
const valueK = Math.min(maxK, Math.max(1, Math.round((configured ?? contextWindow) / CODEX_CONTEXT_UNIT)));
|
|
56
|
+
const setValueK = (nextK) => {
|
|
57
|
+
if (!Number.isFinite(nextK))
|
|
58
|
+
return;
|
|
59
|
+
const normalizedK = Math.min(maxK, Math.max(1, Math.trunc(nextK)));
|
|
60
|
+
const normalized = normalizedK * CODEX_CONTEXT_UNIT;
|
|
61
|
+
if (normalized === contextWindow)
|
|
62
|
+
void unsetSetting('contextWindow');
|
|
63
|
+
else
|
|
64
|
+
void setSetting('contextWindow', normalized);
|
|
65
|
+
};
|
|
66
|
+
return (_jsxs("div", { style: { marginTop: 10, display: 'grid', gap: 5 }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', gap: 12 }, children: [_jsx("strong", { style: { color: 'var(--dsw-alias-label-primary)', fontSize: 12 }, children: t('contextSize') }), _jsxs("span", { style: { color: 'var(--dsw-alias-label-secondary)', fontSize: 11 }, children: [valueK, "K"] })] }), _jsx("input", { type: "range", min: 1, max: maxK, step: 1, value: valueK, disabled: snapshot.writable === false, "aria-label": t('contextSize'), onChange: event => { setValueK(Number(event.target.value)); } }), _jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 7 }, children: [_jsx("input", { type: "number", min: 1, max: maxK, step: 1, value: valueK, disabled: snapshot.writable === false, "aria-label": t('contextSize'), onChange: event => { setValueK(Number(event.target.value)); }, style: {
|
|
67
|
+
width: 76,
|
|
68
|
+
border: '1px solid var(--dsw-alias-border-primary)',
|
|
69
|
+
borderRadius: 5,
|
|
70
|
+
padding: '3px 5px',
|
|
71
|
+
color: 'var(--dsw-alias-label-primary)',
|
|
72
|
+
background: 'var(--dsw-alias-fill-primary)',
|
|
73
|
+
font: 'inherit',
|
|
74
|
+
fontSize: 11,
|
|
75
|
+
} }), _jsx("span", { style: { color: 'var(--dsw-alias-label-secondary)', fontSize: 11 }, children: "K" }), _jsx("span", { style: { color: 'var(--dsw-alias-label-secondary)', fontSize: 11 }, children: t('contextSizeDescription') })] }), configured !== undefined && (_jsx("button", { type: "button", onClick: () => { void unsetSetting('contextWindow'); }, style: {
|
|
76
|
+
justifySelf: 'start',
|
|
77
|
+
border: 0,
|
|
78
|
+
padding: 0,
|
|
79
|
+
color: 'var(--dsw-static-blue-500)',
|
|
80
|
+
background: 'transparent',
|
|
81
|
+
cursor: 'pointer',
|
|
82
|
+
font: 'inherit',
|
|
83
|
+
fontSize: 11,
|
|
84
|
+
}, children: t('contextRestore') }))] }));
|
|
85
|
+
}
|
|
86
|
+
export const inject = ['slots', 'locale', 'settingsScope'];
|
|
87
|
+
/** Mount Fast inside the model selector and context size inside the meter panel. */
|
|
88
|
+
export function apply(ctx) {
|
|
89
|
+
ctx.effect(() => ctx.locale.register(NS, { en, zh }), 'codex client: dictionaries');
|
|
90
|
+
const settings = ctx.settingsScope.bind({ namespace: SETTINGS_NAMESPACE });
|
|
91
|
+
const injected = () => ({
|
|
92
|
+
hooks: { settings },
|
|
93
|
+
setSetting: (field, value) => settings.set(field, value),
|
|
94
|
+
unsetSetting: (field) => settings.unset(field),
|
|
95
|
+
});
|
|
96
|
+
ctx.slots.inject('conversation.input.model.settings', () => ctx.slots.register({
|
|
97
|
+
name: 'conversation.input.model.settings',
|
|
98
|
+
id: 'codex-fast',
|
|
99
|
+
order: 0,
|
|
100
|
+
locale: NS,
|
|
101
|
+
inject: injected,
|
|
102
|
+
}, FastModeButton));
|
|
103
|
+
ctx.slots.inject('conversation.input.context.settings', () => ctx.slots.register({
|
|
104
|
+
name: 'conversation.input.context.settings',
|
|
105
|
+
id: 'codex-context-size',
|
|
106
|
+
order: 0,
|
|
107
|
+
locale: NS,
|
|
108
|
+
inject: injected,
|
|
109
|
+
}, ContextSizeControl));
|
|
110
|
+
}
|
|
111
|
+
export default { inject, apply };
|
|
112
|
+
//# sourceMappingURL=index.js.map
|
package/lib/types/index.d.ts
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
/** Codex-compatible prompt overlay and core tools for a dsh agent preset. */
|
|
2
2
|
import type { Context } from '@deepseek-ai/cordis';
|
|
3
3
|
import z from '@deepseek-ai/schemastery';
|
|
4
|
+
import type { LlmCallConfig } from '@deepseek-ai/dsh-llm';
|
|
5
|
+
declare module '@deepseek-ai/dsh-llm' {
|
|
6
|
+
interface LlmCallConfig {
|
|
7
|
+
/** Codex request context capacity override, in tokens. */
|
|
8
|
+
contextWindow?: number;
|
|
9
|
+
/** Provider-facing service tier, for example Responses `priority`. */
|
|
10
|
+
serviceTier?: string;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
4
13
|
export declare const name = "codex";
|
|
5
14
|
export declare const inject: string[];
|
|
6
15
|
/** Configuration for the Codex shell result bridge. */
|
|
@@ -20,6 +29,15 @@ export interface Config {
|
|
|
20
29
|
}
|
|
21
30
|
/** Runtime configuration schema for the Codex tool bridge. */
|
|
22
31
|
export declare const Config: z<Config>;
|
|
32
|
+
/** Live Codex-only request controls shared by the Web controls and agent layer. */
|
|
33
|
+
export declare const CODEX_SETTINGS_NAMESPACE: import("@deepseek-ai/dsh-settings").SettingsNamespace;
|
|
34
|
+
export interface CodexSettings {
|
|
35
|
+
/** Use the Responses priority service tier for GPT requests. */
|
|
36
|
+
fast: boolean;
|
|
37
|
+
/** Optional context capacity override, in tokens. */
|
|
38
|
+
contextWindow?: number;
|
|
39
|
+
}
|
|
40
|
+
export declare const CODEX_SETTINGS_SCHEMA: z<CodexSettings>;
|
|
23
41
|
export interface CodexModelProfile {
|
|
24
42
|
id: string;
|
|
25
43
|
input?: string[];
|
|
@@ -28,6 +46,8 @@ export interface CodexModelProfile {
|
|
|
28
46
|
}
|
|
29
47
|
/** Add Codex defaults without overwriting explicit user capabilities. */
|
|
30
48
|
export declare function enrichCodexModel(model: CodexModelProfile): CodexModelProfile;
|
|
49
|
+
/** Apply the live Codex controls to one agent request without leaking them to other routes. */
|
|
50
|
+
export declare function applyCodexRequestSettings(request: LlmCallConfig, settings: CodexSettings): LlmCallConfig;
|
|
31
51
|
/** Mount the Codex prompt/tool layer inside one fixed agent preset. */
|
|
32
52
|
export declare function apply(ctx: Context, config?: Config): void;
|
|
33
53
|
declare const _default: {
|
package/lib/types/index.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
/** Codex-compatible prompt overlay and core tools for a dsh agent preset. */
|
|
2
2
|
import z from '@deepseek-ai/schemastery';
|
|
3
|
-
import { settingsNamespace } from '@deepseek-ai/dsh-settings';
|
|
3
|
+
import { installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings';
|
|
4
4
|
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
5
|
+
import { CODEX_CONTEXT_MAX } from "./context.js";
|
|
5
6
|
import { applyPatchHunks, parsePatch } from "./patch.js";
|
|
6
7
|
import { renderExecResult, runExecCommand, runWriteStdin } from "./exec.js";
|
|
7
8
|
import { hostedWebSearchStream, installHostedWebSearch, remoteCompactStream } from "./remote.js";
|
|
8
9
|
export const name = 'codex';
|
|
9
|
-
export const inject = ['tools', 'systemPrompt', 'shell', 'fs', 'llm', 'credentials'];
|
|
10
|
+
export const inject = ['tools', 'systemPrompt', 'shell', 'fs', 'llm', 'credentials', 'settings'];
|
|
10
11
|
/** Runtime configuration schema for the Codex tool bridge. */
|
|
11
12
|
export const Config = z.object({
|
|
12
13
|
defaultYieldTimeMs: z.number().step(1).min(0).default(10_000),
|
|
@@ -17,6 +18,13 @@ export const Config = z.object({
|
|
|
17
18
|
remoteCompact: z.boolean().default(true),
|
|
18
19
|
});
|
|
19
20
|
const LLM_PI_AI_SETTINGS = settingsNamespace('llm-pi-ai');
|
|
21
|
+
/** Live Codex-only request controls shared by the Web controls and agent layer. */
|
|
22
|
+
export const CODEX_SETTINGS_NAMESPACE = settingsNamespace('codex');
|
|
23
|
+
export const CODEX_SETTINGS_SCHEMA = z.object({
|
|
24
|
+
fast: z.boolean().default(false),
|
|
25
|
+
contextWindow: z.number().step(1).min(1).max(CODEX_CONTEXT_MAX),
|
|
26
|
+
});
|
|
27
|
+
const CODEX_SETTINGS_ENTRY = { fast: false };
|
|
20
28
|
const GPT_REASONING_EFFORTS = {
|
|
21
29
|
low: 'low',
|
|
22
30
|
medium: 'medium',
|
|
@@ -108,6 +116,26 @@ function watchConfiguredGptModels(ctx) {
|
|
|
108
116
|
});
|
|
109
117
|
schedule();
|
|
110
118
|
}
|
|
119
|
+
/** Install the optional settings source used by the request waterfall. */
|
|
120
|
+
function installCodexSettings(ctx) {
|
|
121
|
+
let source = () => CODEX_SETTINGS_ENTRY;
|
|
122
|
+
installSettingsSection(ctx, CODEX_SETTINGS_NAMESPACE, CODEX_SETTINGS_SCHEMA, CODEX_SETTINGS_ENTRY, {
|
|
123
|
+
setSource: (current) => { source = current; },
|
|
124
|
+
onChange: () => { },
|
|
125
|
+
});
|
|
126
|
+
return { current: () => source() };
|
|
127
|
+
}
|
|
128
|
+
/** Apply the live Codex controls to one agent request without leaking them to other routes. */
|
|
129
|
+
export function applyCodexRequestSettings(request, settings) {
|
|
130
|
+
const { contextWindow: _inheritedContextWindow, serviceTier: _inheritedServiceTier, ...withoutCodexControls } = request;
|
|
131
|
+
if (!isGptModel(request.model))
|
|
132
|
+
return withoutCodexControls;
|
|
133
|
+
return {
|
|
134
|
+
...withoutCodexControls,
|
|
135
|
+
...settings.contextWindow === undefined ? {} : { contextWindow: settings.contextWindow },
|
|
136
|
+
...settings.fast ? { serviceTier: 'priority' } : {},
|
|
137
|
+
};
|
|
138
|
+
}
|
|
111
139
|
const CODEX_BASE_PROMPT = String.raw `You are Codex, based on {{model}}. You are running as a coding agent in dsh Web on a user's computer.
|
|
112
140
|
|
|
113
141
|
## General
|
|
@@ -414,12 +442,20 @@ export function apply(ctx, config = {}) {
|
|
|
414
442
|
// provider routes. Codex adds only scoped transport behavior and capability
|
|
415
443
|
// metadata; failed remote operations continue through the generic path.
|
|
416
444
|
watchConfiguredGptModels(ctx);
|
|
445
|
+
const codexSettings = installCodexSettings(ctx);
|
|
446
|
+
// Keep these controls in the request config rather than mutating provider
|
|
447
|
+
// settings. That makes a change apply to the next step without rebuilding
|
|
448
|
+
// the user's model catalog, while the LLM service still freezes it per call.
|
|
449
|
+
ctx.on('agent/request', async (_payload, next) => {
|
|
450
|
+
const request = await next();
|
|
451
|
+
return applyCodexRequestSettings(request, codexSettings.current());
|
|
452
|
+
});
|
|
417
453
|
if ((resolved.hostedWebSearch || resolved.remoteCompact) && typeof ctx.effect === 'function') {
|
|
418
454
|
const disposeHostedWebSearch = installHostedWebSearch();
|
|
419
455
|
ctx.effect(() => disposeHostedWebSearch, 'codex: Responses transport wrapper');
|
|
420
456
|
}
|
|
421
457
|
if (resolved.hostedWebSearch || resolved.remoteCompact) {
|
|
422
|
-
ctx.on('llm/stream', (options, next) => {
|
|
458
|
+
ctx.on('llm/stream', ((options, next) => {
|
|
423
459
|
if (resolved.remoteCompact && options.purpose === 'compaction' && isGptModel(options.model)) {
|
|
424
460
|
return remoteCompactStream(ctx, options, next);
|
|
425
461
|
}
|
|
@@ -429,7 +465,7 @@ export function apply(ctx, config = {}) {
|
|
|
429
465
|
return hostedWebSearchStream(next);
|
|
430
466
|
}
|
|
431
467
|
return next();
|
|
432
|
-
});
|
|
468
|
+
}));
|
|
433
469
|
}
|
|
434
470
|
ctx.systemPrompt.section({ name: 'codex:base', order: 10, text: CODEX_BASE_PROMPT });
|
|
435
471
|
registerExecTools(ctx, resolved);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shuind/dsh-codex-harness",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "A minimal Codex harness for GPT models that do not fit DSH's native interface, while remaining compatible with the DSH plugin ecosystem.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -18,6 +18,10 @@
|
|
|
18
18
|
"types": "./lib/types/installer.d.ts",
|
|
19
19
|
"default": "./lib/installer.js"
|
|
20
20
|
},
|
|
21
|
+
"./client": {
|
|
22
|
+
"types": "./lib/types/client/index.d.ts",
|
|
23
|
+
"default": "./lib/client.js"
|
|
24
|
+
},
|
|
21
25
|
"./cordis.patch.yml": "./cordis.patch.yml",
|
|
22
26
|
"./src/*": "./src/*",
|
|
23
27
|
"./package.json": "./package.json"
|
|
@@ -28,6 +32,7 @@
|
|
|
28
32
|
"lib/installer.js",
|
|
29
33
|
"lib/types/**/*.js",
|
|
30
34
|
"lib/types/**/*.d.ts",
|
|
35
|
+
"lib/client.js",
|
|
31
36
|
"cordis.patch.yml",
|
|
32
37
|
"presets/codex",
|
|
33
38
|
"README.md",
|
|
@@ -58,6 +63,16 @@
|
|
|
58
63
|
"dsh": {
|
|
59
64
|
"bundle": {
|
|
60
65
|
"patch": "./cordis.patch.yml"
|
|
66
|
+
},
|
|
67
|
+
"client": {
|
|
68
|
+
"inject": [
|
|
69
|
+
"@deepseek-ai/dsh-client-locale",
|
|
70
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-conversation",
|
|
72
|
+
"@deepseek-ai/dsh-client-ui-settings",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-slots"
|
|
74
|
+
],
|
|
75
|
+
"platform": "web"
|
|
61
76
|
}
|
|
62
77
|
},
|
|
63
78
|
"dependencies": {
|
|
@@ -67,6 +82,11 @@
|
|
|
67
82
|
"peerDependencies": {
|
|
68
83
|
"@deepseek-ai/cordis": ">=4.0.1",
|
|
69
84
|
"@deepseek-ai/dsh-agent": ">=0.1.0-rc.6",
|
|
85
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.8",
|
|
86
|
+
"@deepseek-ai/dsh-client-runtime": ">=0.1.0-rc.8",
|
|
87
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.0-rc.8",
|
|
88
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.0-rc.8",
|
|
89
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.0-rc.8",
|
|
70
90
|
"@deepseek-ai/dsh-credentials": ">=0.1.0-rc.8",
|
|
71
91
|
"@deepseek-ai/dsh-fs": ">=0.0.1-rc.1",
|
|
72
92
|
"@deepseek-ai/dsh-invariants": ">=0.0.1-rc.1",
|
|
@@ -89,6 +109,21 @@
|
|
|
89
109
|
"@deepseek-ai/dsh-agent": {
|
|
90
110
|
"optional": true
|
|
91
111
|
},
|
|
112
|
+
"@deepseek-ai/dsh-client-locale": {
|
|
113
|
+
"optional": true
|
|
114
|
+
},
|
|
115
|
+
"@deepseek-ai/dsh-client-runtime": {
|
|
116
|
+
"optional": true
|
|
117
|
+
},
|
|
118
|
+
"@deepseek-ai/dsh-client-ui-conversation": {
|
|
119
|
+
"optional": true
|
|
120
|
+
},
|
|
121
|
+
"@deepseek-ai/dsh-client-ui-settings": {
|
|
122
|
+
"optional": true
|
|
123
|
+
},
|
|
124
|
+
"@deepseek-ai/dsh-client-ui-slots": {
|
|
125
|
+
"optional": true
|
|
126
|
+
},
|
|
92
127
|
"@deepseek-ai/dsh-credentials": {
|
|
93
128
|
"optional": true
|
|
94
129
|
},
|
|
@@ -135,6 +170,11 @@
|
|
|
135
170
|
"devDependencies": {
|
|
136
171
|
"@deepseek-ai/cordis": "4.0.1",
|
|
137
172
|
"@deepseek-ai/dsh-agent": "0.1.0-rc.6",
|
|
173
|
+
"@deepseek-ai/dsh-client-locale": "0.1.0-rc.8",
|
|
174
|
+
"@deepseek-ai/dsh-client-runtime": "0.1.0-rc.8",
|
|
175
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.0-rc.8",
|
|
176
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.0-rc.8",
|
|
177
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.0-rc.8",
|
|
138
178
|
"@deepseek-ai/dsh-credentials": "0.1.0-rc.8",
|
|
139
179
|
"@deepseek-ai/dsh-fs": "0.1.0-rc.6",
|
|
140
180
|
"@deepseek-ai/dsh-invariants": "0.1.0-rc.6",
|
|
@@ -150,6 +190,8 @@
|
|
|
150
190
|
"@deepseek-ai/dsh-terminal": "0.1.0-rc.6",
|
|
151
191
|
"@deepseek-ai/dsh-tools": "0.1.0-rc.6",
|
|
152
192
|
"@types/node": "^22.20.0",
|
|
193
|
+
"@types/react": "~18.3.1",
|
|
194
|
+
"react": "^18.3.1",
|
|
153
195
|
"tsdown": "^0.22.2",
|
|
154
196
|
"typescript": "^6.0.3",
|
|
155
197
|
"unrun": "^0.3.1",
|