@botbotgo/agent-harness 0.0.34 → 0.0.36
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/contracts/types.d.ts +1 -0
- package/dist/package-version.d.ts +1 -1
- package/dist/package-version.js +1 -1
- package/dist/runtime/agent-runtime-adapter.js +1 -1
- package/dist/runtime/tool-hitl.d.ts +2 -1
- package/dist/runtime/tool-hitl.js +55 -2
- package/dist/workspace/agent-binding-compiler.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.35";
|
package/dist/package-version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const AGENT_HARNESS_VERSION = "0.0.
|
|
1
|
+
export const AGENT_HARNESS_VERSION = "0.0.35";
|
|
@@ -367,7 +367,7 @@ export class AgentRuntimeAdapter {
|
|
|
367
367
|
if (!compiledTool) {
|
|
368
368
|
return resolvedTool;
|
|
369
369
|
}
|
|
370
|
-
const wrappedTool = wrapToolForExecution(resolvedTool, compiledTool);
|
|
370
|
+
const wrappedTool = wrapToolForExecution(resolvedTool, compiledTool, binding);
|
|
371
371
|
const modelFacingName = toolNameMapping.originalToModelFacing.get(compiledTool.name) ?? compiledTool.name;
|
|
372
372
|
const structuredTool = asStructuredExecutableTool(wrappedTool, modelFacingName, compiledTool.description);
|
|
373
373
|
if (structuredTool !== wrappedTool) {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CompiledTool } from "../contracts/types.js";
|
|
2
|
+
import type { CompiledAgentBinding } from "../contracts/types.js";
|
|
2
3
|
type InterruptFn = <I = unknown, R = unknown>(value: I) => R;
|
|
3
4
|
export declare function wrapToolForHumanInTheLoop<T>(resolvedTool: T, compiledTool: CompiledTool, interruptFn?: InterruptFn): T;
|
|
4
|
-
export declare function wrapToolForExecution<T>(resolvedTool: T, compiledTool: CompiledTool, interruptFn?: InterruptFn): T;
|
|
5
|
+
export declare function wrapToolForExecution<T>(resolvedTool: T, compiledTool: CompiledTool, binding?: CompiledAgentBinding, interruptFn?: InterruptFn): T;
|
|
5
6
|
export {};
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { interrupt } from "@langchain/langgraph";
|
|
2
|
+
import path from "node:path";
|
|
2
3
|
const DEDUPED_REMOTE_TOOL_NAMES = new Set(["builtin.fetch_url", "builtin.web_search"]);
|
|
4
|
+
const PATH_LIKE_INPUT_KEYS = new Set(["path", "root", "dir", "directory", "cwd"]);
|
|
5
|
+
const ROOT_SCOPING_INPUT_KEYS = new Set(["root", "dir", "directory", "cwd"]);
|
|
3
6
|
function toInputPreview(input) {
|
|
4
7
|
if (typeof input === "object" && input && !Array.isArray(input)) {
|
|
5
8
|
return input;
|
|
@@ -103,6 +106,56 @@ function wrapToolWithDedupe(resolvedTool, compiledTool) {
|
|
|
103
106
|
},
|
|
104
107
|
});
|
|
105
108
|
}
|
|
106
|
-
|
|
107
|
-
|
|
109
|
+
function shouldConstrainWorkspacePaths(compiledTool) {
|
|
110
|
+
const normalized = `${compiledTool.name} ${compiledTool.description}`.toLowerCase();
|
|
111
|
+
if (/(web[_ .-]?search|fetch[_ .-]?url|https?:\/\/|\burl\b)/.test(normalized)) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
return /(workspace|repo|repository|sandbox|filesystem|file|directory|folder|path|memory|source[- ]control|code search|context search|rag|index|grep|glob|read|write|edit)/.test(normalized);
|
|
115
|
+
}
|
|
116
|
+
function guardWorkspaceBoundToolInput(input, compiledTool, binding) {
|
|
117
|
+
const workspaceRoot = binding?.harnessRuntime.workspaceRoot;
|
|
118
|
+
if (!workspaceRoot || typeof input !== "object" || !input || Array.isArray(input) || !shouldConstrainWorkspacePaths(compiledTool)) {
|
|
119
|
+
return input;
|
|
120
|
+
}
|
|
121
|
+
const record = { ...input };
|
|
122
|
+
for (const [key, value] of Object.entries(record)) {
|
|
123
|
+
if (!PATH_LIKE_INPUT_KEYS.has(key) || typeof value !== "string") {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
const candidate = value.trim();
|
|
127
|
+
if (!candidate || /^[a-z]+:\/\//i.test(candidate)) {
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const absolute = path.resolve(workspaceRoot, candidate);
|
|
131
|
+
const relative = path.relative(workspaceRoot, absolute);
|
|
132
|
+
if (relative.startsWith("..") || path.isAbsolute(relative)) {
|
|
133
|
+
if (ROOT_SCOPING_INPUT_KEYS.has(key)) {
|
|
134
|
+
record[key] = workspaceRoot;
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
throw new Error(`Tool ${compiledTool.name} input ${key} resolves outside the workspace root`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return record;
|
|
141
|
+
}
|
|
142
|
+
export function wrapToolForExecution(resolvedTool, compiledTool, binding, interruptFn = interrupt) {
|
|
143
|
+
const guardedTool = typeof resolvedTool === "object" && resolvedTool !== null
|
|
144
|
+
? new Proxy(resolvedTool, {
|
|
145
|
+
get(obj, prop, receiver) {
|
|
146
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
147
|
+
if (prop === "invoke" && typeof value === "function") {
|
|
148
|
+
return (input, config) => obj.invoke(guardWorkspaceBoundToolInput(input, compiledTool, binding), config);
|
|
149
|
+
}
|
|
150
|
+
if (prop === "call" && typeof value === "function") {
|
|
151
|
+
return (input, config) => obj.call(guardWorkspaceBoundToolInput(input, compiledTool, binding), config);
|
|
152
|
+
}
|
|
153
|
+
if (prop === "func" && typeof value === "function") {
|
|
154
|
+
return (input, config) => obj.func(guardWorkspaceBoundToolInput(input, compiledTool, binding), config);
|
|
155
|
+
}
|
|
156
|
+
return value;
|
|
157
|
+
},
|
|
158
|
+
})
|
|
159
|
+
: resolvedTool;
|
|
160
|
+
return wrapToolWithDedupe(wrapToolForHumanInTheLoop(guardedTool, compiledTool, interruptFn), compiledTool);
|
|
108
161
|
}
|
|
@@ -154,6 +154,7 @@ export function compileBinding(workspaceRoot, agent, agents, referencedSubagentI
|
|
|
154
154
|
agent,
|
|
155
155
|
harnessRuntime: {
|
|
156
156
|
runRoot,
|
|
157
|
+
workspaceRoot,
|
|
157
158
|
hostFacing: !internalSubagent,
|
|
158
159
|
...(checkpointer ? { checkpointer: checkpointer.config } : {}),
|
|
159
160
|
...(store ? { store: store.config } : {}),
|