@shuind/dsh-codex-harness 0.1.23 → 0.1.24
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 +9 -4
- package/lib/client.js +10 -5
- package/lib/installer.js +23 -15
- package/lib/types/client/index.js +6 -6
- package/lib/types/context.d.ts +3 -0
- package/lib/types/context.js +9 -0
- package/lib/types/installer.d.ts +2 -0
- package/lib/types/installer.js +22 -14
- package/package.json +2 -1
- package/presets/codex-collaboration/agent.cordis.yml +91 -0
- package/presets/codex-collaboration/preset.yml +3 -0
package/README.md
CHANGED
|
@@ -13,12 +13,12 @@
|
|
|
13
13
|
- **Responses 原生 apply_patch**:在 GPT Responses 请求的插件传输边界,把普通 JSON function tool 改写为 `type: "custom"` + OpenAI `lark` grammar;下一轮历史同步改写为 `custom_tool_call`。如果中转站拒绝 custom tool,则自动回退到普通 function tool,不改变 DSH 工具执行器。
|
|
14
14
|
- **远程搜索与压缩**:OpenAI Responses 请求默认优先使用 hosted `web_search` 和 `/responses/compact`;失败时回退到 DSH 的本地实现。
|
|
15
15
|
- **上下文容量**:在 Web 中设置 `1K`–`1000K` tokens,设置值作用于下一次请求。
|
|
16
|
-
- **活动状态**:Codex
|
|
16
|
+
- **活动状态**:Codex 等待模型响应或进行上下文压缩时,在 `Deep diving...` 右侧显示对应状态和耗时,让长时间 Deep Diving 不再像卡住。
|
|
17
17
|
|
|
18
18
|
## 安装
|
|
19
19
|
|
|
20
20
|
```sh
|
|
21
|
-
dsh plugin --profile web add @shuind/dsh-codex-harness@0.1.
|
|
21
|
+
dsh plugin --profile web add @shuind/dsh-codex-harness@0.1.24
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
重启 Web,创建新会话,在模式菜单中选择 **Codex 模式**。
|
|
@@ -63,9 +63,14 @@ Codex 等待模型首个输出时,Web 会在 `Deep diving...` 右侧显示 `
|
|
|
63
63
|
|
|
64
64
|
## 随包提供的 Codex preset
|
|
65
65
|
|
|
66
|
-
安装插件后,首次启动对应的 DSH profile
|
|
66
|
+
安装插件后,首次启动对应的 DSH profile 时,插件会安装两套随包提供的 preset:
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
- **Codex 模式**:使用精简版 Codex 提示词。
|
|
69
|
+
- **Codex 协作模式**:在精简版 Codex 提示词后追加协作提示词。
|
|
70
|
+
|
|
71
|
+
它们分别位于 `${DSH_HOME:-$HOME/.dsh}/.agent-presets/codex/` 和 `${DSH_HOME:-$HOME/.dsh}/.agent-presets/codex-collaboration/`。如果对应目录已经存在,插件会保留你的文件,不会覆盖自定义内容。
|
|
72
|
+
|
|
73
|
+
在 Web 的 **Agent 预设** 中选择 **Codex 模式** 或 **Codex 协作模式**,再新建会话即可使用随包提供的 Codex 工具、网页搜索、远程压缩和 Skills 组合。两套 preset 共用 Fast、思考强度、GPT 图片输入和上下文容量设置;只有系统提示词是否包含协作指导不同。
|
|
69
74
|
|
|
70
75
|
## 自定义 preset
|
|
71
76
|
|
package/lib/client.js
CHANGED
|
@@ -13,6 +13,11 @@ window.__ModuleLoader__.load({
|
|
|
13
13
|
/** User-selectable Codex context controls use whole K-token units. */
|
|
14
14
|
const CODEX_CONTEXT_UNIT = 1e3;
|
|
15
15
|
const CODEX_CONTEXT_MAX = 1e6;
|
|
16
|
+
const CODEX_PRESET_IDS = /* @__PURE__ */ new Set(["codex", "codex-collaboration"]);
|
|
17
|
+
/** Both shipped presets use the same Codex request controls in Web. */
|
|
18
|
+
function isCodexPresetId(value) {
|
|
19
|
+
return value !== void 0 && CODEX_PRESET_IDS.has(value);
|
|
20
|
+
}
|
|
16
21
|
//#endregion
|
|
17
22
|
//#region lib/types/client/activity.js
|
|
18
23
|
/** Client-only inference used while the host activity projection frame is in flight. */
|
|
@@ -63,7 +68,7 @@ window.__ModuleLoader__.load({
|
|
|
63
68
|
const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
|
|
64
69
|
const snapshot = useSettings((state) => state);
|
|
65
70
|
const fast = snapshot.value?.fast ?? false;
|
|
66
|
-
if (agentPreset
|
|
71
|
+
if (!isCodexPresetId(agentPreset)) return null;
|
|
67
72
|
return (0, react_jsx_runtime.jsxs)("button", {
|
|
68
73
|
type: "button",
|
|
69
74
|
role: "menuitemcheckbox",
|
|
@@ -108,7 +113,7 @@ window.__ModuleLoader__.load({
|
|
|
108
113
|
const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
|
|
109
114
|
const snapshot = useSettings((state) => state);
|
|
110
115
|
const fast = snapshot.value?.fast ?? false;
|
|
111
|
-
if (agentPreset
|
|
116
|
+
if (!isCodexPresetId(agentPreset)) return null;
|
|
112
117
|
return (0, react_jsx_runtime.jsxs)("button", {
|
|
113
118
|
type: "button",
|
|
114
119
|
role: "switch",
|
|
@@ -279,20 +284,20 @@ window.__ModuleLoader__.load({
|
|
|
279
284
|
const agentPreset = useSessions((state) => state.byId[sessionId]?.agentPreset);
|
|
280
285
|
const projectedActivity = useProjection("codexActivity");
|
|
281
286
|
const fallbackStartedAt = useSession((snapshot) => awaitingModelStartedAt(snapshot));
|
|
282
|
-
const activity = projectedActivity !== void 0 ? projectedActivity : agentPreset
|
|
287
|
+
const activity = projectedActivity !== void 0 ? projectedActivity : isCodexPresetId(agentPreset) && fallbackStartedAt !== void 0 ? {
|
|
283
288
|
activity: "awaiting-model",
|
|
284
289
|
startedAt: fallbackStartedAt
|
|
285
290
|
} : null;
|
|
286
291
|
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
287
292
|
(0, react.useEffect)(() => {
|
|
288
|
-
if (agentPreset
|
|
293
|
+
if (!isCodexPresetId(agentPreset) || activity === void 0 || activity === null) return void 0;
|
|
289
294
|
setNow(Date.now());
|
|
290
295
|
const timer = setInterval(() => {
|
|
291
296
|
setNow(Date.now());
|
|
292
297
|
}, 1e3);
|
|
293
298
|
return () => clearInterval(timer);
|
|
294
299
|
}, [agentPreset, activity?.startedAt]);
|
|
295
|
-
if (agentPreset
|
|
300
|
+
if (!isCodexPresetId(agentPreset) || activity === void 0 || activity === null) return null;
|
|
296
301
|
const label = activity.activity === "awaiting-model" ? t("activityAwaitingModel") : t("activityCompacting");
|
|
297
302
|
return (0, react_jsx_runtime.jsxs)("span", {
|
|
298
303
|
id: "codex-activity",
|
package/lib/installer.js
CHANGED
|
@@ -4,9 +4,9 @@ import { dirname, join, resolve } from "node:path";
|
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
//#region lib/types/installer.js
|
|
6
6
|
/** Install the user-visible Codex agent preset supplied by this bundle. */
|
|
7
|
-
const PRESET_ID = "codex";
|
|
8
7
|
const PRESET_FILES = ["agent.cordis.yml", "preset.yml"];
|
|
9
8
|
const SOURCE_PRESET_DIR = fileURLToPath(new URL("../presets/codex/", import.meta.url));
|
|
9
|
+
const SOURCE_COLLABORATION_PRESET_DIR = fileURLToPath(new URL("../presets/codex-collaboration/", import.meta.url));
|
|
10
10
|
function dshHomePath(...segments) {
|
|
11
11
|
const configured = process.env.DSH_HOME?.trim();
|
|
12
12
|
const expanded = configured === void 0 || configured.length === 0 ? join(homedir(), ".dsh") : configured === "~" ? homedir() : configured.startsWith("~/") || configured.startsWith("~\\") ? join(homedir(), configured.slice(2)) : configured;
|
|
@@ -14,21 +14,11 @@ function dshHomePath(...segments) {
|
|
|
14
14
|
}
|
|
15
15
|
/** Bundle plugin name for the preset installer. */
|
|
16
16
|
const name = "codex-preset-installer";
|
|
17
|
-
|
|
18
|
-
* Install the shipped Codex preset only when the user has not authored one.
|
|
19
|
-
*
|
|
20
|
-
* The directory is committed with a staging rename so a failed copy cannot
|
|
21
|
-
* leave a half-written preset that hides the mode from the roster. Existing
|
|
22
|
-
* directories are intentionally preserved, including user customizations.
|
|
23
|
-
*
|
|
24
|
-
* @param targetDir - destination preset directory.
|
|
25
|
-
* @param sourceDir - directory containing the packaged preset files.
|
|
26
|
-
*/
|
|
27
|
-
function installCodexPreset(targetDir = dshHomePath(".agent-presets", PRESET_ID), sourceDir = SOURCE_PRESET_DIR) {
|
|
17
|
+
function installPreset(targetDir, sourceDir, presetId) {
|
|
28
18
|
if (existsSync(targetDir)) return;
|
|
29
19
|
const parentDir = dirname(targetDir);
|
|
30
20
|
mkdirSync(parentDir, { recursive: true });
|
|
31
|
-
const stagingDir = mkdtempSync(join(parentDir, `.${
|
|
21
|
+
const stagingDir = mkdtempSync(join(parentDir, `.${presetId}-`));
|
|
32
22
|
try {
|
|
33
23
|
for (const file of PRESET_FILES) copyFileSync(join(sourceDir, file), join(stagingDir, file));
|
|
34
24
|
try {
|
|
@@ -43,12 +33,30 @@ function installCodexPreset(targetDir = dshHomePath(".agent-presets", PRESET_ID)
|
|
|
43
33
|
});
|
|
44
34
|
}
|
|
45
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Install the shipped Codex preset only when the user has not authored one.
|
|
38
|
+
*
|
|
39
|
+
* The directory is committed with a staging rename so a failed copy cannot
|
|
40
|
+
* leave a half-written preset that hides the mode from the roster. Existing
|
|
41
|
+
* directories are intentionally preserved, including user customizations.
|
|
42
|
+
*
|
|
43
|
+
* @param targetDir - destination preset directory.
|
|
44
|
+
* @param sourceDir - directory containing the packaged preset files.
|
|
45
|
+
*/
|
|
46
|
+
function installCodexPreset(targetDir = dshHomePath(".agent-presets", "codex"), sourceDir = SOURCE_PRESET_DIR) {
|
|
47
|
+
installPreset(targetDir, sourceDir, "codex");
|
|
48
|
+
}
|
|
49
|
+
/** Install the shipped Codex preset with the optional collaboration guidance enabled. */
|
|
50
|
+
function installCodexCollaborationPreset(targetDir = dshHomePath(".agent-presets", "codex-collaboration"), sourceDir = SOURCE_COLLABORATION_PRESET_DIR) {
|
|
51
|
+
installPreset(targetDir, sourceDir, "codex-collaboration");
|
|
52
|
+
}
|
|
46
53
|
/** Install the preset during profile boot without changing the host tool catalog. */
|
|
47
54
|
function apply(ctx) {
|
|
48
55
|
try {
|
|
49
56
|
installCodexPreset();
|
|
57
|
+
installCodexCollaborationPreset();
|
|
50
58
|
} catch (error) {
|
|
51
|
-
ctx.logger.warn(`dsh-codex: could not install the Codex
|
|
59
|
+
ctx.logger.warn(`dsh-codex: could not install the Codex presets: ${String(error)}`);
|
|
52
60
|
}
|
|
53
61
|
}
|
|
54
62
|
var installer_default = {
|
|
@@ -56,4 +64,4 @@ var installer_default = {
|
|
|
56
64
|
apply
|
|
57
65
|
};
|
|
58
66
|
//#endregion
|
|
59
|
-
export { apply, installer_default as default, installCodexPreset, name };
|
|
67
|
+
export { apply, installer_default as default, installCodexCollaborationPreset, installCodexPreset, name };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
/** Browser controls for the Codex request settings mounted by the Host plugin. */
|
|
3
3
|
import { useEffect, useState } from 'react';
|
|
4
|
-
import { CODEX_CONTEXT_MAX, CODEX_CONTEXT_UNIT,
|
|
4
|
+
import { CODEX_CONTEXT_MAX, CODEX_CONTEXT_UNIT, isCodexPresetId } from "../context.js";
|
|
5
5
|
import { awaitingModelStartedAt } from "./activity.js";
|
|
6
6
|
const NS = 'codex';
|
|
7
7
|
const SETTINGS_NAMESPACE = 'codex';
|
|
@@ -42,7 +42,7 @@ function FastModeButton({ sessionId, useSessions, useSettings, setSetting, t })
|
|
|
42
42
|
const agentPreset = useSessions(state => state.byId[sessionId]?.agentPreset);
|
|
43
43
|
const snapshot = useSettings(state => state);
|
|
44
44
|
const fast = snapshot.value?.fast ?? false;
|
|
45
|
-
if (agentPreset
|
|
45
|
+
if (!isCodexPresetId(agentPreset))
|
|
46
46
|
return null;
|
|
47
47
|
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: {
|
|
48
48
|
boxSizing: 'border-box',
|
|
@@ -70,7 +70,7 @@ function FastModeFallback(props) {
|
|
|
70
70
|
const agentPreset = useSessions(state => state.byId[sessionId]?.agentPreset);
|
|
71
71
|
const snapshot = useSettings(state => state);
|
|
72
72
|
const fast = snapshot.value?.fast ?? false;
|
|
73
|
-
if (agentPreset
|
|
73
|
+
if (!isCodexPresetId(agentPreset))
|
|
74
74
|
return null;
|
|
75
75
|
return (_jsxs("button", { type: "button", role: "switch", disabled: snapshot.writable === false, "aria-checked": fast, "aria-label": fast ? t('fastOn') : t('fastOff'), title: fast ? t('fastOn') : t('fastOff'), onClick: () => { void setSetting('fast', !fast); }, style: {
|
|
76
76
|
boxSizing: 'border-box',
|
|
@@ -149,18 +149,18 @@ export function ActivityLine({ sessionId, useSession, useSessions, useProjection
|
|
|
149
149
|
const fallbackStartedAt = useSession((snapshot) => awaitingModelStartedAt(snapshot));
|
|
150
150
|
// `undefined` means the key has not arrived yet; `null` is an authoritative
|
|
151
151
|
// clear and must not be resurrected by the local snapshot fallback.
|
|
152
|
-
const activity = projectedActivity !== undefined ? projectedActivity : (agentPreset
|
|
152
|
+
const activity = projectedActivity !== undefined ? projectedActivity : (isCodexPresetId(agentPreset) && fallbackStartedAt !== undefined
|
|
153
153
|
? { activity: 'awaiting-model', startedAt: fallbackStartedAt }
|
|
154
154
|
: null);
|
|
155
155
|
const [now, setNow] = useState(() => Date.now());
|
|
156
156
|
useEffect(() => {
|
|
157
|
-
if (agentPreset
|
|
157
|
+
if (!isCodexPresetId(agentPreset) || activity === undefined || activity === null)
|
|
158
158
|
return undefined;
|
|
159
159
|
setNow(Date.now());
|
|
160
160
|
const timer = setInterval(() => { setNow(Date.now()); }, 1_000);
|
|
161
161
|
return () => clearInterval(timer);
|
|
162
162
|
}, [agentPreset, activity?.startedAt]);
|
|
163
|
-
if (agentPreset
|
|
163
|
+
if (!isCodexPresetId(agentPreset) || activity === undefined || activity === null)
|
|
164
164
|
return null;
|
|
165
165
|
const label = activity.activity === 'awaiting-model'
|
|
166
166
|
? t('activityAwaitingModel')
|
package/lib/types/context.d.ts
CHANGED
|
@@ -2,4 +2,7 @@
|
|
|
2
2
|
export declare const CODEX_CONTEXT_UNIT = 1000;
|
|
3
3
|
export declare const CODEX_CONTEXT_MAX = 1000000;
|
|
4
4
|
export declare const CODEX_PRESET_ID = "codex";
|
|
5
|
+
export declare const CODEX_COLLABORATION_PRESET_ID = "codex-collaboration";
|
|
6
|
+
/** Both shipped presets use the same Codex request controls in Web. */
|
|
7
|
+
export declare function isCodexPresetId(value: string | undefined): boolean;
|
|
5
8
|
//# sourceMappingURL=context.d.ts.map
|
package/lib/types/context.js
CHANGED
|
@@ -2,4 +2,13 @@
|
|
|
2
2
|
export const CODEX_CONTEXT_UNIT = 1_000;
|
|
3
3
|
export const CODEX_CONTEXT_MAX = 1_000_000;
|
|
4
4
|
export const CODEX_PRESET_ID = 'codex';
|
|
5
|
+
export const CODEX_COLLABORATION_PRESET_ID = 'codex-collaboration';
|
|
6
|
+
const CODEX_PRESET_IDS = new Set([
|
|
7
|
+
CODEX_PRESET_ID,
|
|
8
|
+
CODEX_COLLABORATION_PRESET_ID,
|
|
9
|
+
]);
|
|
10
|
+
/** Both shipped presets use the same Codex request controls in Web. */
|
|
11
|
+
export function isCodexPresetId(value) {
|
|
12
|
+
return value !== undefined && CODEX_PRESET_IDS.has(value);
|
|
13
|
+
}
|
|
5
14
|
//# sourceMappingURL=context.js.map
|
package/lib/types/installer.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ export declare const name = "codex-preset-installer";
|
|
|
13
13
|
* @param sourceDir - directory containing the packaged preset files.
|
|
14
14
|
*/
|
|
15
15
|
export declare function installCodexPreset(targetDir?: string, sourceDir?: string): void;
|
|
16
|
+
/** Install the shipped Codex preset with the optional collaboration guidance enabled. */
|
|
17
|
+
export declare function installCodexCollaborationPreset(targetDir?: string, sourceDir?: string): void;
|
|
16
18
|
/** Install the preset during profile boot without changing the host tool catalog. */
|
|
17
19
|
export declare function apply(ctx: Context): void;
|
|
18
20
|
declare const _default: {
|
package/lib/types/installer.js
CHANGED
|
@@ -3,9 +3,9 @@ import { copyFileSync, existsSync, mkdirSync, mkdtempSync, renameSync, rmSync }
|
|
|
3
3
|
import { homedir } from 'node:os';
|
|
4
4
|
import { dirname, join, resolve } from 'node:path';
|
|
5
5
|
import { fileURLToPath } from 'node:url';
|
|
6
|
-
const PRESET_ID = 'codex';
|
|
7
6
|
const PRESET_FILES = ['agent.cordis.yml', 'preset.yml'];
|
|
8
7
|
const SOURCE_PRESET_DIR = fileURLToPath(new URL('../presets/codex/', import.meta.url));
|
|
8
|
+
const SOURCE_COLLABORATION_PRESET_DIR = fileURLToPath(new URL('../presets/codex-collaboration/', import.meta.url));
|
|
9
9
|
function dshHomePath(...segments) {
|
|
10
10
|
const configured = process.env.DSH_HOME?.trim();
|
|
11
11
|
const expanded = configured === undefined || configured.length === 0
|
|
@@ -19,22 +19,12 @@ function dshHomePath(...segments) {
|
|
|
19
19
|
}
|
|
20
20
|
/** Bundle plugin name for the preset installer. */
|
|
21
21
|
export const name = 'codex-preset-installer';
|
|
22
|
-
|
|
23
|
-
* Install the shipped Codex preset only when the user has not authored one.
|
|
24
|
-
*
|
|
25
|
-
* The directory is committed with a staging rename so a failed copy cannot
|
|
26
|
-
* leave a half-written preset that hides the mode from the roster. Existing
|
|
27
|
-
* directories are intentionally preserved, including user customizations.
|
|
28
|
-
*
|
|
29
|
-
* @param targetDir - destination preset directory.
|
|
30
|
-
* @param sourceDir - directory containing the packaged preset files.
|
|
31
|
-
*/
|
|
32
|
-
export function installCodexPreset(targetDir = dshHomePath('.agent-presets', PRESET_ID), sourceDir = SOURCE_PRESET_DIR) {
|
|
22
|
+
function installPreset(targetDir, sourceDir, presetId) {
|
|
33
23
|
if (existsSync(targetDir))
|
|
34
24
|
return;
|
|
35
25
|
const parentDir = dirname(targetDir);
|
|
36
26
|
mkdirSync(parentDir, { recursive: true });
|
|
37
|
-
const stagingDir = mkdtempSync(join(parentDir, `.${
|
|
27
|
+
const stagingDir = mkdtempSync(join(parentDir, `.${presetId}-`));
|
|
38
28
|
try {
|
|
39
29
|
for (const file of PRESET_FILES)
|
|
40
30
|
copyFileSync(join(sourceDir, file), join(stagingDir, file));
|
|
@@ -51,13 +41,31 @@ export function installCodexPreset(targetDir = dshHomePath('.agent-presets', PRE
|
|
|
51
41
|
rmSync(stagingDir, { recursive: true, force: true });
|
|
52
42
|
}
|
|
53
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Install the shipped Codex preset only when the user has not authored one.
|
|
46
|
+
*
|
|
47
|
+
* The directory is committed with a staging rename so a failed copy cannot
|
|
48
|
+
* leave a half-written preset that hides the mode from the roster. Existing
|
|
49
|
+
* directories are intentionally preserved, including user customizations.
|
|
50
|
+
*
|
|
51
|
+
* @param targetDir - destination preset directory.
|
|
52
|
+
* @param sourceDir - directory containing the packaged preset files.
|
|
53
|
+
*/
|
|
54
|
+
export function installCodexPreset(targetDir = dshHomePath('.agent-presets', 'codex'), sourceDir = SOURCE_PRESET_DIR) {
|
|
55
|
+
installPreset(targetDir, sourceDir, 'codex');
|
|
56
|
+
}
|
|
57
|
+
/** Install the shipped Codex preset with the optional collaboration guidance enabled. */
|
|
58
|
+
export function installCodexCollaborationPreset(targetDir = dshHomePath('.agent-presets', 'codex-collaboration'), sourceDir = SOURCE_COLLABORATION_PRESET_DIR) {
|
|
59
|
+
installPreset(targetDir, sourceDir, 'codex-collaboration');
|
|
60
|
+
}
|
|
54
61
|
/** Install the preset during profile boot without changing the host tool catalog. */
|
|
55
62
|
export function apply(ctx) {
|
|
56
63
|
try {
|
|
57
64
|
installCodexPreset();
|
|
65
|
+
installCodexCollaborationPreset();
|
|
58
66
|
}
|
|
59
67
|
catch (error) {
|
|
60
|
-
ctx.logger.warn(`dsh-codex: could not install the Codex
|
|
68
|
+
ctx.logger.warn(`dsh-codex: could not install the Codex presets: ${String(error)}`);
|
|
61
69
|
}
|
|
62
70
|
}
|
|
63
71
|
export default { name, apply };
|
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.24",
|
|
4
4
|
"description": "A Codex harness with a streamlined system prompt 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",
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"lib/client.js",
|
|
36
36
|
"cordis.patch.yml",
|
|
37
37
|
"presets/codex",
|
|
38
|
+
"presets/codex-collaboration",
|
|
38
39
|
"README.md",
|
|
39
40
|
"README.zh.md",
|
|
40
41
|
"LICENSE"
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# The Codex collaboration preset. It shares the standard Codex composition
|
|
2
|
+
# while enabling the optional collaboration guidance in the prompt layer.
|
|
3
|
+
|
|
4
|
+
- id: persona
|
|
5
|
+
name: '@deepseek-ai/dsh-persona'
|
|
6
|
+
config:
|
|
7
|
+
# Keep identity, model, cwd, and runtime context in one persona section.
|
|
8
|
+
text: >-
|
|
9
|
+
You are Codex, a coding agent based on the {{model}} model. Your working directory is {{cwd}}.
|
|
10
|
+
includeRuntimeContext: true
|
|
11
|
+
|
|
12
|
+
- id: agent-instructions
|
|
13
|
+
name: '@deepseek-ai/dsh-agent-instructions'
|
|
14
|
+
config:
|
|
15
|
+
maxBytes: 65536
|
|
16
|
+
|
|
17
|
+
# The collaboration variant only changes this flag; execution remains
|
|
18
|
+
# delegated to the same dsh Codex tool layer.
|
|
19
|
+
- id: codex-tools
|
|
20
|
+
name: '@shuind/dsh-codex-harness'
|
|
21
|
+
config:
|
|
22
|
+
collaborationPrompt: true
|
|
23
|
+
|
|
24
|
+
# Background jobs use the host-plane registry. A busy agent receives a
|
|
25
|
+
# completion in its next step; an idle agent keeps it pending until the next
|
|
26
|
+
# user/tool wake, so finishing work never opens an unsolicited model turn.
|
|
27
|
+
- id: codex-jobs
|
|
28
|
+
name: '@deepseek-ai/dsh-tool-jobs'
|
|
29
|
+
config:
|
|
30
|
+
completionDelivery: quiet
|
|
31
|
+
|
|
32
|
+
# The generic DSH pi-ai adapter still owns the user's configured provider,
|
|
33
|
+
# endpoint, API key, and model. Codex's remote-first transport wrapper is
|
|
34
|
+
# installed only in this Codex scope and falls back to the generic DSH path.
|
|
35
|
+
|
|
36
|
+
# Keep the local tool mounted as the fallback. Codex rewrites the final GPT
|
|
37
|
+
# Responses request to a hosted web_search tool first; a failed remote request
|
|
38
|
+
# is retried through this unchanged local function-tool path.
|
|
39
|
+
- id: codex-web-search
|
|
40
|
+
name: '@deepseek-ai/dsh-tool-web'
|
|
41
|
+
config:
|
|
42
|
+
search: true
|
|
43
|
+
fetch: false
|
|
44
|
+
|
|
45
|
+
# PTY execution is optional. Pipe-backed exec_command remains available on all
|
|
46
|
+
# platforms through the shell capability consumed by the Codex tool layer.
|
|
47
|
+
- id: codex-terminal
|
|
48
|
+
name: cordis:group
|
|
49
|
+
group: true
|
|
50
|
+
isolate:
|
|
51
|
+
terminals: true
|
|
52
|
+
config:
|
|
53
|
+
- id: terminals
|
|
54
|
+
name: '@deepseek-ai/dsh-terminal'
|
|
55
|
+
|
|
56
|
+
- id: terminal-bash
|
|
57
|
+
name: '@deepseek-ai/dsh-terminal-bash'
|
|
58
|
+
disabled: !!js process.platform === 'win32'
|
|
59
|
+
config:
|
|
60
|
+
timeoutMs: 300000
|
|
61
|
+
|
|
62
|
+
# Context compaction is agent-scoped in Web. The token meter stays on the host
|
|
63
|
+
# plane, while this group owns the backend, `/compact`, and optional tool-result
|
|
64
|
+
# pruning for Codex sessions.
|
|
65
|
+
- id: compaction
|
|
66
|
+
name: cordis:group
|
|
67
|
+
group: true
|
|
68
|
+
isolate:
|
|
69
|
+
compaction: true
|
|
70
|
+
toolResultPruner: true
|
|
71
|
+
config:
|
|
72
|
+
- id: compaction-basic
|
|
73
|
+
name: '@deepseek-ai/dsh-compaction-basic'
|
|
74
|
+
|
|
75
|
+
- id: command-compact
|
|
76
|
+
name: '@deepseek-ai/dsh-command-compact'
|
|
77
|
+
|
|
78
|
+
- id: tool-result-pruner
|
|
79
|
+
name: '@deepseek-ai/dsh-compaction-tool-result-pruner'
|
|
80
|
+
config:
|
|
81
|
+
thresholdChars: 8192
|
|
82
|
+
headChars: 4096
|
|
83
|
+
tailChars: 1024
|
|
84
|
+
|
|
85
|
+
# Skills are the dsh extensibility seam and do not change the four Codex core
|
|
86
|
+
# tool names.
|
|
87
|
+
- id: skill-filesystem
|
|
88
|
+
name: '@deepseek-ai/dsh-skill-filesystem'
|
|
89
|
+
|
|
90
|
+
- id: tool-skill
|
|
91
|
+
name: '@deepseek-ai/dsh-tool-skill'
|