lark-remote 0.5.12 → 0.5.14
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/CHANGELOG.md +28 -2
- package/README.en.md +1 -14
- package/README.md +1 -14
- package/dist/agent-kinds.d.ts +27 -0
- package/dist/agent-kinds.js +38 -0
- package/dist/bridge/approval-actions.d.ts +95 -0
- package/dist/bridge/approval-actions.js +104 -0
- package/dist/bridge/approval-coordinator.d.ts +1 -0
- package/dist/bridge/approval-coordinator.js +12 -24
- package/dist/bridge/final-usage.d.ts +8 -17
- package/dist/bridge/final-usage.js +1 -18
- package/dist/bridge/index.d.ts +52 -38
- package/dist/bridge/index.js +255 -433
- package/dist/bridge/queue-manager.d.ts +25 -1
- package/dist/bridge/queue-manager.js +179 -160
- package/dist/bridge/run-approval.d.ts +16 -0
- package/dist/bridge/run-approval.js +41 -0
- package/dist/bridge/run-usage.d.ts +32 -0
- package/dist/bridge/run-usage.js +87 -0
- package/dist/bridge/session-writeback.d.ts +19 -0
- package/dist/bridge/session-writeback.js +36 -0
- package/dist/card/approval-render.d.ts +3 -2
- package/dist/card/approval-render.js +3 -2
- package/dist/card/bash-card-session.js +2 -5
- package/dist/{router → card}/card-helpers.d.ts +7 -7
- package/dist/{router → card}/card-helpers.js +8 -8
- package/dist/card/card-session.d.ts +6 -2
- package/dist/card/card-session.js +28 -28
- package/dist/card/card-shared.d.ts +4 -4
- package/dist/card/card-shared.js +4 -10
- package/dist/card/collapsible.js +3 -2
- package/dist/card/final-answer-overflow.d.ts +1 -0
- package/dist/card/final-answer-overflow.js +46 -0
- package/dist/card/run-card-session.d.ts +2 -2
- package/dist/card/run-card-session.js +4 -9
- package/dist/card/run-renderer.d.ts +14 -0
- package/dist/card/run-renderer.js +126 -23
- package/dist/card/run-state.d.ts +40 -51
- package/dist/card/run-state.js +96 -34
- package/dist/card/usage-format.d.ts +30 -0
- package/dist/{router → card}/usage-format.js +3 -10
- package/dist/clone.js +6 -1
- package/dist/config/codex-config.js +4 -4
- package/dist/config/index.d.ts +18 -20
- package/dist/config/index.js +6 -20
- package/dist/config/pi-config.js +6 -4
- package/dist/connector/index.d.ts +2 -4
- package/dist/connector/index.js +7 -11
- package/dist/{runner/dsh → dsh}/auth.js +3 -4
- package/dist/dsh/home.d.ts +2 -0
- package/dist/dsh/home.js +8 -0
- package/dist/dsh/protocol.d.ts +9 -0
- package/dist/dsh/protocol.js +61 -0
- package/dist/inbound/turn-assembler.js +6 -0
- package/dist/index.js +25 -414
- package/dist/message-handlers.d.ts +26 -0
- package/dist/message-handlers.js +275 -0
- package/dist/model-catalog.d.ts +14 -0
- package/dist/model-catalog.js +25 -0
- package/dist/platform/path.d.ts +9 -0
- package/dist/platform/path.js +18 -0
- package/dist/router/active-run-usage.d.ts +4 -0
- package/dist/router/active-run-usage.js +12 -0
- package/dist/router/card-action-payload.d.ts +1 -1
- package/dist/router/card-action-payload.js +1 -1
- package/dist/router/commands/ls.d.ts +9 -0
- package/dist/router/commands/ls.js +243 -0
- package/dist/router/commands/order.d.ts +12 -0
- package/dist/router/commands/order.js +178 -0
- package/dist/router/commands/resume.d.ts +48 -0
- package/dist/router/commands/resume.js +246 -0
- package/dist/router/commands/ws.d.ts +15 -0
- package/dist/router/commands/ws.js +189 -0
- package/dist/router/config/claude.js +5 -4
- package/dist/router/config/codex.js +2 -6
- package/dist/router/config/common/render.d.ts +5 -1
- package/dist/router/config/common/render.js +6 -13
- package/dist/router/config/common/turn-idle.d.ts +2 -0
- package/dist/router/config/common/turn-idle.js +9 -0
- package/dist/router/config/dsh.d.ts +1 -1
- package/dist/router/config/index.d.ts +1 -1
- package/dist/router/config/kimi.js +2 -6
- package/dist/router/config/opencode.js +2 -6
- package/dist/router/config/types.d.ts +11 -3
- package/dist/router/index.d.ts +55 -33
- package/dist/router/index.js +233 -1376
- package/dist/router/paging.d.ts +13 -0
- package/dist/router/paging.js +20 -0
- package/dist/router/path-validation.d.ts +27 -0
- package/dist/router/path-validation.js +45 -0
- package/dist/runner/agent-choices-common.d.ts +1 -1
- package/dist/runner/claude/runner.d.ts +23 -6
- package/dist/runner/claude/runner.js +6 -20
- package/dist/runner/claude/session.js +1 -1
- package/dist/runner/codex/app-server/runner.d.ts +3 -1
- package/dist/runner/codex/app-server/translator.d.ts +13 -0
- package/dist/runner/codex/app-server/translator.js +114 -151
- package/dist/runner/common/acp/base-acp-runner.d.ts +3 -1
- package/dist/runner/common/acp/base-translator.d.ts +3 -8
- package/dist/runner/common/acp/base-translator.js +16 -7
- package/dist/runner/common/connection-based-runner.d.ts +3 -1
- package/dist/runner/common/jsonrpc/transport.js +17 -7
- package/dist/runner/common/spawning-runner.js +10 -4
- package/dist/runner/common/turn-started.d.ts +2 -0
- package/dist/runner/common/turn-started.js +10 -0
- package/dist/runner/dsh/client.d.ts +2 -10
- package/dist/runner/dsh/client.js +13 -220
- package/dist/runner/dsh/daemon.d.ts +0 -2
- package/dist/runner/dsh/daemon.js +9 -7
- package/dist/runner/dsh/errors.d.ts +5 -0
- package/dist/runner/dsh/errors.js +11 -0
- package/dist/runner/dsh/exit-cancel.d.ts +0 -2
- package/dist/runner/dsh/exit-cancel.js +2 -2
- package/dist/runner/dsh/inflight.d.ts +0 -2
- package/dist/runner/dsh/inflight.js +1 -1
- package/dist/runner/dsh/mux-stream.d.ts +26 -0
- package/dist/runner/dsh/mux-stream.js +176 -0
- package/dist/runner/dsh/runner.d.ts +21 -1
- package/dist/runner/dsh/runner.js +76 -73
- package/dist/runner/dsh/translator.d.ts +1 -11
- package/dist/runner/dsh/translator.js +1 -1
- package/dist/runner/index.d.ts +1 -1
- package/dist/runner/kimi/acp/runner.d.ts +22 -1
- package/dist/runner/kimi/acp/runner.js +83 -60
- package/dist/runner/kimi/acp/translator.js +1 -12
- package/dist/runner/opencode/acp/error-monitor.d.ts +11 -0
- package/dist/runner/opencode/acp/error-monitor.js +31 -2
- package/dist/runner/opencode/acp/runner.d.ts +3 -1
- package/dist/runner/opencode/acp/translator.js +1 -12
- package/dist/runner/pi/rpc/runner.d.ts +2 -1
- package/dist/runner/pi/rpc/translator.d.ts +2 -8
- package/dist/runner/pi/rpc/translator.js +2 -7
- package/dist/runner/probe.d.ts +1 -1
- package/dist/runner/probe.js +10 -9
- package/dist/runner/registry.d.ts +2 -20
- package/dist/runner/registry.js +0 -32
- package/dist/runner/types.d.ts +37 -155
- package/dist/runner/types.js +4 -24
- package/dist/session/claude/session-index.d.ts +11 -4
- package/dist/session/claude/session-index.js +34 -10
- package/dist/session/claude/session-reader.d.ts +1 -1
- package/dist/session/claude/sessions.d.ts +2 -2
- package/dist/session/claude/sessions.js +41 -26
- package/dist/session/codex/rollout-reader.d.ts +1 -1
- package/dist/session/codex/rollout-reader.js +14 -13
- package/dist/session/codex/sessions.d.ts +1 -1
- package/dist/session/codex/sessions.js +4 -2
- package/dist/session/common/jsonl.js +7 -1
- package/dist/session/common/pagination.d.ts +2 -0
- package/dist/session/common/pagination.js +1 -1
- package/dist/session/common/recency.d.ts +6 -0
- package/dist/session/common/recency.js +7 -5
- package/dist/session/common/two-pass.d.ts +1 -1
- package/dist/session/common/usage-accumulator.d.ts +1 -1
- package/dist/session/dsh/sessions.d.ts +1 -1
- package/dist/session/dsh/sessions.js +37 -12
- package/dist/session/kimi/sessions.d.ts +1 -1
- package/dist/session/kimi/sessions.js +37 -10
- package/dist/session/opencode/sessions.d.ts +1 -1
- package/dist/session/opencode/sessions.js +53 -48
- package/dist/session/pi/sessions.d.ts +1 -1
- package/dist/session/pi/sessions.js +23 -9
- package/dist/session/registry.d.ts +2 -1
- package/dist/session/session-store.d.ts +1 -2
- package/dist/session/session-store.js +14 -7
- package/dist/session-contract.d.ts +178 -0
- package/dist/session-contract.js +9 -0
- package/package.json +1 -1
- package/dist/router/usage-format.d.ts +0 -60
- /package/dist/{runner/dsh → dsh}/auth.d.ts +0 -0
- /package/dist/{runner/dsh → dsh}/types.d.ts +0 -0
- /package/dist/{runner/dsh → dsh}/types.js +0 -0
|
@@ -18,6 +18,8 @@ export class CodexAppServerTranslator {
|
|
|
18
18
|
turnStatus = 'pending';
|
|
19
19
|
/** Full agentMessage text per item id (item-scoped snapshot). */
|
|
20
20
|
textByItem = new Map();
|
|
21
|
+
/** agentMessage item ids whose protocol phase is `final_answer`. */
|
|
22
|
+
finalTextItems = new Set();
|
|
21
23
|
/**
|
|
22
24
|
* Reasoning content per item id: paragraphs keyed by `contentIndex`
|
|
23
25
|
* (textDelta) plus the summary stream (summaryTextDelta). Each reasoning
|
|
@@ -141,15 +143,19 @@ export class CodexAppServerTranslator {
|
|
|
141
143
|
const text = item.text ?? '';
|
|
142
144
|
if (text && this.textByItem.get(item.id) !== text) {
|
|
143
145
|
this.textByItem.set(item.id, text);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
146
|
+
const final = item.phase === 'final_answer';
|
|
147
|
+
events.push(final
|
|
148
|
+
? {
|
|
149
|
+
type: 'final_answer',
|
|
150
|
+
text,
|
|
151
|
+
itemId: item.id,
|
|
152
|
+
complete: true,
|
|
153
|
+
timestamp: this.now(),
|
|
154
|
+
}
|
|
155
|
+
: this.turnDiffEvent({
|
|
156
|
+
threadId: params?.threadId ?? this.threadId,
|
|
157
|
+
turnId: params?.turn?.id ?? this.turnId,
|
|
158
|
+
}, { text, itemId: item.id, complete: true }));
|
|
153
159
|
}
|
|
154
160
|
}
|
|
155
161
|
else if (item.type === 'plan') {
|
|
@@ -158,15 +164,10 @@ export class CodexAppServerTranslator {
|
|
|
158
164
|
const planText = item.text ?? '';
|
|
159
165
|
if (planText && this.planByItem.get(item.id) !== planText) {
|
|
160
166
|
this.planByItem.set(item.id, planText);
|
|
161
|
-
events.push({
|
|
162
|
-
type: 'turn_diff',
|
|
163
|
-
plan: planText,
|
|
164
|
-
itemId: item.id,
|
|
165
|
-
complete: true,
|
|
167
|
+
events.push(this.turnDiffEvent({
|
|
166
168
|
threadId: params?.threadId ?? this.threadId,
|
|
167
169
|
turnId: params?.turn?.id ?? this.turnId,
|
|
168
|
-
|
|
169
|
-
});
|
|
170
|
+
}, { plan: planText, itemId: item.id, complete: true }));
|
|
170
171
|
}
|
|
171
172
|
}
|
|
172
173
|
}
|
|
@@ -228,6 +229,7 @@ export class CodexAppServerTranslator {
|
|
|
228
229
|
// 的 turnId 闸门挡掉。
|
|
229
230
|
this.usage = { inputTokens: 0, outputTokens: 0 };
|
|
230
231
|
this.textByItem.clear();
|
|
232
|
+
this.finalTextItems.clear();
|
|
231
233
|
this.reasoningByItem.clear();
|
|
232
234
|
this.toolOutputByItem.clear();
|
|
233
235
|
this.toolItemMeta.clear();
|
|
@@ -249,30 +251,28 @@ export class CodexAppServerTranslator {
|
|
|
249
251
|
const prev = this.textByItem.get(params.itemId) ?? '';
|
|
250
252
|
const next = prev + params.delta;
|
|
251
253
|
this.textByItem.set(params.itemId, next);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
254
|
+
if (this.finalTextItems.has(params.itemId)) {
|
|
255
|
+
return [
|
|
256
|
+
{
|
|
257
|
+
type: 'final_answer',
|
|
258
|
+
text: next,
|
|
259
|
+
itemId: params.itemId,
|
|
260
|
+
complete: false,
|
|
261
|
+
timestamp: this.now(),
|
|
262
|
+
},
|
|
263
|
+
];
|
|
264
|
+
}
|
|
265
|
+
return [this.turnDiffEvent(params, { text: next, itemId: params.itemId })];
|
|
262
266
|
}
|
|
263
267
|
handleReasoningDelta(params) {
|
|
264
268
|
// summaryTextDelta 流的是摘要文本;与 content 段落分开累积,避免段落交错。
|
|
265
269
|
const entry = this.reasoningEntry(params.itemId);
|
|
266
270
|
entry.summary += params.delta;
|
|
267
271
|
return [
|
|
268
|
-
{
|
|
269
|
-
type: 'turn_diff',
|
|
272
|
+
this.turnDiffEvent(params, {
|
|
270
273
|
reasoning: this.reasoningSnapshotFor(entry),
|
|
271
274
|
itemId: params.itemId,
|
|
272
|
-
|
|
273
|
-
turnId: params.turnId,
|
|
274
|
-
timestamp: this.now(),
|
|
275
|
-
},
|
|
275
|
+
}),
|
|
276
276
|
];
|
|
277
277
|
}
|
|
278
278
|
handleReasoningPartAdded() {
|
|
@@ -287,15 +287,11 @@ export class CodexAppServerTranslator {
|
|
|
287
287
|
// 权威文件变更(含聚合后的 diff);以快照语义替换本 item 的变更列表。
|
|
288
288
|
this.fileChangeItems.set(item.id, item.changes);
|
|
289
289
|
return [
|
|
290
|
-
{
|
|
291
|
-
type: 'turn_diff',
|
|
290
|
+
this.turnDiffEvent(params, {
|
|
292
291
|
fileChanges: normalizeFileChanges(item.changes),
|
|
293
292
|
itemId: item.id,
|
|
294
293
|
complete: true,
|
|
295
|
-
|
|
296
|
-
turnId: params.turnId,
|
|
297
|
-
timestamp: this.now(),
|
|
298
|
-
},
|
|
294
|
+
}),
|
|
299
295
|
];
|
|
300
296
|
}
|
|
301
297
|
if (item.type === 'reasoning') {
|
|
@@ -307,15 +303,11 @@ export class CodexAppServerTranslator {
|
|
|
307
303
|
entry.content = new Map(content.map((c, i) => [i, c]));
|
|
308
304
|
entry.summary = summary.join('\n');
|
|
309
305
|
return [
|
|
310
|
-
{
|
|
311
|
-
type: 'turn_diff',
|
|
306
|
+
this.turnDiffEvent(params, {
|
|
312
307
|
reasoning: this.reasoningSnapshotFor(entry),
|
|
313
308
|
itemId: item.id,
|
|
314
309
|
complete: true,
|
|
315
|
-
|
|
316
|
-
turnId: params.turnId,
|
|
317
|
-
timestamp: this.now(),
|
|
318
|
-
},
|
|
310
|
+
}),
|
|
319
311
|
];
|
|
320
312
|
}
|
|
321
313
|
}
|
|
@@ -335,17 +327,13 @@ export class CodexAppServerTranslator {
|
|
|
335
327
|
const meta = this.toolItemMeta.get(item.id);
|
|
336
328
|
this.toolItemMeta.delete(item.id);
|
|
337
329
|
return [
|
|
338
|
-
{
|
|
339
|
-
type: 'turn_diff',
|
|
330
|
+
this.turnDiffEvent(params, {
|
|
340
331
|
toolOutput: authoritative,
|
|
341
332
|
...meta,
|
|
342
333
|
itemId: item.id,
|
|
343
334
|
complete: true,
|
|
344
335
|
toolStatus: commandExecutionStatusToToolStatus(item.status),
|
|
345
|
-
|
|
346
|
-
turnId: params.turnId,
|
|
347
|
-
timestamp: this.now(),
|
|
348
|
-
},
|
|
336
|
+
}),
|
|
349
337
|
];
|
|
350
338
|
}
|
|
351
339
|
if (item.type === 'agentMessage') {
|
|
@@ -358,16 +346,25 @@ export class CodexAppServerTranslator {
|
|
|
358
346
|
if (text || accumulated) {
|
|
359
347
|
const finalText = text || accumulated;
|
|
360
348
|
this.textByItem.set(item.id, finalText);
|
|
349
|
+
if (item.phase === 'final_answer' ||
|
|
350
|
+
this.finalTextItems.has(item.id)) {
|
|
351
|
+
this.finalTextItems.delete(item.id);
|
|
352
|
+
return [
|
|
353
|
+
{
|
|
354
|
+
type: 'final_answer',
|
|
355
|
+
text: finalText,
|
|
356
|
+
itemId: item.id,
|
|
357
|
+
complete: true,
|
|
358
|
+
timestamp: this.now(),
|
|
359
|
+
},
|
|
360
|
+
];
|
|
361
|
+
}
|
|
361
362
|
return [
|
|
362
|
-
{
|
|
363
|
-
type: 'turn_diff',
|
|
363
|
+
this.turnDiffEvent(params, {
|
|
364
364
|
text: finalText,
|
|
365
365
|
itemId: item.id,
|
|
366
366
|
complete: true,
|
|
367
|
-
|
|
368
|
-
turnId: params.turnId,
|
|
369
|
-
timestamp: this.now(),
|
|
370
|
-
},
|
|
367
|
+
}),
|
|
371
368
|
];
|
|
372
369
|
}
|
|
373
370
|
}
|
|
@@ -376,15 +373,11 @@ export class CodexAppServerTranslator {
|
|
|
376
373
|
if (text) {
|
|
377
374
|
this.planByItem.set(item.id, text);
|
|
378
375
|
return [
|
|
379
|
-
{
|
|
380
|
-
type: 'turn_diff',
|
|
376
|
+
this.turnDiffEvent(params, {
|
|
381
377
|
plan: text,
|
|
382
378
|
itemId: item.id,
|
|
383
379
|
complete: true,
|
|
384
|
-
|
|
385
|
-
turnId: params.turnId,
|
|
386
|
-
timestamp: this.now(),
|
|
387
|
-
},
|
|
380
|
+
}),
|
|
388
381
|
];
|
|
389
382
|
}
|
|
390
383
|
}
|
|
@@ -396,16 +389,12 @@ export class CodexAppServerTranslator {
|
|
|
396
389
|
this.toolItemMeta.delete(item.id);
|
|
397
390
|
this.startedToolItems.delete(item.id);
|
|
398
391
|
return [
|
|
399
|
-
{
|
|
400
|
-
type: 'turn_diff',
|
|
392
|
+
this.turnDiffEvent(params, {
|
|
401
393
|
toolOutput: this.toolOutputByItem.get(item.id) ?? '',
|
|
402
394
|
...meta,
|
|
403
395
|
itemId: item.id,
|
|
404
396
|
complete: true,
|
|
405
|
-
|
|
406
|
-
turnId: params.turnId,
|
|
407
|
-
timestamp: this.now(),
|
|
408
|
-
},
|
|
397
|
+
}),
|
|
409
398
|
];
|
|
410
399
|
}
|
|
411
400
|
return [];
|
|
@@ -416,14 +405,10 @@ export class CodexAppServerTranslator {
|
|
|
416
405
|
const prev = entry.content.get(index) ?? '';
|
|
417
406
|
entry.content.set(index, prev + params.delta);
|
|
418
407
|
return [
|
|
419
|
-
{
|
|
420
|
-
type: 'turn_diff',
|
|
408
|
+
this.turnDiffEvent(params, {
|
|
421
409
|
reasoning: this.reasoningSnapshotFor(entry),
|
|
422
410
|
itemId: params.itemId,
|
|
423
|
-
|
|
424
|
-
turnId: params.turnId,
|
|
425
|
-
timestamp: this.now(),
|
|
426
|
-
},
|
|
411
|
+
}),
|
|
427
412
|
];
|
|
428
413
|
}
|
|
429
414
|
handleCommandOutputDelta(params) {
|
|
@@ -431,15 +416,11 @@ export class CodexAppServerTranslator {
|
|
|
431
416
|
const next = prev + params.delta;
|
|
432
417
|
this.toolOutputByItem.set(params.itemId, next);
|
|
433
418
|
return [
|
|
434
|
-
{
|
|
435
|
-
type: 'turn_diff',
|
|
419
|
+
this.turnDiffEvent(params, {
|
|
436
420
|
toolOutput: next,
|
|
437
421
|
...this.toolItemMeta.get(params.itemId),
|
|
438
422
|
itemId: params.itemId,
|
|
439
|
-
|
|
440
|
-
turnId: params.turnId,
|
|
441
|
-
timestamp: this.now(),
|
|
442
|
-
},
|
|
423
|
+
}),
|
|
443
424
|
];
|
|
444
425
|
}
|
|
445
426
|
handlePlanUpdated(params) {
|
|
@@ -449,14 +430,10 @@ export class CodexAppServerTranslator {
|
|
|
449
430
|
const next = prev + params.delta;
|
|
450
431
|
this.planByItem.set(params.itemId, next);
|
|
451
432
|
return [
|
|
452
|
-
{
|
|
453
|
-
type: 'turn_diff',
|
|
433
|
+
this.turnDiffEvent(params, {
|
|
454
434
|
plan: next,
|
|
455
435
|
itemId: params.itemId,
|
|
456
|
-
|
|
457
|
-
turnId: params.turnId,
|
|
458
|
-
timestamp: this.now(),
|
|
459
|
-
},
|
|
436
|
+
}),
|
|
460
437
|
];
|
|
461
438
|
}
|
|
462
439
|
handleTokenUsageUpdated(params) {
|
|
@@ -635,6 +612,26 @@ export class CodexAppServerTranslator {
|
|
|
635
612
|
}
|
|
636
613
|
handleItemStarted(params) {
|
|
637
614
|
const item = params.item;
|
|
615
|
+
if (item.type === 'agentMessage') {
|
|
616
|
+
const phase = item.phase;
|
|
617
|
+
if (phase === 'final_answer') {
|
|
618
|
+
this.finalTextItems.add(item.id);
|
|
619
|
+
const text = item.text ?? '';
|
|
620
|
+
if (text) {
|
|
621
|
+
this.textByItem.set(item.id, text);
|
|
622
|
+
return [
|
|
623
|
+
{
|
|
624
|
+
type: 'final_answer',
|
|
625
|
+
text,
|
|
626
|
+
itemId: item.id,
|
|
627
|
+
complete: false,
|
|
628
|
+
timestamp: this.now(),
|
|
629
|
+
},
|
|
630
|
+
];
|
|
631
|
+
}
|
|
632
|
+
}
|
|
633
|
+
return [];
|
|
634
|
+
}
|
|
638
635
|
if (item.type === 'fileChange' && Array.isArray(item.changes)) {
|
|
639
636
|
this.fileChangeItems.set(item.id, item.changes);
|
|
640
637
|
const pending = this.pendingFileApprovalByItemId.get(item.id);
|
|
@@ -649,112 +646,78 @@ export class CodexAppServerTranslator {
|
|
|
649
646
|
view: { ...pending.view, fileChanges },
|
|
650
647
|
timestamp: new Date().toISOString(),
|
|
651
648
|
},
|
|
652
|
-
{
|
|
653
|
-
type: 'turn_diff',
|
|
649
|
+
this.turnDiffEvent(params, {
|
|
654
650
|
fileChanges,
|
|
655
651
|
itemId: item.id,
|
|
656
|
-
|
|
657
|
-
turnId: params.turnId,
|
|
658
|
-
timestamp: this.now(),
|
|
659
|
-
},
|
|
652
|
+
}),
|
|
660
653
|
];
|
|
661
654
|
}
|
|
662
655
|
}
|
|
663
656
|
return [
|
|
664
|
-
{
|
|
665
|
-
type: 'turn_diff',
|
|
657
|
+
this.turnDiffEvent(params, {
|
|
666
658
|
fileChanges: normalizeFileChanges(item.changes),
|
|
667
659
|
itemId: item.id,
|
|
668
|
-
|
|
669
|
-
turnId: params.turnId,
|
|
670
|
-
timestamp: this.now(),
|
|
671
|
-
},
|
|
660
|
+
}),
|
|
672
661
|
];
|
|
673
662
|
}
|
|
674
663
|
if (item.type === 'commandExecution') {
|
|
675
664
|
// item/started 锚定工具块位置(真实时序):命令开始时即创建工具块,
|
|
676
665
|
// 而不是等到首个输出 delta——否则后续 reasoning item 会插到 command 之前。
|
|
677
|
-
this.
|
|
678
|
-
// 信息保真 记录工具身份,随 turn_diff 透传(run-state 首见时写入)。
|
|
679
|
-
this.toolItemMeta.set(item.id, {
|
|
666
|
+
return this.beginToolItem(item.id, params, {
|
|
680
667
|
toolName: 'Bash',
|
|
681
668
|
toolInput: { command: item.command, ...(item.cwd ? { cwd: item.cwd } : {}) },
|
|
682
669
|
toolHint: 'shell',
|
|
683
670
|
});
|
|
684
|
-
return [
|
|
685
|
-
{
|
|
686
|
-
type: 'turn_diff',
|
|
687
|
-
toolOutput: '',
|
|
688
|
-
...this.toolItemMeta.get(item.id),
|
|
689
|
-
itemId: item.id,
|
|
690
|
-
threadId: params.threadId,
|
|
691
|
-
turnId: params.turnId,
|
|
692
|
-
timestamp: this.now(),
|
|
693
|
-
},
|
|
694
|
-
];
|
|
695
671
|
}
|
|
696
672
|
if (item.type === 'webSearch') {
|
|
697
|
-
this.
|
|
698
|
-
this.toolItemMeta.set(item.id, {
|
|
673
|
+
return this.beginToolItem(item.id, params, {
|
|
699
674
|
toolName: 'WebSearch',
|
|
700
675
|
toolInput: { query: item.query },
|
|
701
676
|
toolHint: 'web',
|
|
702
677
|
});
|
|
703
|
-
return [
|
|
704
|
-
{
|
|
705
|
-
type: 'turn_diff',
|
|
706
|
-
toolOutput: '',
|
|
707
|
-
...this.toolItemMeta.get(item.id),
|
|
708
|
-
itemId: item.id,
|
|
709
|
-
threadId: params.threadId,
|
|
710
|
-
turnId: params.turnId,
|
|
711
|
-
timestamp: this.now(),
|
|
712
|
-
},
|
|
713
|
-
];
|
|
714
678
|
}
|
|
715
679
|
if (item.type === 'mcpToolCall') {
|
|
716
680
|
// ThreadItem union 含 catch-all 成员,判别收窄会与泛型成员并集;
|
|
717
681
|
// 显式断言到具体 interface(字段名已经 v2 schema 确认)。
|
|
718
682
|
const mcpItem = item;
|
|
719
|
-
this.
|
|
720
|
-
this.toolItemMeta.set(item.id, {
|
|
683
|
+
return this.beginToolItem(item.id, params, {
|
|
721
684
|
toolName: `mcp__${mcpItem.server}__${mcpItem.tool}`,
|
|
722
685
|
toolInput: mcpItem.arguments ?? {},
|
|
723
686
|
toolHint: 'search',
|
|
724
687
|
});
|
|
725
|
-
return [
|
|
726
|
-
{
|
|
727
|
-
type: 'turn_diff',
|
|
728
|
-
toolOutput: '',
|
|
729
|
-
...this.toolItemMeta.get(item.id),
|
|
730
|
-
itemId: item.id,
|
|
731
|
-
threadId: params.threadId,
|
|
732
|
-
turnId: params.turnId,
|
|
733
|
-
timestamp: this.now(),
|
|
734
|
-
},
|
|
735
|
-
];
|
|
736
688
|
}
|
|
737
689
|
if (item.type === 'dynamicToolCall') {
|
|
738
690
|
const dynItem = item;
|
|
739
|
-
this.
|
|
740
|
-
this.toolItemMeta.set(item.id, {
|
|
691
|
+
return this.beginToolItem(item.id, params, {
|
|
741
692
|
toolName: dynItem.tool,
|
|
742
693
|
toolInput: dynItem.arguments ?? {},
|
|
743
694
|
});
|
|
744
|
-
return [
|
|
745
|
-
{
|
|
746
|
-
type: 'turn_diff',
|
|
747
|
-
toolOutput: '',
|
|
748
|
-
...this.toolItemMeta.get(item.id),
|
|
749
|
-
itemId: item.id,
|
|
750
|
-
threadId: params.threadId,
|
|
751
|
-
turnId: params.turnId,
|
|
752
|
-
timestamp: this.now(),
|
|
753
|
-
},
|
|
754
|
-
];
|
|
755
695
|
}
|
|
756
696
|
return [];
|
|
757
697
|
}
|
|
698
|
+
/**
|
|
699
|
+
* turn_diff 的统一信封:`type` + threadId/turnId/timestamp 三个公共字段在此
|
|
700
|
+
* 一次装配(十余个构造点原本各抄一遍,还得挂 `as TurnDiffEvent`)。
|
|
701
|
+
*/
|
|
702
|
+
turnDiffEvent(ids, fields) {
|
|
703
|
+
return {
|
|
704
|
+
type: 'turn_diff',
|
|
705
|
+
...fields,
|
|
706
|
+
threadId: ids.threadId,
|
|
707
|
+
turnId: ids.turnId,
|
|
708
|
+
timestamp: this.now(),
|
|
709
|
+
};
|
|
710
|
+
}
|
|
711
|
+
/**
|
|
712
|
+
* 工具型 item 的 started 处理(commandExecution / webSearch / mcpToolCall /
|
|
713
|
+
* dynamicToolCall 四个分支同形):登记「已开始」锚点 + 记录工具身份 meta,
|
|
714
|
+
* 再发一帧空的 turn_diff 把工具块按真实时序插进卡片。
|
|
715
|
+
*/
|
|
716
|
+
beginToolItem(itemId, params, meta) {
|
|
717
|
+
this.startedToolItems.add(itemId);
|
|
718
|
+
this.toolItemMeta.set(itemId, meta);
|
|
719
|
+
return [this.turnDiffEvent(params, { toolOutput: '', ...meta, itemId })];
|
|
720
|
+
}
|
|
758
721
|
handlePermissionsApproval(requestId, params) {
|
|
759
722
|
const permItems = this.buildPermissionItems(params.permissions);
|
|
760
723
|
const view = {
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
* Bash notifications and serves terminal/* reverse RPC; opencode is plain
|
|
19
19
|
* - getStatusInfo / updateApprovalMode: agent-specific extras & mode vocab
|
|
20
20
|
*/
|
|
21
|
-
import type {
|
|
21
|
+
import type { AgentKind } from '../../../agent-kinds.js';
|
|
22
|
+
import type { AgentSessionReader } from '../../../session-contract.js';
|
|
23
|
+
import type { AgentEvent, SpawnOptions } from '../../types.js';
|
|
22
24
|
import { ConnectionManager } from '../jsonrpc/connection-manager.js';
|
|
23
25
|
import { JsonRpcClient } from '../jsonrpc/client.js';
|
|
24
26
|
import { type SessionNewResult, type SessionResumeResult, type SessionPromptResult, type RequestPermissionParams } from './protocol-types.js';
|
|
@@ -19,16 +19,10 @@
|
|
|
19
19
|
* buildToolUseUpdate — tool_use patch from tool_call_update
|
|
20
20
|
* onUsageSample — extra usage bookkeeping (opencode: cost)
|
|
21
21
|
*/
|
|
22
|
-
import type { AgentEvent, ApprovalRequestedEvent, ResultEvent } from '../../types.js';
|
|
22
|
+
import type { AgentEvent, ApprovalRequestedEvent, ApprovalView, ResultEvent, TurnStartedEvent } from '../../types.js';
|
|
23
23
|
import { type AgentMessageChunkEvent, type AgentThoughtChunkEvent, type ToolCallEvent, type ToolCallUpdateEvent, type UsageUpdateEvent, type RequestPermissionParams, type AcpPlanEvent } from './protocol-types.js';
|
|
24
24
|
/** Self-produced turn_started event (no wire equivalent — produced on prompt start). */
|
|
25
|
-
export
|
|
26
|
-
type: 'turn_started';
|
|
27
|
-
threadId: string;
|
|
28
|
-
turnId: string;
|
|
29
|
-
operationKind: 'turn' | 'compaction';
|
|
30
|
-
timestamp?: string;
|
|
31
|
-
}
|
|
25
|
+
export type AcpTurnStartedEvent = TurnStartedEvent;
|
|
32
26
|
/**
|
|
33
27
|
* Live usage snapshot from usage_update. The ACP wire carries context
|
|
34
28
|
* occupancy (`used`) and the model context window (`size`) — there is NO
|
|
@@ -96,6 +90,7 @@ export declare abstract class BaseAcpTranslator {
|
|
|
96
90
|
* is sent (no wire notification for this — self-produced).
|
|
97
91
|
*/
|
|
98
92
|
produceTurnStarted(sessionId: string, turnId: string): AcpTurnStartedEvent;
|
|
93
|
+
protected approvalRequestedEvents(requestId: number | string, sessionId: string, view: ApprovalView): ApprovalRequestedEvent[];
|
|
99
94
|
/**
|
|
100
95
|
* Translate a prompt response into a result event.
|
|
101
96
|
* stopReason: end_turn → success; cancelled → interrupted (independent
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { makeTurnStartedEvent } from '../turn-started.js';
|
|
1
2
|
import { NotificationMethod, ServerRequestMethod, SessionEventType, } from './protocol-types.js';
|
|
2
3
|
/**
|
|
3
4
|
* ACP tool kind → 常用工具名映射(信息保真,数据驱动无 agent 分支)。
|
|
@@ -145,13 +146,21 @@ export class BaseAcpTranslator {
|
|
|
145
146
|
*/
|
|
146
147
|
produceTurnStarted(sessionId, turnId) {
|
|
147
148
|
this.currentTurnId = turnId;
|
|
148
|
-
return
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
149
|
+
return makeTurnStartedEvent(sessionId, turnId, this.operationKind);
|
|
150
|
+
}
|
|
151
|
+
approvalRequestedEvents(requestId, sessionId, view) {
|
|
152
|
+
return [
|
|
153
|
+
{
|
|
154
|
+
type: 'approval_requested',
|
|
155
|
+
requestId,
|
|
156
|
+
kind: 'command',
|
|
157
|
+
threadId: sessionId,
|
|
158
|
+
turnId: '',
|
|
159
|
+
itemId: '',
|
|
160
|
+
view,
|
|
161
|
+
timestamp: new Date().toISOString(),
|
|
162
|
+
},
|
|
163
|
+
];
|
|
155
164
|
}
|
|
156
165
|
/**
|
|
157
166
|
* Translate a prompt response into a result event.
|
|
@@ -14,7 +14,9 @@
|
|
|
14
14
|
* handleNotification/handleServerRequest, respondApproval, pendingApprovals,
|
|
15
15
|
* updateApprovalMode, getStatusInfo) and provide the small abstract hooks below.
|
|
16
16
|
*/
|
|
17
|
-
import type { AgentKind
|
|
17
|
+
import type { AgentKind } from '../../agent-kinds.js';
|
|
18
|
+
import type { AgentSessionReader } from '../../session-contract.js';
|
|
19
|
+
import type { AgentEvent, AgentRunner, AgentStatusInfo, SpawnOptions } from '../types.js';
|
|
18
20
|
import type { AgentStopper } from '../../platform/agent-stopper.js';
|
|
19
21
|
export declare abstract class ConnectionBasedRunner<TClient, TEvent = AgentEvent> implements AgentRunner {
|
|
20
22
|
readonly kind: AgentKind;
|
|
@@ -12,6 +12,10 @@ import { binaryName } from '../../../platform/identity.js';
|
|
|
12
12
|
import { createTerminator } from '../../../platform/terminator.js';
|
|
13
13
|
import { agentStopperRegistry, } from '../../../platform/agent-stopper.js';
|
|
14
14
|
import { getLogger } from '../../../logger/index.js';
|
|
15
|
+
/** 日志用的错误摘要(onClose 的 reason 仍是稳定分类码)。 */
|
|
16
|
+
function describeErr(err) {
|
|
17
|
+
return err instanceof Error ? err.message : String(err);
|
|
18
|
+
}
|
|
15
19
|
/** Max bytes for a single line before we disconnect (10MB). */
|
|
16
20
|
const MAX_LINE_BYTES = 10 * 1024 * 1024;
|
|
17
21
|
/** Max bytes retained from stderr for diagnostics (64KB). */
|
|
@@ -205,8 +209,8 @@ export class JsonlRpcTransport {
|
|
|
205
209
|
this.writeQueue.push(Buffer.from(JSON.stringify(msg) + '\n', 'utf8'));
|
|
206
210
|
this.flush();
|
|
207
211
|
}
|
|
208
|
-
catch {
|
|
209
|
-
this.handleClose('epipe');
|
|
212
|
+
catch (err) {
|
|
213
|
+
this.handleClose('epipe', describeErr(err));
|
|
210
214
|
}
|
|
211
215
|
}
|
|
212
216
|
/** Send queued lines to stdin, pausing on backpressure until drain. */
|
|
@@ -229,7 +233,7 @@ export class JsonlRpcTransport {
|
|
|
229
233
|
try {
|
|
230
234
|
const ok = stdin.write(chunk, (err) => {
|
|
231
235
|
if (err) {
|
|
232
|
-
this.handleClose('epipe');
|
|
236
|
+
this.handleClose('epipe', describeErr(err));
|
|
233
237
|
}
|
|
234
238
|
});
|
|
235
239
|
if (!ok) {
|
|
@@ -240,8 +244,8 @@ export class JsonlRpcTransport {
|
|
|
240
244
|
next();
|
|
241
245
|
}
|
|
242
246
|
}
|
|
243
|
-
catch {
|
|
244
|
-
this.handleClose('epipe');
|
|
247
|
+
catch (err) {
|
|
248
|
+
this.handleClose('epipe', describeErr(err));
|
|
245
249
|
}
|
|
246
250
|
};
|
|
247
251
|
next();
|
|
@@ -288,10 +292,11 @@ export class JsonlRpcTransport {
|
|
|
288
292
|
this.registration = null;
|
|
289
293
|
this.stoppers.unregister(this.agent, reg.pid, reg.stopper);
|
|
290
294
|
}
|
|
291
|
-
handleClose(reason) {
|
|
295
|
+
handleClose(reason, detail) {
|
|
292
296
|
if (this._closed)
|
|
293
297
|
return;
|
|
294
298
|
this._closed = true;
|
|
299
|
+
const dropped = this.writeQueue.length;
|
|
295
300
|
this.writeQueue = [];
|
|
296
301
|
// Remove the exit listener to avoid double-firing
|
|
297
302
|
if (this.proc) {
|
|
@@ -319,7 +324,12 @@ export class JsonlRpcTransport {
|
|
|
319
324
|
// 统一关闭出口:EPIPE/超长行/进程 error 都必须通知上层(connection-manager
|
|
320
325
|
// 靠 onClose 删除 slot、client 靠它 failPending),否则 slot 悬挂死连接。
|
|
321
326
|
this.events?.onClose(reason);
|
|
322
|
-
|
|
327
|
+
// reason 是给上层的稳定分类码;原始 err 与被丢弃的排队条数只进日志,
|
|
328
|
+
// 否则「stdin 写失败」到底写了什么、丢了什么都查不出来。
|
|
329
|
+
const suffix = [detail, dropped > 0 ? `${dropped} queued message(s) dropped` : undefined]
|
|
330
|
+
.filter(Boolean)
|
|
331
|
+
.join('; ');
|
|
332
|
+
getLogger().info(`[jsonrpc-transport] closed: ${reason}${suffix ? ` (${suffix})` : ''}`);
|
|
323
333
|
}
|
|
324
334
|
}
|
|
325
335
|
//# sourceMappingURL=transport.js.map
|
|
@@ -374,13 +374,19 @@ export class SpawningRunner {
|
|
|
374
374
|
try {
|
|
375
375
|
process.kill(-pid, 'SIGTERM');
|
|
376
376
|
}
|
|
377
|
-
catch {
|
|
378
|
-
|
|
377
|
+
catch (err) {
|
|
378
|
+
const code = err.code;
|
|
379
|
+
if (code === 'ESRCH') {
|
|
380
|
+
getLogger().debug(`[${this.logTag}] orphan process group ${-pid} already exited`);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
getLogger().warn(`[${this.logTag}] killOrphan failed to signal process group ${-pid}: ${err?.message ?? String(err)}`);
|
|
384
|
+
}
|
|
379
385
|
}
|
|
380
386
|
bestEffortUnlink(this.pidFilePath);
|
|
381
387
|
}
|
|
382
|
-
catch {
|
|
383
|
-
|
|
388
|
+
catch (err) {
|
|
389
|
+
getLogger().warn(`[${this.logTag}] killOrphan failed for ${this.pidFilePath}: ${err?.message ?? String(err)}`);
|
|
384
390
|
}
|
|
385
391
|
}
|
|
386
392
|
/**
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export function makeTurnStartedEvent(sessionId, turnId, operationKind) {
|
|
2
|
+
return {
|
|
3
|
+
type: 'turn_started',
|
|
4
|
+
threadId: sessionId,
|
|
5
|
+
turnId,
|
|
6
|
+
operationKind: operationKind === 'compact' ? 'compaction' : 'turn',
|
|
7
|
+
timestamp: new Date().toISOString(),
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=turn-started.js.map
|