@botbotgo/agent-harness 0.0.1

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.
Files changed (87) hide show
  1. package/dist/api.d.ts +22 -0
  2. package/dist/api.js +48 -0
  3. package/dist/config/direct.yaml +48 -0
  4. package/dist/config/embedding-model.yaml +30 -0
  5. package/dist/config/model.yaml +44 -0
  6. package/dist/config/orchestra.yaml +92 -0
  7. package/dist/config/runtime.yaml +47 -0
  8. package/dist/config/vector-store.yaml +26 -0
  9. package/dist/contracts/types.d.ts +359 -0
  10. package/dist/contracts/types.js +1 -0
  11. package/dist/extensions.d.ts +16 -0
  12. package/dist/extensions.js +251 -0
  13. package/dist/index.d.ts +7 -0
  14. package/dist/index.js +7 -0
  15. package/dist/persistence/file-store.d.ts +39 -0
  16. package/dist/persistence/file-store.js +282 -0
  17. package/dist/presentation.d.ts +4 -0
  18. package/dist/presentation.js +175 -0
  19. package/dist/runtime/agent-runtime-adapter.d.ts +33 -0
  20. package/dist/runtime/agent-runtime-adapter.js +445 -0
  21. package/dist/runtime/event-bus.d.ts +6 -0
  22. package/dist/runtime/event-bus.js +15 -0
  23. package/dist/runtime/file-checkpoint-saver.d.ts +20 -0
  24. package/dist/runtime/file-checkpoint-saver.js +91 -0
  25. package/dist/runtime/harness.d.ts +57 -0
  26. package/dist/runtime/harness.js +696 -0
  27. package/dist/runtime/index.d.ts +10 -0
  28. package/dist/runtime/index.js +10 -0
  29. package/dist/runtime/inventory.d.ts +25 -0
  30. package/dist/runtime/inventory.js +62 -0
  31. package/dist/runtime/parsing/index.d.ts +2 -0
  32. package/dist/runtime/parsing/index.js +2 -0
  33. package/dist/runtime/parsing/output-parsing.d.ts +12 -0
  34. package/dist/runtime/parsing/output-parsing.js +424 -0
  35. package/dist/runtime/parsing/stream-event-parsing.d.ts +27 -0
  36. package/dist/runtime/parsing/stream-event-parsing.js +161 -0
  37. package/dist/runtime/policy-engine.d.ts +9 -0
  38. package/dist/runtime/policy-engine.js +23 -0
  39. package/dist/runtime/store.d.ts +50 -0
  40. package/dist/runtime/store.js +118 -0
  41. package/dist/runtime/support/embedding-models.d.ts +4 -0
  42. package/dist/runtime/support/embedding-models.js +33 -0
  43. package/dist/runtime/support/harness-support.d.ts +27 -0
  44. package/dist/runtime/support/harness-support.js +116 -0
  45. package/dist/runtime/support/index.d.ts +4 -0
  46. package/dist/runtime/support/index.js +4 -0
  47. package/dist/runtime/support/llamaindex.d.ts +24 -0
  48. package/dist/runtime/support/llamaindex.js +108 -0
  49. package/dist/runtime/support/runtime-factories.d.ts +3 -0
  50. package/dist/runtime/support/runtime-factories.js +39 -0
  51. package/dist/runtime/support/skill-metadata.d.ts +1 -0
  52. package/dist/runtime/support/skill-metadata.js +34 -0
  53. package/dist/runtime/support/vector-stores.d.ts +7 -0
  54. package/dist/runtime/support/vector-stores.js +130 -0
  55. package/dist/runtime/thread-memory-sync.d.ts +14 -0
  56. package/dist/runtime/thread-memory-sync.js +88 -0
  57. package/dist/runtime/tool-hitl.d.ts +5 -0
  58. package/dist/runtime/tool-hitl.js +108 -0
  59. package/dist/utils/fs.d.ts +6 -0
  60. package/dist/utils/fs.js +39 -0
  61. package/dist/utils/id.d.ts +1 -0
  62. package/dist/utils/id.js +8 -0
  63. package/dist/vendor/builtins.d.ts +23 -0
  64. package/dist/vendor/builtins.js +103 -0
  65. package/dist/vendor/sources.d.ts +12 -0
  66. package/dist/vendor/sources.js +115 -0
  67. package/dist/workspace/agent-binding-compiler.d.ts +4 -0
  68. package/dist/workspace/agent-binding-compiler.js +181 -0
  69. package/dist/workspace/compile.d.ts +2 -0
  70. package/dist/workspace/compile.js +107 -0
  71. package/dist/workspace/index.d.ts +6 -0
  72. package/dist/workspace/index.js +6 -0
  73. package/dist/workspace/object-loader.d.ts +16 -0
  74. package/dist/workspace/object-loader.js +405 -0
  75. package/dist/workspace/resource-compilers.d.ts +13 -0
  76. package/dist/workspace/resource-compilers.js +182 -0
  77. package/dist/workspace/support/discovery.d.ts +5 -0
  78. package/dist/workspace/support/discovery.js +108 -0
  79. package/dist/workspace/support/index.d.ts +2 -0
  80. package/dist/workspace/support/index.js +2 -0
  81. package/dist/workspace/support/source-collectors.d.ts +3 -0
  82. package/dist/workspace/support/source-collectors.js +30 -0
  83. package/dist/workspace/support/workspace-ref-utils.d.ts +8 -0
  84. package/dist/workspace/support/workspace-ref-utils.js +50 -0
  85. package/dist/workspace/validate.d.ts +3 -0
  86. package/dist/workspace/validate.js +65 -0
  87. package/package.json +32 -0
@@ -0,0 +1,10 @@
1
+ export { AgentRuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX } from "./agent-runtime-adapter.js";
2
+ export { EventBus } from "./event-bus.js";
3
+ export { FileCheckpointSaver } from "./file-checkpoint-saver.js";
4
+ export { AgentHarness } from "./harness.js";
5
+ export { describeWorkspaceInventory, findAgentBinding, listAgentSkills, listAgentTools, listAvailableAgents, listSpecialists, } from "./inventory.js";
6
+ export * from "./parsing/index.js";
7
+ export { PolicyEngine } from "./policy-engine.js";
8
+ export { createInMemoryStore, FileBackedStore } from "./store.js";
9
+ export * from "./support/index.js";
10
+ export { ThreadMemorySync } from "./thread-memory-sync.js";
@@ -0,0 +1,10 @@
1
+ export { AgentRuntimeAdapter, AGENT_INTERRUPT_SENTINEL_PREFIX } from "./agent-runtime-adapter.js";
2
+ export { EventBus } from "./event-bus.js";
3
+ export { FileCheckpointSaver } from "./file-checkpoint-saver.js";
4
+ export { AgentHarness } from "./harness.js";
5
+ export { describeWorkspaceInventory, findAgentBinding, listAgentSkills, listAgentTools, listAvailableAgents, listSpecialists, } from "./inventory.js";
6
+ export * from "./parsing/index.js";
7
+ export { PolicyEngine } from "./policy-engine.js";
8
+ export { createInMemoryStore, FileBackedStore } from "./store.js";
9
+ export * from "./support/index.js";
10
+ export { ThreadMemorySync } from "./thread-memory-sync.js";
@@ -0,0 +1,25 @@
1
+ import type { CompiledAgentBinding, WorkspaceBundle } from "../contracts/types.js";
2
+ export type InventoryToolRecord = {
3
+ name: string;
4
+ description: string;
5
+ };
6
+ export type InventorySkillRecord = {
7
+ name: string;
8
+ path: string;
9
+ };
10
+ export type InventoryAgentRecord = {
11
+ id: string;
12
+ description: string;
13
+ role: "host" | "specialist";
14
+ tools: InventoryToolRecord[];
15
+ skills: InventorySkillRecord[];
16
+ };
17
+ export declare function findAgentBinding(workspace: WorkspaceBundle, agentId: string): CompiledAgentBinding | undefined;
18
+ export declare function listAgentTools(workspace: WorkspaceBundle, agentId: string): InventoryToolRecord[];
19
+ export declare function listAgentSkills(workspace: WorkspaceBundle, agentId: string): InventorySkillRecord[];
20
+ export declare function listSpecialists(workspace: WorkspaceBundle): InventoryAgentRecord[];
21
+ export declare function listAvailableAgents(workspace: WorkspaceBundle): InventoryAgentRecord[];
22
+ export declare function describeWorkspaceInventory(workspace: WorkspaceBundle): {
23
+ workspaceRoot: string;
24
+ agents: InventoryAgentRecord[];
25
+ };
@@ -0,0 +1,62 @@
1
+ import { readSkillName } from "./support/skill-metadata.js";
2
+ function listHostBindings(workspace) {
3
+ return Array.from(workspace.bindings.values()).filter((binding) => binding.harnessRuntime.hostFacing);
4
+ }
5
+ export function findAgentBinding(workspace, agentId) {
6
+ return workspace.bindings.get(agentId);
7
+ }
8
+ function dedupeTools(tools) {
9
+ const deduped = new Map();
10
+ for (const tool of tools) {
11
+ deduped.set(tool.name, { name: tool.name, description: tool.description });
12
+ }
13
+ return Array.from(deduped.values());
14
+ }
15
+ function toSkillRecords(skillPaths) {
16
+ return Array.from(new Set(skillPaths)).map((skillPath) => ({
17
+ name: readSkillName(skillPath),
18
+ path: skillPath,
19
+ }));
20
+ }
21
+ export function listAgentTools(workspace, agentId) {
22
+ const binding = findAgentBinding(workspace, agentId);
23
+ if (!binding) {
24
+ return [];
25
+ }
26
+ return dedupeTools(binding.langchainAgentParams?.tools ?? binding.deepAgentParams?.tools ?? []);
27
+ }
28
+ export function listAgentSkills(workspace, agentId) {
29
+ const binding = findAgentBinding(workspace, agentId);
30
+ if (!binding) {
31
+ return [];
32
+ }
33
+ return toSkillRecords(binding.deepAgentParams?.skills ?? []);
34
+ }
35
+ function describeSubagent(subagent) {
36
+ return {
37
+ id: subagent.name,
38
+ description: subagent.description,
39
+ role: "specialist",
40
+ tools: dedupeTools(subagent.tools ?? []),
41
+ skills: toSkillRecords(subagent.skills ?? []),
42
+ };
43
+ }
44
+ export function listSpecialists(workspace) {
45
+ return listHostBindings(workspace).flatMap((binding) => (binding.deepAgentParams?.subagents ?? []).map(describeSubagent));
46
+ }
47
+ export function listAvailableAgents(workspace) {
48
+ const topLevel = listHostBindings(workspace).map((binding) => ({
49
+ id: binding.agent.id,
50
+ description: binding.agent.description,
51
+ role: "host",
52
+ tools: listAgentTools(workspace, binding.agent.id),
53
+ skills: listAgentSkills(workspace, binding.agent.id),
54
+ }));
55
+ return [...topLevel, ...listSpecialists(workspace)];
56
+ }
57
+ export function describeWorkspaceInventory(workspace) {
58
+ return {
59
+ workspaceRoot: workspace.workspaceRoot,
60
+ agents: listAvailableAgents(workspace),
61
+ };
62
+ }
@@ -0,0 +1,2 @@
1
+ export { extractReasoningText, extractToolFallbackContext, extractVisibleOutput, hasToolCalls, isLikelyToolArgsObject, readTextContent, sanitizeVisibleText, tryParseJson, wrapResolvedModel, } from "./output-parsing.js";
2
+ export { extractAgentStep, extractInterruptPayload, extractReasoningStreamOutput, extractTerminalStreamOutput, extractToolResult, normalizeTerminalOutputKey, readStreamDelta, type RuntimeStreamChunk, } from "./stream-event-parsing.js";
@@ -0,0 +1,2 @@
1
+ export { extractReasoningText, extractToolFallbackContext, extractVisibleOutput, hasToolCalls, isLikelyToolArgsObject, readTextContent, sanitizeVisibleText, tryParseJson, wrapResolvedModel, } from "./output-parsing.js";
2
+ export { extractAgentStep, extractInterruptPayload, extractReasoningStreamOutput, extractTerminalStreamOutput, extractToolResult, normalizeTerminalOutputKey, readStreamDelta, } from "./stream-event-parsing.js";
@@ -0,0 +1,12 @@
1
+ export declare function sanitizeVisibleText(value: string): string;
2
+ export declare function tryParseJson(value: string): unknown | null;
3
+ export declare function salvageToolArgs(value: unknown): Record<string, unknown> | null;
4
+ export declare function isLikelyToolArgsObject(value: unknown): boolean;
5
+ export declare function readTextContent(value: unknown): string;
6
+ export declare function hasToolCalls(value: unknown): boolean;
7
+ export declare function extractToolFallbackContext(value: unknown): string;
8
+ export declare function extractVisibleOutput(value: unknown): string;
9
+ export declare function isToolCallParseFailure(error: unknown): boolean;
10
+ export declare const STRICT_TOOL_JSON_INSTRUCTION = "When calling tools, return only the tool call itself. The arguments must be a pure JSON object with no explanatory text before or after it.";
11
+ export declare function wrapResolvedModel<T>(value: T): T;
12
+ export declare function extractReasoningText(value: unknown): string;
@@ -0,0 +1,424 @@
1
+ import { AIMessage } from "langchain";
2
+ export function sanitizeVisibleText(value) {
3
+ return value
4
+ .replace(/[A-Za-z0-9_]*Middleware\.after_model/g, "")
5
+ .replace(/todoListMiddleware\.after_model/g, "")
6
+ .replace(/__end__+/g, "")
7
+ .trim();
8
+ }
9
+ export function tryParseJson(value) {
10
+ try {
11
+ return JSON.parse(value);
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ function extractBalancedJsonObject(value) {
18
+ const start = value.indexOf("{");
19
+ if (start < 0)
20
+ return null;
21
+ let depth = 0;
22
+ let inString = false;
23
+ let escaping = false;
24
+ for (let index = start; index < value.length; index += 1) {
25
+ const char = value[index];
26
+ if (inString) {
27
+ if (escaping) {
28
+ escaping = false;
29
+ continue;
30
+ }
31
+ if (char === "\\") {
32
+ escaping = true;
33
+ continue;
34
+ }
35
+ if (char === "\"") {
36
+ inString = false;
37
+ }
38
+ continue;
39
+ }
40
+ if (char === "\"") {
41
+ inString = true;
42
+ continue;
43
+ }
44
+ if (char === "{") {
45
+ depth += 1;
46
+ continue;
47
+ }
48
+ if (char === "}") {
49
+ depth -= 1;
50
+ if (depth === 0) {
51
+ return value.slice(start, index + 1);
52
+ }
53
+ }
54
+ }
55
+ return null;
56
+ }
57
+ export function salvageToolArgs(value) {
58
+ if (typeof value === "object" && value && !Array.isArray(value)) {
59
+ return value;
60
+ }
61
+ if (typeof value !== "string") {
62
+ return null;
63
+ }
64
+ const trimmed = value.trim();
65
+ if (!trimmed) {
66
+ return {};
67
+ }
68
+ const direct = tryParseJson(trimmed);
69
+ if (typeof direct === "object" && direct && !Array.isArray(direct)) {
70
+ return direct;
71
+ }
72
+ const embedded = extractBalancedJsonObject(trimmed);
73
+ if (!embedded) {
74
+ return null;
75
+ }
76
+ const parsed = tryParseJson(embedded);
77
+ return typeof parsed === "object" && parsed && !Array.isArray(parsed) ? parsed : null;
78
+ }
79
+ function normalizeWriteTodosArgs(args) {
80
+ if (!Array.isArray(args.todos)) {
81
+ return args;
82
+ }
83
+ return {
84
+ ...args,
85
+ todos: args.todos.map((todo) => {
86
+ if (typeof todo !== "object" || !todo || Array.isArray(todo)) {
87
+ return todo;
88
+ }
89
+ const record = todo;
90
+ const content = typeof record.content === "string" && record.content.trim().length > 0
91
+ ? record.content
92
+ : typeof record.description === "string" && record.description.trim().length > 0
93
+ ? record.description
94
+ : undefined;
95
+ const normalized = {};
96
+ if (content !== undefined)
97
+ normalized.content = content;
98
+ if (typeof record.status === "string")
99
+ normalized.status = record.status;
100
+ return Object.keys(normalized).length > 0 ? normalized : todo;
101
+ }),
102
+ };
103
+ }
104
+ function normalizeKnownToolArgs(toolName, args) {
105
+ if (toolName === "write_todos") {
106
+ return normalizeWriteTodosArgs(args);
107
+ }
108
+ return args;
109
+ }
110
+ export function isLikelyToolArgsObject(value) {
111
+ if (typeof value !== "object" || !value || Array.isArray(value)) {
112
+ return false;
113
+ }
114
+ const keys = Object.keys(value);
115
+ if (keys.length === 0 || keys.length > 8) {
116
+ return false;
117
+ }
118
+ if (keys.some((key) => ["messages", "output", "content", "todos", "files", "skillsMetadata", "memoryContents"].includes(key))) {
119
+ return false;
120
+ }
121
+ return Object.values(value).every((item) => {
122
+ if (item == null)
123
+ return true;
124
+ if (typeof item === "string" || typeof item === "number" || typeof item === "boolean")
125
+ return true;
126
+ return Array.isArray(item) && item.every((entry) => typeof entry === "string" || typeof entry === "number" || typeof entry === "boolean");
127
+ });
128
+ }
129
+ function isLikelyMemoryWriteArgsObject(value) {
130
+ if (typeof value !== "object" || !value || Array.isArray(value)) {
131
+ return false;
132
+ }
133
+ const typed = value;
134
+ const target = typeof typed.file_path === "string"
135
+ ? typed.file_path
136
+ : typeof typed.path === "string"
137
+ ? typed.path
138
+ : "";
139
+ return target.startsWith("/memories/") && typeof typed.content === "string";
140
+ }
141
+ export function readTextContent(value) {
142
+ if (typeof value === "string")
143
+ return value;
144
+ if (Array.isArray(value))
145
+ return value.map((item) => readTextContent(item)).join("");
146
+ if (typeof value === "object" && value) {
147
+ if (isLikelyMemoryWriteArgsObject(value)) {
148
+ return "";
149
+ }
150
+ if ("text" in value && typeof value.text === "string") {
151
+ return value.text;
152
+ }
153
+ if ("content" in value) {
154
+ return readTextContent(value.content);
155
+ }
156
+ if ("lc_kwargs" in value && typeof value.lc_kwargs === "object") {
157
+ return readTextContent((value.lc_kwargs).content);
158
+ }
159
+ if ("kwargs" in value && typeof value.kwargs === "object") {
160
+ return readTextContent((value.kwargs).content);
161
+ }
162
+ }
163
+ return "";
164
+ }
165
+ function extractMessageContent(message) {
166
+ if (typeof message !== "object" || !message)
167
+ return "";
168
+ const typed = message;
169
+ if (typeof typed.content === "string")
170
+ return typed.content;
171
+ if (typeof typed.kwargs === "object" && typed.kwargs) {
172
+ return readTextContent(typed.kwargs.content);
173
+ }
174
+ return "";
175
+ }
176
+ function isToolMessageLike(message) {
177
+ if (typeof message !== "object" || !message)
178
+ return false;
179
+ const typed = message;
180
+ const ids = Array.isArray(typed.id) ? typed.id.filter((item) => typeof item === "string") : [];
181
+ const typeName = ids.at(-1);
182
+ const runtimeType = typeof typed._getType === "function"
183
+ ? typed._getType()
184
+ : typeof typed.getType === "function"
185
+ ? typed.getType()
186
+ : undefined;
187
+ return typeName === "ToolMessage" || runtimeType === "tool";
188
+ }
189
+ function extractToolMessageContents(messages) {
190
+ if (!Array.isArray(messages))
191
+ return [];
192
+ const results = [];
193
+ for (const message of messages) {
194
+ if (!isToolMessageLike(message))
195
+ continue;
196
+ const content = extractMessageContent(message);
197
+ if (content)
198
+ results.push(content);
199
+ }
200
+ return results;
201
+ }
202
+ export function hasToolCalls(value) {
203
+ if (typeof value !== "object" || !value)
204
+ return false;
205
+ const typed = value;
206
+ if (Array.isArray(typed.tool_calls) && typed.tool_calls.length > 0)
207
+ return true;
208
+ if (typeof typed.kwargs === "object" && typed.kwargs) {
209
+ return Array.isArray(typed.kwargs.tool_calls) && typed.kwargs.tool_calls.length > 0;
210
+ }
211
+ return false;
212
+ }
213
+ function extractAssistantTextFromMessages(messages) {
214
+ if (!Array.isArray(messages))
215
+ return "";
216
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
217
+ const message = messages[index];
218
+ if (typeof message !== "object" || !message)
219
+ continue;
220
+ const typed = message;
221
+ const ids = Array.isArray(typed.id) ? typed.id.filter((item) => typeof item === "string") : [];
222
+ const typeName = ids.at(-1);
223
+ const runtimeType = typeof message._getType === "function"
224
+ ? message._getType()
225
+ : typeof message.getType === "function"
226
+ ? message.getType()
227
+ : undefined;
228
+ const kwargs = typeof typed.kwargs === "object" && typed.kwargs ? typed.kwargs : undefined;
229
+ if (typeName === "AIMessage" || runtimeType === "ai" || kwargs?.content !== undefined) {
230
+ if (hasToolCalls(message))
231
+ continue;
232
+ if (Array.isArray(kwargs?.tool_calls) && kwargs.tool_calls.length > 0)
233
+ continue;
234
+ const content = extractMessageContent(message);
235
+ if (content)
236
+ return content;
237
+ }
238
+ }
239
+ return "";
240
+ }
241
+ function extractStructuredOutputText(value) {
242
+ if (typeof value !== "object" || !value)
243
+ return "";
244
+ if (isLikelyMemoryWriteArgsObject(value))
245
+ return "";
246
+ const typed = value;
247
+ const fromMessages = extractAssistantTextFromMessages(typed.messages);
248
+ if (fromMessages)
249
+ return fromMessages;
250
+ if (typed.output && typeof typed.output === "object") {
251
+ const outputRecord = typed.output;
252
+ const nestedMessages = extractAssistantTextFromMessages(outputRecord.messages);
253
+ if (nestedMessages)
254
+ return nestedMessages;
255
+ const nestedContent = readTextContent(outputRecord.content);
256
+ if (nestedContent)
257
+ return nestedContent;
258
+ }
259
+ return readTextContent(typed.content);
260
+ }
261
+ export function extractToolFallbackContext(value) {
262
+ if (typeof value !== "object" || !value)
263
+ return "";
264
+ const typed = value;
265
+ const messages = extractToolMessageContents(typed.messages);
266
+ if (messages.length > 0)
267
+ return messages.slice(-3).join("\n\n");
268
+ if (typed.output && typeof typed.output === "object") {
269
+ const nested = extractToolFallbackContext(typed.output);
270
+ if (nested)
271
+ return nested;
272
+ }
273
+ return "";
274
+ }
275
+ export function extractVisibleOutput(value) {
276
+ const structured = extractStructuredOutputText(value);
277
+ if (structured)
278
+ return structured;
279
+ if (typeof value === "string") {
280
+ const parsed = tryParseJson(value);
281
+ if (parsed) {
282
+ if (isLikelyMemoryWriteArgsObject(parsed))
283
+ return "";
284
+ const parsedStructured = extractStructuredOutputText(parsed);
285
+ if (parsedStructured)
286
+ return parsedStructured;
287
+ if (isLikelyToolArgsObject(parsed))
288
+ return "";
289
+ }
290
+ return value;
291
+ }
292
+ if (typeof value === "object" && value) {
293
+ const typed = value;
294
+ if (typed.output !== undefined) {
295
+ const nested = extractVisibleOutput(typed.output);
296
+ if (nested)
297
+ return nested;
298
+ }
299
+ if (typed.content !== undefined) {
300
+ const nested = extractVisibleOutput(typed.content);
301
+ if (nested)
302
+ return nested;
303
+ }
304
+ }
305
+ return "";
306
+ }
307
+ function isAiMessageLike(value) {
308
+ if (typeof value !== "object" || !value)
309
+ return false;
310
+ const typed = value;
311
+ return typeof typed._getType === "function" && typed._getType() === "ai" && ("content" in typed || "tool_calls" in typed);
312
+ }
313
+ function normalizeAgentMessage(value) {
314
+ if (!AIMessage.isInstance(value) && !isAiMessageLike(value))
315
+ return value;
316
+ const typed = value;
317
+ const normalizedToolCalls = Array.isArray(typed.tool_calls)
318
+ ? typed.tool_calls.map((toolCall) => {
319
+ if (typeof toolCall !== "object" || !toolCall)
320
+ return toolCall;
321
+ const parsedArgs = salvageToolArgs(toolCall.args);
322
+ return parsedArgs ? { ...toolCall, args: normalizeKnownToolArgs(toolCall.name, parsedArgs) } : toolCall;
323
+ })
324
+ : [];
325
+ const normalizedInvalidToolCalls = Array.isArray(typed.invalid_tool_calls)
326
+ ? typed.invalid_tool_calls
327
+ .map((toolCall) => {
328
+ if (typeof toolCall !== "object" || !toolCall)
329
+ return null;
330
+ const parsedArgs = salvageToolArgs(toolCall.args);
331
+ if (!parsedArgs)
332
+ return toolCall;
333
+ return {
334
+ ...toolCall,
335
+ args: normalizeKnownToolArgs(toolCall.name, parsedArgs),
336
+ type: "tool_call",
337
+ error: undefined,
338
+ };
339
+ })
340
+ .filter((toolCall) => toolCall !== null)
341
+ : [];
342
+ const recoveredToolCalls = normalizedInvalidToolCalls.filter((toolCall) => typeof toolCall.args === "object" && !!toolCall.args && !Array.isArray(toolCall.args));
343
+ const normalizedContent = typeof typed.content === "string" || Array.isArray(typed.content)
344
+ ? typed.content
345
+ : typeof typed.content === "object" && typed.content
346
+ ? readTextContent(typed.content)
347
+ : "";
348
+ return new AIMessage({
349
+ content: normalizedContent,
350
+ name: typeof typed.name === "string" ? typed.name : undefined,
351
+ additional_kwargs: typeof typed.additional_kwargs === "object" && typed.additional_kwargs ? typed.additional_kwargs : {},
352
+ response_metadata: typeof typed.response_metadata === "object" && typed.response_metadata ? typed.response_metadata : {},
353
+ id: typeof typed.id === "string" ? typed.id : undefined,
354
+ tool_calls: [...normalizedToolCalls, ...recoveredToolCalls],
355
+ invalid_tool_calls: normalizedInvalidToolCalls.filter((toolCall) => toolCall.type !== "tool_call"),
356
+ usage_metadata: typeof typed.usage_metadata === "object" && typed.usage_metadata ? typed.usage_metadata : undefined,
357
+ });
358
+ }
359
+ export function isToolCallParseFailure(error) {
360
+ if (!(error instanceof Error))
361
+ return false;
362
+ return /error parsing tool call:/i.test(error.message);
363
+ }
364
+ export const STRICT_TOOL_JSON_INSTRUCTION = "When calling tools, return only the tool call itself. The arguments must be a pure JSON object with no explanatory text before or after it.";
365
+ function appendStrictToolInstruction(input) {
366
+ if (Array.isArray(input)) {
367
+ return [...input, { role: "system", content: STRICT_TOOL_JSON_INSTRUCTION }];
368
+ }
369
+ if (typeof input === "object" && input && Array.isArray(input.messages)) {
370
+ return {
371
+ ...input,
372
+ messages: [...(input.messages), { role: "system", content: STRICT_TOOL_JSON_INSTRUCTION }],
373
+ };
374
+ }
375
+ return input;
376
+ }
377
+ export function wrapResolvedModel(value) {
378
+ if (typeof value !== "object" || value === null)
379
+ return value;
380
+ const target = value;
381
+ return new Proxy(target, {
382
+ get(currentTarget, prop, receiver) {
383
+ const member = Reflect.get(currentTarget, prop, receiver);
384
+ if (prop === "invoke" && typeof member === "function") {
385
+ return async (...args) => {
386
+ try {
387
+ return normalizeAgentMessage(await member.apply(currentTarget, args));
388
+ }
389
+ catch (error) {
390
+ if (!isToolCallParseFailure(error)) {
391
+ throw error;
392
+ }
393
+ const retryArgs = [...args];
394
+ retryArgs[0] = appendStrictToolInstruction(retryArgs[0]);
395
+ return normalizeAgentMessage(await member.apply(currentTarget, retryArgs));
396
+ }
397
+ };
398
+ }
399
+ if ((prop === "bindTools" || prop === "withConfig" || prop === "withStructuredOutput") && typeof member === "function") {
400
+ return (...args) => wrapResolvedModel(member.apply(currentTarget, args));
401
+ }
402
+ if (typeof member === "function")
403
+ return member.bind(currentTarget);
404
+ return member;
405
+ },
406
+ });
407
+ }
408
+ export function extractReasoningText(value) {
409
+ if (typeof value !== "object" || !value)
410
+ return "";
411
+ const typed = value;
412
+ const chunk = typed.data?.chunk ?? value;
413
+ if (typeof chunk !== "object" || !chunk)
414
+ return "";
415
+ if ("additional_kwargs" in chunk && typeof chunk.additional_kwargs === "object") {
416
+ const kwargs = chunk.additional_kwargs;
417
+ return typeof kwargs?.reasoning === "string" ? kwargs.reasoning : "";
418
+ }
419
+ if ("kwargs" in chunk && typeof chunk.kwargs === "object") {
420
+ const kwargs = chunk.kwargs;
421
+ return typeof kwargs?.additional_kwargs?.reasoning === "string" ? kwargs.additional_kwargs.reasoning : "";
422
+ }
423
+ return "";
424
+ }
@@ -0,0 +1,27 @@
1
+ export type RuntimeStreamChunk = {
2
+ kind: "content";
3
+ content: string;
4
+ } | {
5
+ kind: "reasoning";
6
+ content: string;
7
+ } | {
8
+ kind: "interrupt";
9
+ content: string;
10
+ } | {
11
+ kind: "step";
12
+ content: string;
13
+ } | {
14
+ kind: "tool-result";
15
+ toolName: string;
16
+ output: unknown;
17
+ };
18
+ export declare function extractTerminalStreamOutput(event: unknown): string;
19
+ export declare function extractReasoningStreamOutput(event: unknown): string;
20
+ export declare function extractAgentStep(event: unknown): string | null;
21
+ export declare function extractToolResult(event: unknown): {
22
+ toolName: string;
23
+ output: unknown;
24
+ } | null;
25
+ export declare function extractInterruptPayload(event: unknown): string | null;
26
+ export declare function normalizeTerminalOutputKey(value: string): string;
27
+ export declare function readStreamDelta(chunk: unknown): string;