@wu529778790/open-im 1.11.8-beta.24 → 1.11.8-beta.26
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/codex/cli-runner.js +72 -24
- package/dist/shared/ai-task.js +3 -1
- package/package.json +1 -1
package/dist/codex/cli-runner.js
CHANGED
|
@@ -217,22 +217,27 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
217
217
|
const event = parseCodexEvent(line);
|
|
218
218
|
if (!event)
|
|
219
219
|
return;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
220
|
+
// Codex CLI JSONL 格式是嵌套的:顶层 type 为 "event_msg" / "response_item",
|
|
221
|
+
// 真正的子类型在 payload.type 里。旧版扁平格式也兼容。
|
|
222
|
+
const topType = event.type;
|
|
223
|
+
const payload = event.payload ?? event;
|
|
224
|
+
const type = payload.type ?? topType;
|
|
225
|
+
log.debug(`[Codex event] topType=${topType} type=${type}`);
|
|
226
|
+
// thread.started / session_meta → 拿 session ID
|
|
227
|
+
if (type === 'thread.started' || type === 'session_meta') {
|
|
228
|
+
const threadId = payload.thread_id ?? payload.session_id ?? event.thread_id ?? '';
|
|
224
229
|
if (threadId)
|
|
225
230
|
callbacks.onSessionId?.(threadId);
|
|
226
231
|
return;
|
|
227
232
|
}
|
|
228
233
|
if (type === 'turn.failed') {
|
|
229
234
|
completed = true;
|
|
230
|
-
const err = event.error;
|
|
235
|
+
const err = payload.error ?? event.error;
|
|
231
236
|
callbacks.onError(err?.message ?? 'Codex turn failed');
|
|
232
237
|
return;
|
|
233
238
|
}
|
|
234
239
|
if (type === 'error') {
|
|
235
|
-
const msg = event.message;
|
|
240
|
+
const msg = payload.message ?? event.message;
|
|
236
241
|
if (msg?.includes('Reconnecting')) {
|
|
237
242
|
return;
|
|
238
243
|
}
|
|
@@ -240,12 +245,12 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
240
245
|
callbacks.onError(msg ?? 'Codex stream error');
|
|
241
246
|
return;
|
|
242
247
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
248
|
+
// item 事件:payload 里可能有 item 字段,或者 payload 本身就是 item
|
|
249
|
+
if (topType === 'response_item' || type === 'item.started' || type === 'item.updated' || type === 'item.completed') {
|
|
250
|
+
const item = payload.item ?? payload;
|
|
251
|
+
const itemType = item.type ?? type;
|
|
252
|
+
if (itemType === 'reasoning') {
|
|
253
|
+
// Codex 的 reasoning 可能是 encrypted_content(不可读),只在有 text 时累加
|
|
249
254
|
const text = item.text;
|
|
250
255
|
if (text) {
|
|
251
256
|
accumulatedThinking += (accumulatedThinking ? '\n\n' : '') + text;
|
|
@@ -253,23 +258,41 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
253
258
|
}
|
|
254
259
|
return;
|
|
255
260
|
}
|
|
261
|
+
// function_call(Codex 新格式:response_item.type=function_call)
|
|
262
|
+
if (itemType === 'function_call') {
|
|
263
|
+
const name = item.name ?? 'unknown';
|
|
264
|
+
const args = item.arguments;
|
|
265
|
+
const toolName = name === 'exec_command' ? 'Bash' : name === 'apply_patch' ? 'Edit' : name;
|
|
266
|
+
toolStats[toolName] = (toolStats[toolName] || 0) + 1;
|
|
267
|
+
callbacks.onToolUse?.(toolName, args ? { arguments: args } : {});
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
// custom_tool_call(apply_patch 等)
|
|
271
|
+
if (itemType === 'custom_tool_call') {
|
|
272
|
+
const name = item.name ?? 'unknown';
|
|
273
|
+
const toolName = name === 'apply_patch' ? 'Edit' : name;
|
|
274
|
+
toolStats[toolName] = (toolStats[toolName] || 0) + 1;
|
|
275
|
+
callbacks.onToolUse?.(toolName, { input: item.input });
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
// command_execution(旧格式)
|
|
256
279
|
if (itemType === 'command_execution') {
|
|
257
280
|
const cmd = item.command;
|
|
258
|
-
if (cmd
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
callbacks.onToolUse?.(toolName, { command: cmd });
|
|
281
|
+
if (cmd) {
|
|
282
|
+
toolStats['Bash'] = (toolStats['Bash'] || 0) + 1;
|
|
283
|
+
callbacks.onToolUse?.('Bash', { command: cmd });
|
|
262
284
|
}
|
|
263
285
|
return;
|
|
264
286
|
}
|
|
265
|
-
|
|
287
|
+
// file_change(旧格式)
|
|
288
|
+
if (itemType === 'file_change') {
|
|
266
289
|
const changes = item.changes;
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
callbacks.onToolUse?.(toolName, { changes });
|
|
290
|
+
toolStats['Edit'] = (toolStats['Edit'] || 0) + 1;
|
|
291
|
+
callbacks.onToolUse?.('Edit', { changes });
|
|
270
292
|
return;
|
|
271
293
|
}
|
|
272
|
-
|
|
294
|
+
// mcp_tool_call(旧格式)
|
|
295
|
+
if (itemType === 'mcp_tool_call') {
|
|
273
296
|
const tool = item.tool;
|
|
274
297
|
const server = item.server;
|
|
275
298
|
if (tool) {
|
|
@@ -279,16 +302,41 @@ export function runCodex(cliPath, prompt, sessionId, workDir, callbacks, options
|
|
|
279
302
|
}
|
|
280
303
|
return;
|
|
281
304
|
}
|
|
282
|
-
|
|
283
|
-
|
|
305
|
+
// agent_message / message — 最终回复文本
|
|
306
|
+
// Codex 新格式:event_msg.payload.type=agent_message, payload.message=文本
|
|
307
|
+
// response_item.payload.type=message, payload.content=[{type:output_text,text:...}]
|
|
308
|
+
if (itemType === 'agent_message' || itemType === 'message') {
|
|
309
|
+
let text;
|
|
310
|
+
if (itemType === 'agent_message') {
|
|
311
|
+
text = item.message ?? item.text;
|
|
312
|
+
}
|
|
313
|
+
else {
|
|
314
|
+
// message 类型,content 是数组
|
|
315
|
+
const content = item.content;
|
|
316
|
+
if (Array.isArray(content)) {
|
|
317
|
+
text = content
|
|
318
|
+
.filter((c) => c.type === 'output_text' && c.text)
|
|
319
|
+
.map((c) => c.text)
|
|
320
|
+
.join('\n');
|
|
321
|
+
}
|
|
322
|
+
}
|
|
284
323
|
if (text) {
|
|
324
|
+
// 只累加 final_answer 或 commentary,避免重复
|
|
325
|
+
const phase = item.phase ?? payload.phase;
|
|
285
326
|
accumulated += (accumulated ? '\n\n' : '') + text;
|
|
286
327
|
callbacks.onText(accumulated);
|
|
287
328
|
}
|
|
288
329
|
return;
|
|
289
330
|
}
|
|
290
331
|
}
|
|
291
|
-
|
|
332
|
+
// task_complete / turn.completed
|
|
333
|
+
if (type === 'task_complete' || type === 'turn.completed') {
|
|
334
|
+
// task_complete 里可能有 last_agent_message
|
|
335
|
+
const lastMsg = payload.last_agent_message;
|
|
336
|
+
if (lastMsg && !accumulated) {
|
|
337
|
+
accumulated = lastMsg;
|
|
338
|
+
callbacks.onText(accumulated);
|
|
339
|
+
}
|
|
292
340
|
completed = true;
|
|
293
341
|
callbacks.onComplete({
|
|
294
342
|
success: true,
|
package/dist/shared/ai-task.js
CHANGED
|
@@ -295,7 +295,9 @@ export function runAITask(deps, ctx, prompt, toolAdapter, platformAdapter) {
|
|
|
295
295
|
toolLines.push(notification);
|
|
296
296
|
if (toolLines.length > 5)
|
|
297
297
|
toolLines.shift();
|
|
298
|
-
|
|
298
|
+
// 不强制发送(force=false),让节流机制合并短时间内的多次工具调用,
|
|
299
|
+
// 避免突发大量消息触发平台频率限制(如 ClawBot ret=-2)。
|
|
300
|
+
throttledUpdate(taskState.latestContent, false);
|
|
299
301
|
},
|
|
300
302
|
onComplete: async (result) => {
|
|
301
303
|
log.info(`[AITask] onComplete fired: settled=${settled}, success=${result.success}, platform=${ctx.platform}, taskKey=${ctx.taskKey}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wu529778790/open-im",
|
|
3
|
-
"version": "1.11.8-beta.
|
|
3
|
+
"version": "1.11.8-beta.26",
|
|
4
4
|
"description": "Your AI coding assistant, in every chat app. Multi-platform IM bridge for Claude Code, Codex, and CodeBuddy.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|