@botbotgo/agent-harness 0.0.2 → 0.0.4
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.
|
@@ -14,6 +14,7 @@ export declare class AgentRuntimeAdapter {
|
|
|
14
14
|
private applyStrictToolJsonInstruction;
|
|
15
15
|
private synthesizeDeepAgentAnswer;
|
|
16
16
|
private resolveModel;
|
|
17
|
+
private buildToolNameMapping;
|
|
17
18
|
private resolveTools;
|
|
18
19
|
private normalizeInterruptPolicy;
|
|
19
20
|
private compileInterruptOn;
|
|
@@ -9,6 +9,7 @@ import { extractReasoningText, extractToolFallbackContext, extractVisibleOutput,
|
|
|
9
9
|
import { extractAgentStep, extractInterruptPayload, extractReasoningStreamOutput, extractTerminalStreamOutput, extractToolResult, normalizeTerminalOutputKey, readStreamDelta, } from "./parsing/stream-event-parsing.js";
|
|
10
10
|
import { wrapToolForExecution } from "./tool-hitl.js";
|
|
11
11
|
const AGENT_INTERRUPT_SENTINEL_PREFIX = "__agent_harness_interrupt__:";
|
|
12
|
+
const MODEL_SAFE_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]+$/;
|
|
12
13
|
function asObject(value) {
|
|
13
14
|
return typeof value === "object" && value ? value : undefined;
|
|
14
15
|
}
|
|
@@ -25,6 +26,56 @@ function normalizeOpenAICompatibleInit(init) {
|
|
|
25
26
|
delete normalized.baseUrl;
|
|
26
27
|
return normalized;
|
|
27
28
|
}
|
|
29
|
+
function sanitizeToolNameForModel(name) {
|
|
30
|
+
const sanitized = name
|
|
31
|
+
.replaceAll(".", "__")
|
|
32
|
+
.replace(/[^a-zA-Z0-9_-]+/g, "_")
|
|
33
|
+
.replace(/^_+|_+$/g, "");
|
|
34
|
+
return sanitized || "tool";
|
|
35
|
+
}
|
|
36
|
+
function buildToolNameMapping(tools) {
|
|
37
|
+
const originalToModelFacing = new Map();
|
|
38
|
+
const modelFacingToOriginal = new Map();
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
for (const tool of tools) {
|
|
41
|
+
const originalName = tool.name;
|
|
42
|
+
const baseName = MODEL_SAFE_TOOL_NAME_PATTERN.test(originalName) ? originalName : sanitizeToolNameForModel(originalName);
|
|
43
|
+
let candidate = baseName;
|
|
44
|
+
let suffix = 2;
|
|
45
|
+
while (seen.has(candidate)) {
|
|
46
|
+
candidate = `${baseName}_${suffix}`;
|
|
47
|
+
suffix += 1;
|
|
48
|
+
}
|
|
49
|
+
seen.add(candidate);
|
|
50
|
+
originalToModelFacing.set(originalName, candidate);
|
|
51
|
+
modelFacingToOriginal.set(candidate, originalName);
|
|
52
|
+
}
|
|
53
|
+
return { originalToModelFacing, modelFacingToOriginal };
|
|
54
|
+
}
|
|
55
|
+
function wrapResolvedToolWithModelFacingName(resolvedTool, modelFacingName) {
|
|
56
|
+
if (typeof resolvedTool !== "object" || resolvedTool === null) {
|
|
57
|
+
return resolvedTool;
|
|
58
|
+
}
|
|
59
|
+
return new Proxy(resolvedTool, {
|
|
60
|
+
get(target, prop, receiver) {
|
|
61
|
+
if (prop === "name") {
|
|
62
|
+
return modelFacingName;
|
|
63
|
+
}
|
|
64
|
+
return Reflect.get(target, prop, receiver);
|
|
65
|
+
},
|
|
66
|
+
getOwnPropertyDescriptor(target, prop) {
|
|
67
|
+
if (prop === "name") {
|
|
68
|
+
return {
|
|
69
|
+
configurable: true,
|
|
70
|
+
enumerable: true,
|
|
71
|
+
writable: false,
|
|
72
|
+
value: modelFacingName,
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return Reflect.getOwnPropertyDescriptor(target, prop);
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
28
79
|
export class AgentRuntimeAdapter {
|
|
29
80
|
options;
|
|
30
81
|
constructor(options = {}) {
|
|
@@ -143,11 +194,20 @@ export class AgentRuntimeAdapter {
|
|
|
143
194
|
}
|
|
144
195
|
return wrapResolvedModel(await initChatModel(model.model, { modelProvider: model.provider, ...model.init }));
|
|
145
196
|
}
|
|
197
|
+
buildToolNameMapping(tools) {
|
|
198
|
+
return buildToolNameMapping(tools);
|
|
199
|
+
}
|
|
146
200
|
resolveTools(tools, binding) {
|
|
147
201
|
const resolved = this.options.toolResolver ? this.options.toolResolver(tools.map((tool) => tool.id), binding) : [];
|
|
202
|
+
const toolNameMapping = this.buildToolNameMapping(tools);
|
|
148
203
|
return resolved.map((resolvedTool, index) => {
|
|
149
204
|
const compiledTool = tools[index];
|
|
150
|
-
|
|
205
|
+
if (!compiledTool) {
|
|
206
|
+
return resolvedTool;
|
|
207
|
+
}
|
|
208
|
+
const wrappedTool = wrapToolForExecution(resolvedTool, compiledTool);
|
|
209
|
+
const modelFacingName = toolNameMapping.originalToModelFacing.get(compiledTool.name) ?? compiledTool.name;
|
|
210
|
+
return modelFacingName === compiledTool.name ? wrappedTool : wrapResolvedToolWithModelFacingName(wrappedTool, modelFacingName);
|
|
151
211
|
});
|
|
152
212
|
}
|
|
153
213
|
normalizeInterruptPolicy(rule) {
|
|
@@ -168,15 +228,17 @@ export class AgentRuntimeAdapter {
|
|
|
168
228
|
decisions.push("reject");
|
|
169
229
|
return decisions.length > 0 ? decisions : null;
|
|
170
230
|
}
|
|
171
|
-
compileInterruptOn(
|
|
231
|
+
compileInterruptOn(tools, compatibilityRules) {
|
|
232
|
+
const toolNameMapping = this.buildToolNameMapping(tools);
|
|
172
233
|
const compiled = new Map();
|
|
173
234
|
for (const [toolName, rule] of Object.entries(compatibilityRules ?? {})) {
|
|
235
|
+
const modelFacingName = toolNameMapping.originalToModelFacing.get(toolName) ?? toolName;
|
|
174
236
|
const allowedDecisions = this.normalizeInterruptPolicy(rule);
|
|
175
237
|
if (!allowedDecisions) {
|
|
176
|
-
compiled.delete(
|
|
238
|
+
compiled.delete(modelFacingName);
|
|
177
239
|
}
|
|
178
240
|
else {
|
|
179
|
-
compiled.set(
|
|
241
|
+
compiled.set(modelFacingName, { allowedDecisions });
|
|
180
242
|
}
|
|
181
243
|
}
|
|
182
244
|
return compiled.size > 0 ? Object.fromEntries(compiled.entries()) : undefined;
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@botbotgo/agent-harness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Agent Harness framework package",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"files": [
|
|
9
10
|
"dist"
|
|
@@ -19,11 +20,12 @@
|
|
|
19
20
|
"exports": {
|
|
20
21
|
".": {
|
|
21
22
|
"types": "./dist/index.d.ts",
|
|
23
|
+
"import": "./dist/index.js",
|
|
22
24
|
"default": "./dist/index.js"
|
|
23
25
|
}
|
|
24
26
|
},
|
|
25
27
|
"dependencies": {
|
|
26
|
-
"@botbotgo/agent-harness-builtin": "0.0.
|
|
28
|
+
"@botbotgo/agent-harness-builtin": "0.0.4"
|
|
27
29
|
},
|
|
28
30
|
"scripts": {
|
|
29
31
|
"build": "rm -rf dist tsconfig.tsbuildinfo && tsc -p tsconfig.json && cp -R config dist/",
|