@botbotgo/agent-harness 0.0.408 → 0.0.410

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.408";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.410";
2
2
  export declare const AGENT_HARNESS_RELEASE_DATE = "2026-05-02";
@@ -1,2 +1,2 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.408";
1
+ export const AGENT_HARNESS_VERSION = "0.0.410";
2
2
  export const AGENT_HARNESS_RELEASE_DATE = "2026-05-02";
@@ -156,8 +156,11 @@ function extractLatestSuccessfulNonTodoToolResultText(executedToolResults) {
156
156
  ?? candidates.at(-1)
157
157
  ?? "";
158
158
  }
159
+ function isNonFunctionObject(value) {
160
+ return Object(value) === value && typeof value !== "function";
161
+ }
159
162
  function readSerializedMessageType(value) {
160
- if (typeof value !== "object" || value === null) {
163
+ if (!isNonFunctionObject(value)) {
161
164
  return "";
162
165
  }
163
166
  const id = value.id;
@@ -167,12 +170,12 @@ function readSerializedMessageType(value) {
167
170
  return id.map((item) => typeof item === "string" ? item : "").filter(Boolean).join(".");
168
171
  }
169
172
  function readToolMessageRecord(value) {
170
- if (typeof value !== "object" || value === null) {
173
+ if (!isNonFunctionObject(value)) {
171
174
  return null;
172
175
  }
173
176
  const typed = value;
174
177
  const messageType = readSerializedMessageType(value);
175
- const kwargs = typeof typed.kwargs === "object" && typed.kwargs !== null ? typed.kwargs : undefined;
178
+ const kwargs = isNonFunctionObject(typed.kwargs) ? typed.kwargs : undefined;
176
179
  const isToolMessage = typed.role === "tool"
177
180
  || typed.type === "tool"
178
181
  || messageType.endsWith("ToolMessage")
@@ -58,12 +58,15 @@ function isFallbackTodoCompletionToolCall(toolCall) {
58
58
  && toolCall.id.startsWith("fallback-complete-")
59
59
  && (toolCall.name === "write_todos" || toolCall.name === "tool_call_write_todos");
60
60
  }
61
+ const TOOL_OUTPUT_TRUNCATION_LIMIT = 4000;
61
62
  function buildDeterministicFinalFromToolEvidence(executedToolResults) {
62
63
  const evidence = executedToolResults
63
64
  .filter((item) => item.isError !== true && item.toolName !== "write_todos" && item.toolName !== "read_todos")
64
65
  .map((item) => {
65
66
  const output = stringifyToolOutput(item.output).trim();
66
- const clipped = output.length > 4000 ? `${output.slice(0, 4000)}\n... [truncated]` : output;
67
+ const clipped = output.length > TOOL_OUTPUT_TRUNCATION_LIMIT
68
+ ? `${output.slice(0, TOOL_OUTPUT_TRUNCATION_LIMIT)}\n... [truncated]`
69
+ : output;
67
70
  return `## ${item.toolName}\n${clipped}`;
68
71
  });
69
72
  const output = [
@@ -119,7 +122,6 @@ export async function runLocalToolInvocationLoop({ binding, request, primaryTool
119
122
  let activeRequest = request;
120
123
  let currentMessages = Array.isArray(activeRequest.messages) ? [...activeRequest.messages] : [];
121
124
  const maxToolIterations = 8;
122
- let pendingResult;
123
125
  let result;
124
126
  const toolCatalog = new Map();
125
127
  for (const tool of primaryTools) {
@@ -130,8 +132,7 @@ export async function runLocalToolInvocationLoop({ binding, request, primaryTool
130
132
  }
131
133
  }
132
134
  for (let iteration = 0; iteration < maxToolIterations; iteration += 1) {
133
- result = pendingResult ?? await callRuntimeWithToolParseRecovery(activeRequest);
134
- pendingResult = undefined;
135
+ result = await callRuntimeWithToolParseRecovery(activeRequest);
135
136
  const toolCalls = extractToolCallsFromResult(result);
136
137
  if (toolCalls.length === 0) {
137
138
  const terminalText = sanitizeVisibleText(extractVisibleOutput(result) || "");
@@ -176,7 +177,6 @@ export async function runLocalToolInvocationLoop({ binding, request, primaryTool
176
177
  return resolvedToolName !== "write_todos" && resolvedToolName !== "read_todos" && toolCall.name !== "write_todos" && toolCall.name !== "read_todos";
177
178
  })) {
178
179
  activeRequest = appendToolRecoveryInstruction(activeRequest, missingPlanRecoveryInstruction);
179
- pendingResult = undefined;
180
180
  continue;
181
181
  }
182
182
  if (!canReplayToolCallsLocally(binding, toolCalls, primaryTools, toolNameMapping, executableTools, builtinExecutableTools)) {
@@ -239,7 +239,7 @@ export async function runLocalToolInvocationLoop({ binding, request, primaryTool
239
239
  const safeToolResult = await maybePersistLargeToolOutput({
240
240
  toolName: activeExecutable.name,
241
241
  output: toolResult,
242
- toolRuntimeContext: toolRuntimeContext,
242
+ toolRuntimeContext,
243
243
  });
244
244
  executedToolResults.push({
245
245
  toolName: activeExecutable.name,
@@ -33,10 +33,7 @@ function planStateHasUnfinishedItems(planState) {
33
33
  return planState.summary.pending > 0 || planState.summary.inProgress > 0;
34
34
  }
35
35
  function planStateHasActiveItems(planState) {
36
- if (!planState) {
37
- return false;
38
- }
39
- return planState.summary.pending > 0 || planState.summary.inProgress > 0;
36
+ return planStateHasUnfinishedItems(planState);
40
37
  }
41
38
  function isSubstantiveTerminalAssistantOutput(value) {
42
39
  const normalized = sanitizeVisibleText(value).trim();
@@ -1044,7 +1041,7 @@ export async function* streamHarnessRun(options) {
1044
1041
  }
1045
1042
  currentPlanState = await refreshPlanStateFromPersistence(options, currentPlanState);
1046
1043
  const terminalAssistantPlanItemStatus = inferPlanItemStatusFromTerminalAssistantOutput(assistantOutput);
1047
- if (terminalAssistantPlanItemStatus && planStateHasActiveItems(currentPlanState)) {
1044
+ if (terminalAssistantPlanItemStatus && currentPlanState && planStateHasActiveItems(currentPlanState)) {
1048
1045
  const reconciledPlanState = reconcilePlanStateToTerminalStatus(currentPlanState, terminalAssistantPlanItemStatus, new Date().toISOString());
1049
1046
  const signature = buildPlanStateSignature(reconciledPlanState);
1050
1047
  if (signature !== lastPlanStateSignature) {
@@ -1121,7 +1121,7 @@ export class AgentHarnessRuntime {
1121
1121
  const summary = typeof latest.output === "object" && latest.output !== null
1122
1122
  ? latest.output.summary
1123
1123
  : undefined;
1124
- if (!summary || typeof summary !== "object" || summary === null) {
1124
+ if (typeof summary !== "object" || summary === null) {
1125
1125
  continue;
1126
1126
  }
1127
1127
  const candidate = summary;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.408",
3
+ "version": "0.0.410",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",