@geminixiang/mikan 1.0.0-beta.80 → 1.0.0-beta.82
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 +27 -0
- package/dist/adapters/github/bot.d.ts.map +1 -1
- package/dist/adapters/github/bot.js +4 -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 +159 -142
- package/dist/harness/presenter.js.map +1 -1
- package/dist/harness/prompt.d.ts +1 -1
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +14 -21
- package/dist/harness/prompt.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 +79 -49
- 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/tools/react.d.ts +1 -0
- package/dist/harness/tools/react.d.ts.map +1 -1
- package/dist/harness/tools/react.js +3 -2
- package/dist/harness/tools/react.js.map +1 -1
- package/dist/harness/types.d.ts +61 -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,10 @@
|
|
|
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 {
|
|
6
|
+
import { toRunEvent, toolResultText } from "./run-events.js";
|
|
7
|
+
import { REACT_TOOL } from "./tools/react.js";
|
|
8
8
|
import * as log from "../log.js";
|
|
9
9
|
import { errorMessage } from "../unknown-values.js";
|
|
10
10
|
const operationSpans = new WeakMap();
|
|
@@ -53,6 +53,9 @@ function createRunStateDefaults() {
|
|
|
53
53
|
subagentToolCalls: new Set(),
|
|
54
54
|
subagentProgressShown: false,
|
|
55
55
|
suppressResponseDeltas: false,
|
|
56
|
+
answerStreamStarted: false,
|
|
57
|
+
workAcknowledged: false,
|
|
58
|
+
publishRunEvent: undefined,
|
|
56
59
|
lastSubagentProgressAt: 0,
|
|
57
60
|
toolProgressTimer: undefined,
|
|
58
61
|
totalUsage: createEmptyUsageTotals(),
|
|
@@ -92,6 +95,7 @@ export function activateRunPresentation(runState, context) {
|
|
|
92
95
|
sessionId: context.sessionUuid,
|
|
93
96
|
},
|
|
94
97
|
triggerAttribution: context.triggerAttribution,
|
|
98
|
+
publishRunEvent: context.publishRunEvent,
|
|
95
99
|
});
|
|
96
100
|
const { responder } = context;
|
|
97
101
|
let queueChain = Promise.resolve();
|
|
@@ -124,6 +128,7 @@ export function activateRunPresentation(runState, context) {
|
|
|
124
128
|
runState.responder = null;
|
|
125
129
|
runState.logCtx = null;
|
|
126
130
|
runState.queue = null;
|
|
131
|
+
runState.publishRunEvent = undefined;
|
|
127
132
|
},
|
|
128
133
|
};
|
|
129
134
|
}
|
|
@@ -134,14 +139,6 @@ export function getFinalAssistantText(session) {
|
|
|
134
139
|
export function isEventTriggerAttribution(triggerAttribution) {
|
|
135
140
|
return triggerAttribution?.startsWith("[event:") === true;
|
|
136
141
|
}
|
|
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
142
|
function formatToolProgress(runState) {
|
|
146
143
|
const lines = Array.from(runState.toolProgress.entries()).flatMap(([toolCallId, item]) => {
|
|
147
144
|
if (runState.subagentToolCalls.has(toolCallId))
|
|
@@ -206,14 +203,6 @@ function flushToolProgressUpdate(responder, runState) {
|
|
|
206
203
|
markSubagentProgressShown(runState, subagentProgress);
|
|
207
204
|
runState.queue?.enqueue(() => replaceResponseWithToolProgress(responder, runState, subagentProgress), "tool progress update");
|
|
208
205
|
}
|
|
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
206
|
async function finalizeErrorResponse(responder, runState, options) {
|
|
218
207
|
if (!runState.reportedLlmError) {
|
|
219
208
|
runState.reportedLlmError = true;
|
|
@@ -272,7 +261,7 @@ export async function finalizeRunResponse(responder, session, runState, options)
|
|
|
272
261
|
if (!finalText.trim())
|
|
273
262
|
return;
|
|
274
263
|
const published = await publishFinalResponse(responder, runState, finalText, options);
|
|
275
|
-
const didWork = Object.keys(session.getLastRunStats().toolCallCounts).some((name) => ![TASK_STATUS_TOOL, START_TASK_TOOL,
|
|
264
|
+
const didWork = Object.keys(session.getLastRunStats().toolCallCounts).some((name) => ![TASK_STATUS_TOOL, START_TASK_TOOL, REACT_TOOL].includes(name));
|
|
276
265
|
if (published && runState.stopReason === "stop" && (didWork || options?.initialTask))
|
|
277
266
|
await responder.notifyCompletion?.();
|
|
278
267
|
}
|
|
@@ -416,22 +405,6 @@ export async function reportUsageSummary(ctx) {
|
|
|
416
405
|
await waitForQueue();
|
|
417
406
|
}
|
|
418
407
|
}
|
|
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
408
|
function serializedLength(value) {
|
|
436
409
|
if (typeof value === "string")
|
|
437
410
|
return value.length;
|
|
@@ -455,8 +428,8 @@ function toolCategory(name, roles) {
|
|
|
455
428
|
return "platform";
|
|
456
429
|
return "function";
|
|
457
430
|
}
|
|
458
|
-
function
|
|
459
|
-
const { runState,
|
|
431
|
+
function observeToolStart(event, context) {
|
|
432
|
+
const { runState, logCtx, baseAttrs } = context;
|
|
460
433
|
const args = (event.args ?? {});
|
|
461
434
|
const label = args.label || event.toolName;
|
|
462
435
|
runState.toolCallCount += 1;
|
|
@@ -468,18 +441,6 @@ function handleToolStart(event, context) {
|
|
|
468
441
|
});
|
|
469
442
|
if (event.toolName === START_TASK_TOOL)
|
|
470
443
|
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
444
|
spansFor(runState).tools.set(event.toolCallId, startOperationSpan(`execute_tool ${event.toolName}`, metricAttributes({
|
|
484
445
|
"gen_ai.operation.name": "execute_tool",
|
|
485
446
|
"gen_ai.tool.name": event.toolName,
|
|
@@ -492,15 +453,6 @@ function handleToolStart(event, context) {
|
|
|
492
453
|
addLifecycleEvent("agent.tool.started", { tool: event.toolName, ...baseAttrs });
|
|
493
454
|
log.logToolStart(logCtx, event.toolName, label, event.args);
|
|
494
455
|
}
|
|
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
456
|
function recordToolMetrics(event, durationMs, context) {
|
|
505
457
|
recordCounter("agent.tool.calls", 1, metricAttributes({
|
|
506
458
|
tool: event.toolName,
|
|
@@ -518,16 +470,15 @@ function recordToolMetrics(event, durationMs, context) {
|
|
|
518
470
|
...context.baseAttrs,
|
|
519
471
|
});
|
|
520
472
|
}
|
|
521
|
-
function
|
|
522
|
-
const { runState,
|
|
523
|
-
const resultStr = extractToolResultText(event.result);
|
|
473
|
+
function observeToolEnd(event, context) {
|
|
474
|
+
const { runState, logCtx } = context;
|
|
524
475
|
const outputCharacters = serializedLength(event.result);
|
|
525
476
|
runState.toolOutputCharacters += outputCharacters;
|
|
526
477
|
if (event.isError)
|
|
527
478
|
runState.toolErrorCount += 1;
|
|
528
479
|
const pending = runState.pendingTools.get(event.toolCallId);
|
|
480
|
+
runState.pendingTools.delete(event.toolCallId);
|
|
529
481
|
if (event.toolName === START_TASK_TOOL) {
|
|
530
|
-
runState.pendingTools.delete(event.toolCallId);
|
|
531
482
|
if (!event.isError)
|
|
532
483
|
runState.finalResponseHandledByTool = true;
|
|
533
484
|
else
|
|
@@ -540,20 +491,6 @@ function handleToolEnd(event, context) {
|
|
|
540
491
|
});
|
|
541
492
|
return;
|
|
542
493
|
}
|
|
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
494
|
const durationMs = pending ? Date.now() - pending.startTime : 0;
|
|
558
495
|
const toolSpan = spansFor(runState).tools.get(event.toolCallId);
|
|
559
496
|
toolSpan?.end({
|
|
@@ -570,6 +507,7 @@ function handleToolEnd(event, context) {
|
|
|
570
507
|
});
|
|
571
508
|
spansFor(runState).tools.delete(event.toolCallId);
|
|
572
509
|
recordToolMetrics(event, durationMs, context);
|
|
510
|
+
const resultStr = toolResultText(event.result);
|
|
573
511
|
if (event.isError) {
|
|
574
512
|
log.logToolError(logCtx, event.toolName, durationMs, resultStr);
|
|
575
513
|
return;
|
|
@@ -579,7 +517,7 @@ function handleToolEnd(event, context) {
|
|
|
579
517
|
runState.finalResponseHandledByTool = true;
|
|
580
518
|
}
|
|
581
519
|
}
|
|
582
|
-
function
|
|
520
|
+
function observeMessageStart(event, context) {
|
|
583
521
|
if (event.message.role !== "assistant")
|
|
584
522
|
return;
|
|
585
523
|
context.runState.llmCallCount += 1;
|
|
@@ -603,7 +541,7 @@ function handleMessageStart(event, context) {
|
|
|
603
541
|
});
|
|
604
542
|
log.logResponseStart(context.logCtx);
|
|
605
543
|
}
|
|
606
|
-
function
|
|
544
|
+
function observeMessageUpdate(event, context) {
|
|
607
545
|
const update = event.assistantMessageEvent;
|
|
608
546
|
if (update.type !== "text_delta" || !update.delta)
|
|
609
547
|
return;
|
|
@@ -612,11 +550,6 @@ function handleMessageUpdate(event, context) {
|
|
|
612
550
|
llmEntry.firstTokenAt = Date.now();
|
|
613
551
|
context.runState.firstTokenLatencyMs ??= llmEntry.firstTokenAt - llmEntry.startedAt;
|
|
614
552
|
}
|
|
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
553
|
}
|
|
621
554
|
function recordAssistantUsage(message, context) {
|
|
622
555
|
if (!message.usage)
|
|
@@ -661,43 +594,7 @@ function recordAssistantUsage(message, context) {
|
|
|
661
594
|
cost_total_usd: message.usage.cost.total,
|
|
662
595
|
});
|
|
663
596
|
}
|
|
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) {
|
|
597
|
+
function observeMessageEnd(event, context) {
|
|
701
598
|
if (event.message.role !== "assistant")
|
|
702
599
|
return;
|
|
703
600
|
const message = event.message;
|
|
@@ -740,14 +637,11 @@ function handleMessageEnd(event, context) {
|
|
|
740
637
|
}),
|
|
741
638
|
error: message.errorMessage ? operationError("LLMError") : undefined,
|
|
742
639
|
});
|
|
743
|
-
presentAssistantMessage(message, context);
|
|
744
640
|
}
|
|
745
|
-
function
|
|
641
|
+
function observeLifecycleEvent(event, context) {
|
|
746
642
|
if (event.type === "compaction_start") {
|
|
747
643
|
context.runState.compactionCount += 1;
|
|
748
|
-
const text = "_Compacting context..._";
|
|
749
644
|
log.logInfo(`Auto-compaction started (reason: ${event.reason})`);
|
|
750
|
-
context.queue.enqueue(() => context.responder.respond(text), "compaction start");
|
|
751
645
|
return;
|
|
752
646
|
}
|
|
753
647
|
if (event.type === "compaction_end") {
|
|
@@ -762,55 +656,168 @@ function handleLifecycleEvent(event, context) {
|
|
|
762
656
|
if (event.type === "auto_retry_start") {
|
|
763
657
|
context.runState.retryCount += 1;
|
|
764
658
|
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
659
|
return;
|
|
768
660
|
}
|
|
769
661
|
context.runState.budgetExceeded = true;
|
|
770
662
|
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
663
|
}
|
|
774
|
-
function
|
|
664
|
+
function observeHarnessEvent(event, context) {
|
|
775
665
|
switch (event.type) {
|
|
776
666
|
case "tool_execution_start":
|
|
777
|
-
|
|
778
|
-
return;
|
|
779
|
-
case "tool_execution_update":
|
|
780
|
-
handleToolUpdate(event, context);
|
|
667
|
+
observeToolStart(event, context);
|
|
781
668
|
return;
|
|
782
669
|
case "tool_execution_end":
|
|
783
|
-
|
|
670
|
+
observeToolEnd(event, context);
|
|
784
671
|
return;
|
|
785
672
|
case "message_start":
|
|
786
|
-
|
|
673
|
+
observeMessageStart(event, context);
|
|
787
674
|
return;
|
|
788
675
|
case "message_update":
|
|
789
|
-
|
|
676
|
+
observeMessageUpdate(event, context);
|
|
790
677
|
return;
|
|
791
678
|
case "message_end":
|
|
792
|
-
|
|
679
|
+
observeMessageEnd(event, context);
|
|
793
680
|
return;
|
|
794
681
|
case "compaction_start":
|
|
795
682
|
case "compaction_end":
|
|
796
683
|
case "auto_retry_start":
|
|
797
684
|
case "budget_exceeded":
|
|
798
|
-
|
|
685
|
+
observeLifecycleEvent(event, context);
|
|
799
686
|
return;
|
|
800
687
|
default:
|
|
801
688
|
return;
|
|
802
689
|
}
|
|
803
690
|
}
|
|
691
|
+
const WORK_ACKNOWLEDGEMENT_REACTION = "saluting_face";
|
|
692
|
+
const TOOLS_THAT_ARE_NOT_WORK = new Set([START_TASK_TOOL, TASK_STATUS_TOOL, REACT_TOOL]);
|
|
693
|
+
function acknowledgeWorkOnce(context) {
|
|
694
|
+
const { runState, responder } = context;
|
|
695
|
+
if (runState.workAcknowledged || !responder.react)
|
|
696
|
+
return;
|
|
697
|
+
runState.workAcknowledged = true;
|
|
698
|
+
responder.react(WORK_ACKNOWLEDGEMENT_REACTION).catch((error) => {
|
|
699
|
+
log.logWarning("Could not acknowledge work with a reaction", errorMessage(error));
|
|
700
|
+
});
|
|
701
|
+
}
|
|
702
|
+
function presentToolStarted(event, context) {
|
|
703
|
+
const { runState, responder, queue } = context;
|
|
704
|
+
if (!TOOLS_THAT_ARE_NOT_WORK.has(event.toolName))
|
|
705
|
+
acknowledgeWorkOnce(context);
|
|
706
|
+
if (event.toolName === START_TASK_TOOL || event.toolName === TASK_STATUS_TOOL)
|
|
707
|
+
return;
|
|
708
|
+
runState.answerStreamStarted = false;
|
|
709
|
+
runState.toolProgress.set(event.toolCallId, { label: event.label, status: "running" });
|
|
710
|
+
if (event.toolName === "subagent") {
|
|
711
|
+
runState.subagentToolCalls.add(event.toolCallId);
|
|
712
|
+
return;
|
|
713
|
+
}
|
|
714
|
+
queue.enqueue(() => replaceResponseWithToolProgress(responder, runState), "tool progress update");
|
|
715
|
+
}
|
|
716
|
+
function presentSubagentProgress(event, context) {
|
|
717
|
+
context.runState.subagentProgress.set(event.toolCallId, event.snapshot);
|
|
718
|
+
context.runState.subagentToolCalls.add(event.toolCallId);
|
|
719
|
+
context.runState.suppressResponseDeltas = true;
|
|
720
|
+
scheduleToolProgressUpdate(context.responder, context.runState);
|
|
721
|
+
}
|
|
722
|
+
function presentToolEnded(event, context) {
|
|
723
|
+
const { runState, responder } = context;
|
|
724
|
+
if (event.toolName === START_TASK_TOOL)
|
|
725
|
+
return;
|
|
726
|
+
const progress = runState.toolProgress.get(event.toolCallId);
|
|
727
|
+
if (progress)
|
|
728
|
+
progress.status = event.isError ? "error" : "done";
|
|
729
|
+
const subagentProgress = runState.subagentProgress.get(event.toolCallId);
|
|
730
|
+
if (subagentProgress) {
|
|
731
|
+
runState.subagentProgress.set(event.toolCallId, settleSubagentProgress(subagentProgress, event.isError));
|
|
732
|
+
}
|
|
733
|
+
if (event.toolName !== TASK_STATUS_TOOL)
|
|
734
|
+
flushToolProgressUpdate(responder, runState);
|
|
735
|
+
const completedProgress = runState.subagentProgress.get(event.toolCallId);
|
|
736
|
+
if (completedProgress)
|
|
737
|
+
runState.completedSubagentProgress.push(completedProgress);
|
|
738
|
+
runState.subagentProgress.delete(event.toolCallId);
|
|
739
|
+
}
|
|
740
|
+
function presentAssistantDelta(event, context) {
|
|
741
|
+
const { runState } = context;
|
|
742
|
+
if (!context.responder.appendResponseDelta || runState.suppressResponseDeltas)
|
|
743
|
+
return;
|
|
744
|
+
const delta = runState.answerStreamStarted
|
|
745
|
+
? event.delta
|
|
746
|
+
: formatResponseWithToolProgress(event.delta, runState);
|
|
747
|
+
runState.answerStreamStarted = true;
|
|
748
|
+
context.queue.enqueue(async () => {
|
|
749
|
+
await context.responder.appendResponseDelta?.(delta);
|
|
750
|
+
}, "response delta");
|
|
751
|
+
}
|
|
752
|
+
function presentThinking(thinking, context) {
|
|
753
|
+
log.logThinking(context.logCtx, thinking);
|
|
754
|
+
context.queue.enqueue(() => context.responder.respond(`_${thinking}_`), "thinking main");
|
|
755
|
+
context.queue.enqueue(() => context.responder.respondDiagnostic(`_${thinking}_`), "thinking diagnostic");
|
|
756
|
+
}
|
|
757
|
+
function presentFinalText(text, context) {
|
|
758
|
+
const finalText = appendTriggerAttribution(formatResponseWithToolProgress(text, context.runState), context.runState.triggerAttribution);
|
|
759
|
+
log.logResponse(context.logCtx, text);
|
|
760
|
+
if (context.runState.completedSubagentProgress.length > 0)
|
|
761
|
+
return;
|
|
762
|
+
if (context.responder.finishResponse) {
|
|
763
|
+
context.queue.enqueue(async () => {
|
|
764
|
+
await context.responder.finishResponse?.(finalText);
|
|
765
|
+
}, "response finish");
|
|
766
|
+
}
|
|
767
|
+
else {
|
|
768
|
+
context.queue.enqueue(() => context.responder.respond(finalText), "response main");
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
function presentAssistantMessage(event, context) {
|
|
772
|
+
for (const thinking of event.thinking)
|
|
773
|
+
presentThinking(thinking, context);
|
|
774
|
+
if (!event.text.trim() || event.callsTools || context.runState.finalResponseHandledByTool)
|
|
775
|
+
return;
|
|
776
|
+
presentFinalText(event.text, context);
|
|
777
|
+
}
|
|
778
|
+
function presentRunEvent(event, context) {
|
|
779
|
+
switch (event.type) {
|
|
780
|
+
case "tool_started":
|
|
781
|
+
presentToolStarted(event, context);
|
|
782
|
+
return;
|
|
783
|
+
case "subagent_progress":
|
|
784
|
+
presentSubagentProgress(event, context);
|
|
785
|
+
return;
|
|
786
|
+
case "tool_ended":
|
|
787
|
+
presentToolEnded(event, context);
|
|
788
|
+
return;
|
|
789
|
+
case "assistant_delta":
|
|
790
|
+
presentAssistantDelta(event, context);
|
|
791
|
+
return;
|
|
792
|
+
case "assistant_message":
|
|
793
|
+
presentAssistantMessage(event, context);
|
|
794
|
+
return;
|
|
795
|
+
case "compaction_started":
|
|
796
|
+
context.queue.enqueue(() => context.responder.respond("_Compacting context..._"), "compaction start");
|
|
797
|
+
return;
|
|
798
|
+
case "retry_started": {
|
|
799
|
+
const text = `_Retrying (${event.attempt}/${event.maxAttempts})..._`;
|
|
800
|
+
context.queue.enqueue(() => context.responder.respond(text), "retry");
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
case "budget_exceeded": {
|
|
804
|
+
const text = `_Stopped: run budget exceeded (${event.reason})_`;
|
|
805
|
+
context.queue.enqueue(() => context.responder.respondDiagnostic(text, { style: "error" }), "budget exceeded");
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
case "run_started":
|
|
809
|
+
case "run_ended":
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
804
813
|
export function attachSessionEventHandlers(params) {
|
|
805
814
|
const { session, runState, model, agentConfig, platformToolRoles } = params;
|
|
806
815
|
session.subscribe((event) => {
|
|
807
816
|
if (!runState.responder || !runState.logCtx || !runState.queue)
|
|
808
817
|
return;
|
|
809
|
-
|
|
818
|
+
observeHarnessEvent(event, {
|
|
810
819
|
runState,
|
|
811
|
-
responder: runState.responder,
|
|
812
820
|
logCtx: runState.logCtx,
|
|
813
|
-
queue: runState.queue,
|
|
814
821
|
baseAttrs: {
|
|
815
822
|
channel_id: runState.logCtx.conversationId,
|
|
816
823
|
session_id: runState.logCtx.sessionId,
|
|
@@ -819,6 +826,16 @@ export function attachSessionEventHandlers(params) {
|
|
|
819
826
|
agentConfig,
|
|
820
827
|
platformToolRoles,
|
|
821
828
|
});
|
|
829
|
+
const runEvent = toRunEvent(event);
|
|
830
|
+
if (!runEvent)
|
|
831
|
+
return;
|
|
832
|
+
runState.publishRunEvent?.(runEvent);
|
|
833
|
+
presentRunEvent(runEvent, {
|
|
834
|
+
runState,
|
|
835
|
+
responder: runState.responder,
|
|
836
|
+
logCtx: runState.logCtx,
|
|
837
|
+
queue: runState.queue,
|
|
838
|
+
});
|
|
822
839
|
});
|
|
823
840
|
}
|
|
824
841
|
//# sourceMappingURL=presenter.js.map
|