@botbotgo/agent-harness 0.0.321 → 0.0.323

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 +1 @@
1
- export declare const AGENT_HARNESS_VERSION = "0.0.320";
1
+ export declare const AGENT_HARNESS_VERSION = "0.0.322";
@@ -1 +1 @@
1
- export const AGENT_HARNESS_VERSION = "0.0.320";
1
+ export const AGENT_HARNESS_VERSION = "0.0.322";
@@ -34,6 +34,9 @@ export function normalizeWorkspaceScopedPath(rootDir, inputPath) {
34
34
  if (typeof inputPath !== "string" || inputPath.length === 0 || !path.isAbsolute(inputPath)) {
35
35
  return inputPath;
36
36
  }
37
+ if (inputPath.startsWith("/large_tool_results/")) {
38
+ throw new Error(`Path '${inputPath}' is an internal runtime spill path, not a workspace file. Do not read internal runtime spill files such as '/large_tool_results/...'. Use the preview already in context, rerun the producing tool with narrower output, or write the needed data to a workspace-relative file instead.`);
39
+ }
37
40
  if (inputPath === "/") {
38
41
  return ".";
39
42
  }
@@ -0,0 +1 @@
1
+ Do not stop at a plan or ask the user to choose the next obvious diagnostic step when the request is for deep investigation, root-cause analysis, or step-by-step execution and tool evidence already exists in the conversation. Continue the investigation yourself with the next concrete tool call. If the task is non-trivial, call write_todos, then keep executing the next diagnostic steps until you can explain the likely causes, impact, and recommended next actions.
@@ -0,0 +1 @@
1
+ The previous tool call tried to read an internal runtime spill path such as '/large_tool_results/...'. Do not read internal runtime spill files. Use the preview already present in the conversation, rerun the producing tool with narrower output if needed, or write the needed data to a workspace-relative file and read that file instead.
@@ -78,6 +78,9 @@ export function normalizeWorkspacePath(context, inputPath, fallback = ".") {
78
78
  if (!workspaceRoot || !path.isAbsolute(rawPath)) {
79
79
  return rawPath;
80
80
  }
81
+ if (rawPath.startsWith("/large_tool_results/")) {
82
+ throw new Error(`Path '${rawPath}' is an internal runtime spill path, not a workspace file. Do not read internal runtime spill files such as '/large_tool_results/...'. Use the preview already in context, rerun the producing tool with narrower output, or write the needed data to a workspace-relative file instead.`);
83
+ }
81
84
  const resolvedWorkspaceRoot = path.resolve(workspaceRoot);
82
85
  const resolvedInputPath = path.resolve(rawPath);
83
86
  if (resolvedInputPath === resolvedWorkspaceRoot || resolvedInputPath.startsWith(`${resolvedWorkspaceRoot}${path.sep}`)) {
@@ -97,6 +97,9 @@ function normalizeWorkspacePathOrThrow(backend, inputPath) {
97
97
  if (!workspaceRoot || !path.isAbsolute(inputPath)) {
98
98
  return inputPath;
99
99
  }
100
+ if (inputPath.startsWith("/large_tool_results/")) {
101
+ throw new Error(`Path '${inputPath}' is an internal runtime spill path, not a workspace file. Do not read internal runtime spill files such as '/large_tool_results/...'. Use the preview already in context, rerun the producing tool with narrower output, or write the needed data to a workspace-relative file instead.`);
102
+ }
100
103
  const normalizedWorkspaceRoot = path.resolve(workspaceRoot);
101
104
  const normalizedInputPath = path.resolve(inputPath);
102
105
  if (normalizedInputPath === normalizedWorkspaceRoot || normalizedInputPath.startsWith(`${normalizedWorkspaceRoot}${path.sep}`)) {
@@ -1,5 +1,6 @@
1
1
  export declare function isToolCallValidationFailure(error: unknown): boolean;
2
2
  export declare function isWorkspacePathScopeFailure(error: unknown): boolean;
3
+ export declare function isInternalRuntimeSpillPathFailure(error: unknown): boolean;
3
4
  export declare function isRepairableWriteTodosPlaceholderFailure(error: unknown): boolean;
4
5
  export declare function isRepairableWriteTodosContentFailure(error: unknown): boolean;
5
6
  export declare function isRepairableWriteTodosEmptyFailure(error: unknown): boolean;
@@ -11,4 +12,4 @@ export declare function resolveExecutionWithoutToolEvidenceTextInstruction(reque
11
12
  export declare function resolveToolCallRecoveryInstruction(error: unknown): string | null;
12
13
  export declare function appendToolRecoveryInstruction(input: unknown, instruction: string): unknown;
13
14
  export declare function wrapResolvedModel<T>(value: T): T;
14
- export { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION } from "../prompts/runtime-prompts.js";
15
+ export { AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION, BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION } from "../prompts/runtime-prompts.js";
@@ -1,4 +1,4 @@
1
- import { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION, } from "../prompts/runtime-prompts.js";
1
+ import { AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION, BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION, } from "../prompts/runtime-prompts.js";
2
2
  import { hasToolCalls, readTextContent, wrapNormalizedMessage } from "./output-content.js";
3
3
  function isToolCallParseFailure(error) {
4
4
  if (!(error instanceof Error))
@@ -52,6 +52,9 @@ function collectErrorMessages(error) {
52
52
  export function isWorkspacePathScopeFailure(error) {
53
53
  return collectErrorMessages(error).some((message) => /outside the workspace root|workspace-relative path/i.test(message));
54
54
  }
55
+ export function isInternalRuntimeSpillPathFailure(error) {
56
+ return collectErrorMessages(error).some((message) => /\/large_tool_results\/|internal runtime spill path/i.test(message));
57
+ }
55
58
  export function isRepairableWriteTodosPlaceholderFailure(error) {
56
59
  if (!(error instanceof Error))
57
60
  return false;
@@ -81,6 +84,7 @@ export function isToolCallRecoveryFailure(error) {
81
84
  isToolCallValidationFailure(error) ||
82
85
  isRepairableWriteTodosEmptyFailure(error) ||
83
86
  isRepairableWriteTodosPlaceholderFailure(error) ||
87
+ isInternalRuntimeSpillPathFailure(error) ||
84
88
  isWorkspacePathScopeFailure(error));
85
89
  }
86
90
  function extractMessageContent(message) {
@@ -123,6 +127,71 @@ function extractLastUserMessageText(input) {
123
127
  }
124
128
  return "";
125
129
  }
130
+ function extractAllUserMessageText(input) {
131
+ if (!Array.isArray(input) && !(typeof input === "object" && input && Array.isArray(input.messages))) {
132
+ return "";
133
+ }
134
+ const messages = Array.isArray(input) ? input : input.messages;
135
+ const values = [];
136
+ for (const message of messages) {
137
+ if (typeof message !== "object" || !message)
138
+ continue;
139
+ const typed = message;
140
+ if (typed.role === "user") {
141
+ const text = extractMessageContent(message).trim();
142
+ if (text)
143
+ values.push(text);
144
+ continue;
145
+ }
146
+ const ids = Array.isArray(typed.id) ? typed.id.filter((item) => typeof item === "string") : [];
147
+ const typeName = ids.at(-1);
148
+ const runtimeType = typeof message._getType === "function"
149
+ ? message._getType()
150
+ : typeof message.getType === "function"
151
+ ? message.getType()
152
+ : undefined;
153
+ if (typeName === "HumanMessage" || runtimeType === "human") {
154
+ const text = extractMessageContent(message).trim();
155
+ if (text)
156
+ values.push(text);
157
+ continue;
158
+ }
159
+ if (typeof typed.kwargs === "object" && typed.kwargs && typed.kwargs.role === "user") {
160
+ const text = extractMessageContent(message).trim();
161
+ if (text)
162
+ values.push(text);
163
+ }
164
+ }
165
+ return values.join("\n").trim();
166
+ }
167
+ function hasToolResultEvidence(input) {
168
+ if (!Array.isArray(input) && !(typeof input === "object" && input && Array.isArray(input.messages))) {
169
+ return false;
170
+ }
171
+ const messages = Array.isArray(input) ? input : input.messages;
172
+ for (const message of messages) {
173
+ if (typeof message !== "object" || !message)
174
+ continue;
175
+ const typed = message;
176
+ if (typed.role === "tool") {
177
+ return true;
178
+ }
179
+ const ids = Array.isArray(typed.id) ? typed.id.filter((item) => typeof item === "string") : [];
180
+ const typeName = ids.at(-1);
181
+ const runtimeType = typeof message._getType === "function"
182
+ ? message._getType()
183
+ : typeof message.getType === "function"
184
+ ? message.getType()
185
+ : undefined;
186
+ if (typeName === "ToolMessage" || runtimeType === "tool") {
187
+ return true;
188
+ }
189
+ if (typeof typed.kwargs === "object" && typed.kwargs && typed.kwargs.role === "tool") {
190
+ return true;
191
+ }
192
+ }
193
+ return false;
194
+ }
126
195
  function isToolRequiredExecutionPrompt(text) {
127
196
  if (!text)
128
197
  return false;
@@ -130,6 +199,12 @@ function isToolRequiredExecutionPrompt(text) {
130
199
  /\b(create|write|edit|read|show|display|append|run|execute|wait|sleep|repeat|loop|file|files|command)\b/i.test(text) ||
131
200
  /(创建|写入|读取|显示|追加|执行|运行|等待|重复|文件|命令|步骤)/.test(text));
132
201
  }
202
+ function isAutonomousInvestigationPrompt(text) {
203
+ if (!text)
204
+ return false;
205
+ return (/\b(root cause|rca|deep investigation|investigate deeply|investigate fully|step by step|find all (?:issues|problems|causes)|continue investigating|keep digging|until complete|until you find)\b/i.test(text) ||
206
+ /(根因分析|深度调查|深入调查|一步一步|逐步分析|逐个分析|继续排查|排查到底|找到所有问题|查出所有问题|直到完成|直到找到.*原因)/.test(text));
207
+ }
133
208
  function isBrowserOrUrlTask(text) {
134
209
  if (!text)
135
210
  return false;
@@ -149,6 +224,18 @@ function claimsMissingBrowserCapability(text) {
149
224
  return (/\b(i do not have the capability to access external websites|i do not have access to external websites|i cannot access external websites|i can(?:not|'t) browse|i do not have (?:direct )?(?:web|browser|browsing) access|i do not have .*tool.*(?:website|url|browser)|i cannot summarize .* because .*tool.*failed|please provide (?:the )?text content.*i (?:will|can) summarize)\b/i.test(text) ||
150
225
  /(我没有直接访问外部网站|我无法直接访问外部网站|我无法访问外部网站|我不能访问外部网站|我无法直接访问外部网站内容|我无法访问网页|请提供文本内容.*我将为您进行总结|我没有.*浏览.*工具|我没有.*网页抓取.*工具|我没有.*访问.*网站.*工具|我无法总结该网页内容,因为.*工具执行失败)/.test(text));
151
226
  }
227
+ function asksUserToChooseObviousNextDiagnosticStep(text) {
228
+ if (!text)
229
+ return false;
230
+ return (/\b(which (?:direction|aspect|node|namespace|part)|what would you like me to check|please choose|please tell me (?:which|what|where) .* (?:check|inspect|investigate)|which .* should we start with)\b/i.test(text) ||
231
+ /(请告诉我.*(哪个|哪一个|什么方向)|请选择.*(方向|项目|节点)|您希望我.*(检查|查看).*(哪个|哪一个|方向)|从哪个方向开始)/.test(text));
232
+ }
233
+ function claimsFutureExecutionWithoutToolEvidence(text) {
234
+ if (!text)
235
+ return false;
236
+ return (/\b(i will|i'll|we will|next i(?:'ll| will)|i am going to)\b.*\b(run|execute|inspect|check|investigate|continue|start)\b/i.test(text) ||
237
+ /(我将|我会|接下来我会|现在我将|我将继续).*(执行|检查|查看|调查|排查|开始|继续)/.test(text));
238
+ }
152
239
  export function isRetrySafeInvalidToolSelectionError(value) {
153
240
  const text = readTextContent(value).trim();
154
241
  if (!text)
@@ -156,9 +243,9 @@ export function isRetrySafeInvalidToolSelectionError(value) {
156
243
  return /is not a valid tool, try one of \[/i.test(text);
157
244
  }
158
245
  export function shouldValidateExecutionWithoutToolEvidence(request) {
159
- const userText = extractLastUserMessageText(request);
246
+ const userText = extractAllUserMessageText(request);
160
247
  const browserOrUrlTask = isBrowserOrUrlTask(userText);
161
- return browserOrUrlTask || isToolRequiredExecutionPrompt(userText);
248
+ return browserOrUrlTask || isToolRequiredExecutionPrompt(userText) || isAutonomousInvestigationPrompt(userText);
162
249
  }
163
250
  function extractAssistantTextFromResult(result) {
164
251
  if (typeof result === "object" && result && "messages" in result) {
@@ -192,14 +279,21 @@ export function resolveExecutionWithoutToolEvidenceInstruction(request, result)
192
279
  return resolveExecutionWithoutToolEvidenceTextInstruction(request, assistantText, hasToolCalls(result));
193
280
  }
194
281
  export function resolveExecutionWithoutToolEvidenceTextInstruction(request, assistantText, toolCallEvidence = false) {
195
- const userText = extractLastUserMessageText(request);
282
+ const userText = extractAllUserMessageText(request);
196
283
  const browserOrUrlTask = isBrowserOrUrlTask(userText);
284
+ const autonomousInvestigationTask = isAutonomousInvestigationPrompt(userText);
285
+ const toolResultEvidence = hasToolResultEvidence(request);
197
286
  if (!shouldValidateExecutionWithoutToolEvidence(request)) {
198
287
  return null;
199
288
  }
200
289
  if (!assistantText || toolCallEvidence) {
201
290
  return null;
202
291
  }
292
+ if (autonomousInvestigationTask &&
293
+ toolResultEvidence &&
294
+ (asksUserToChooseObviousNextDiagnosticStep(assistantText) || claimsFutureExecutionWithoutToolEvidence(assistantText))) {
295
+ return AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION;
296
+ }
203
297
  if (browserOrUrlTask && claimsMissingBrowserCapability(assistantText)) {
204
298
  return BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION;
205
299
  }
@@ -215,6 +309,9 @@ export function resolveToolCallRecoveryInstruction(error) {
215
309
  if (isRepairableWriteTodosPlaceholderFailure(error)) {
216
310
  return WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION;
217
311
  }
312
+ if (isInternalRuntimeSpillPathFailure(error)) {
313
+ return INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION;
314
+ }
218
315
  if (isWorkspacePathScopeFailure(error)) {
219
316
  return WORKSPACE_RELATIVE_PATH_INSTRUCTION;
220
317
  }
@@ -285,4 +382,4 @@ export function wrapResolvedModel(value) {
285
382
  },
286
383
  });
287
384
  }
288
- export { BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION } from "../prompts/runtime-prompts.js";
385
+ export { AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION, BROWSER_CAPABILITY_DISCLAIMER_RECOVERY_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION, EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION, INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION, INVALID_TOOL_SELECTION_RECOVERY_INSTRUCTION, STRICT_TOOL_JSON_INSTRUCTION, WORKSPACE_RELATIVE_PATH_INSTRUCTION, WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION, WRITE_TODOS_FULL_ENTRY_INSTRUCTION, WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION } from "../prompts/runtime-prompts.js";
@@ -9,6 +9,8 @@ export declare const WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION: string;
9
9
  export declare const WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION: string;
10
10
  export declare const EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION: string;
11
11
  export declare const EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION: string;
12
+ export declare const AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION: string;
13
+ export declare const INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION: string;
12
14
  export declare const WORKSPACE_RELATIVE_PATH_INSTRUCTION: string;
13
15
  export declare function renderDurableMemoryContextPrompt(memoryContext: string): string;
14
16
  export declare function renderSlashCommandSkillInstruction(input: {
@@ -12,6 +12,8 @@ export const WRITE_TODOS_NON_EMPTY_INITIAL_LIST_INSTRUCTION = readRuntimePrompt(
12
12
  export const WRITE_TODOS_DESCRIPTIVE_CONTENT_INSTRUCTION = readRuntimePrompt("write-todos-descriptive-content");
13
13
  export const EXECUTION_WITH_TOOL_EVIDENCE_INSTRUCTION = readRuntimePrompt("execution-with-tool-evidence");
14
14
  export const EXECUTION_WITH_TOOL_EVIDENCE_RETRY_INSTRUCTION = readRuntimePrompt("execution-with-tool-evidence-retry");
15
+ export const AUTONOMOUS_INVESTIGATION_RECOVERY_INSTRUCTION = readRuntimePrompt("autonomous-investigation-recovery");
16
+ export const INTERNAL_RUNTIME_SPILL_PATH_INSTRUCTION = readRuntimePrompt("internal-runtime-spill-path");
15
17
  export const WORKSPACE_RELATIVE_PATH_INSTRUCTION = readRuntimePrompt("workspace-relative-path");
16
18
  export function renderDurableMemoryContextPrompt(memoryContext) {
17
19
  return renderBundledTemplate("prompts/runtime/durable-memory-context.md", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@botbotgo/agent-harness",
3
- "version": "0.0.321",
3
+ "version": "0.0.323",
4
4
  "description": "Workspace runtime for multi-agent applications",
5
5
  "license": "MIT",
6
6
  "type": "module",