@tyvm/knowhow 0.0.20 → 0.0.22

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 (72) hide show
  1. package/package.json +3 -1
  2. package/src/agents/base/base.ts +16 -77
  3. package/src/agents/tools/executeScript/README.md +78 -0
  4. package/src/agents/tools/executeScript/definition.ts +73 -0
  5. package/src/agents/tools/executeScript/examples/quick-test.ts +80 -0
  6. package/src/agents/tools/executeScript/examples/serialization-test.ts +309 -0
  7. package/src/agents/tools/executeScript/examples/test-runner.ts +204 -0
  8. package/src/agents/tools/executeScript/index.ts +74 -0
  9. package/src/agents/tools/index.ts +1 -0
  10. package/src/agents/tools/list.ts +2 -1
  11. package/src/cli.ts +2 -6
  12. package/src/clients/index.ts +23 -9
  13. package/src/services/Tools.ts +150 -9
  14. package/src/services/script-execution/SandboxContext.ts +278 -0
  15. package/src/services/script-execution/ScriptExecutor.ts +337 -0
  16. package/src/services/script-execution/ScriptPolicy.ts +236 -0
  17. package/src/services/script-execution/ScriptTracer.ts +249 -0
  18. package/src/services/script-execution/types.ts +134 -0
  19. package/ts_build/src/agents/base/base.js +2 -53
  20. package/ts_build/src/agents/base/base.js.map +1 -1
  21. package/ts_build/src/agents/tools/executeScript/definition.d.ts +2 -0
  22. package/ts_build/src/agents/tools/executeScript/definition.js +70 -0
  23. package/ts_build/src/agents/tools/executeScript/definition.js.map +1 -0
  24. package/ts_build/src/agents/tools/executeScript/examples/quick-test.d.ts +3 -0
  25. package/ts_build/src/agents/tools/executeScript/examples/quick-test.js +68 -0
  26. package/ts_build/src/agents/tools/executeScript/examples/quick-test.js.map +1 -0
  27. package/ts_build/src/agents/tools/executeScript/examples/serialization-test.d.ts +15 -0
  28. package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js +267 -0
  29. package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js.map +1 -0
  30. package/ts_build/src/agents/tools/executeScript/examples/simple-example.d.ts +20 -0
  31. package/ts_build/src/agents/tools/executeScript/examples/simple-example.js +35 -0
  32. package/ts_build/src/agents/tools/executeScript/examples/simple-example.js.map +1 -0
  33. package/ts_build/src/agents/tools/executeScript/examples/test-runner.d.ts +4 -0
  34. package/ts_build/src/agents/tools/executeScript/examples/test-runner.js +202 -0
  35. package/ts_build/src/agents/tools/executeScript/examples/test-runner.js.map +1 -0
  36. package/ts_build/src/agents/tools/executeScript/handler.d.ts +27 -0
  37. package/ts_build/src/agents/tools/executeScript/handler.js +64 -0
  38. package/ts_build/src/agents/tools/executeScript/handler.js.map +1 -0
  39. package/ts_build/src/agents/tools/executeScript/index.d.ts +27 -0
  40. package/ts_build/src/agents/tools/executeScript/index.js +64 -0
  41. package/ts_build/src/agents/tools/executeScript/index.js.map +1 -0
  42. package/ts_build/src/agents/tools/executeScript.d.ts +29 -0
  43. package/ts_build/src/agents/tools/executeScript.js +124 -0
  44. package/ts_build/src/agents/tools/executeScript.js.map +1 -0
  45. package/ts_build/src/agents/tools/index.d.ts +1 -0
  46. package/ts_build/src/agents/tools/index.js +1 -0
  47. package/ts_build/src/agents/tools/index.js.map +1 -1
  48. package/ts_build/src/agents/tools/list.js +2 -0
  49. package/ts_build/src/agents/tools/list.js.map +1 -1
  50. package/ts_build/src/cli.js +2 -6
  51. package/ts_build/src/cli.js.map +1 -1
  52. package/ts_build/src/clients/index.d.ts +9 -2
  53. package/ts_build/src/clients/index.js +17 -4
  54. package/ts_build/src/clients/index.js.map +1 -1
  55. package/ts_build/src/services/Tools.d.ts +11 -1
  56. package/ts_build/src/services/Tools.js +94 -3
  57. package/ts_build/src/services/Tools.js.map +1 -1
  58. package/ts_build/src/services/script-execution/SandboxContext.d.ts +34 -0
  59. package/ts_build/src/services/script-execution/SandboxContext.js +188 -0
  60. package/ts_build/src/services/script-execution/SandboxContext.js.map +1 -0
  61. package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +17 -0
  62. package/ts_build/src/services/script-execution/ScriptExecutor.js +207 -0
  63. package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -0
  64. package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +27 -0
  65. package/ts_build/src/services/script-execution/ScriptPolicy.js +150 -0
  66. package/ts_build/src/services/script-execution/ScriptPolicy.js.map +1 -0
  67. package/ts_build/src/services/script-execution/ScriptTracer.d.ts +19 -0
  68. package/ts_build/src/services/script-execution/ScriptTracer.js +186 -0
  69. package/ts_build/src/services/script-execution/ScriptTracer.js.map +1 -0
  70. package/ts_build/src/services/script-execution/types.d.ts +108 -0
  71. package/ts_build/src/services/script-execution/types.js +3 -0
  72. package/ts_build/src/services/script-execution/types.js.map +1 -0
@@ -0,0 +1,204 @@
1
+ #!/usr/bin/env ts-node
2
+ /**
3
+ * Test runner for the executeScript tool
4
+ * Usage: npx ts-node src/agents/tools/executeScript/examples/test-runner.ts
5
+ */
6
+
7
+ import { executeScript } from "../../executeScript";
8
+ import { Tools } from "../../../../services";
9
+ import { Clients } from "../../../../clients";
10
+ import { includedTools } from "../../../tools/list";
11
+ import * as allTools from "../../../tools";
12
+
13
+ // Sample script to test with
14
+ const testScript = `
15
+ // Test script that demonstrates various executeScript capabilities
16
+ console.log("Starting test script execution...");
17
+
18
+ async function main() {
19
+ // Test 1: Simple console output
20
+ console.log("Test 1: Basic logging works");
21
+
22
+ // Test 2: Call a tool (file search)
23
+ try {
24
+ console.log("Test 2: Calling fileSearch tool...");
25
+ const searchResult = await callTool("fileSearch", {
26
+ searchTerm: "package.json"
27
+ });
28
+ console.log("File search result:", searchResult);
29
+ } catch (error) {
30
+ console.error("Tool call failed:", error.message);
31
+ }
32
+
33
+ // Test 3: Call another tool (text search)
34
+ try {
35
+ console.log("Test 3: Calling textSearch tool...");
36
+ const textResult = await callTool("textSearch", {
37
+ searchTerm: "executeScript"
38
+ });
39
+ console.log("Text search found", textResult?.length || 0, "matches");
40
+ } catch (error) {
41
+ console.error("Text search failed:", error.message);
42
+ }
43
+
44
+ // Test 4: Make an LLM call
45
+ try {
46
+ console.log("Test 4: Making LLM call...");
47
+ const llmResponse = await llm([
48
+ {
49
+ role: "system",
50
+ content: "You are a helpful assistant. Respond with exactly one sentence."
51
+ },
52
+ {
53
+ role: "user",
54
+ content: "What is 2+2? Just give the answer briefly."
55
+ }
56
+ ], {
57
+ model: "gpt-4o-mini",
58
+ max_tokens: 50
59
+ });
60
+
61
+ console.log("LLM Response:", llmResponse.choices[0].message.content);
62
+ } catch (error) {
63
+ console.error("LLM call failed:", error.message);
64
+ }
65
+
66
+ // Test 5: Create an artifact
67
+ try {
68
+ console.log("Test 5: Creating artifact...");
69
+ createArtifact("test-results.md", \`# Test Results
70
+
71
+ Script executed successfully at: \${new Date().toISOString()}
72
+
73
+ This is a test artifact created by the executeScript tool.
74
+
75
+ ## Test Summary
76
+ - Console logging: ✓
77
+ - Tool calls: ✓
78
+ - LLM calls: ✓
79
+ - Artifact creation: ✓
80
+ \`, "markdown");
81
+ console.log("Artifact created successfully");
82
+ } catch (error) {
83
+ console.error("Artifact creation failed:", error.message);
84
+ }
85
+
86
+ // Return final result
87
+ return {
88
+ success: true,
89
+ message: "All tests completed successfully",
90
+ timestamp: new Date().toISOString(),
91
+ testsRun: 5
92
+ };
93
+ }
94
+
95
+ // Execute the main function
96
+ await main().then(result => {
97
+ console.log("=== SCRIPT COMPLETED ===");
98
+ console.log("Final result:", JSON.stringify(result, null, 2));
99
+ }).catch(error => {
100
+ console.error("=== SCRIPT FAILED ===");
101
+ console.error("Error:", error);
102
+ throw error;
103
+ });
104
+ `;
105
+
106
+ async function runTest() {
107
+ console.log("🚀 Starting executeScript test...\n");
108
+
109
+ try {
110
+ Tools.defineTools(includedTools, allTools);
111
+
112
+ const context = {
113
+ tools: Tools,
114
+ clients: Clients,
115
+ };
116
+
117
+ console.log("📋 Test Parameters:");
118
+ console.log("- Max Tool Calls: 10");
119
+ console.log("- Max Tokens: 1000");
120
+ console.log("- Max Execution Time: 60s");
121
+ console.log("- Max Cost: $0.50\n");
122
+
123
+ const startTime = Date.now();
124
+
125
+ // Execute the test script
126
+ const result = await executeScript(
127
+ {
128
+ script: testScript,
129
+ maxToolCalls: 10,
130
+ maxTokens: 1000,
131
+ maxExecutionTimeMs: 60000,
132
+ maxCostUsd: 0.5,
133
+ },
134
+ context
135
+ );
136
+
137
+ const executionTime = Date.now() - startTime;
138
+
139
+ console.log("\n" + "=".repeat(60));
140
+ console.log("🎯 TEST RESULTS");
141
+ console.log("=".repeat(60));
142
+ console.log(`⏱️ Execution Time: ${executionTime}ms`);
143
+ console.log(`✅ Success: ${result.success}`);
144
+
145
+ if (result.success) {
146
+ console.log(`📊 Result:`, result.result);
147
+ console.log(`🔧 Tool Calls Made: ${result.quotaUsage.toolCalls}`);
148
+ console.log(`🎯 Tokens Used: ${result.quotaUsage.tokens}`);
149
+ console.log(`💰 Cost: $${result.quotaUsage.costUsd.toFixed(4)}`);
150
+
151
+ if (result.artifacts.length > 0) {
152
+ console.log(`📁 Artifacts Created: ${result.artifacts.length}`);
153
+ result.artifacts.forEach((artifact) => {
154
+ console.log(
155
+ ` - ${artifact.name} (${artifact.type}, ${artifact.contentLength} bytes)`
156
+ );
157
+ });
158
+ }
159
+
160
+ if (result.consoleOutput.length > 0) {
161
+ console.log(
162
+ `\n📝 Console Output (${result.consoleOutput.length} entries):`
163
+ );
164
+ result.consoleOutput.forEach((entry) => {
165
+ console.log(` ${entry}`);
166
+ });
167
+ }
168
+
169
+ if (result.violations.length > 0) {
170
+ console.log(`\n⚠️ Policy Violations: ${result.violations.length}`);
171
+ result.violations.forEach((violation) => {
172
+ console.log(` - ${JSON.stringify(violation)}`);
173
+ });
174
+ }
175
+ } else {
176
+ console.log(`❌ Error: ${result.error}`);
177
+
178
+ if (result.consoleOutput.length > 0) {
179
+ console.log(`\n📝 Console Output Before Failure:`);
180
+ result.consoleOutput.forEach((entry) => {
181
+ console.log(` ${entry}`);
182
+ });
183
+ }
184
+ }
185
+
186
+ console.log("\n" + "=".repeat(60));
187
+ console.log(result.success ? "🎉 TEST PASSED!" : "💥 TEST FAILED!");
188
+ console.log("=".repeat(60));
189
+ } catch (error) {
190
+ console.error("\n💥 TEST RUNNER ERROR:");
191
+ console.error(error);
192
+ process.exit(1);
193
+ }
194
+ }
195
+
196
+ // Run the test if this file is executed directly
197
+ if (require.main === module) {
198
+ runTest().catch((error) => {
199
+ console.error("Unhandled error:", error);
200
+ process.exit(1);
201
+ });
202
+ }
203
+
204
+ export { runTest, testScript };
@@ -0,0 +1,74 @@
1
+ import { ScriptExecutor } from "../../../services/script-execution/ScriptExecutor";
2
+ import { Tools } from "../../../services";
3
+ import { Clients } from "../../../clients";
4
+ import {
5
+ ExecutionRequest,
6
+ ExecutionResult,
7
+ } from "../../../services/script-execution/types";
8
+
9
+
10
+ export const executeScript = async (
11
+ { script, maxToolCalls, maxTokens, maxExecutionTimeMs, maxCostUsd },
12
+ context
13
+ ) => {
14
+ try {
15
+ // Create script executor with access to tools and clients
16
+ const executor = new ScriptExecutor(Tools, Clients);
17
+
18
+ // Execute the script
19
+ const result = await executor.execute({
20
+ script,
21
+ quotas: {
22
+ maxToolCalls: maxToolCalls || 50,
23
+ maxTokens: maxTokens || 10000,
24
+ maxExecutionTimeMs: maxExecutionTimeMs || 30000,
25
+ maxCostUsd: maxCostUsd || 1.0,
26
+ maxMemoryMb: 100,
27
+ },
28
+ });
29
+
30
+ // If there were policy violations, include them in the response
31
+ const violations = result.trace.events
32
+ .filter((e) => e.type.includes("violation") || e.type.includes("error"))
33
+ .map((e) => e.data);
34
+
35
+ // Format the response
36
+ return {
37
+ success: result.success,
38
+ result: result.result,
39
+ error: result.error,
40
+ artifacts: result.artifacts.map((a) => ({
41
+ id: a.id,
42
+ name: a.name,
43
+ type: a.type,
44
+ contentLength: a.content.length,
45
+ createdAt: a.createdAt,
46
+ })),
47
+ consoleOutput: result.consoleOutput,
48
+ metrics: result.trace.metrics,
49
+ violations,
50
+ executionTimeMs: result.trace.endTime - result.trace.startTime,
51
+ quotaUsage: {
52
+ toolCalls: result.trace.metrics.toolCallCount,
53
+ tokens: result.trace.metrics.tokenUsage.total,
54
+ costUsd: result.trace.metrics.costUsd,
55
+ },
56
+ };
57
+ } catch (error) {
58
+ return {
59
+ success: false,
60
+ error: error instanceof Error ? error.message : String(error),
61
+ result: null,
62
+ artifacts: [],
63
+ consoleOutput: [],
64
+ metrics: null,
65
+ violations: [],
66
+ executionTimeMs: 0,
67
+ quotaUsage: {
68
+ toolCalls: 0,
69
+ tokens: 0,
70
+ costUsd: 0,
71
+ },
72
+ };
73
+ }
74
+ };
@@ -23,3 +23,4 @@ export * from "./aiClient";
23
23
  export * from "./googleSearch";
24
24
  export * from "./loadWebpage";
25
25
  export * from "./stringReplace";
26
+ export * from "./executeScript";
@@ -7,6 +7,7 @@ import * as github from "./github/definitions";
7
7
  import * as asana from "./asana/definitions";
8
8
  import * as language from "./language/definitions";
9
9
  import { googleSearchDefinition } from "./googleSearch";
10
+ import { executeScriptDefinition } from "./executeScript/definition";
10
11
 
11
12
  export const includedTools = [
12
13
  {
@@ -552,7 +553,7 @@ export const includedTools = [
552
553
  },
553
554
  },
554
555
  },
555
-
556
+ executeScriptDefinition,
556
557
  googleSearchDefinition,
557
558
  ...asana.definitions,
558
559
  ...github.definitions,
package/src/cli.ts CHANGED
@@ -11,7 +11,7 @@ import { Vimmer } from "./agents/vim/vim";
11
11
  import { Developer } from "./agents/developer/developer";
12
12
  import { Tools } from "./services";
13
13
  import { includedTools } from "./agents/tools/list";
14
- import * as allTools from "./agents/tools/index";
14
+ import * as allTools from "./agents/tools";
15
15
  import { Mcp } from "./services/Mcp";
16
16
  import { login } from "./login";
17
17
  import { worker } from "./worker";
@@ -24,12 +24,8 @@ async function main() {
24
24
  Agents.registerAgent(Patcher);
25
25
  Agents.registerAgent(Developer);
26
26
  Agents.loadAgentsFromConfig();
27
- Tools.addTools(includedTools);
28
27
 
29
- const toolFunctions = Object.entries(allTools)
30
- .filter(([_, value]) => typeof value === 'function')
31
- .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {});
32
- Tools.addFunctions(toolFunctions);
28
+ Tools.defineTools(includedTools, allTools);
33
29
 
34
30
  await Mcp.connectToConfigured(Tools);
35
31
  await Clients.registerConfiguredModels();
@@ -153,13 +153,24 @@ export class AIClient {
153
153
  );
154
154
  }
155
155
 
156
- private providerHasModel(provider: string, model: string): boolean {
156
+ providerHasModel(provider: string, model: string): boolean {
157
157
  const models = this.clientModels[provider];
158
158
  if (!models) return false;
159
159
  return models.includes(model);
160
160
  }
161
161
 
162
- private detectProviderModel(provider: string, model?: string) {
162
+ findModel(modelPrefix: string) {
163
+ for (const provider of Object.keys(this.clientModels)) {
164
+ const models = this.clientModels[provider];
165
+ const foundModel = models.find((m) => m.startsWith(modelPrefix));
166
+ if (foundModel) {
167
+ return { provider, model: foundModel };
168
+ }
169
+ }
170
+ return undefined;
171
+ }
172
+
173
+ detectProviderModel(provider: string, model?: string) {
163
174
  if (this.providerHasModel(provider, model)) {
164
175
  return { provider, model };
165
176
  }
@@ -170,18 +181,21 @@ export class AIClient {
170
181
  const inferredProvider = split[0];
171
182
  const inferredModel = split.slice(1).join("/");
172
183
 
184
+ // Exact match
173
185
  if (this.providerHasModel(inferredProvider, inferredModel)) {
174
186
  return { provider: inferredProvider, model: inferredModel };
175
187
  }
176
- }
177
188
 
178
- const providers = Object.keys(this.clientModels);
179
- const foundProvider = providers.find((p) =>
180
- this.providerHasModel(p, model)
181
- );
189
+ // Starts with match
190
+ const foundBySplit = this.findModel(inferredModel);
191
+ if (foundBySplit) {
192
+ return foundBySplit;
193
+ }
194
+ }
182
195
 
183
- if (foundProvider) {
184
- return { provider: foundProvider, model };
196
+ const foundByModel = this.findModel(model);
197
+ if (foundByModel) {
198
+ return foundByModel;
185
199
  }
186
200
 
187
201
  return { provider, model };
@@ -1,7 +1,14 @@
1
1
  import { ChatCompletionTool } from "openai/resources/chat";
2
+ import { replaceEscapedNewLines, restoreEscapedNewLines } from "../utils";
2
3
  import { includedTools } from "../agents/tools/list";
3
- import { Tool } from "../clients/types";
4
- import { ToolOverrideRegistration, ToolWrapperRegistration, ToolOverrideFunction, ToolWrapper, createPatternMatcher } from "./types";
4
+ import { Tool, ToolCall } from "../clients/types";
5
+ import {
6
+ ToolOverrideRegistration,
7
+ ToolWrapperRegistration,
8
+ ToolOverrideFunction,
9
+ ToolWrapper,
10
+ createPatternMatcher,
11
+ } from "./types";
5
12
 
6
13
  export class ToolsService {
7
14
  tools = [] as Tool[];
@@ -61,7 +68,7 @@ export class ToolsService {
61
68
  const wrappers = this.findMatchingWrappers(name);
62
69
  if (wrappers.length > 0) {
63
70
  let wrappedFunction = func;
64
-
71
+
65
72
  // Apply wrappers in priority order
66
73
  for (const wrapperReg of wrappers) {
67
74
  const currentFunction = wrappedFunction;
@@ -70,7 +77,7 @@ export class ToolsService {
70
77
  return await wrapperReg.wrapper(currentFunction, args, tool);
71
78
  };
72
79
  }
73
-
80
+
74
81
  this.functions[name] = wrappedFunction;
75
82
  return;
76
83
  }
@@ -90,15 +97,147 @@ export class ToolsService {
90
97
  }
91
98
 
92
99
  addTools(tools: Tool[]) {
93
- this.tools.push(...tools);
100
+ // Prevent duplicate tool names
101
+ const existingTools = this.getToolNames();
102
+ const filteredTools = tools.filter(
103
+ (tool) => !existingTools.includes(tool.function.name)
104
+ );
105
+
106
+ this.tools.push(...filteredTools);
94
107
  }
95
108
 
96
109
  addFunctions(fns: { [fnName: string]: (...args: any) => any }) {
97
110
  for (const fnName of Object.keys(fns)) {
111
+ if (typeof fns[fnName] !== "function") {
112
+ // Skip non-function entries
113
+ continue;
114
+ }
98
115
  this.setFunction(fnName, fns[fnName]);
99
116
  }
100
117
  }
101
118
 
119
+ defineTools(
120
+ tools: Tool[],
121
+ functions: { [fnName: string]: ((...args: any) => any) | any }
122
+ ) {
123
+ this.addTools(tools);
124
+ this.addFunctions(functions);
125
+ }
126
+
127
+ async callTool(toolCall: ToolCall, enabledTools = this.getToolNames()) {
128
+ const functionName = toolCall.function.name;
129
+ const functionArgs = JSON.parse(
130
+ restoreEscapedNewLines(toolCall.function.arguments)
131
+ );
132
+
133
+ try {
134
+ // Check if tool is enabled
135
+ if (!enabledTools.includes(functionName)) {
136
+ const options = enabledTools.join(", ");
137
+ throw new Error(
138
+ `Function ${functionName} not enabled, options are ${options}`
139
+ );
140
+ }
141
+
142
+ // Check if tool definition exists
143
+ const toolDefinition = this.getTool(functionName);
144
+ if (!toolDefinition) {
145
+ throw new Error(`Tool ${functionName} not found`);
146
+ }
147
+
148
+ // Check if function implementation exists
149
+ const functionToCall = this.getFunction(functionName);
150
+ if (!functionToCall) {
151
+ const options = enabledTools.join(", ");
152
+ throw new Error(
153
+ `Function ${functionName} not found, options are ${options}`
154
+ );
155
+ }
156
+
157
+ // Prepare function arguments
158
+ const properties = toolDefinition?.function?.parameters?.properties || {};
159
+ const isPositional =
160
+ toolDefinition?.function?.parameters?.positional || false;
161
+ const fnArgs = isPositional
162
+ ? Object.keys(properties).map((p) => functionArgs[p])
163
+ : functionArgs;
164
+
165
+ console.log(
166
+ `Calling function ${functionName} with args:`,
167
+ JSON.stringify(fnArgs, null, 2)
168
+ );
169
+
170
+ // Execute the function
171
+ const functionResponse = await Promise.resolve(
172
+ isPositional ? functionToCall(...fnArgs) : functionToCall(fnArgs)
173
+ ).catch((e) => {
174
+ throw new Error("ERROR: " + e.message);
175
+ });
176
+
177
+ // Helper function to convert objects to JSON
178
+ const toJsonIfObject = (arg: any) => {
179
+ if (typeof arg === "object") {
180
+ return JSON.stringify(arg, null, 2);
181
+ }
182
+ return arg;
183
+ };
184
+
185
+ let toolMessages = [];
186
+
187
+ // Handle special case for parallel tool use
188
+ if (functionName === "multi_tool_use.parallel") {
189
+ const args = fnArgs[0] as {
190
+ recipient_name: string;
191
+ parameters: any;
192
+ }[];
193
+
194
+ toolMessages = args.map((call, index) => {
195
+ return {
196
+ tool_call_id: toolCall.id + "_" + index,
197
+ role: "tool",
198
+ name: call.recipient_name.split(".").pop(),
199
+ content: toJsonIfObject(functionResponse[index]) || "Done",
200
+ };
201
+ });
202
+ } else {
203
+ toolMessages = [
204
+ {
205
+ tool_call_id: toolCall.id,
206
+ role: "tool",
207
+ name: functionName,
208
+ content: toJsonIfObject(functionResponse) || "Done",
209
+ },
210
+ ];
211
+ }
212
+
213
+ return {
214
+ toolMessages,
215
+ toolCallId: toolCall.id,
216
+ functionName,
217
+ functionArgs,
218
+ functionResp: functionResponse,
219
+ };
220
+ } catch (error) {
221
+ console.log(error.message);
222
+ const toolMessages = [
223
+ {
224
+ tool_call_id: toolCall.id,
225
+ role: "tool",
226
+ name: "error",
227
+ content: error.message,
228
+ },
229
+ ];
230
+
231
+ return {
232
+ toolMessages,
233
+ toolCallId: toolCall.id,
234
+ functionName,
235
+ functionArgs,
236
+ functionResp: undefined,
237
+ };
238
+ }
239
+ }
240
+
102
241
  // Tool Override Methods
103
242
  registerOverride(
104
243
  pattern: string | RegExp,
@@ -119,14 +258,16 @@ export class ToolsService {
119
258
  }
120
259
 
121
260
  removeOverride(pattern: string | RegExp): void {
122
- this.overrides = this.overrides.filter(reg => reg.pattern !== pattern);
261
+ this.overrides = this.overrides.filter((reg) => reg.pattern !== pattern);
123
262
  }
124
263
 
125
264
  removeWrapper(pattern: string | RegExp): void {
126
- this.wrappers = this.wrappers.filter(reg => reg.pattern !== pattern);
265
+ this.wrappers = this.wrappers.filter((reg) => reg.pattern !== pattern);
127
266
  }
128
267
 
129
- private findMatchingOverride(toolName: string): ToolOverrideRegistration | null {
268
+ private findMatchingOverride(
269
+ toolName: string
270
+ ): ToolOverrideRegistration | null {
130
271
  for (const registration of this.overrides) {
131
272
  const matcher = createPatternMatcher(registration.pattern);
132
273
  if (matcher.matches(toolName)) {
@@ -161,4 +302,4 @@ export class ToolsService {
161
302
  }
162
303
  }
163
304
 
164
- export const Tools = new ToolsService();
305
+ export const Tools = new ToolsService();