@botbotgo/agent-harness 0.0.393 → 0.0.394

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.
@@ -1,2 +1,2 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.393";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.394";
2
2
  export declare const AGENT_HARNESS_RELEASE_DATE = "2026-05-02";
@@ -1,2 +1,2 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.393";
1
+ export const AGENT_HARNESS_VERSION = "0.0.394";
2
2
  export const AGENT_HARNESS_RELEASE_DATE = "2026-05-02";
@@ -5,6 +5,7 @@ import { buildRawModelMessages } from "../model/message-assembly.js";
5
5
  import { projectRuntimeStreamEvent, createStreamEventProjectionState } from "../stream-event-projection.js";
6
6
  import { projectTextStreamChunks } from "../stream-text-consumption.js";
7
7
  import { computeRemainingTimeoutMs } from "../resilience.js";
8
+ import { stringifyToolOutput } from "../tool/tool-arguments.js";
8
9
  import { UPSTREAM_REQUEST_CONFIG_KEY, UPSTREAM_SESSION_CONFIG_KEY } from "../upstream-configurable-keys.js";
9
10
  export class ExecutionReconciliationError extends Error {
10
11
  constructor(message) {
@@ -164,6 +165,26 @@ function hasCompletedPlanWithEvidence(evidence) {
164
165
  && !hasMissingDelegatedExecutionEvidence(evidence)
165
166
  && !hasMissingDelegatedFindings(evidence);
166
167
  }
168
+ function buildDeterministicFinalFromStreamToolEvidence(executedToolResults) {
169
+ const evidence = executedToolResults
170
+ .filter((item) => item.isError !== true && !isPlanToolName(item.toolName))
171
+ .map((item) => {
172
+ const visible = toVisibleContent(item.output);
173
+ const raw = visible || stringifyToolOutput(item.output).trim();
174
+ const clipped = raw.length > 4000 ? `${raw.slice(0, 4000)}\n... [truncated]` : raw;
175
+ return `## ${item.toolName}\n${clipped}`;
176
+ });
177
+ return [
178
+ "Status: completed",
179
+ "",
180
+ "Summary:",
181
+ "- Completed the required TODO burn down after collecting tool evidence.",
182
+ "- Returning an evidence-grounded deterministic summary because the streamed model did not produce a clean final synthesis before the required plan completed.",
183
+ "",
184
+ "Evidence:",
185
+ evidence.length > 0 ? evidence.join("\n\n") : "(no non-planning tool evidence captured)",
186
+ ].join("\n");
187
+ }
167
188
  function readBindingExecutionParams(binding) {
168
189
  const params = binding.execution?.params ?? binding.deepAgentParams ?? binding.langchainAgentParams;
169
190
  return {
@@ -498,6 +519,7 @@ export async function* streamRuntimeExecution(options) {
498
519
  try {
499
520
  let sawCompletedPlanToolResult = false;
500
521
  let sawSuccessfulNonTodoToolResult = false;
522
+ const streamedToolResults = [];
501
523
  for await (const event of options.iterateWithTimeout(events, options.streamIdleTimeoutMs, "agent streamEvents", options.streamDeadlineAt, options.invokeTimeoutMs)) {
502
524
  const projectedChunks = projectRuntimeStreamEvent({
503
525
  event,
@@ -522,6 +544,13 @@ export async function* streamRuntimeExecution(options) {
522
544
  if (chunk.kind === "tool-result" && chunk.isError === true && isRetrySafeInvalidToolSelectionError(chunk.output)) {
523
545
  sawRetrySafeInvalidToolSelectionError = true;
524
546
  }
547
+ if (chunk.kind === "tool-result") {
548
+ streamedToolResults.push({
549
+ toolName: chunk.toolName,
550
+ output: chunk.output,
551
+ isError: chunk.isError,
552
+ });
553
+ }
525
554
  if (chunk.kind === "tool-result" && !isPlanToolName(chunk.toolName) && chunk.isError !== true) {
526
555
  sawSuccessfulNonTodoToolResult = true;
527
556
  }
@@ -534,23 +563,25 @@ export async function* streamRuntimeExecution(options) {
534
563
  if (eventContainsNonTodoToolResult || eventContainsNonRetrySafeChunk) {
535
564
  emittedUnsafeStreamSideEffects = true;
536
565
  }
537
- if (chunk.kind === "content" && (shouldDeferStreamContent() || projectionState.hasFailedTaskDelegation)) {
566
+ const shouldDeferRequiredPlanContent = requiresPlanEvidence(options.binding)
567
+ && projectionState.sawPlanState
568
+ && !hasCompletedPlanWithEvidence(buildExecutionRecoveryEvidence({ projectionState }));
569
+ if (chunk.kind === "content"
570
+ && (shouldDeferStreamContent() || projectionState.hasFailedTaskDelegation || shouldDeferRequiredPlanContent)) {
538
571
  deferredStreamContent.push(chunk);
539
572
  continue;
540
573
  }
541
574
  yield chunk;
542
575
  }
543
576
  if (requiresPlanEvidence(options.binding) && sawCompletedPlanToolResult && sawSuccessfulNonTodoToolResult) {
544
- if (deferredStreamContent.length > 0) {
545
- yield* flushDeferredStreamContent();
546
- }
577
+ deferredStreamContent.length = 0;
578
+ yield { kind: "content", content: buildDeterministicFinalFromStreamToolEvidence(streamedToolResults) };
547
579
  return;
548
580
  }
549
581
  const eventExecutionEvidence = buildExecutionRecoveryEvidence({ projectionState });
550
582
  if (requiresPlanEvidence(options.binding) && hasCompletedPlanWithEvidence(eventExecutionEvidence)) {
551
- if (deferredStreamContent.length > 0) {
552
- yield* flushDeferredStreamContent();
553
- }
583
+ deferredStreamContent.length = 0;
584
+ yield { kind: "content", content: buildDeterministicFinalFromStreamToolEvidence(streamedToolResults) };
554
585
  return;
555
586
  }
556
587
  const terminalVisibleOutput = readTerminalEventVisibleOutput(event);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.393",
3
+ "version": "0.0.394",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",