@botbotgo/agent-harness 0.0.313 → 0.0.315
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/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/adapter/direct-builtin-utility.d.ts +4 -0
- package/dist/runtime/adapter/direct-builtin-utility.js +35 -0
- package/dist/runtime/adapter/flow/invocation-flow.d.ts +1 -0
- package/dist/runtime/adapter/flow/invocation-flow.js +1 -0
- package/dist/runtime/adapter/flow/invoke-runtime.d.ts +1 -0
- package/dist/runtime/adapter/flow/invoke-runtime.js +1 -0
- package/dist/runtime/adapter/local-tool-invocation.d.ts +2 -1
- package/dist/runtime/adapter/local-tool-invocation.js +12 -4
- package/dist/runtime/adapter/middleware-assembly.d.ts +3 -0
- package/dist/runtime/adapter/middleware-assembly.js +1 -0
- package/dist/runtime/adapter/tool/builtin-middleware-tools.d.ts +1 -0
- package/dist/runtime/adapter/tool/builtin-middleware-tools.js +19 -13
- package/dist/runtime/adapter/tool/tool-output-artifacts.d.ts +35 -0
- package/dist/runtime/adapter/tool/tool-output-artifacts.js +88 -0
- package/dist/runtime/agent-runtime-adapter.d.ts +1 -0
- package/dist/runtime/agent-runtime-adapter.js +80 -4
- package/dist/runtime/harness.js +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export declare const AGENT_HARNESS_VERSION = "0.0.314";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.314";
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
const DIRECT_LISTING_PATTERNS = [
|
|
2
|
+
/^ls$/iu,
|
|
3
|
+
/^list files$/iu,
|
|
4
|
+
/^list the files$/iu,
|
|
5
|
+
/^list files in (?:the )?(?:current )?directory$/iu,
|
|
6
|
+
/^show files$/iu,
|
|
7
|
+
/^show me the files$/iu,
|
|
8
|
+
/^show the files$/iu,
|
|
9
|
+
/^列出文件$/u,
|
|
10
|
+
/^列出当前目录(?:下)?文件$/u,
|
|
11
|
+
/^查看文件列表$/u,
|
|
12
|
+
];
|
|
1
13
|
const GENERIC_ASSISTANT_SUMMARY_MAX_CHARS = 180;
|
|
2
14
|
const GENERIC_ASSISTANT_SUMMARY_MAX_LINES = 6;
|
|
3
15
|
function parseListingEntry(line) {
|
|
@@ -88,3 +100,26 @@ export function summarizeAssistantText(text) {
|
|
|
88
100
|
}
|
|
89
101
|
return summarizeGenericAssistantResponse(normalized);
|
|
90
102
|
}
|
|
103
|
+
function extractPlainTextInput(input) {
|
|
104
|
+
if (typeof input === "string") {
|
|
105
|
+
const normalized = input.trim();
|
|
106
|
+
return normalized.length > 0 ? normalized : undefined;
|
|
107
|
+
}
|
|
108
|
+
if (!Array.isArray(input)) {
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
const text = input
|
|
112
|
+
.filter((part) => part?.type === "text" && typeof part.text === "string")
|
|
113
|
+
.map((part) => part.text.trim())
|
|
114
|
+
.filter((part) => part.length > 0)
|
|
115
|
+
.join("\n")
|
|
116
|
+
.trim();
|
|
117
|
+
return text.length > 0 ? text : undefined;
|
|
118
|
+
}
|
|
119
|
+
export function shouldDirectlyListWorkspaceFiles(input) {
|
|
120
|
+
const normalized = extractPlainTextInput(input);
|
|
121
|
+
if (!normalized) {
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
return DIRECT_LISTING_PATTERNS.some((pattern) => pattern.test(normalized));
|
|
125
|
+
}
|
|
@@ -22,6 +22,7 @@ export declare function executeRequestInvocation(options: {
|
|
|
22
22
|
state?: Record<string, unknown>;
|
|
23
23
|
files?: Record<string, unknown>;
|
|
24
24
|
memoryContext?: string;
|
|
25
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
25
26
|
}) => Promise<Map<string, ExecutableTool>>;
|
|
26
27
|
callRuntimeWithToolParseRecovery: (request: unknown) => Promise<Record<string, unknown>>;
|
|
27
28
|
}): Promise<RequestResult>;
|
|
@@ -34,6 +34,7 @@ export async function executeRequestInvocation(options) {
|
|
|
34
34
|
executableTools,
|
|
35
35
|
builtinExecutableTools: builtinExecutableTools,
|
|
36
36
|
callRuntimeWithToolParseRecovery: options.callRuntimeWithToolParseRecovery,
|
|
37
|
+
toolRuntimeContext: invokeOptions.toolRuntimeContext,
|
|
37
38
|
});
|
|
38
39
|
const result = localOrUpstreamInvocation.result;
|
|
39
40
|
const executedToolResults = [...localOrUpstreamInvocation.executedToolResults];
|
|
@@ -16,6 +16,7 @@ export declare function invokeRuntimeWithLocalTools(options: {
|
|
|
16
16
|
executableTools: Map<string, ExecutableTool>;
|
|
17
17
|
builtinExecutableTools: Map<string, ExecutableTool>;
|
|
18
18
|
callRuntimeWithToolParseRecovery: (request: unknown) => Promise<Record<string, unknown>>;
|
|
19
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
19
20
|
}): Promise<{
|
|
20
21
|
result: Record<string, unknown>;
|
|
21
22
|
executedToolResults: ExecutedToolResult[];
|
|
@@ -14,5 +14,6 @@ export async function invokeRuntimeWithLocalTools(options) {
|
|
|
14
14
|
executableTools: options.executableTools,
|
|
15
15
|
builtinExecutableTools: options.builtinExecutableTools,
|
|
16
16
|
callRuntimeWithToolParseRecovery: options.callRuntimeWithToolParseRecovery,
|
|
17
|
+
toolRuntimeContext: options.toolRuntimeContext,
|
|
17
18
|
});
|
|
18
19
|
}
|
|
@@ -14,10 +14,11 @@ type LocalToolInvocationParams = {
|
|
|
14
14
|
executableTools: Map<string, ExecutableTool>;
|
|
15
15
|
builtinExecutableTools: Map<string, ExecutableTool>;
|
|
16
16
|
callRuntimeWithToolParseRecovery: (request: unknown) => Promise<Record<string, unknown>>;
|
|
17
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
17
18
|
};
|
|
18
19
|
type LocalToolInvocationResult = {
|
|
19
20
|
result: Record<string, unknown>;
|
|
20
21
|
executedToolResults: ExecutedToolResult[];
|
|
21
22
|
};
|
|
22
|
-
export declare function runLocalToolInvocationLoop({ binding, request, primaryTools, toolNameMapping, executableTools, builtinExecutableTools, callRuntimeWithToolParseRecovery, }: LocalToolInvocationParams): Promise<LocalToolInvocationResult>;
|
|
23
|
+
export declare function runLocalToolInvocationLoop({ binding, request, primaryTools, toolNameMapping, executableTools, builtinExecutableTools, callRuntimeWithToolParseRecovery, toolRuntimeContext, }: LocalToolInvocationParams): Promise<LocalToolInvocationResult>;
|
|
23
24
|
export {};
|
|
@@ -3,6 +3,7 @@ import { createModelFacingToolNameLookupCandidates, resolveModelFacingToolName }
|
|
|
3
3
|
import { canReplayToolCallsLocally } from "./tool/tool-replay.js";
|
|
4
4
|
import { extractToolCallsFromResult, normalizeToolArgsForSchema, stringifyToolOutput } from "./tool/tool-arguments.js";
|
|
5
5
|
import { extractMemoryCandidatesFromToolOutput } from "../harness/system/runtime-memory-candidates.js";
|
|
6
|
+
import { maybePersistLargeToolOutput } from "./tool/tool-output-artifacts.js";
|
|
6
7
|
const TOOL_FOLLOW_UP_INSTRUCTION = "One or more tool results are already available in this conversation. Answer the user's current request directly from the existing context and tool results. Do not ask the user to repeat inputs that are already present above.";
|
|
7
8
|
function extractLatestUserInput(request) {
|
|
8
9
|
const typedRequest = request;
|
|
@@ -19,7 +20,7 @@ function extractLatestUserInput(request) {
|
|
|
19
20
|
}
|
|
20
21
|
return undefined;
|
|
21
22
|
}
|
|
22
|
-
export async function runLocalToolInvocationLoop({ binding, request, primaryTools, toolNameMapping, executableTools, builtinExecutableTools, callRuntimeWithToolParseRecovery, }) {
|
|
23
|
+
export async function runLocalToolInvocationLoop({ binding, request, primaryTools, toolNameMapping, executableTools, builtinExecutableTools, callRuntimeWithToolParseRecovery, toolRuntimeContext, }) {
|
|
23
24
|
const executedToolResults = [];
|
|
24
25
|
let activeRequest = request;
|
|
25
26
|
let currentMessages = Array.isArray(activeRequest.messages) ? [...activeRequest.messages] : [];
|
|
@@ -74,17 +75,24 @@ export async function runLocalToolInvocationLoop({ binding, request, primaryTool
|
|
|
74
75
|
const normalizedArgs = normalizeToolArgsForSchema(toolCall.args, activeExecutable.schema, toolCall.rawArgsInput, {
|
|
75
76
|
latestUserInput,
|
|
76
77
|
});
|
|
77
|
-
const toolResult =
|
|
78
|
+
const toolResult = toolRuntimeContext
|
|
79
|
+
? await activeExecutable.invoke(normalizedArgs, { toolRuntimeContext })
|
|
80
|
+
: await activeExecutable.invoke(normalizedArgs);
|
|
78
81
|
const memoryCandidates = compiledTool ? extractMemoryCandidatesFromToolOutput(compiledTool, toolResult) : [];
|
|
79
|
-
|
|
82
|
+
const safeToolResult = await maybePersistLargeToolOutput({
|
|
80
83
|
toolName: activeExecutable.name,
|
|
81
84
|
output: toolResult,
|
|
85
|
+
toolRuntimeContext: toolRuntimeContext,
|
|
86
|
+
});
|
|
87
|
+
executedToolResults.push({
|
|
88
|
+
toolName: activeExecutable.name,
|
|
89
|
+
output: safeToolResult,
|
|
82
90
|
...(memoryCandidates.length > 0 ? { memoryCandidates } : {}),
|
|
83
91
|
});
|
|
84
92
|
nextMessages.push(new ToolMessage({
|
|
85
93
|
name: activeExecutable.name,
|
|
86
94
|
tool_call_id: toolCall.id ?? `tool-${iteration + 1}-${toolIndex + 1}`,
|
|
87
|
-
content: stringifyToolOutput(
|
|
95
|
+
content: stringifyToolOutput(safeToolResult),
|
|
88
96
|
}));
|
|
89
97
|
}
|
|
90
98
|
currentMessages = nextMessages;
|
|
@@ -73,16 +73,19 @@ export declare function resolveBuiltinMiddlewareTools(input: {
|
|
|
73
73
|
context?: Record<string, unknown>;
|
|
74
74
|
state?: Record<string, unknown>;
|
|
75
75
|
files?: Record<string, unknown>;
|
|
76
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
76
77
|
};
|
|
77
78
|
resolveBuiltinMiddlewareBackend: (binding: CompiledAgentBinding, options?: {
|
|
78
79
|
context?: Record<string, unknown>;
|
|
79
80
|
state?: Record<string, unknown>;
|
|
80
81
|
files?: Record<string, unknown>;
|
|
82
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
81
83
|
}) => unknown;
|
|
82
84
|
invokeBuiltinTaskTool: (binding: CompiledAgentBinding, toolInput: unknown, options?: {
|
|
83
85
|
context?: Record<string, unknown>;
|
|
84
86
|
state?: Record<string, unknown>;
|
|
85
87
|
files?: Record<string, unknown>;
|
|
88
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
86
89
|
}) => Promise<unknown>;
|
|
87
90
|
}): Promise<Map<string, ExecutableTool>>;
|
|
88
91
|
export declare function materializeAutomaticSummarizationMiddleware(input: {
|
|
@@ -182,6 +182,7 @@ export async function resolveBuiltinMiddlewareTools(input) {
|
|
|
182
182
|
return createBuiltinMiddlewareTools(backend, {
|
|
183
183
|
includeTaskTool: isDeepAgentBinding(input.binding),
|
|
184
184
|
workspaceRoot: input.binding.harnessRuntime.workspaceRoot,
|
|
185
|
+
toolRuntimeContext: input.options?.toolRuntimeContext,
|
|
185
186
|
invokeTaskTool: isDeepAgentBinding(input.binding)
|
|
186
187
|
? async (toolInput) => input.invokeBuiltinTaskTool(input.binding, toolInput, input.options)
|
|
187
188
|
: undefined,
|
|
@@ -250,4 +250,5 @@ export declare function createBuiltinMiddlewareTools(backend: BuiltinMiddlewareB
|
|
|
250
250
|
includeTaskTool: boolean;
|
|
251
251
|
invokeTaskTool?: (input: unknown) => Promise<unknown>;
|
|
252
252
|
workspaceRoot?: string;
|
|
253
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
253
254
|
}): Promise<Map<string, BuiltinExecutableTool>>;
|
|
@@ -3,6 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
import { isSandboxBackend } from "deepagents";
|
|
4
4
|
import { isRecord } from "../../../utils/object.js";
|
|
5
5
|
import { formatBuiltinTodoSnapshot, isLowSignalTodoContent, summarizeBuiltinWriteTodosArgs, truncateLines } from "../runtime-adapter-support.js";
|
|
6
|
+
import { maybePersistLargeToolOutput, resolveToolRuntimeContext } from "./tool-output-artifacts.js";
|
|
6
7
|
export const BUILTIN_MIDDLEWARE_TOOL_DESCRIPTORS = [
|
|
7
8
|
{ name: "write_todos", description: "Create and update the runtime todo board for multi-step work." },
|
|
8
9
|
{ name: "read_todos", description: "Read the current runtime todo board." },
|
|
@@ -159,6 +160,11 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
159
160
|
blocked: 0,
|
|
160
161
|
},
|
|
161
162
|
};
|
|
163
|
+
const finalizeOutput = async (toolName, output, toolConfig) => maybePersistLargeToolOutput({
|
|
164
|
+
toolName,
|
|
165
|
+
output,
|
|
166
|
+
toolRuntimeContext: resolveToolRuntimeContext(toolConfig, options.toolRuntimeContext),
|
|
167
|
+
});
|
|
162
168
|
tools.set("write_todos", {
|
|
163
169
|
name: "write_todos",
|
|
164
170
|
description: "Create and update the runtime todo board for multi-step work.",
|
|
@@ -200,11 +206,11 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
200
206
|
name: "ls",
|
|
201
207
|
description: "List files in a directory.",
|
|
202
208
|
schema: z.object({ path: z.string().optional().default("/") }).passthrough(),
|
|
203
|
-
invoke: async (input) => {
|
|
209
|
+
invoke: async (input, toolConfig) => {
|
|
204
210
|
const targetPath = normalizeWorkspacePathOrThrow(pathScopedBackend, isRecord(input) && typeof input.path === "string" ? input.path : "/");
|
|
205
211
|
const shallowListing = await tryExecuteShallowDirectoryListing(pathScopedBackend, targetPath);
|
|
206
212
|
if (typeof shallowListing === "string") {
|
|
207
|
-
return shallowListing.length > 0 ? shallowListing : `No files found in ${targetPath}
|
|
213
|
+
return finalizeOutput("ls", shallowListing.length > 0 ? shallowListing : `No files found in ${targetPath}`, toolConfig);
|
|
208
214
|
}
|
|
209
215
|
const legacyInfos = (await Promise.resolve(backend.lsInfo?.(targetPath))) ?? [];
|
|
210
216
|
const infos = legacyInfos.length > 0
|
|
@@ -217,14 +223,14 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
217
223
|
if (infos.length === 0) {
|
|
218
224
|
return `No files found in ${targetPath}`;
|
|
219
225
|
}
|
|
220
|
-
return truncateLines(infos.map((info) => info.is_dir ? `${info.path} (directory)` : `${info.path}${info.size ? ` (${info.size} bytes)` : ""}`));
|
|
226
|
+
return finalizeOutput("ls", truncateLines(infos.map((info) => info.is_dir ? `${info.path} (directory)` : `${info.path}${info.size ? ` (${info.size} bytes)` : ""}`)), toolConfig);
|
|
221
227
|
},
|
|
222
228
|
});
|
|
223
229
|
tools.set("list_files", {
|
|
224
230
|
name: "list_files",
|
|
225
231
|
description: "List files in a directory.",
|
|
226
232
|
schema: z.object({ path: z.string().optional().default("/") }).passthrough(),
|
|
227
|
-
invoke: async (input) => tools.get("ls").invoke(input),
|
|
233
|
+
invoke: async (input, toolConfig) => tools.get("ls").invoke(input, toolConfig),
|
|
228
234
|
});
|
|
229
235
|
tools.set("read_file", {
|
|
230
236
|
name: "read_file",
|
|
@@ -352,7 +358,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
352
358
|
name: "execute",
|
|
353
359
|
description: "Run a shell command in the workspace sandbox.",
|
|
354
360
|
schema: z.object({ command: z.string() }).passthrough(),
|
|
355
|
-
invoke: async (input) => {
|
|
361
|
+
invoke: async (input, toolConfig) => {
|
|
356
362
|
if (!isSandboxBackend(backend) || typeof backend.execute !== "function") {
|
|
357
363
|
return "Error: Execution not available. This agent's backend does not support command execution (SandboxBackendProtocol).";
|
|
358
364
|
}
|
|
@@ -365,29 +371,29 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
365
371
|
if (result.truncated) {
|
|
366
372
|
parts.push("\n[Output was truncated due to size limits]");
|
|
367
373
|
}
|
|
368
|
-
return parts.join("");
|
|
374
|
+
return finalizeOutput("execute", parts.join(""), toolConfig);
|
|
369
375
|
},
|
|
370
376
|
});
|
|
371
377
|
tools.set("run_command", {
|
|
372
378
|
name: "run_command",
|
|
373
379
|
description: "Run a shell command in the workspace sandbox.",
|
|
374
380
|
schema: z.object({ command: z.string() }).passthrough(),
|
|
375
|
-
invoke: async (input) => tools.get("execute").invoke(input),
|
|
381
|
+
invoke: async (input, toolConfig) => tools.get("execute").invoke(input, toolConfig),
|
|
376
382
|
});
|
|
377
383
|
tools.set("fetch_url", {
|
|
378
384
|
name: "fetch_url",
|
|
379
385
|
description: "Fetch a URL and return the response body.",
|
|
380
386
|
schema: z.object({ url: z.string() }).passthrough(),
|
|
381
|
-
invoke: async (input) => {
|
|
387
|
+
invoke: async (input, toolConfig) => {
|
|
382
388
|
if (typeof backend.fetchUrl !== "function") {
|
|
383
389
|
return notAvailable("fetch_url", "URL fetching");
|
|
384
390
|
}
|
|
385
391
|
const typed = isRecord(input) ? input : {};
|
|
386
392
|
const result = await Promise.resolve(backend.fetchUrl(typeof typed.url === "string" ? typed.url : ""));
|
|
387
393
|
if (typeof result === "string") {
|
|
388
|
-
return result;
|
|
394
|
+
return finalizeOutput("fetch_url", result, toolConfig);
|
|
389
395
|
}
|
|
390
|
-
return formatHttpResponse(result);
|
|
396
|
+
return finalizeOutput("fetch_url", formatHttpResponse(result), toolConfig);
|
|
391
397
|
},
|
|
392
398
|
});
|
|
393
399
|
tools.set("http_request", {
|
|
@@ -399,7 +405,7 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
399
405
|
headers: z.record(z.string(), z.string()).optional(),
|
|
400
406
|
body: z.string().optional(),
|
|
401
407
|
}).passthrough(),
|
|
402
|
-
invoke: async (input) => {
|
|
408
|
+
invoke: async (input, toolConfig) => {
|
|
403
409
|
if (typeof backend.httpRequest !== "function") {
|
|
404
410
|
return notAvailable("http_request", "structured HTTP requests");
|
|
405
411
|
}
|
|
@@ -413,9 +419,9 @@ export async function createBuiltinMiddlewareTools(backend, options) {
|
|
|
413
419
|
body: typeof typed.body === "string" ? typed.body : undefined,
|
|
414
420
|
}));
|
|
415
421
|
if (typeof result === "string") {
|
|
416
|
-
return result;
|
|
422
|
+
return finalizeOutput("http_request", result, toolConfig);
|
|
417
423
|
}
|
|
418
|
-
return formatHttpResponse(result);
|
|
424
|
+
return finalizeOutput("http_request", formatHttpResponse(result), toolConfig);
|
|
419
425
|
},
|
|
420
426
|
});
|
|
421
427
|
tools.set("send_message", {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
type ArtifactCreateInput = {
|
|
2
|
+
sessionId: string;
|
|
3
|
+
requestId: string;
|
|
4
|
+
kind: string;
|
|
5
|
+
path: string;
|
|
6
|
+
content: unknown;
|
|
7
|
+
artifactId?: string;
|
|
8
|
+
createdAt?: string;
|
|
9
|
+
};
|
|
10
|
+
type ArtifactCreateResult = {
|
|
11
|
+
artifactId: string;
|
|
12
|
+
kind: string;
|
|
13
|
+
path: string;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
};
|
|
16
|
+
type ToolRuntimeContext = {
|
|
17
|
+
runtime?: {
|
|
18
|
+
current?: {
|
|
19
|
+
sessionId?: string;
|
|
20
|
+
requestId?: string;
|
|
21
|
+
};
|
|
22
|
+
artifacts?: {
|
|
23
|
+
create?: (input: ArtifactCreateInput) => Promise<ArtifactCreateResult> | ArtifactCreateResult;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export declare function resolveToolRuntimeContext(toolConfig?: Record<string, unknown>, fallback?: Record<string, unknown>): ToolRuntimeContext | undefined;
|
|
28
|
+
export declare function maybePersistLargeToolOutput(input: {
|
|
29
|
+
toolName: string;
|
|
30
|
+
output: unknown;
|
|
31
|
+
toolRuntimeContext?: Record<string, unknown>;
|
|
32
|
+
maxInlineChars?: number;
|
|
33
|
+
previewChars?: number;
|
|
34
|
+
}): Promise<unknown>;
|
|
35
|
+
export {};
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
function asRecord(value) {
|
|
2
|
+
return typeof value === "object" && value !== null && !Array.isArray(value)
|
|
3
|
+
? value
|
|
4
|
+
: undefined;
|
|
5
|
+
}
|
|
6
|
+
function toSerializedToolOutput(output) {
|
|
7
|
+
if (typeof output === "string") {
|
|
8
|
+
return output;
|
|
9
|
+
}
|
|
10
|
+
try {
|
|
11
|
+
return JSON.stringify(output, null, 2);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return String(output);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function truncatePreview(text, maxChars) {
|
|
18
|
+
if (text.length <= maxChars) {
|
|
19
|
+
return text;
|
|
20
|
+
}
|
|
21
|
+
return `${text.slice(0, Math.max(0, maxChars - 15))}\n...[truncated]`;
|
|
22
|
+
}
|
|
23
|
+
function sanitizeArtifactToolName(toolName) {
|
|
24
|
+
return toolName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "tool";
|
|
25
|
+
}
|
|
26
|
+
export function resolveToolRuntimeContext(toolConfig, fallback) {
|
|
27
|
+
const dynamic = asRecord(toolConfig?.toolRuntimeContext);
|
|
28
|
+
const configurable = asRecord(toolConfig?.configurable);
|
|
29
|
+
const fallbackRuntime = asRecord(asRecord(fallback)?.runtime);
|
|
30
|
+
const fallbackCurrent = asRecord(fallbackRuntime?.current);
|
|
31
|
+
const resolved = (dynamic ?? fallback);
|
|
32
|
+
const runtime = asRecord(resolved?.runtime);
|
|
33
|
+
if (!runtime) {
|
|
34
|
+
return resolved;
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
...resolved,
|
|
38
|
+
runtime: {
|
|
39
|
+
...runtime,
|
|
40
|
+
current: {
|
|
41
|
+
...fallbackCurrent,
|
|
42
|
+
...asRecord(runtime.current),
|
|
43
|
+
...(typeof configurable?.thread_id === "string" ? { sessionId: configurable.thread_id } : {}),
|
|
44
|
+
...(typeof configurable?.request_id === "string" ? { requestId: configurable.request_id } : {}),
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
export async function maybePersistLargeToolOutput(input) {
|
|
50
|
+
const maxInlineChars = input.maxInlineChars ?? 12_000;
|
|
51
|
+
const previewChars = input.previewChars ?? 2_000;
|
|
52
|
+
const serialized = toSerializedToolOutput(input.output);
|
|
53
|
+
if (serialized.length <= maxInlineChars) {
|
|
54
|
+
return input.output;
|
|
55
|
+
}
|
|
56
|
+
const runtimeContext = input.toolRuntimeContext;
|
|
57
|
+
const runtime = runtimeContext?.runtime;
|
|
58
|
+
const sessionId = runtime?.current?.sessionId;
|
|
59
|
+
const requestId = runtime?.current?.requestId;
|
|
60
|
+
const createArtifact = runtime?.artifacts?.create;
|
|
61
|
+
const createdAt = new Date().toISOString();
|
|
62
|
+
const safeToolName = sanitizeArtifactToolName(input.toolName);
|
|
63
|
+
let artifact;
|
|
64
|
+
if (typeof createArtifact === "function" && typeof sessionId === "string" && typeof requestId === "string") {
|
|
65
|
+
artifact = await Promise.resolve(createArtifact({
|
|
66
|
+
sessionId,
|
|
67
|
+
requestId,
|
|
68
|
+
kind: "tool-output",
|
|
69
|
+
path: `artifacts/tool-output-${safeToolName}-${Date.now()}.json`,
|
|
70
|
+
createdAt,
|
|
71
|
+
content: {
|
|
72
|
+
toolName: input.toolName,
|
|
73
|
+
createdAt,
|
|
74
|
+
output: input.output,
|
|
75
|
+
},
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
truncated: true,
|
|
80
|
+
toolName: input.toolName,
|
|
81
|
+
message: artifact
|
|
82
|
+
? "Full tool output was stored as a request artifact because it exceeded the inline size limit."
|
|
83
|
+
: "Tool output exceeded the inline size limit and was truncated for runtime stability.",
|
|
84
|
+
originalSizeChars: serialized.length,
|
|
85
|
+
preview: truncatePreview(serialized, previewChars),
|
|
86
|
+
...(artifact ? { artifact } : {}),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
@@ -32,6 +32,7 @@ export declare class AgentRuntimeAdapter {
|
|
|
32
32
|
private resolveFilesystemRootDir;
|
|
33
33
|
private resolveBuiltinMiddlewareBackend;
|
|
34
34
|
private buildFunctionToolRuntimeContext;
|
|
35
|
+
private tryHandleDirectWorkspaceListing;
|
|
35
36
|
private createDeclaredMiddlewareResolverOptions;
|
|
36
37
|
private createAssemblyResolvers;
|
|
37
38
|
private invokeBuiltinTaskTool;
|
|
@@ -11,6 +11,7 @@ import { applyToolRecoveryInstruction as applyToolRecoveryInstructionHelper, app
|
|
|
11
11
|
import { invokeBuiltinTaskTool as invokeBuiltinTaskToolHelper, materializeAutomaticSummarizationMiddleware as materializeAutomaticSummarizationMiddlewareHelper, resolveBuiltinMiddlewareBackend as resolveBuiltinMiddlewareBackendHelper, resolveBuiltinMiddlewareTools as resolveBuiltinMiddlewareToolsHelper, resolveLangChainRuntimeExtensionMiddleware as resolveLangChainRuntimeExtensionMiddlewareHelper, resolveMiddleware as resolveMiddlewareHelper, resolveSubagents as resolveSubagentsHelper, } from "./adapter/middleware-assembly.js";
|
|
12
12
|
import { resolveBindingTimeout, resolveStreamIdleTimeout, } from "./adapter/resilience.js";
|
|
13
13
|
import { createResolvedModel } from "./adapter/model/model-providers.js";
|
|
14
|
+
import { shouldDirectlyListWorkspaceFiles } from "./adapter/direct-builtin-utility.js";
|
|
14
15
|
import { resolveAdapterTools } from "./adapter/tool-resolution.js";
|
|
15
16
|
import { resolveRuntimeStreamExecutionContext, } from "./adapter/flow/execution-context.js";
|
|
16
17
|
import { isRetryableProviderError } from "./adapter/resilience.js";
|
|
@@ -173,6 +174,30 @@ export class AgentRuntimeAdapter {
|
|
|
173
174
|
},
|
|
174
175
|
};
|
|
175
176
|
}
|
|
177
|
+
async tryHandleDirectWorkspaceListing(binding, input, options = {}) {
|
|
178
|
+
if (!shouldDirectlyListWorkspaceFiles(input)) {
|
|
179
|
+
return undefined;
|
|
180
|
+
}
|
|
181
|
+
const builtinTools = await this.resolveBuiltinMiddlewareTools(binding, {
|
|
182
|
+
context: options.context,
|
|
183
|
+
state: options.state,
|
|
184
|
+
files: options.files,
|
|
185
|
+
sessionId: options.sessionId,
|
|
186
|
+
requestId: options.requestId,
|
|
187
|
+
});
|
|
188
|
+
const listTool = builtinTools.get("list_files") ?? builtinTools.get("ls");
|
|
189
|
+
if (!listTool) {
|
|
190
|
+
return undefined;
|
|
191
|
+
}
|
|
192
|
+
const output = await listTool.invoke({ path: "." });
|
|
193
|
+
if (typeof output !== "string" || output.trim().length === 0) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
return {
|
|
197
|
+
toolName: listTool.name,
|
|
198
|
+
output,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
176
201
|
createDeclaredMiddlewareResolverOptions(binding, options = {}) {
|
|
177
202
|
return {
|
|
178
203
|
resolveModel: (model) => this.resolveModel(model),
|
|
@@ -277,7 +302,12 @@ export class AgentRuntimeAdapter {
|
|
|
277
302
|
const resolvedModel = await this.resolveModel(primaryModel);
|
|
278
303
|
const resolvedTools = this.resolveTools(primaryTools, binding);
|
|
279
304
|
const builtinMiddlewareTools = materializeModelExposedBuiltinMiddlewareTools({
|
|
280
|
-
builtinTools: await this.resolveBuiltinMiddlewareTools(binding, {
|
|
305
|
+
builtinTools: await this.resolveBuiltinMiddlewareTools(binding, {
|
|
306
|
+
sessionId: options.sessionId ?? options.legacySessionId,
|
|
307
|
+
toolRuntimeContext: this.buildFunctionToolRuntimeContext(binding, {
|
|
308
|
+
sessionId: options.sessionId ?? options.legacySessionId,
|
|
309
|
+
}),
|
|
310
|
+
}),
|
|
281
311
|
explicitToolNames: primaryTools.map((tool) => tool.name),
|
|
282
312
|
});
|
|
283
313
|
const resolvedMiddleware = await this.resolveMiddleware(binding, interruptOn, { sessionId: options.sessionId ?? options.legacySessionId });
|
|
@@ -305,9 +335,9 @@ export class AgentRuntimeAdapter {
|
|
|
305
335
|
if (isLangChainBinding(binding)) {
|
|
306
336
|
return this.createLangChainRunnable(binding, { sessionId: options.sessionId ?? options.legacySessionId });
|
|
307
337
|
}
|
|
308
|
-
return this.createDeepAgentRunnable(binding);
|
|
338
|
+
return this.createDeepAgentRunnable(binding, { sessionId: options.sessionId ?? options.legacySessionId });
|
|
309
339
|
}
|
|
310
|
-
async createDeepAgentRunnable(binding) {
|
|
340
|
+
async createDeepAgentRunnable(binding, options = {}) {
|
|
311
341
|
const executionKind = getBindingExecutionKind(binding);
|
|
312
342
|
const primaryModel = getBindingPrimaryModel(binding);
|
|
313
343
|
const primaryTools = getBindingPrimaryTools(binding);
|
|
@@ -317,7 +347,12 @@ export class AgentRuntimeAdapter {
|
|
|
317
347
|
const resolvedModel = await this.resolveModel(primaryModel);
|
|
318
348
|
const resolvedTools = this.resolveTools(primaryTools, binding);
|
|
319
349
|
const builtinMiddlewareTools = materializeModelExposedBuiltinMiddlewareTools({
|
|
320
|
-
builtinTools: await this.resolveBuiltinMiddlewareTools(binding
|
|
350
|
+
builtinTools: await this.resolveBuiltinMiddlewareTools(binding, {
|
|
351
|
+
sessionId: options.sessionId ?? options.legacySessionId,
|
|
352
|
+
toolRuntimeContext: this.buildFunctionToolRuntimeContext(binding, {
|
|
353
|
+
sessionId: options.sessionId ?? options.legacySessionId,
|
|
354
|
+
}),
|
|
355
|
+
}),
|
|
321
356
|
explicitToolNames: primaryTools.map((tool) => tool.name),
|
|
322
357
|
});
|
|
323
358
|
const resolvedMiddleware = await this.resolveMiddleware(binding);
|
|
@@ -398,6 +433,30 @@ export class AgentRuntimeAdapter {
|
|
|
398
433
|
}
|
|
399
434
|
}
|
|
400
435
|
async invoke(binding, input, sessionId, requestId, resumePayload, history = [], options = {}) {
|
|
436
|
+
const directListing = await this.tryHandleDirectWorkspaceListing(binding, input, {
|
|
437
|
+
...options,
|
|
438
|
+
sessionId,
|
|
439
|
+
requestId,
|
|
440
|
+
});
|
|
441
|
+
if (directListing) {
|
|
442
|
+
return {
|
|
443
|
+
sessionId,
|
|
444
|
+
requestId,
|
|
445
|
+
agentId: binding.agent.id,
|
|
446
|
+
state: "completed",
|
|
447
|
+
output: directListing.output,
|
|
448
|
+
finalMessageText: directListing.output,
|
|
449
|
+
metadata: {
|
|
450
|
+
executedToolResults: [{
|
|
451
|
+
toolName: directListing.toolName,
|
|
452
|
+
output: directListing.output,
|
|
453
|
+
}],
|
|
454
|
+
upstreamResult: {
|
|
455
|
+
directUtility: directListing.toolName,
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
};
|
|
459
|
+
}
|
|
401
460
|
const callRuntime = async (activeBinding, activeRequest) => {
|
|
402
461
|
return this.invokeWithProviderRetry(activeBinding, async () => {
|
|
403
462
|
const runnable = await this.create(activeBinding, { sessionId });
|
|
@@ -444,6 +503,23 @@ export class AgentRuntimeAdapter {
|
|
|
444
503
|
}));
|
|
445
504
|
}
|
|
446
505
|
async *stream(binding, input, sessionId, history = [], options = {}) {
|
|
506
|
+
const directListing = await this.tryHandleDirectWorkspaceListing(binding, input, {
|
|
507
|
+
...options,
|
|
508
|
+
sessionId,
|
|
509
|
+
requestId: options.requestId,
|
|
510
|
+
});
|
|
511
|
+
if (directListing) {
|
|
512
|
+
yield {
|
|
513
|
+
kind: "tool-result",
|
|
514
|
+
toolName: directListing.toolName,
|
|
515
|
+
output: directListing.output,
|
|
516
|
+
};
|
|
517
|
+
yield {
|
|
518
|
+
kind: "content",
|
|
519
|
+
content: directListing.output,
|
|
520
|
+
};
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
447
523
|
const invokeTimeoutMs = resolveBindingTimeout(binding);
|
|
448
524
|
const streamIdleTimeoutMs = resolveStreamIdleTimeout(binding);
|
|
449
525
|
const streamDeadlineAt = invokeTimeoutMs ? Date.now() + invokeTimeoutMs : undefined;
|
package/dist/runtime/harness.js
CHANGED
|
@@ -174,6 +174,7 @@ export class AgentHarnessRuntime {
|
|
|
174
174
|
artifacts: {
|
|
175
175
|
list: (sessionId, requestId) => this.listRequestArtifacts(sessionId, requestId),
|
|
176
176
|
read: (sessionId, requestId, artifactPath) => this.readRequestArtifact(sessionId, requestId, artifactPath),
|
|
177
|
+
create: (artifact) => this.recordArtifact(artifact),
|
|
177
178
|
},
|
|
178
179
|
schedules: {
|
|
179
180
|
manage: (options) => this.manageSchedule(options),
|