chatccc 0.2.263 → 0.2.264
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.
|
@@ -92,10 +92,16 @@ export function createDshAdapter(options = {}) {
|
|
|
92
92
|
const task = (async () => {
|
|
93
93
|
try {
|
|
94
94
|
await runtime.start();
|
|
95
|
+
// DSH 引擎在 LLM 调用失败时不会让 run() reject:错误被写进 turn/end 事件
|
|
96
|
+
// 的 reason(kind="error")后,session 进入 idle,run() 返回空 finalResponse。
|
|
97
|
+
// 这里把第一个 turn 错误收集起来,run() 结束后重新抛出,交给 session.ts
|
|
98
|
+
// 的统一终态错误分类与脱敏展示,避免飞书里"静默失败"。
|
|
99
|
+
let turnError = null;
|
|
95
100
|
const result = await runtime.run(userText, {
|
|
96
101
|
sessionId,
|
|
97
102
|
onNotification: (notification) => {
|
|
98
103
|
rawLog?.writeLine(JSON.stringify(notification));
|
|
104
|
+
turnError ??= extractTurnError(notification);
|
|
99
105
|
const message = notificationToMessage(notification);
|
|
100
106
|
if (message)
|
|
101
107
|
queue.push(message);
|
|
@@ -104,10 +110,24 @@ export function createDshAdapter(options = {}) {
|
|
|
104
110
|
if (result.finalResponse) {
|
|
105
111
|
rawLog?.writeLine(JSON.stringify({ type: "run.result", result }));
|
|
106
112
|
queue.push({ type: "assistant", blocks: [{ type: "text_final", text: result.finalResponse }], isFinalResponse: true });
|
|
113
|
+
completed = true;
|
|
114
|
+
}
|
|
115
|
+
else if (turnError) {
|
|
116
|
+
queue.fail(turnError);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
// 引擎正常结束但零输出(无错误、无回复):给出明确提示,避免用户只看到"失败"。
|
|
120
|
+
queue.push({
|
|
121
|
+
type: "assistant",
|
|
122
|
+
blocks: [{ type: "text_final", text: "DeepSeek Harness 本轮未产生任何回复(引擎未报告错误)。" }],
|
|
123
|
+
isFinalResponse: true,
|
|
124
|
+
});
|
|
125
|
+
completed = true;
|
|
126
|
+
}
|
|
127
|
+
if (completed) {
|
|
128
|
+
knownSessions.set(sessionId, { sessionId, cwd, lastModified: Date.now(), model: options.model ?? "deepseek-v4-flash" });
|
|
129
|
+
queue.end();
|
|
107
130
|
}
|
|
108
|
-
completed = true;
|
|
109
|
-
knownSessions.set(sessionId, { sessionId, cwd, lastModified: Date.now(), model: options.model ?? "deepseek-v4-flash" });
|
|
110
|
-
queue.end();
|
|
111
131
|
}
|
|
112
132
|
catch (error) {
|
|
113
133
|
queue.fail(error instanceof Error ? error : new Error(String(error)));
|
|
@@ -136,6 +156,32 @@ export function createDshAdapter(options = {}) {
|
|
|
136
156
|
},
|
|
137
157
|
};
|
|
138
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* 从 DSH 引擎的 session.event 里提取第一个 turn/end 错误。
|
|
161
|
+
*
|
|
162
|
+
* DSH 引擎(dsh-agent-loop)在 turn 失败时把错误持久化到 `turn/end` 事件的
|
|
163
|
+
* `data.reason`(`{ kind: "error", error: { message, code, status? } }`),随后
|
|
164
|
+
* `kick()` 吞掉该错误并让 session 进入 idle。SDK 的 `run()` 因此正常返回空
|
|
165
|
+
* `finalResponse`,而不是 reject。此函数把该错误还原成 Error,供 prompt()
|
|
166
|
+
* 重新抛出,复用 session.ts 的统一终态错误分类(401/429/网络等)与脱敏。
|
|
167
|
+
*/
|
|
168
|
+
function extractTurnError(notification) {
|
|
169
|
+
if (notification.method !== "session.event")
|
|
170
|
+
return null;
|
|
171
|
+
const event = asRecord(notification.params.event);
|
|
172
|
+
if (!event || event.type !== "turn/end")
|
|
173
|
+
return null;
|
|
174
|
+
const data = asRecord(event.data);
|
|
175
|
+
const reason = asRecord(data?.reason);
|
|
176
|
+
if (!reason || reason.kind !== "error")
|
|
177
|
+
return null;
|
|
178
|
+
const failure = asRecord(reason.error);
|
|
179
|
+
const code = typeof failure?.code === "string" ? failure.code : "";
|
|
180
|
+
const status = typeof failure?.status === "number" ? `HTTP ${failure.status}` : "";
|
|
181
|
+
const message = typeof failure?.message === "string" ? failure.message : "";
|
|
182
|
+
const detail = [status, code ? `[${code}]` : "", message].filter(Boolean).join(" ").trim();
|
|
183
|
+
return new Error(detail || "DeepSeek Harness 引擎报告了未提供详情的执行错误");
|
|
184
|
+
}
|
|
139
185
|
function notificationToMessage(notification) {
|
|
140
186
|
if (notification.method === "session.status") {
|
|
141
187
|
return notification.params.status === "running"
|