@botbotgo/agent-harness 0.0.341 → 0.0.342
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/cli/chat-stream.js
CHANGED
|
@@ -22,6 +22,8 @@ export async function streamChatMessage(input) {
|
|
|
22
22
|
let liveRequestAnnotations = [];
|
|
23
23
|
let persistedRequestTreeEventCount = 0;
|
|
24
24
|
let persistedRequestTreeTodoSignature = "";
|
|
25
|
+
let previousTodoStatuses = new Map();
|
|
26
|
+
const renderedTodoTransitionLines = new Set();
|
|
25
27
|
const requestTreeRenderThrottleMs = 75;
|
|
26
28
|
let suppressRequestTreeRendering = false;
|
|
27
29
|
let lastStableRequestTreeKey;
|
|
@@ -193,6 +195,46 @@ export async function streamChatMessage(input) {
|
|
|
193
195
|
return true;
|
|
194
196
|
};
|
|
195
197
|
const formatAgentProgressLabel = (agentId) => agentId && agentId.trim().length > 0 ? ` agent:${agentId}` : "";
|
|
198
|
+
const buildTodoTransitionKey = (todo) => todo.key || todo.id || `content:${todo.content.trim().toLowerCase()}`;
|
|
199
|
+
const readTerminalTodoTransitionLabel = (status) => {
|
|
200
|
+
if (status === "completed") {
|
|
201
|
+
return "completed";
|
|
202
|
+
}
|
|
203
|
+
if (status === "failed") {
|
|
204
|
+
return "failed";
|
|
205
|
+
}
|
|
206
|
+
if (status === "cancelled") {
|
|
207
|
+
return "cancelled";
|
|
208
|
+
}
|
|
209
|
+
return null;
|
|
210
|
+
};
|
|
211
|
+
const writeTodoTransitionProgress = (snapshot) => {
|
|
212
|
+
const nextStatuses = new Map();
|
|
213
|
+
const lines = [];
|
|
214
|
+
for (const todo of snapshot.plan.items) {
|
|
215
|
+
const key = buildTodoTransitionKey(todo);
|
|
216
|
+
nextStatuses.set(key, todo.status);
|
|
217
|
+
const label = readTerminalTodoTransitionLabel(todo.status);
|
|
218
|
+
if (!label) {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
const previousStatus = previousTodoStatuses.get(key);
|
|
222
|
+
if (!previousStatus || previousStatus === todo.status) {
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
225
|
+
const text = `TODO ${label}: ${todo.content}.`;
|
|
226
|
+
if (renderedTodoTransitionLines.has(text)) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
renderedTodoTransitionLines.add(text);
|
|
230
|
+
lines.push(`[${formatPerfClock(Date.now())} +${formatElapsed(Date.now())}]${formatAgentProgressLabel(snapshot.agentId)} ${text}\n`);
|
|
231
|
+
}
|
|
232
|
+
previousTodoStatuses = nextStatuses;
|
|
233
|
+
if (lines.length === 0) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
writeChatStderr(lines.join(""));
|
|
237
|
+
};
|
|
196
238
|
const renderContentBlocks = (contentBlocks, agentId) => {
|
|
197
239
|
latestAgentId = agentId || latestAgentId;
|
|
198
240
|
const rendered = contentBlocks
|
|
@@ -221,6 +263,9 @@ export async function streamChatMessage(input) {
|
|
|
221
263
|
latestAgentId = snapshot.agentId || latestAgentId;
|
|
222
264
|
latestSnapshot = snapshot;
|
|
223
265
|
firstSnapshotAt ??= Date.now();
|
|
266
|
+
if (!input.requestEvents) {
|
|
267
|
+
writeTodoTransitionProgress(snapshot);
|
|
268
|
+
}
|
|
224
269
|
if (input.requestEvents && !suppressRequestTreeRendering) {
|
|
225
270
|
const now = Date.now();
|
|
226
271
|
const nextTreeKey = buildRequestSnapshotRenderKey(snapshot);
|
|
@@ -283,6 +328,9 @@ export async function streamChatMessage(input) {
|
|
|
283
328
|
if (wroteContent || wroteRenderableBlocks) {
|
|
284
329
|
return;
|
|
285
330
|
}
|
|
331
|
+
if (renderedTodoTransitionLines.has(delta.text)) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
286
334
|
const progressLine = `[${formatPerfClock(Date.now())} +${formatElapsed(Date.now())}]${formatAgentProgressLabel(delta.agentId)} ${delta.text}\n`;
|
|
287
335
|
if (input.requestEvents && input.liveRequestTree && !suppressRequestTreeRendering && lastRenderedRequestTree) {
|
|
288
336
|
liveRequestAnnotations.push(progressLine);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.342";
|
|
2
2
|
export declare const AGENT_HARNESS_RELEASE_DATE = "2026-04-24";
|
package/dist/package-version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.342";
|
|
2
2
|
export const AGENT_HARNESS_RELEASE_DATE = "2026-04-24";
|
|
@@ -363,6 +363,32 @@ function summarizePlanState(planState) {
|
|
|
363
363
|
const suffix = planState.items.length > items.length ? ` | +${planState.items.length - items.length} more` : "";
|
|
364
364
|
return `TODO: ${items.join(" | ")}${suffix}`;
|
|
365
365
|
}
|
|
366
|
+
function summarizePlanStateTerminalTransitions(previousPlanState, nextPlanState) {
|
|
367
|
+
const previousByKey = new Map((previousPlanState?.items ?? []).map((item) => [normalizePlanItemKey(item), item]));
|
|
368
|
+
const terminalLabel = (status) => {
|
|
369
|
+
switch (status) {
|
|
370
|
+
case "completed":
|
|
371
|
+
return "completed";
|
|
372
|
+
case "failed":
|
|
373
|
+
return "failed";
|
|
374
|
+
case "cancelled":
|
|
375
|
+
return "cancelled";
|
|
376
|
+
default:
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
};
|
|
380
|
+
return nextPlanState.items.flatMap((item) => {
|
|
381
|
+
const label = terminalLabel(item.status);
|
|
382
|
+
if (!label) {
|
|
383
|
+
return [];
|
|
384
|
+
}
|
|
385
|
+
const previousStatus = previousByKey.get(normalizePlanItemKey(item))?.status;
|
|
386
|
+
if (previousStatus === item.status) {
|
|
387
|
+
return [];
|
|
388
|
+
}
|
|
389
|
+
return [`TODO ${label}: ${item.content}.`];
|
|
390
|
+
});
|
|
391
|
+
}
|
|
366
392
|
function createSurfaceCommentary(surfaceItem) {
|
|
367
393
|
const name = normalizeCommentaryText(surfaceItem.name);
|
|
368
394
|
if (!name) {
|
|
@@ -574,12 +600,16 @@ export async function* streamHarnessRun(options) {
|
|
|
574
600
|
const mergedPlanState = mergePartialPlanState(currentPlanState, upstreamPlanState);
|
|
575
601
|
const signature = buildPlanStateSignature(mergedPlanState);
|
|
576
602
|
if (signature !== lastPlanStateSignature && shouldEmitPlanState(currentPlanState, mergedPlanState)) {
|
|
603
|
+
const previousPlanState = currentPlanState;
|
|
577
604
|
planStateVersion = mergedPlanState.version;
|
|
578
605
|
lastPlanStateSignature = signature;
|
|
579
606
|
currentPlanState = mergedPlanState;
|
|
580
607
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, mergedPlanState)) {
|
|
581
608
|
yield item;
|
|
582
609
|
}
|
|
610
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, mergedPlanState)) {
|
|
611
|
+
yield* emitCommentary(commentary);
|
|
612
|
+
}
|
|
583
613
|
const commentary = summarizePlanState(mergedPlanState);
|
|
584
614
|
if (commentary) {
|
|
585
615
|
yield* emitCommentary(commentary);
|
|
@@ -733,11 +763,15 @@ export async function* streamHarnessRun(options) {
|
|
|
733
763
|
const mergedPlanState = mergePartialPlanState(currentPlanState, planState);
|
|
734
764
|
const signature = buildPlanStateSignature(mergedPlanState);
|
|
735
765
|
if (signature !== lastPlanStateSignature && shouldEmitPlanState(currentPlanState, mergedPlanState)) {
|
|
766
|
+
const previousPlanState = currentPlanState;
|
|
736
767
|
lastPlanStateSignature = signature;
|
|
737
768
|
currentPlanState = mergedPlanState;
|
|
738
769
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, mergedPlanState)) {
|
|
739
770
|
yield item;
|
|
740
771
|
}
|
|
772
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, mergedPlanState)) {
|
|
773
|
+
yield* emitCommentary(commentary);
|
|
774
|
+
}
|
|
741
775
|
const commentary = summarizePlanState(mergedPlanState);
|
|
742
776
|
if (commentary) {
|
|
743
777
|
yield* emitCommentary(commentary);
|
|
@@ -751,12 +785,16 @@ export async function* streamHarnessRun(options) {
|
|
|
751
785
|
const reconciledPlanState = reconcilePlanStateToTerminalStatus(currentPlanState, terminalStructuredStatus, new Date().toISOString());
|
|
752
786
|
const signature = buildPlanStateSignature(reconciledPlanState);
|
|
753
787
|
if (signature !== lastPlanStateSignature) {
|
|
788
|
+
const previousPlanState = currentPlanState;
|
|
754
789
|
planStateVersion = reconciledPlanState.version;
|
|
755
790
|
lastPlanStateSignature = signature;
|
|
756
791
|
currentPlanState = reconciledPlanState;
|
|
757
792
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, reconciledPlanState)) {
|
|
758
793
|
yield item;
|
|
759
794
|
}
|
|
795
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, reconciledPlanState)) {
|
|
796
|
+
yield* emitCommentary(commentary);
|
|
797
|
+
}
|
|
760
798
|
const commentary = summarizePlanState(reconciledPlanState);
|
|
761
799
|
if (commentary) {
|
|
762
800
|
yield* emitCommentary(commentary);
|
|
@@ -816,12 +854,16 @@ export async function* streamHarnessRun(options) {
|
|
|
816
854
|
const mergedPlanState = mergePartialPlanState(currentPlanState, finalPlanState);
|
|
817
855
|
const signature = buildPlanStateSignature(mergedPlanState);
|
|
818
856
|
if (signature !== lastPlanStateSignature && shouldEmitPlanState(currentPlanState, mergedPlanState)) {
|
|
857
|
+
const previousPlanState = currentPlanState;
|
|
819
858
|
planStateVersion = mergedPlanState.version;
|
|
820
859
|
lastPlanStateSignature = signature;
|
|
821
860
|
currentPlanState = mergedPlanState;
|
|
822
861
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, mergedPlanState)) {
|
|
823
862
|
yield item;
|
|
824
863
|
}
|
|
864
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, mergedPlanState)) {
|
|
865
|
+
yield* emitCommentary(commentary);
|
|
866
|
+
}
|
|
825
867
|
const commentary = summarizePlanState(mergedPlanState);
|
|
826
868
|
if (commentary) {
|
|
827
869
|
yield* emitCommentary(commentary);
|
|
@@ -834,12 +876,16 @@ export async function* streamHarnessRun(options) {
|
|
|
834
876
|
const reconciledPlanState = reconcilePlanStateToTerminalStatus(currentPlanState, terminalStructuredStatus, new Date().toISOString());
|
|
835
877
|
const signature = buildPlanStateSignature(reconciledPlanState);
|
|
836
878
|
if (signature !== lastPlanStateSignature) {
|
|
879
|
+
const previousPlanState = currentPlanState;
|
|
837
880
|
planStateVersion = reconciledPlanState.version;
|
|
838
881
|
lastPlanStateSignature = signature;
|
|
839
882
|
currentPlanState = reconciledPlanState;
|
|
840
883
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, reconciledPlanState)) {
|
|
841
884
|
yield item;
|
|
842
885
|
}
|
|
886
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, reconciledPlanState)) {
|
|
887
|
+
yield* emitCommentary(commentary);
|
|
888
|
+
}
|
|
843
889
|
const commentary = summarizePlanState(reconciledPlanState);
|
|
844
890
|
if (commentary) {
|
|
845
891
|
yield* emitCommentary(commentary);
|
|
@@ -852,12 +898,16 @@ export async function* streamHarnessRun(options) {
|
|
|
852
898
|
const reconciledPlanState = reconcilePlanStateToTerminalStatus(currentPlanState, "completed", new Date().toISOString());
|
|
853
899
|
const signature = buildPlanStateSignature(reconciledPlanState);
|
|
854
900
|
if (signature !== lastPlanStateSignature) {
|
|
901
|
+
const previousPlanState = currentPlanState;
|
|
855
902
|
planStateVersion = reconciledPlanState.version;
|
|
856
903
|
lastPlanStateSignature = signature;
|
|
857
904
|
currentPlanState = reconciledPlanState;
|
|
858
905
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, reconciledPlanState)) {
|
|
859
906
|
yield item;
|
|
860
907
|
}
|
|
908
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, reconciledPlanState)) {
|
|
909
|
+
yield* emitCommentary(commentary);
|
|
910
|
+
}
|
|
861
911
|
const commentary = summarizePlanState(reconciledPlanState);
|
|
862
912
|
if (commentary) {
|
|
863
913
|
yield* emitCommentary(commentary);
|
|
@@ -916,12 +966,16 @@ export async function* streamHarnessRun(options) {
|
|
|
916
966
|
const reconciledPlanState = reconcilePlanStateToTerminalStatus(currentPlanState, terminalStructuredStatus, new Date().toISOString());
|
|
917
967
|
const signature = buildPlanStateSignature(reconciledPlanState);
|
|
918
968
|
if (signature !== lastPlanStateSignature) {
|
|
969
|
+
const previousPlanState = currentPlanState;
|
|
919
970
|
planStateVersion = reconciledPlanState.version;
|
|
920
971
|
lastPlanStateSignature = signature;
|
|
921
972
|
currentPlanState = reconciledPlanState;
|
|
922
973
|
for (const item of await emitPlanStateUpdate(options, currentAgentId, reconciledPlanState)) {
|
|
923
974
|
yield item;
|
|
924
975
|
}
|
|
976
|
+
for (const commentary of summarizePlanStateTerminalTransitions(previousPlanState, reconciledPlanState)) {
|
|
977
|
+
yield* emitCommentary(commentary);
|
|
978
|
+
}
|
|
925
979
|
const commentary = summarizePlanState(reconciledPlanState);
|
|
926
980
|
if (commentary) {
|
|
927
981
|
yield* emitCommentary(commentary);
|