@geminixiang/mikan 1.0.0-beta.80 → 1.0.0-beta.81
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 +19 -0
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +3 -4
- package/dist/adapters/github/bot.js.map +1 -1
- package/dist/adapters/github/client.d.ts +4 -0
- package/dist/adapters/github/client.d.ts.map +1 -1
- package/dist/adapters/github/client.js +41 -23
- package/dist/adapters/github/client.js.map +1 -1
- package/dist/adapters/github/github-ops.js +16 -12
- package/dist/adapters/github/github-ops.js.map +1 -1
- package/dist/adapters/slack/bot.d.ts.map +1 -1
- package/dist/adapters/slack/bot.js +6 -3
- package/dist/adapters/slack/bot.js.map +1 -1
- package/dist/adapters/web/server.d.ts +2 -0
- package/dist/adapters/web/server.d.ts.map +1 -1
- package/dist/adapters/web/server.js +11 -4
- package/dist/adapters/web/server.js.map +1 -1
- package/dist/adapters/web/session-view/portal.d.ts.map +1 -1
- package/dist/adapters/web/session-view/portal.js +84 -63
- package/dist/adapters/web/session-view/portal.js.map +1 -1
- package/dist/adapters/web/session-view/types.d.ts +2 -0
- package/dist/adapters/web/session-view/types.d.ts.map +1 -1
- package/dist/adapters/web/session-view/types.js.map +1 -1
- package/dist/env-manifest.d.ts +1 -0
- package/dist/env-manifest.d.ts.map +1 -1
- package/dist/env-manifest.js +7 -0
- package/dist/env-manifest.js.map +1 -1
- package/dist/harness/loop-guard.d.ts +10 -0
- package/dist/harness/loop-guard.d.ts.map +1 -0
- package/dist/harness/loop-guard.js +111 -0
- package/dist/harness/loop-guard.js.map +1 -0
- package/dist/harness/presenter.d.ts.map +1 -1
- package/dist/harness/presenter.js +143 -141
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/run-events.d.ts +10 -0
- package/dist/harness/run-events.d.ts.map +1 -0
- package/dist/harness/run-events.js +129 -0
- package/dist/harness/run-events.js.map +1 -0
- package/dist/harness/runner.d.ts.map +1 -1
- package/dist/harness/runner.js +78 -48
- package/dist/harness/runner.js.map +1 -1
- package/dist/harness/session.d.ts +5 -0
- package/dist/harness/session.d.ts.map +1 -1
- package/dist/harness/session.js +71 -1
- package/dist/harness/session.js.map +1 -1
- package/dist/harness/types.d.ts +60 -0
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/main.js +11 -8
- package/dist/main.js.map +1 -1
- package/dist/runtime/conversation-runtime.js +1 -0
- package/dist/runtime/conversation-runtime.js.map +1 -1
- package/dist/runtime/types.d.ts +2 -1
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/runtime/types.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { contentText } from "@earendil-works/pi-ai";
|
|
2
|
-
import { mergeSubagentProgress,
|
|
2
|
+
import { mergeSubagentProgress, renderSubagentDashboard, settleSubagentProgress, } from "./tools/subagent.js";
|
|
3
3
|
import { addLifecycleEvent, metricAttributes, recordCounter, recordDistribution, recordGauge, reportUserFacingError, startOperationSpan, updateActiveSpanAttribution, } from "../observability/index.js";
|
|
4
4
|
import { appendTriggerAttribution } from "./prompt.js";
|
|
5
5
|
import { START_TASK_TOOL, TASK_STATUS_TOOL } from "./tools/task.js";
|
|
6
|
-
import {
|
|
7
|
-
import { JEV_BROWSER_TOOL } from "./tools/jev-browser.js";
|
|
6
|
+
import { toRunEvent, toolResultText } from "./run-events.js";
|
|
8
7
|
import * as log from "../log.js";
|
|
9
8
|
import { errorMessage } from "../unknown-values.js";
|
|
10
9
|
const operationSpans = new WeakMap();
|
|
@@ -53,6 +52,8 @@ function createRunStateDefaults() {
|
|
|
53
52
|
subagentToolCalls: new Set(),
|
|
54
53
|
subagentProgressShown: false,
|
|
55
54
|
suppressResponseDeltas: false,
|
|
55
|
+
answerStreamStarted: false,
|
|
56
|
+
publishRunEvent: undefined,
|
|
56
57
|
lastSubagentProgressAt: 0,
|
|
57
58
|
toolProgressTimer: undefined,
|
|
58
59
|
totalUsage: createEmptyUsageTotals(),
|
|
@@ -92,6 +93,7 @@ export function activateRunPresentation(runState, context) {
|
|
|
92
93
|
sessionId: context.sessionUuid,
|
|
93
94
|
},
|
|
94
95
|
triggerAttribution: context.triggerAttribution,
|
|
96
|
+
publishRunEvent: context.publishRunEvent,
|
|
95
97
|
});
|
|
96
98
|
const { responder } = context;
|
|
97
99
|
let queueChain = Promise.resolve();
|
|
@@ -124,6 +126,7 @@ export function activateRunPresentation(runState, context) {
|
|
|
124
126
|
runState.responder = null;
|
|
125
127
|
runState.logCtx = null;
|
|
126
128
|
runState.queue = null;
|
|
129
|
+
runState.publishRunEvent = undefined;
|
|
127
130
|
},
|
|
128
131
|
};
|
|
129
132
|
}
|
|
@@ -134,14 +137,6 @@ export function getFinalAssistantText(session) {
|
|
|
134
137
|
export function isEventTriggerAttribution(triggerAttribution) {
|
|
135
138
|
return triggerAttribution?.startsWith("[event:") === true;
|
|
136
139
|
}
|
|
137
|
-
function extractToolLabel(toolName, args) {
|
|
138
|
-
const label = args?.label;
|
|
139
|
-
const text = typeof label === "string" ? label.trim() || toolName : toolName;
|
|
140
|
-
if ((toolName === JEV_TOOL || toolName === JEV_BROWSER_TOOL) && text !== toolName) {
|
|
141
|
-
return `${toolName} · ${text}`;
|
|
142
|
-
}
|
|
143
|
-
return text;
|
|
144
|
-
}
|
|
145
140
|
function formatToolProgress(runState) {
|
|
146
141
|
const lines = Array.from(runState.toolProgress.entries()).flatMap(([toolCallId, item]) => {
|
|
147
142
|
if (runState.subagentToolCalls.has(toolCallId))
|
|
@@ -206,14 +201,6 @@ function flushToolProgressUpdate(responder, runState) {
|
|
|
206
201
|
markSubagentProgressShown(runState, subagentProgress);
|
|
207
202
|
runState.queue?.enqueue(() => replaceResponseWithToolProgress(responder, runState, subagentProgress), "tool progress update");
|
|
208
203
|
}
|
|
209
|
-
function extractSubagentProgress(partialResult) {
|
|
210
|
-
if (!partialResult || typeof partialResult !== "object")
|
|
211
|
-
return undefined;
|
|
212
|
-
const details = partialResult.details;
|
|
213
|
-
if (!details || typeof details !== "object")
|
|
214
|
-
return undefined;
|
|
215
|
-
return parseSubagentProgressSnapshot(details.progress);
|
|
216
|
-
}
|
|
217
204
|
async function finalizeErrorResponse(responder, runState, options) {
|
|
218
205
|
if (!runState.reportedLlmError) {
|
|
219
206
|
runState.reportedLlmError = true;
|
|
@@ -416,22 +403,6 @@ export async function reportUsageSummary(ctx) {
|
|
|
416
403
|
await waitForQueue();
|
|
417
404
|
}
|
|
418
405
|
}
|
|
419
|
-
function toolResultContentText(result) {
|
|
420
|
-
if (!result || typeof result !== "object" || !("content" in result))
|
|
421
|
-
return undefined;
|
|
422
|
-
const content = result.content;
|
|
423
|
-
if (!Array.isArray(content))
|
|
424
|
-
return undefined;
|
|
425
|
-
const textParts = content
|
|
426
|
-
.filter((part) => part.type === "text" && part.text)
|
|
427
|
-
.map((part) => part.text);
|
|
428
|
-
return textParts.length > 0 ? textParts.join("\n") : undefined;
|
|
429
|
-
}
|
|
430
|
-
function extractToolResultText(result) {
|
|
431
|
-
if (typeof result === "string")
|
|
432
|
-
return result;
|
|
433
|
-
return toolResultContentText(result) ?? JSON.stringify(result);
|
|
434
|
-
}
|
|
435
406
|
function serializedLength(value) {
|
|
436
407
|
if (typeof value === "string")
|
|
437
408
|
return value.length;
|
|
@@ -455,8 +426,8 @@ function toolCategory(name, roles) {
|
|
|
455
426
|
return "platform";
|
|
456
427
|
return "function";
|
|
457
428
|
}
|
|
458
|
-
function
|
|
459
|
-
const { runState,
|
|
429
|
+
function observeToolStart(event, context) {
|
|
430
|
+
const { runState, logCtx, baseAttrs } = context;
|
|
460
431
|
const args = (event.args ?? {});
|
|
461
432
|
const label = args.label || event.toolName;
|
|
462
433
|
runState.toolCallCount += 1;
|
|
@@ -468,18 +439,6 @@ function handleToolStart(event, context) {
|
|
|
468
439
|
});
|
|
469
440
|
if (event.toolName === START_TASK_TOOL)
|
|
470
441
|
return;
|
|
471
|
-
if (event.toolName !== TASK_STATUS_TOOL) {
|
|
472
|
-
runState.toolProgress.set(event.toolCallId, {
|
|
473
|
-
label: extractToolLabel(event.toolName, event.args),
|
|
474
|
-
status: "running",
|
|
475
|
-
});
|
|
476
|
-
}
|
|
477
|
-
if (event.toolName === "subagent") {
|
|
478
|
-
runState.subagentToolCalls.add(event.toolCallId);
|
|
479
|
-
}
|
|
480
|
-
else if (event.toolName !== TASK_STATUS_TOOL) {
|
|
481
|
-
queue.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
|
|
482
|
-
}
|
|
483
442
|
spansFor(runState).tools.set(event.toolCallId, startOperationSpan(`execute_tool ${event.toolName}`, metricAttributes({
|
|
484
443
|
"gen_ai.operation.name": "execute_tool",
|
|
485
444
|
"gen_ai.tool.name": event.toolName,
|
|
@@ -492,15 +451,6 @@ function handleToolStart(event, context) {
|
|
|
492
451
|
addLifecycleEvent("agent.tool.started", { tool: event.toolName, ...baseAttrs });
|
|
493
452
|
log.logToolStart(logCtx, event.toolName, label, event.args);
|
|
494
453
|
}
|
|
495
|
-
function handleToolUpdate(event, context) {
|
|
496
|
-
const subagentProgress = extractSubagentProgress(event.partialResult);
|
|
497
|
-
if (!subagentProgress)
|
|
498
|
-
return;
|
|
499
|
-
context.runState.subagentProgress.set(event.toolCallId, subagentProgress);
|
|
500
|
-
context.runState.subagentToolCalls.add(event.toolCallId);
|
|
501
|
-
context.runState.suppressResponseDeltas = true;
|
|
502
|
-
scheduleToolProgressUpdate(context.responder, context.runState);
|
|
503
|
-
}
|
|
504
454
|
function recordToolMetrics(event, durationMs, context) {
|
|
505
455
|
recordCounter("agent.tool.calls", 1, metricAttributes({
|
|
506
456
|
tool: event.toolName,
|
|
@@ -518,16 +468,15 @@ function recordToolMetrics(event, durationMs, context) {
|
|
|
518
468
|
...context.baseAttrs,
|
|
519
469
|
});
|
|
520
470
|
}
|
|
521
|
-
function
|
|
522
|
-
const { runState,
|
|
523
|
-
const resultStr = extractToolResultText(event.result);
|
|
471
|
+
function observeToolEnd(event, context) {
|
|
472
|
+
const { runState, logCtx } = context;
|
|
524
473
|
const outputCharacters = serializedLength(event.result);
|
|
525
474
|
runState.toolOutputCharacters += outputCharacters;
|
|
526
475
|
if (event.isError)
|
|
527
476
|
runState.toolErrorCount += 1;
|
|
528
477
|
const pending = runState.pendingTools.get(event.toolCallId);
|
|
478
|
+
runState.pendingTools.delete(event.toolCallId);
|
|
529
479
|
if (event.toolName === START_TASK_TOOL) {
|
|
530
|
-
runState.pendingTools.delete(event.toolCallId);
|
|
531
480
|
if (!event.isError)
|
|
532
481
|
runState.finalResponseHandledByTool = true;
|
|
533
482
|
else
|
|
@@ -540,20 +489,6 @@ function handleToolEnd(event, context) {
|
|
|
540
489
|
});
|
|
541
490
|
return;
|
|
542
491
|
}
|
|
543
|
-
const progress = runState.toolProgress.get(event.toolCallId);
|
|
544
|
-
if (progress)
|
|
545
|
-
progress.status = event.isError ? "error" : "done";
|
|
546
|
-
const subagentProgress = runState.subagentProgress.get(event.toolCallId);
|
|
547
|
-
if (subagentProgress) {
|
|
548
|
-
runState.subagentProgress.set(event.toolCallId, settleSubagentProgress(subagentProgress, event.isError));
|
|
549
|
-
}
|
|
550
|
-
if (event.toolName !== TASK_STATUS_TOOL)
|
|
551
|
-
flushToolProgressUpdate(responder, runState);
|
|
552
|
-
const completedProgress = runState.subagentProgress.get(event.toolCallId);
|
|
553
|
-
if (completedProgress)
|
|
554
|
-
runState.completedSubagentProgress.push(completedProgress);
|
|
555
|
-
runState.subagentProgress.delete(event.toolCallId);
|
|
556
|
-
runState.pendingTools.delete(event.toolCallId);
|
|
557
492
|
const durationMs = pending ? Date.now() - pending.startTime : 0;
|
|
558
493
|
const toolSpan = spansFor(runState).tools.get(event.toolCallId);
|
|
559
494
|
toolSpan?.end({
|
|
@@ -570,6 +505,7 @@ function handleToolEnd(event, context) {
|
|
|
570
505
|
});
|
|
571
506
|
spansFor(runState).tools.delete(event.toolCallId);
|
|
572
507
|
recordToolMetrics(event, durationMs, context);
|
|
508
|
+
const resultStr = toolResultText(event.result);
|
|
573
509
|
if (event.isError) {
|
|
574
510
|
log.logToolError(logCtx, event.toolName, durationMs, resultStr);
|
|
575
511
|
return;
|
|
@@ -579,7 +515,7 @@ function handleToolEnd(event, context) {
|
|
|
579
515
|
runState.finalResponseHandledByTool = true;
|
|
580
516
|
}
|
|
581
517
|
}
|
|
582
|
-
function
|
|
518
|
+
function observeMessageStart(event, context) {
|
|
583
519
|
if (event.message.role !== "assistant")
|
|
584
520
|
return;
|
|
585
521
|
context.runState.llmCallCount += 1;
|
|
@@ -603,7 +539,7 @@ function handleMessageStart(event, context) {
|
|
|
603
539
|
});
|
|
604
540
|
log.logResponseStart(context.logCtx);
|
|
605
541
|
}
|
|
606
|
-
function
|
|
542
|
+
function observeMessageUpdate(event, context) {
|
|
607
543
|
const update = event.assistantMessageEvent;
|
|
608
544
|
if (update.type !== "text_delta" || !update.delta)
|
|
609
545
|
return;
|
|
@@ -612,11 +548,6 @@ function handleMessageUpdate(event, context) {
|
|
|
612
548
|
llmEntry.firstTokenAt = Date.now();
|
|
613
549
|
context.runState.firstTokenLatencyMs ??= llmEntry.firstTokenAt - llmEntry.startedAt;
|
|
614
550
|
}
|
|
615
|
-
if (context.responder.appendResponseDelta && !context.runState.suppressResponseDeltas) {
|
|
616
|
-
context.queue.enqueue(async () => {
|
|
617
|
-
await context.responder.appendResponseDelta?.(update.delta);
|
|
618
|
-
}, "response delta");
|
|
619
|
-
}
|
|
620
551
|
}
|
|
621
552
|
function recordAssistantUsage(message, context) {
|
|
622
553
|
if (!message.usage)
|
|
@@ -661,43 +592,7 @@ function recordAssistantUsage(message, context) {
|
|
|
661
592
|
cost_total_usd: message.usage.cost.total,
|
|
662
593
|
});
|
|
663
594
|
}
|
|
664
|
-
function
|
|
665
|
-
log.logThinking(context.logCtx, thinking);
|
|
666
|
-
context.queue.enqueue(() => context.responder.respond(`_${thinking}_`), "thinking main");
|
|
667
|
-
context.queue.enqueue(() => context.responder.respondDiagnostic(`_${thinking}_`), "thinking diagnostic");
|
|
668
|
-
}
|
|
669
|
-
function presentFinalText(text, context) {
|
|
670
|
-
const finalText = appendTriggerAttribution(formatResponseWithToolProgress(text, context.runState), context.runState.triggerAttribution);
|
|
671
|
-
log.logResponse(context.logCtx, text);
|
|
672
|
-
if (context.runState.completedSubagentProgress.length > 0)
|
|
673
|
-
return;
|
|
674
|
-
if (context.responder.finishResponse) {
|
|
675
|
-
context.queue.enqueue(async () => {
|
|
676
|
-
await context.responder.finishResponse?.(finalText);
|
|
677
|
-
}, "response finish");
|
|
678
|
-
}
|
|
679
|
-
else {
|
|
680
|
-
context.queue.enqueue(() => context.responder.respond(finalText), "response main");
|
|
681
|
-
}
|
|
682
|
-
}
|
|
683
|
-
function presentAssistantMessage(message, context) {
|
|
684
|
-
const thinkingParts = [];
|
|
685
|
-
const textParts = [];
|
|
686
|
-
const hasToolCall = message.content.some((part) => ["tool_use", "toolCall", "tool-call"].includes(part.type ?? ""));
|
|
687
|
-
for (const part of message.content) {
|
|
688
|
-
if (part.type === "thinking")
|
|
689
|
-
thinkingParts.push(part.thinking);
|
|
690
|
-
else if (part.type === "text")
|
|
691
|
-
textParts.push(part.text);
|
|
692
|
-
}
|
|
693
|
-
for (const thinking of thinkingParts)
|
|
694
|
-
presentThinking(thinking, context);
|
|
695
|
-
const text = textParts.join("\n");
|
|
696
|
-
if (!text.trim() || hasToolCall || context.runState.finalResponseHandledByTool)
|
|
697
|
-
return;
|
|
698
|
-
presentFinalText(text, context);
|
|
699
|
-
}
|
|
700
|
-
function handleMessageEnd(event, context) {
|
|
595
|
+
function observeMessageEnd(event, context) {
|
|
701
596
|
if (event.message.role !== "assistant")
|
|
702
597
|
return;
|
|
703
598
|
const message = event.message;
|
|
@@ -740,14 +635,11 @@ function handleMessageEnd(event, context) {
|
|
|
740
635
|
}),
|
|
741
636
|
error: message.errorMessage ? operationError("LLMError") : undefined,
|
|
742
637
|
});
|
|
743
|
-
presentAssistantMessage(message, context);
|
|
744
638
|
}
|
|
745
|
-
function
|
|
639
|
+
function observeLifecycleEvent(event, context) {
|
|
746
640
|
if (event.type === "compaction_start") {
|
|
747
641
|
context.runState.compactionCount += 1;
|
|
748
|
-
const text = "_Compacting context..._";
|
|
749
642
|
log.logInfo(`Auto-compaction started (reason: ${event.reason})`);
|
|
750
|
-
context.queue.enqueue(() => context.responder.respond(text), "compaction start");
|
|
751
643
|
return;
|
|
752
644
|
}
|
|
753
645
|
if (event.type === "compaction_end") {
|
|
@@ -762,55 +654,155 @@ function handleLifecycleEvent(event, context) {
|
|
|
762
654
|
if (event.type === "auto_retry_start") {
|
|
763
655
|
context.runState.retryCount += 1;
|
|
764
656
|
log.logWarning(`Retrying (${event.attempt}/${event.maxAttempts})`, event.errorMessage);
|
|
765
|
-
const text = `_Retrying (${event.attempt}/${event.maxAttempts})..._`;
|
|
766
|
-
context.queue.enqueue(() => context.responder.respond(text), "retry");
|
|
767
657
|
return;
|
|
768
658
|
}
|
|
769
659
|
context.runState.budgetExceeded = true;
|
|
770
660
|
log.logWarning("Run stopped by budget circuit breaker", `${event.reason} (tokens=${event.tokens}, cost=${event.costUsd.toFixed(2)}, calls=${event.llmCalls}, ${event.durationMs}ms)`);
|
|
771
|
-
const text = `_Stopped: run budget exceeded (${event.reason})_`;
|
|
772
|
-
context.queue.enqueue(() => context.responder.respondDiagnostic(text, { style: "error" }), "budget exceeded");
|
|
773
661
|
}
|
|
774
|
-
function
|
|
662
|
+
function observeHarnessEvent(event, context) {
|
|
775
663
|
switch (event.type) {
|
|
776
664
|
case "tool_execution_start":
|
|
777
|
-
|
|
778
|
-
return;
|
|
779
|
-
case "tool_execution_update":
|
|
780
|
-
handleToolUpdate(event, context);
|
|
665
|
+
observeToolStart(event, context);
|
|
781
666
|
return;
|
|
782
667
|
case "tool_execution_end":
|
|
783
|
-
|
|
668
|
+
observeToolEnd(event, context);
|
|
784
669
|
return;
|
|
785
670
|
case "message_start":
|
|
786
|
-
|
|
671
|
+
observeMessageStart(event, context);
|
|
787
672
|
return;
|
|
788
673
|
case "message_update":
|
|
789
|
-
|
|
674
|
+
observeMessageUpdate(event, context);
|
|
790
675
|
return;
|
|
791
676
|
case "message_end":
|
|
792
|
-
|
|
677
|
+
observeMessageEnd(event, context);
|
|
793
678
|
return;
|
|
794
679
|
case "compaction_start":
|
|
795
680
|
case "compaction_end":
|
|
796
681
|
case "auto_retry_start":
|
|
797
682
|
case "budget_exceeded":
|
|
798
|
-
|
|
683
|
+
observeLifecycleEvent(event, context);
|
|
799
684
|
return;
|
|
800
685
|
default:
|
|
801
686
|
return;
|
|
802
687
|
}
|
|
803
688
|
}
|
|
689
|
+
function presentToolStarted(event, context) {
|
|
690
|
+
const { runState, responder, queue } = context;
|
|
691
|
+
if (event.toolName === START_TASK_TOOL || event.toolName === TASK_STATUS_TOOL)
|
|
692
|
+
return;
|
|
693
|
+
runState.answerStreamStarted = false;
|
|
694
|
+
runState.toolProgress.set(event.toolCallId, { label: event.label, status: "running" });
|
|
695
|
+
if (event.toolName === "subagent") {
|
|
696
|
+
runState.subagentToolCalls.add(event.toolCallId);
|
|
697
|
+
return;
|
|
698
|
+
}
|
|
699
|
+
queue.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
|
|
700
|
+
}
|
|
701
|
+
function presentSubagentProgress(event, context) {
|
|
702
|
+
context.runState.subagentProgress.set(event.toolCallId, event.snapshot);
|
|
703
|
+
context.runState.subagentToolCalls.add(event.toolCallId);
|
|
704
|
+
context.runState.suppressResponseDeltas = true;
|
|
705
|
+
scheduleToolProgressUpdate(context.responder, context.runState);
|
|
706
|
+
}
|
|
707
|
+
function presentToolEnded(event, context) {
|
|
708
|
+
const { runState, responder } = context;
|
|
709
|
+
if (event.toolName === START_TASK_TOOL)
|
|
710
|
+
return;
|
|
711
|
+
const progress = runState.toolProgress.get(event.toolCallId);
|
|
712
|
+
if (progress)
|
|
713
|
+
progress.status = event.isError ? "error" : "done";
|
|
714
|
+
const subagentProgress = runState.subagentProgress.get(event.toolCallId);
|
|
715
|
+
if (subagentProgress) {
|
|
716
|
+
runState.subagentProgress.set(event.toolCallId, settleSubagentProgress(subagentProgress, event.isError));
|
|
717
|
+
}
|
|
718
|
+
if (event.toolName !== TASK_STATUS_TOOL)
|
|
719
|
+
flushToolProgressUpdate(responder, runState);
|
|
720
|
+
const completedProgress = runState.subagentProgress.get(event.toolCallId);
|
|
721
|
+
if (completedProgress)
|
|
722
|
+
runState.completedSubagentProgress.push(completedProgress);
|
|
723
|
+
runState.subagentProgress.delete(event.toolCallId);
|
|
724
|
+
}
|
|
725
|
+
function presentAssistantDelta(event, context) {
|
|
726
|
+
const { runState } = context;
|
|
727
|
+
if (!context.responder.appendResponseDelta || runState.suppressResponseDeltas)
|
|
728
|
+
return;
|
|
729
|
+
const delta = runState.answerStreamStarted
|
|
730
|
+
? event.delta
|
|
731
|
+
: formatResponseWithToolProgress(event.delta, runState);
|
|
732
|
+
runState.answerStreamStarted = true;
|
|
733
|
+
context.queue.enqueue(async () => {
|
|
734
|
+
await context.responder.appendResponseDelta?.(delta);
|
|
735
|
+
}, "response delta");
|
|
736
|
+
}
|
|
737
|
+
function presentThinking(thinking, context) {
|
|
738
|
+
log.logThinking(context.logCtx, thinking);
|
|
739
|
+
context.queue.enqueue(() => context.responder.respond(`_${thinking}_`), "thinking main");
|
|
740
|
+
context.queue.enqueue(() => context.responder.respondDiagnostic(`_${thinking}_`), "thinking diagnostic");
|
|
741
|
+
}
|
|
742
|
+
function presentFinalText(text, context) {
|
|
743
|
+
const finalText = appendTriggerAttribution(formatResponseWithToolProgress(text, context.runState), context.runState.triggerAttribution);
|
|
744
|
+
log.logResponse(context.logCtx, text);
|
|
745
|
+
if (context.runState.completedSubagentProgress.length > 0)
|
|
746
|
+
return;
|
|
747
|
+
if (context.responder.finishResponse) {
|
|
748
|
+
context.queue.enqueue(async () => {
|
|
749
|
+
await context.responder.finishResponse?.(finalText);
|
|
750
|
+
}, "response finish");
|
|
751
|
+
}
|
|
752
|
+
else {
|
|
753
|
+
context.queue.enqueue(() => context.responder.respond(finalText), "response main");
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
function presentAssistantMessage(event, context) {
|
|
757
|
+
for (const thinking of event.thinking)
|
|
758
|
+
presentThinking(thinking, context);
|
|
759
|
+
if (!event.text.trim() || event.callsTools || context.runState.finalResponseHandledByTool)
|
|
760
|
+
return;
|
|
761
|
+
presentFinalText(event.text, context);
|
|
762
|
+
}
|
|
763
|
+
function presentRunEvent(event, context) {
|
|
764
|
+
switch (event.type) {
|
|
765
|
+
case "tool_started":
|
|
766
|
+
presentToolStarted(event, context);
|
|
767
|
+
return;
|
|
768
|
+
case "subagent_progress":
|
|
769
|
+
presentSubagentProgress(event, context);
|
|
770
|
+
return;
|
|
771
|
+
case "tool_ended":
|
|
772
|
+
presentToolEnded(event, context);
|
|
773
|
+
return;
|
|
774
|
+
case "assistant_delta":
|
|
775
|
+
presentAssistantDelta(event, context);
|
|
776
|
+
return;
|
|
777
|
+
case "assistant_message":
|
|
778
|
+
presentAssistantMessage(event, context);
|
|
779
|
+
return;
|
|
780
|
+
case "compaction_started":
|
|
781
|
+
context.queue.enqueue(() => context.responder.respond("_Compacting context..._"), "compaction start");
|
|
782
|
+
return;
|
|
783
|
+
case "retry_started": {
|
|
784
|
+
const text = `_Retrying (${event.attempt}/${event.maxAttempts})..._`;
|
|
785
|
+
context.queue.enqueue(() => context.responder.respond(text), "retry");
|
|
786
|
+
return;
|
|
787
|
+
}
|
|
788
|
+
case "budget_exceeded": {
|
|
789
|
+
const text = `_Stopped: run budget exceeded (${event.reason})_`;
|
|
790
|
+
context.queue.enqueue(() => context.responder.respondDiagnostic(text, { style: "error" }), "budget exceeded");
|
|
791
|
+
return;
|
|
792
|
+
}
|
|
793
|
+
case "run_started":
|
|
794
|
+
case "run_ended":
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
804
798
|
export function attachSessionEventHandlers(params) {
|
|
805
799
|
const { session, runState, model, agentConfig, platformToolRoles } = params;
|
|
806
800
|
session.subscribe((event) => {
|
|
807
801
|
if (!runState.responder || !runState.logCtx || !runState.queue)
|
|
808
802
|
return;
|
|
809
|
-
|
|
803
|
+
observeHarnessEvent(event, {
|
|
810
804
|
runState,
|
|
811
|
-
responder: runState.responder,
|
|
812
805
|
logCtx: runState.logCtx,
|
|
813
|
-
queue: runState.queue,
|
|
814
806
|
baseAttrs: {
|
|
815
807
|
channel_id: runState.logCtx.conversationId,
|
|
816
808
|
session_id: runState.logCtx.sessionId,
|
|
@@ -819,6 +811,16 @@ export function attachSessionEventHandlers(params) {
|
|
|
819
811
|
agentConfig,
|
|
820
812
|
platformToolRoles,
|
|
821
813
|
});
|
|
814
|
+
const runEvent = toRunEvent(event);
|
|
815
|
+
if (!runEvent)
|
|
816
|
+
return;
|
|
817
|
+
runState.publishRunEvent?.(runEvent);
|
|
818
|
+
presentRunEvent(runEvent, {
|
|
819
|
+
runState,
|
|
820
|
+
responder: runState.responder,
|
|
821
|
+
logCtx: runState.logCtx,
|
|
822
|
+
queue: runState.queue,
|
|
823
|
+
});
|
|
822
824
|
});
|
|
823
825
|
}
|
|
824
826
|
//# sourceMappingURL=presenter.js.map
|