@tyvm/knowhow 0.0.108-dev.c7d102c → 0.0.108-dev.ed88cf4
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/package.json +2 -3
- package/src/agents/tools/index.ts +0 -1
- package/src/agents/tools/list.ts +0 -2
- package/src/chat/CliChatService.ts +10 -1
- package/src/chat/renderer/CompactRenderer.ts +20 -0
- package/src/chat/renderer/ConsoleRenderer.ts +19 -0
- package/src/chat/renderer/FancyRenderer.ts +19 -0
- package/src/chat/renderer/types.ts +11 -0
- package/src/cli.ts +91 -664
- package/src/clients/index.ts +6 -5
- package/src/commands/agent.ts +246 -0
- package/src/commands/misc.ts +174 -0
- package/src/commands/modules.ts +182 -0
- package/src/commands/services.ts +77 -0
- package/src/commands/workers.ts +160 -0
- package/src/config.ts +37 -0
- package/src/index.ts +1 -0
- package/src/logger.ts +197 -0
- package/src/plugins/plugins.ts +0 -21
- package/src/processors/JsonCompressor.ts +3 -3
- package/src/services/EventService.ts +61 -1
- package/src/services/modules/index.ts +70 -50
- package/src/services/modules/types.ts +4 -0
- package/src/tunnel.ts +216 -0
- package/src/types.ts +0 -1
- package/src/worker.ts +65 -336
- package/src/workers/auth/WsMiddleware.ts +99 -0
- package/src/workers/auth/authMiddleware.ts +104 -0
- package/src/workers/auth/types.ts +14 -2
- package/tests/unit/commands/github-credentials.test.ts +211 -0
- package/tests/unit/modules/moduleLoading.test.ts +39 -37
- package/tests/unit/plugins/pluginLoading.test.ts +0 -85
- package/ts_build/package.json +2 -3
- package/ts_build/src/agents/tools/index.d.ts +0 -1
- package/ts_build/src/agents/tools/index.js +0 -1
- package/ts_build/src/agents/tools/index.js.map +1 -1
- package/ts_build/src/agents/tools/list.js +0 -2
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/chat/CliChatService.js +13 -1
- package/ts_build/src/chat/CliChatService.js.map +1 -1
- package/ts_build/src/chat/renderer/CompactRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/CompactRenderer.js +16 -0
- package/ts_build/src/chat/renderer/CompactRenderer.js.map +1 -1
- package/ts_build/src/chat/renderer/ConsoleRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.js +16 -0
- package/ts_build/src/chat/renderer/ConsoleRenderer.js.map +1 -1
- package/ts_build/src/chat/renderer/FancyRenderer.d.ts +4 -0
- package/ts_build/src/chat/renderer/FancyRenderer.js +16 -0
- package/ts_build/src/chat/renderer/FancyRenderer.js.map +1 -1
- package/ts_build/src/chat/renderer/types.d.ts +2 -0
- package/ts_build/src/cli.js +47 -525
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/index.js +2 -4
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/commands/agent.d.ts +6 -0
- package/ts_build/src/commands/agent.js +229 -0
- package/ts_build/src/commands/agent.js.map +1 -0
- package/ts_build/src/commands/misc.d.ts +10 -0
- package/ts_build/src/commands/misc.js +197 -0
- package/ts_build/src/commands/misc.js.map +1 -0
- package/ts_build/src/commands/modules.d.ts +3 -0
- package/ts_build/src/commands/modules.js +160 -0
- package/ts_build/src/commands/modules.js.map +1 -0
- package/ts_build/src/commands/services.d.ts +5 -0
- package/ts_build/src/commands/services.js +87 -0
- package/ts_build/src/commands/services.js.map +1 -0
- package/ts_build/src/commands/workers.d.ts +6 -0
- package/ts_build/src/commands/workers.js +163 -0
- package/ts_build/src/commands/workers.js.map +1 -0
- package/ts_build/src/config.d.ts +1 -0
- package/ts_build/src/config.js +32 -0
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/index.d.ts +1 -0
- package/ts_build/src/index.js +3 -1
- package/ts_build/src/index.js.map +1 -1
- package/ts_build/src/logger.d.ts +21 -0
- package/ts_build/src/logger.js +106 -0
- package/ts_build/src/logger.js.map +1 -0
- package/ts_build/src/plugins/plugins.d.ts +0 -2
- package/ts_build/src/plugins/plugins.js +0 -11
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/processors/JsonCompressor.js +1 -1
- package/ts_build/src/services/EventService.d.ts +6 -1
- package/ts_build/src/services/EventService.js +29 -0
- package/ts_build/src/services/EventService.js.map +1 -1
- package/ts_build/src/services/modules/index.d.ts +33 -0
- package/ts_build/src/services/modules/index.js +46 -45
- package/ts_build/src/services/modules/index.js.map +1 -1
- package/ts_build/src/services/modules/types.d.ts +4 -0
- package/ts_build/src/tunnel.d.ts +27 -0
- package/ts_build/src/tunnel.js +112 -0
- package/ts_build/src/tunnel.js.map +1 -0
- package/ts_build/src/types.d.ts +0 -1
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/worker.d.ts +1 -4
- package/ts_build/src/worker.js +38 -244
- package/ts_build/src/worker.js.map +1 -1
- package/ts_build/src/workers/auth/WsMiddleware.d.ts +8 -0
- package/ts_build/src/workers/auth/WsMiddleware.js +65 -0
- package/ts_build/src/workers/auth/WsMiddleware.js.map +1 -0
- package/ts_build/src/workers/auth/authMiddleware.d.ts +3 -0
- package/ts_build/src/workers/auth/authMiddleware.js +60 -0
- package/ts_build/src/workers/auth/authMiddleware.js.map +1 -0
- package/ts_build/src/workers/auth/types.d.ts +8 -1
- package/ts_build/tests/unit/commands/github-credentials.test.d.ts +1 -0
- package/ts_build/tests/unit/commands/github-credentials.test.js +146 -0
- package/ts_build/tests/unit/commands/github-credentials.test.js.map +1 -0
- package/ts_build/tests/unit/modules/moduleLoading.test.js +20 -26
- package/ts_build/tests/unit/modules/moduleLoading.test.js.map +1 -1
- package/ts_build/tests/unit/plugins/pluginLoading.test.js +0 -65
- package/ts_build/tests/unit/plugins/pluginLoading.test.js.map +1 -1
- package/src/agents/tools/executeScript/README.md +0 -94
- package/src/agents/tools/executeScript/definition.ts +0 -79
- package/src/agents/tools/executeScript/examples/dependency-injection-validation.ts +0 -272
- package/src/agents/tools/executeScript/examples/quick-test.ts +0 -74
- package/src/agents/tools/executeScript/examples/serialization-test.ts +0 -321
- package/src/agents/tools/executeScript/examples/test-runner.ts +0 -197
- package/src/agents/tools/executeScript/index.ts +0 -98
- package/src/services/script-execution/SandboxContext.ts +0 -282
- package/src/services/script-execution/ScriptExecutor.ts +0 -441
- package/src/services/script-execution/ScriptPolicy.ts +0 -194
- package/src/services/script-execution/ScriptTracer.ts +0 -249
- package/src/services/script-execution/types.ts +0 -134
- package/ts_build/src/agents/tools/executeScript/definition.d.ts +0 -2
- package/ts_build/src/agents/tools/executeScript/definition.js +0 -76
- package/ts_build/src/agents/tools/executeScript/definition.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.d.ts +0 -18
- package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.js +0 -192
- package/ts_build/src/agents/tools/executeScript/examples/dependency-injection-validation.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/quick-test.d.ts +0 -3
- package/ts_build/src/agents/tools/executeScript/examples/quick-test.js +0 -64
- package/ts_build/src/agents/tools/executeScript/examples/quick-test.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/serialization-test.d.ts +0 -15
- package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js +0 -266
- package/ts_build/src/agents/tools/executeScript/examples/serialization-test.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/examples/test-runner.d.ts +0 -4
- package/ts_build/src/agents/tools/executeScript/examples/test-runner.js +0 -208
- package/ts_build/src/agents/tools/executeScript/examples/test-runner.js.map +0 -1
- package/ts_build/src/agents/tools/executeScript/index.d.ts +0 -28
- package/ts_build/src/agents/tools/executeScript/index.js +0 -72
- package/ts_build/src/agents/tools/executeScript/index.js.map +0 -1
- package/ts_build/src/services/script-execution/SandboxContext.d.ts +0 -34
- package/ts_build/src/services/script-execution/SandboxContext.js +0 -189
- package/ts_build/src/services/script-execution/SandboxContext.js.map +0 -1
- package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +0 -19
- package/ts_build/src/services/script-execution/ScriptExecutor.js +0 -269
- package/ts_build/src/services/script-execution/ScriptExecutor.js.map +0 -1
- package/ts_build/src/services/script-execution/ScriptPolicy.d.ts +0 -28
- package/ts_build/src/services/script-execution/ScriptPolicy.js +0 -115
- package/ts_build/src/services/script-execution/ScriptPolicy.js.map +0 -1
- package/ts_build/src/services/script-execution/ScriptTracer.d.ts +0 -19
- package/ts_build/src/services/script-execution/ScriptTracer.js +0 -186
- package/ts_build/src/services/script-execution/ScriptTracer.js.map +0 -1
- package/ts_build/src/services/script-execution/types.d.ts +0 -108
- package/ts_build/src/services/script-execution/types.js +0 -3
- package/ts_build/src/services/script-execution/types.js.map +0 -1
|
@@ -1,197 +0,0 @@
|
|
|
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 { services } 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
|
-
const { Tools } = services();
|
|
109
|
-
|
|
110
|
-
try {
|
|
111
|
-
Tools.defineTools(includedTools, allTools);
|
|
112
|
-
|
|
113
|
-
console.log("📋 Test Parameters:");
|
|
114
|
-
console.log("- Max Tool Calls: 10");
|
|
115
|
-
console.log("- Max Tokens: 1000");
|
|
116
|
-
console.log("- Max Execution Time: 60s");
|
|
117
|
-
console.log("- Max Cost: $0.50\n");
|
|
118
|
-
|
|
119
|
-
const startTime = Date.now();
|
|
120
|
-
|
|
121
|
-
// Execute the test script
|
|
122
|
-
const result = await executeScript({
|
|
123
|
-
script: testScript,
|
|
124
|
-
maxToolCalls: 10,
|
|
125
|
-
maxTokens: 1000,
|
|
126
|
-
maxExecutionTimeMs: 60000,
|
|
127
|
-
maxCostUsd: 0.5,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
const executionTime = Date.now() - startTime;
|
|
131
|
-
|
|
132
|
-
console.log("\n" + "=".repeat(60));
|
|
133
|
-
console.log("🎯 TEST RESULTS");
|
|
134
|
-
console.log("=".repeat(60));
|
|
135
|
-
console.log(`⏱️ Execution Time: ${executionTime}ms`);
|
|
136
|
-
console.log(`✅ Success: ${result.success}`);
|
|
137
|
-
|
|
138
|
-
if (result.success) {
|
|
139
|
-
console.log(`📊 Result:`, result.result);
|
|
140
|
-
console.log(`🔧 Tool Calls Made: ${result.quotaUsage.toolCalls}`);
|
|
141
|
-
console.log(`🎯 Tokens Used: ${result.quotaUsage.tokens}`);
|
|
142
|
-
console.log(`💰 Cost: $${result.quotaUsage.costUsd.toFixed(4)}`);
|
|
143
|
-
|
|
144
|
-
if (result.artifacts.length > 0) {
|
|
145
|
-
console.log(`📁 Artifacts Created: ${result.artifacts.length}`);
|
|
146
|
-
result.artifacts.forEach((artifact) => {
|
|
147
|
-
console.log(
|
|
148
|
-
` - ${artifact.name} (${artifact.type}, ${artifact.contentLength} bytes)`
|
|
149
|
-
);
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (result.consoleOutput.length > 0) {
|
|
154
|
-
console.log(
|
|
155
|
-
`\n📝 Console Output (${result.consoleOutput.length} entries):`
|
|
156
|
-
);
|
|
157
|
-
result.consoleOutput.forEach((entry) => {
|
|
158
|
-
console.log(` ${entry}`);
|
|
159
|
-
});
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
if (result.violations.length > 0) {
|
|
163
|
-
console.log(`\n⚠️ Policy Violations: ${result.violations.length}`);
|
|
164
|
-
result.violations.forEach((violation) => {
|
|
165
|
-
console.log(` - ${JSON.stringify(violation)}`);
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
} else {
|
|
169
|
-
console.log(`❌ Error: ${result.error}`);
|
|
170
|
-
|
|
171
|
-
if (result.consoleOutput.length > 0) {
|
|
172
|
-
console.log(`\n📝 Console Output Before Failure:`);
|
|
173
|
-
result.consoleOutput.forEach((entry) => {
|
|
174
|
-
console.log(` ${entry}`);
|
|
175
|
-
});
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
console.log("\n" + "=".repeat(60));
|
|
180
|
-
console.log(result.success ? "🎉 TEST PASSED!" : "💥 TEST FAILED!");
|
|
181
|
-
console.log("=".repeat(60));
|
|
182
|
-
} catch (error) {
|
|
183
|
-
console.error("\n💥 TEST RUNNER ERROR:");
|
|
184
|
-
console.error(error);
|
|
185
|
-
process.exit(1);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
// Run the test if this file is executed directly
|
|
190
|
-
if (require.main === module) {
|
|
191
|
-
runTest().catch((error) => {
|
|
192
|
-
console.error("Unhandled error:", error);
|
|
193
|
-
process.exit(1);
|
|
194
|
-
});
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export { runTest, testScript };
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { ScriptExecutor } from "../../../services/script-execution/ScriptExecutor";
|
|
2
|
-
import { ToolsService } from "../../../services/Tools";
|
|
3
|
-
import {
|
|
4
|
-
ExecutionRequest,
|
|
5
|
-
ExecutionResult,
|
|
6
|
-
} from "../../../services/script-execution/types";
|
|
7
|
-
import { services } from "../../../services";
|
|
8
|
-
|
|
9
|
-
export async function executeScript({
|
|
10
|
-
script,
|
|
11
|
-
maxToolCalls,
|
|
12
|
-
maxTokens,
|
|
13
|
-
maxExecutionTimeMs,
|
|
14
|
-
maxCostUsd,
|
|
15
|
-
allowNetworkAccess,
|
|
16
|
-
}: {
|
|
17
|
-
script: string;
|
|
18
|
-
maxToolCalls?: number;
|
|
19
|
-
maxTokens?: number;
|
|
20
|
-
maxExecutionTimeMs?: number;
|
|
21
|
-
maxCostUsd?: number;
|
|
22
|
-
allowNetworkAccess?: boolean;
|
|
23
|
-
}) {
|
|
24
|
-
try {
|
|
25
|
-
// Get context from bound ToolsService
|
|
26
|
-
const toolService = (
|
|
27
|
-
this instanceof ToolsService ? this : services().Tools
|
|
28
|
-
) as ToolsService;
|
|
29
|
-
const toolContext = toolService.getContext();
|
|
30
|
-
const { Clients, Tools } = toolContext;
|
|
31
|
-
|
|
32
|
-
if (!Clients) {
|
|
33
|
-
throw new Error("Clients not available in tool context");
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// Create script executor with access to tools and clients
|
|
37
|
-
const executor = new ScriptExecutor(Tools, Clients);
|
|
38
|
-
|
|
39
|
-
// Execute the script
|
|
40
|
-
const result = await executor.execute({
|
|
41
|
-
script,
|
|
42
|
-
quotas: {
|
|
43
|
-
maxToolCalls: maxToolCalls || 50,
|
|
44
|
-
maxTokens: maxTokens || 10000,
|
|
45
|
-
maxExecutionTimeMs: maxExecutionTimeMs || 30000,
|
|
46
|
-
maxCostUsd: maxCostUsd || 1.0,
|
|
47
|
-
maxMemoryMb: 100,
|
|
48
|
-
},
|
|
49
|
-
policy: {
|
|
50
|
-
allowNetworkAccess: allowNetworkAccess ?? false,
|
|
51
|
-
},
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
// If there were policy violations, include them in the response
|
|
55
|
-
const violations = result.trace.events
|
|
56
|
-
.filter((e) => e.type.includes("violation") || e.type.includes("error"))
|
|
57
|
-
.map((e) => e.data);
|
|
58
|
-
|
|
59
|
-
// Format the response
|
|
60
|
-
return {
|
|
61
|
-
success: result.success,
|
|
62
|
-
result: result.result,
|
|
63
|
-
error: result.error,
|
|
64
|
-
artifacts: result.artifacts.map((a) => ({
|
|
65
|
-
id: a.id,
|
|
66
|
-
name: a.name,
|
|
67
|
-
type: a.type,
|
|
68
|
-
contentLength: a.content.length,
|
|
69
|
-
createdAt: a.createdAt,
|
|
70
|
-
})),
|
|
71
|
-
consoleOutput: result.consoleOutput,
|
|
72
|
-
metrics: result.trace.metrics,
|
|
73
|
-
violations,
|
|
74
|
-
executionTimeMs: result.trace.endTime - result.trace.startTime,
|
|
75
|
-
quotaUsage: {
|
|
76
|
-
toolCalls: result.trace.metrics.toolCallCount,
|
|
77
|
-
tokens: result.trace.metrics.tokenUsage.total,
|
|
78
|
-
costUsd: result.trace.metrics.costUsd,
|
|
79
|
-
},
|
|
80
|
-
};
|
|
81
|
-
} catch (error) {
|
|
82
|
-
return {
|
|
83
|
-
success: false,
|
|
84
|
-
error: error instanceof Error ? error.message : String(error),
|
|
85
|
-
result: null,
|
|
86
|
-
artifacts: [],
|
|
87
|
-
consoleOutput: [],
|
|
88
|
-
metrics: null,
|
|
89
|
-
violations: [],
|
|
90
|
-
executionTimeMs: 0,
|
|
91
|
-
quotaUsage: {
|
|
92
|
-
toolCalls: 0,
|
|
93
|
-
tokens: 0,
|
|
94
|
-
costUsd: 0,
|
|
95
|
-
},
|
|
96
|
-
};
|
|
97
|
-
}
|
|
98
|
-
}
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import { AIClient } from "../../clients";
|
|
2
|
-
import { ScriptTracer } from "./ScriptTracer";
|
|
3
|
-
import { ScriptPolicyEnforcer } from "./ScriptPolicy";
|
|
4
|
-
import { Artifact, QuotaUsage } from "./types";
|
|
5
|
-
import { Message } from "../../clients/types";
|
|
6
|
-
import { ToolsService } from "../Tools";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Provides the execution context for scripts with controlled access to tools and AI
|
|
10
|
-
*/
|
|
11
|
-
export class SandboxContext {
|
|
12
|
-
private artifacts: Artifact[] = [];
|
|
13
|
-
private consoleOutput: string[] = [];
|
|
14
|
-
|
|
15
|
-
constructor(
|
|
16
|
-
private toolsService: ToolsService,
|
|
17
|
-
private clients: AIClient,
|
|
18
|
-
private tracer: ScriptTracer,
|
|
19
|
-
private policyEnforcer: ScriptPolicyEnforcer
|
|
20
|
-
) {}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Console implementation that captures output
|
|
24
|
-
*/
|
|
25
|
-
console = {
|
|
26
|
-
log: (...args: any[]) => {
|
|
27
|
-
const message = args
|
|
28
|
-
.map((arg) =>
|
|
29
|
-
typeof arg === "object" ? JSON.stringify(arg) : String(arg)
|
|
30
|
-
)
|
|
31
|
-
.join(" ");
|
|
32
|
-
this.consoleOutput.push(`[LOG] ${message}`);
|
|
33
|
-
this.tracer.emitEvent("console_log", { message, args });
|
|
34
|
-
},
|
|
35
|
-
|
|
36
|
-
error: (...args: any[]) => {
|
|
37
|
-
const message = args
|
|
38
|
-
.map((arg) =>
|
|
39
|
-
typeof arg === "object" ? JSON.stringify(arg) : String(arg)
|
|
40
|
-
)
|
|
41
|
-
.join(" ");
|
|
42
|
-
this.consoleOutput.push(`[ERROR] ${message}`);
|
|
43
|
-
this.tracer.emitEvent("console_error", { message, args });
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
warn: (...args: any[]) => {
|
|
47
|
-
const message = args
|
|
48
|
-
.map((arg) =>
|
|
49
|
-
typeof arg === "object" ? JSON.stringify(arg) : String(arg)
|
|
50
|
-
)
|
|
51
|
-
.join(" ");
|
|
52
|
-
this.consoleOutput.push(`[WARN] ${message}`);
|
|
53
|
-
this.tracer.emitEvent("console_warn", { message, args });
|
|
54
|
-
},
|
|
55
|
-
|
|
56
|
-
info: (...args: any[]) => {
|
|
57
|
-
const message = args
|
|
58
|
-
.map((arg) =>
|
|
59
|
-
typeof arg === "object" ? JSON.stringify(arg) : String(arg)
|
|
60
|
-
)
|
|
61
|
-
.join(" ");
|
|
62
|
-
this.consoleOutput.push(`[INFO] ${message}`);
|
|
63
|
-
this.tracer.emitEvent("console_info", { message, args });
|
|
64
|
-
},
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Call a tool through the tools service
|
|
69
|
-
*/
|
|
70
|
-
async callTool(toolName: string, parameters: any): Promise<any> {
|
|
71
|
-
// Check policy first
|
|
72
|
-
if (!this.policyEnforcer.checkToolCall(toolName)) {
|
|
73
|
-
throw new Error(`Tool call '${toolName}' blocked by policy`);
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if (toolName === "executeScript") {
|
|
77
|
-
throw new Error("Nested script execution is not allowed in sandbox");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
this.tracer.emitEvent("tool_call_start", {
|
|
81
|
-
toolName,
|
|
82
|
-
parameters: this.sanitizeForLogging(parameters),
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
// Record the tool call
|
|
87
|
-
this.policyEnforcer.recordToolCall();
|
|
88
|
-
|
|
89
|
-
// Create a proper ToolCall object
|
|
90
|
-
const toolCall = {
|
|
91
|
-
id: `script-tool-${Date.now()}-${Math.random()
|
|
92
|
-
.toString(36)
|
|
93
|
-
.substr(2, 9)}`,
|
|
94
|
-
type: "function" as const,
|
|
95
|
-
function: {
|
|
96
|
-
name: toolName,
|
|
97
|
-
arguments: JSON.stringify(parameters),
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
// Call the actual tool through the Tools service
|
|
102
|
-
const result = await this.toolsService.callTool(toolCall);
|
|
103
|
-
|
|
104
|
-
this.tracer.emitEvent("tool_call_success", {
|
|
105
|
-
toolName,
|
|
106
|
-
result: this.sanitizeForLogging(result),
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
return result;
|
|
110
|
-
} catch (error) {
|
|
111
|
-
this.tracer.emitEvent("tool_call_error", {
|
|
112
|
-
toolName,
|
|
113
|
-
error: error instanceof Error ? error.message : String(error),
|
|
114
|
-
});
|
|
115
|
-
throw error;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* Call LLM through the clients service
|
|
121
|
-
*/
|
|
122
|
-
async llm(
|
|
123
|
-
messages: Message[],
|
|
124
|
-
options: {
|
|
125
|
-
model?: string;
|
|
126
|
-
maxTokens?: number;
|
|
127
|
-
temperature?: number;
|
|
128
|
-
} = {}
|
|
129
|
-
) {
|
|
130
|
-
const estimatedTokens = this.estimateTokens(messages);
|
|
131
|
-
|
|
132
|
-
// Check token quota
|
|
133
|
-
if (!this.policyEnforcer.checkTokenUsage(estimatedTokens)) {
|
|
134
|
-
throw new Error("Token quota would be exceeded");
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
this.tracer.emitEvent("llm_call_start", {
|
|
138
|
-
messageCount: messages.length,
|
|
139
|
-
estimatedTokens,
|
|
140
|
-
model: options.model,
|
|
141
|
-
options: this.sanitizeForLogging(options),
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
// Record token usage
|
|
146
|
-
this.policyEnforcer.recordTokenUsage(estimatedTokens);
|
|
147
|
-
|
|
148
|
-
// Use the actual Clients service to make LLM calls
|
|
149
|
-
const completionOptions = {
|
|
150
|
-
model: options.model,
|
|
151
|
-
messages,
|
|
152
|
-
max_tokens: options.maxTokens,
|
|
153
|
-
};
|
|
154
|
-
|
|
155
|
-
// Detect provider from model or use default
|
|
156
|
-
const response = await this.clients.createCompletion(
|
|
157
|
-
"",
|
|
158
|
-
completionOptions
|
|
159
|
-
);
|
|
160
|
-
|
|
161
|
-
this.tracer.emitEvent("llm_call_success", {
|
|
162
|
-
model: response.model,
|
|
163
|
-
usage: response.usage,
|
|
164
|
-
usdCost: response.usd_cost,
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
return response;
|
|
168
|
-
} catch (error) {
|
|
169
|
-
this.tracer.emitEvent("llm_call_error", {
|
|
170
|
-
error: error instanceof Error ? error.message : String(error),
|
|
171
|
-
});
|
|
172
|
-
throw error;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Get current quota usage
|
|
178
|
-
*/
|
|
179
|
-
getQuotaUsage(): QuotaUsage {
|
|
180
|
-
return this.policyEnforcer.getUsage();
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Create an artifact
|
|
185
|
-
*/
|
|
186
|
-
async createArtifact(
|
|
187
|
-
name: string,
|
|
188
|
-
content: string,
|
|
189
|
-
type: "text" | "json" | "csv" | "html" | "markdown" = "text"
|
|
190
|
-
): Promise<Artifact> {
|
|
191
|
-
const artifact: Artifact = {
|
|
192
|
-
id: `artifact-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
|
|
193
|
-
name,
|
|
194
|
-
type,
|
|
195
|
-
content,
|
|
196
|
-
createdAt: new Date().toISOString(),
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
this.artifacts.push(artifact);
|
|
200
|
-
|
|
201
|
-
this.tracer.emitEvent("artifact_created", {
|
|
202
|
-
artifactId: artifact.id,
|
|
203
|
-
name,
|
|
204
|
-
type,
|
|
205
|
-
contentLength: content.length,
|
|
206
|
-
});
|
|
207
|
-
|
|
208
|
-
return artifact;
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async sleep(ms: number): Promise<void> {
|
|
212
|
-
if (typeof ms !== "number" || ms < 0 || ms > 2000) {
|
|
213
|
-
throw new Error("Invalid sleep duration, sleep must be >0 and <2000");
|
|
214
|
-
}
|
|
215
|
-
await new Promise((res) => setTimeout(res, ms));
|
|
216
|
-
this.tracer.emitEvent("sleep", { durationMs: ms });
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/**
|
|
220
|
-
* Get all created artifacts
|
|
221
|
-
*/
|
|
222
|
-
getArtifacts(): Artifact[] {
|
|
223
|
-
return [...this.artifacts];
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
/**
|
|
227
|
-
* Get console output
|
|
228
|
-
*/
|
|
229
|
-
getConsoleOutput(): string[] {
|
|
230
|
-
return [...this.consoleOutput];
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Estimate tokens for text (rough approximation)
|
|
235
|
-
*/
|
|
236
|
-
private estimateTokens(messages: any[]): number {
|
|
237
|
-
let totalText = "";
|
|
238
|
-
for (const message of messages) {
|
|
239
|
-
if (typeof message === "string") {
|
|
240
|
-
totalText += message;
|
|
241
|
-
} else if (message && typeof message.content === "string") {
|
|
242
|
-
totalText += message.content;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
// Rough estimation: ~4 characters per token
|
|
246
|
-
return Math.ceil(totalText.length / 4);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Sanitize data for logging (remove sensitive information)
|
|
251
|
-
*/
|
|
252
|
-
private sanitizeForLogging(data: any): any {
|
|
253
|
-
if (data === null || data === undefined) {
|
|
254
|
-
return data;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
if (typeof data === "string") {
|
|
258
|
-
// Truncate very long strings
|
|
259
|
-
return data.length > 500 ? data.substring(0, 500) + "..." : data;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
if (typeof data === "object") {
|
|
263
|
-
const sanitized: any = {};
|
|
264
|
-
for (const [key, value] of Object.entries(data)) {
|
|
265
|
-
// Skip potentially sensitive keys
|
|
266
|
-
if (
|
|
267
|
-
key.toLowerCase().includes("password") ||
|
|
268
|
-
key.toLowerCase().includes("token") ||
|
|
269
|
-
key.toLowerCase().includes("secret") ||
|
|
270
|
-
key.toLowerCase().includes("key")
|
|
271
|
-
) {
|
|
272
|
-
sanitized[key] = "[REDACTED]";
|
|
273
|
-
} else {
|
|
274
|
-
sanitized[key] = this.sanitizeForLogging(value);
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
return sanitized;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
return data;
|
|
281
|
-
}
|
|
282
|
-
}
|