chatccc 0.2.264 → 0.2.265
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/dist/src/adapters/dsh-adapter.js +65 -39
- package/package.json +1 -1
|
@@ -20,6 +20,18 @@ export function __setDshSdkModuleForTest(module) {
|
|
|
20
20
|
injectedSdk = module;
|
|
21
21
|
}
|
|
22
22
|
export function createDshAdapter(options = {}) {
|
|
23
|
+
// DSH 引擎的 JSON-RPC `session/prompt` 只支持 create、不支持 resume:已持久化的
|
|
24
|
+
// session 必须在同一个 runtime 进程内复用,否则第二次 prompt 会因 "id collision"
|
|
25
|
+
// 失败(新 runtime 内存里没有该 session,走 create 路径与磁盘 log 冲突)。
|
|
26
|
+
// 因此这里按 sessionId 缓存长驻 runtime,正常完成不关闭,close/abort/崩溃时关闭。
|
|
27
|
+
const runtimes = new Map();
|
|
28
|
+
const disposeRuntime = (sessionId) => {
|
|
29
|
+
const entry = runtimes.get(sessionId);
|
|
30
|
+
if (!entry)
|
|
31
|
+
return;
|
|
32
|
+
runtimes.delete(sessionId);
|
|
33
|
+
void entry.harness.close().catch(() => { });
|
|
34
|
+
};
|
|
23
35
|
return {
|
|
24
36
|
displayName: "DeepSeek Harness",
|
|
25
37
|
sessionDescPrefix: "DSH Session:",
|
|
@@ -36,31 +48,42 @@ export function createDshAdapter(options = {}) {
|
|
|
36
48
|
const sdk = injectedSdk ?? await import(__rewriteRelativeImportExtension(pathToFileURL(entryPath).href));
|
|
37
49
|
const sessionRoot = join(homedir(), ".chatccc", "dsh-sessions");
|
|
38
50
|
await mkdir(sessionRoot, { recursive: true });
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
// 复用长驻 runtime:同一 session 的多次 prompt 必须在同一 runtime 进程内完成
|
|
52
|
+
// (DSH 的 session/prompt 无 resume 能力,见上方 runtimes 注释)。cwd 变化时
|
|
53
|
+
// 重建(旧 runtime 已绑定旧 cwd,无法切换工作目录)。
|
|
54
|
+
let entry = runtimes.get(sessionId);
|
|
55
|
+
if (!entry || entry.cwd !== cwd) {
|
|
56
|
+
if (entry)
|
|
57
|
+
disposeRuntime(sessionId);
|
|
58
|
+
const runtime = new sdk.DeepSeekHarness({
|
|
59
|
+
launch: {
|
|
60
|
+
command: process.execPath,
|
|
61
|
+
args: [
|
|
62
|
+
join(installationDir, "node_modules", "@deepseek-ai", "dsh-sdk-jsonrpc-demo", "lib", "bin.js"),
|
|
63
|
+
join(installationDir, "dsh-runtime.cordis.yml"),
|
|
64
|
+
],
|
|
65
|
+
cwd,
|
|
66
|
+
env: {
|
|
67
|
+
...process.env,
|
|
68
|
+
DSH_CWD: cwd,
|
|
69
|
+
DSH_SESSION_ROOT: sessionRoot,
|
|
70
|
+
...(options.apiKey ? { DEEPSEEK_API_KEY: options.apiKey } : {}),
|
|
71
|
+
...(options.baseUrl ? { DEEPSEEK_BASE_URL: options.baseUrl } : {}),
|
|
72
|
+
// 子代理模型:subModel 留空时跟随主模型(与 CCC 的 ccc.subModel 语义一致)
|
|
73
|
+
DSH_SUBAGENT_PROVIDER: options.provider ?? "deepseek-official",
|
|
74
|
+
DSH_SUBAGENT_MODEL: options.subModel || options.model || "deepseek-v4-flash",
|
|
75
|
+
DSH_SUBAGENT_MAX_TOKENS: String(options.maxTokens ?? 49152),
|
|
76
|
+
},
|
|
57
77
|
},
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
78
|
+
cwd,
|
|
79
|
+
provider: options.provider ?? "deepseek-official",
|
|
80
|
+
model: options.model ?? "deepseek-v4-flash",
|
|
81
|
+
...(options.maxTokens ? { maxTokens: options.maxTokens } : {}),
|
|
82
|
+
});
|
|
83
|
+
entry = { harness: runtime, cwd };
|
|
84
|
+
runtimes.set(sessionId, entry);
|
|
85
|
+
}
|
|
86
|
+
const runtime = entry.harness;
|
|
64
87
|
const queue = new AsyncMessageQueue();
|
|
65
88
|
const rawLogConfig = config.rawStreamLogs.dsh;
|
|
66
89
|
let rawLog = null;
|
|
@@ -78,16 +101,11 @@ export function createDshAdapter(options = {}) {
|
|
|
78
101
|
catch (error) {
|
|
79
102
|
console.error(`[DSH raw stream log] create failed: ${error.message}`);
|
|
80
103
|
}
|
|
81
|
-
let closed = false;
|
|
82
104
|
let completed = false;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
void runtime.close();
|
|
88
|
-
};
|
|
89
|
-
promptOptions?.onSessionCreated?.(closeRuntime);
|
|
90
|
-
const onAbort = () => closeRuntime();
|
|
105
|
+
// abort / stop-stuck 时关闭该 session 的 runtime 以中止进行中的请求;
|
|
106
|
+
// 正常完成不关闭,保留 runtime 供同一 session 的后续 prompt 复用。
|
|
107
|
+
promptOptions?.onSessionCreated?.(() => disposeRuntime(sessionId));
|
|
108
|
+
const onAbort = () => disposeRuntime(sessionId);
|
|
91
109
|
signal?.addEventListener("abort", onAbort, { once: true });
|
|
92
110
|
const task = (async () => {
|
|
93
111
|
try {
|
|
@@ -130,13 +148,21 @@ export function createDshAdapter(options = {}) {
|
|
|
130
148
|
}
|
|
131
149
|
}
|
|
132
150
|
catch (error) {
|
|
133
|
-
|
|
151
|
+
// runtime 崩溃 / 传输关闭 / id collision 等:关闭并移除,下次 prompt 重建。
|
|
152
|
+
// 注意:DSH 无 resume 能力,重启 ChatCCC 后磁盘残留同 id log 会再次 id collision;
|
|
153
|
+
// 这里附加清晰的用户提示,引导 /forget 清空会话而非静默失败。
|
|
154
|
+
disposeRuntime(sessionId);
|
|
155
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
156
|
+
if (/id collision/i.test(failure.message)) {
|
|
157
|
+
queue.fail(new Error(`${failure.message}。该 DeepSeek Harness 会话的历史无法跨进程恢复(引擎的 JSON-RPC 仅支持 create 不支持 resume),请使用 /forget 清空本会话或新建会话后重试。`));
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
queue.fail(failure);
|
|
161
|
+
}
|
|
134
162
|
}
|
|
135
163
|
finally {
|
|
136
164
|
signal?.removeEventListener("abort", onAbort);
|
|
137
|
-
await runtime.close().catch(() => { });
|
|
138
165
|
await rawLog?.close({ keep: rawLogConfig.keepCompleted || signal?.aborted === true || !completed });
|
|
139
|
-
closed = true;
|
|
140
166
|
}
|
|
141
167
|
})();
|
|
142
168
|
try {
|
|
@@ -145,14 +171,14 @@ export function createDshAdapter(options = {}) {
|
|
|
145
171
|
await task;
|
|
146
172
|
}
|
|
147
173
|
finally {
|
|
148
|
-
|
|
174
|
+
// 正常完成保留 runtime 供复用;abort 已在 onAbort 中 dispose。
|
|
149
175
|
}
|
|
150
176
|
},
|
|
151
177
|
async getSessionInfo(sessionId) {
|
|
152
178
|
return knownSessions.get(sessionId) ?? { sessionId };
|
|
153
179
|
},
|
|
154
|
-
async closeSession() {
|
|
155
|
-
|
|
180
|
+
async closeSession(sessionId) {
|
|
181
|
+
disposeRuntime(sessionId);
|
|
156
182
|
},
|
|
157
183
|
};
|
|
158
184
|
}
|