@framers/agentos 0.1.94 → 0.1.96
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/README.md +10 -0
- package/dist/api/AgentOS.d.ts +13 -0
- package/dist/api/AgentOS.d.ts.map +1 -1
- package/dist/api/AgentOS.js +36 -1
- package/dist/api/AgentOS.js.map +1 -1
- package/dist/api/usageLedger.d.ts.map +1 -1
- package/dist/api/usageLedger.js.map +1 -1
- package/dist/core/tools/IToolOrchestrator.d.ts +38 -1
- package/dist/core/tools/IToolOrchestrator.d.ts.map +1 -1
- package/dist/core/tools/ToolOrchestrator.d.ts +58 -1
- package/dist/core/tools/ToolOrchestrator.d.ts.map +1 -1
- package/dist/core/tools/ToolOrchestrator.js +116 -1
- package/dist/core/tools/ToolOrchestrator.js.map +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.d.ts +19 -0
- package/dist/discovery/CapabilityDiscoveryEngine.d.ts.map +1 -1
- package/dist/discovery/CapabilityDiscoveryEngine.js +54 -0
- package/dist/discovery/CapabilityDiscoveryEngine.js.map +1 -1
- package/dist/discovery/types.d.ts +8 -1
- package/dist/discovery/types.d.ts.map +1 -1
- package/dist/discovery/types.js.map +1 -1
- package/dist/emergent/ComposableToolBuilder.d.ts +125 -0
- package/dist/emergent/ComposableToolBuilder.d.ts.map +1 -0
- package/dist/emergent/ComposableToolBuilder.js +318 -0
- package/dist/emergent/ComposableToolBuilder.js.map +1 -0
- package/dist/emergent/EmergentCapabilityEngine.d.ts +168 -0
- package/dist/emergent/EmergentCapabilityEngine.d.ts.map +1 -0
- package/dist/emergent/EmergentCapabilityEngine.js +437 -0
- package/dist/emergent/EmergentCapabilityEngine.js.map +1 -0
- package/dist/emergent/EmergentJudge.d.ts +283 -0
- package/dist/emergent/EmergentJudge.d.ts.map +1 -0
- package/dist/emergent/EmergentJudge.js +463 -0
- package/dist/emergent/EmergentJudge.js.map +1 -0
- package/dist/emergent/EmergentToolRegistry.d.ts +286 -0
- package/dist/emergent/EmergentToolRegistry.d.ts.map +1 -0
- package/dist/emergent/EmergentToolRegistry.js +546 -0
- package/dist/emergent/EmergentToolRegistry.js.map +1 -0
- package/dist/emergent/ForgeToolMetaTool.d.ts +124 -0
- package/dist/emergent/ForgeToolMetaTool.d.ts.map +1 -0
- package/dist/emergent/ForgeToolMetaTool.js +170 -0
- package/dist/emergent/ForgeToolMetaTool.js.map +1 -0
- package/dist/emergent/SandboxedToolForge.d.ts +185 -0
- package/dist/emergent/SandboxedToolForge.d.ts.map +1 -0
- package/dist/emergent/SandboxedToolForge.js +383 -0
- package/dist/emergent/SandboxedToolForge.js.map +1 -0
- package/dist/emergent/index.d.ts +25 -0
- package/dist/emergent/index.d.ts.map +1 -0
- package/dist/emergent/index.js +20 -0
- package/dist/emergent/index.js.map +1 -0
- package/dist/emergent/types.d.ts +596 -0
- package/dist/emergent/types.d.ts.map +1 -0
- package/dist/emergent/types.js +36 -0
- package/dist/emergent/types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview SandboxedToolForge — runs agent-generated JavaScript code in an
|
|
3
|
+
* isolated sandbox with strict resource limits and API allowlisting.
|
|
4
|
+
*
|
|
5
|
+
* @module @framers/agentos/emergent/SandboxedToolForge
|
|
6
|
+
*
|
|
7
|
+
* Overview:
|
|
8
|
+
* - Attempts to use `isolated-vm` for true V8 isolate sandboxing when available.
|
|
9
|
+
* - Falls back to Node.js `vm` module with timeout when `isolated-vm` is not installed.
|
|
10
|
+
* - Enforces configurable memory limits (default 128 MB), execution timeouts (default 5 s),
|
|
11
|
+
* and a strict API blocklist that prevents access to `eval`, `Function`, `process`,
|
|
12
|
+
* `require`, `import`, `child_process`, and `fs.write*`.
|
|
13
|
+
*
|
|
14
|
+
* Allowlisted APIs (each requires explicit opt-in via {@link SandboxAPI}):
|
|
15
|
+
* - `fetch` — HTTP requests (domain-restricted via {@link SandboxedToolForgeConfig.fetchDomainAllowlist}).
|
|
16
|
+
* - `fs.readFile` — Read-only file access (path-restricted, max 1 MB).
|
|
17
|
+
* - `crypto` — Hashing and HMAC only (`createHash`, `createHmac`).
|
|
18
|
+
*
|
|
19
|
+
* Security model:
|
|
20
|
+
* 1. **Static validation** ({@link validateCode}) rejects dangerous patterns
|
|
21
|
+
* (regex scan) before any code reaches the runtime.
|
|
22
|
+
* 2. **Runtime isolation** executes validated code inside a minimal context that
|
|
23
|
+
* exposes only JSON, Math, Date, TextEncoder, TextDecoder, and explicitly
|
|
24
|
+
* opted-in APIs.
|
|
25
|
+
* 3. **Resource bounding** enforces wall-clock timeout so runaway loops cannot
|
|
26
|
+
* starve the host process.
|
|
27
|
+
*/
|
|
28
|
+
import { createContext, runInContext } from 'node:vm';
|
|
29
|
+
import { createHash, createHmac, randomUUID } from 'node:crypto';
|
|
30
|
+
import { readFile } from 'node:fs/promises';
|
|
31
|
+
import * as path from 'node:path';
|
|
32
|
+
// ============================================================================
|
|
33
|
+
// BANNED PATTERN DEFINITIONS
|
|
34
|
+
// ============================================================================
|
|
35
|
+
/**
|
|
36
|
+
* Patterns that are ALWAYS banned regardless of the allowlist.
|
|
37
|
+
* Each entry is a tuple of `[regex, human-readable description]`.
|
|
38
|
+
*/
|
|
39
|
+
const ALWAYS_BANNED = [
|
|
40
|
+
[/\beval\s*\(/, 'eval() is forbidden'],
|
|
41
|
+
[/\bFunction\s*\(/, 'Function() is forbidden'],
|
|
42
|
+
[/\bnew\s+Function\s*\(/, 'new Function() is forbidden'],
|
|
43
|
+
[/\brequire\s*\(/, 'require() is forbidden'],
|
|
44
|
+
[/\bimport\s+/, 'import statements are forbidden'],
|
|
45
|
+
[/\bimport\s*\(/, 'dynamic import() is forbidden'],
|
|
46
|
+
[/\bprocess\s*\./, 'process access is forbidden'],
|
|
47
|
+
[/\bchild_process\b/, 'child_process access is forbidden'],
|
|
48
|
+
[/\bfs\s*\.\s*write/, 'fs.write* is forbidden'],
|
|
49
|
+
[/\bfs\s*\.\s*unlink/, 'fs.unlink is forbidden'],
|
|
50
|
+
[/\bfs\s*\.\s*rm\b/, 'fs.rm is forbidden'],
|
|
51
|
+
[/\bfs\s*\.\s*rmdir/, 'fs.rmdir is forbidden'],
|
|
52
|
+
[/\bfs\s*\.\s*appendFile/, 'fs.appendFile is forbidden'],
|
|
53
|
+
[/\bfs\s*\.\s*truncate/, 'fs.truncate is forbidden'],
|
|
54
|
+
];
|
|
55
|
+
// ============================================================================
|
|
56
|
+
// SANDBOXED TOOL FORGE
|
|
57
|
+
// ============================================================================
|
|
58
|
+
/**
|
|
59
|
+
* Runs agent-generated code in an isolated sandbox with strict resource limits.
|
|
60
|
+
*
|
|
61
|
+
* Attempts to use `isolated-vm` for true V8 isolate sandboxing. Falls back to
|
|
62
|
+
* Node.js `vm` module with timeout if `isolated-vm` is not installed.
|
|
63
|
+
*
|
|
64
|
+
* Resource limits:
|
|
65
|
+
* - Memory: configurable, default 128 MB
|
|
66
|
+
* - Execution time: configurable, default 5000 ms
|
|
67
|
+
* - Blocked APIs: eval, Function, process, require, import, child_process, fs.write*
|
|
68
|
+
*
|
|
69
|
+
* Allowlisted APIs (each requires explicit opt-in):
|
|
70
|
+
* - `fetch`: HTTP requests (domain-restricted)
|
|
71
|
+
* - `fs.readFile`: Read-only file access (path-restricted, max 1 MB)
|
|
72
|
+
* - `crypto`: Hashing and HMAC only
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* ```ts
|
|
76
|
+
* const forge = new SandboxedToolForge({ timeoutMs: 3000 });
|
|
77
|
+
*
|
|
78
|
+
* const result = await forge.execute({
|
|
79
|
+
* code: 'function execute(input) { return input.a + input.b; }',
|
|
80
|
+
* input: { a: 2, b: 3 },
|
|
81
|
+
* allowlist: [],
|
|
82
|
+
* memoryMB: 128,
|
|
83
|
+
* timeoutMs: 3000,
|
|
84
|
+
* });
|
|
85
|
+
*
|
|
86
|
+
* console.log(result.output); // 5
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
export class SandboxedToolForge {
|
|
90
|
+
/**
|
|
91
|
+
* Create a new SandboxedToolForge instance.
|
|
92
|
+
*
|
|
93
|
+
* @param config - Optional configuration overrides. All fields have sensible
|
|
94
|
+
* defaults (128 MB memory, 5000 ms timeout, no domain restrictions).
|
|
95
|
+
*/
|
|
96
|
+
constructor(config) {
|
|
97
|
+
this.memoryMB = config?.memoryMB ?? 128;
|
|
98
|
+
this.timeoutMs = config?.timeoutMs ?? 5000;
|
|
99
|
+
this.fetchDomainAllowlist = (config?.fetchDomainAllowlist ?? []).map((d) => d.toLowerCase());
|
|
100
|
+
this.fsReadRoots = (config?.fsReadRoots ?? [process.cwd()]).map((root) => path.resolve(root));
|
|
101
|
+
}
|
|
102
|
+
// --------------------------------------------------------------------------
|
|
103
|
+
// PUBLIC: validateCode
|
|
104
|
+
// --------------------------------------------------------------------------
|
|
105
|
+
/**
|
|
106
|
+
* Static analysis of code — reject dangerous patterns before execution.
|
|
107
|
+
*
|
|
108
|
+
* Scans the source string for banned API usage patterns using regex matching.
|
|
109
|
+
* If an API is not present in the allowlist, references to it are also flagged.
|
|
110
|
+
*
|
|
111
|
+
* Checked patterns (always banned):
|
|
112
|
+
* - `eval()`, `new Function()`, `require()`, `import`, `process.*`
|
|
113
|
+
* - `child_process`, `fs.write*`, `fs.unlink`, `fs.rm`, `fs.rmdir`
|
|
114
|
+
*
|
|
115
|
+
* Conditionally banned (when not in allowlist):
|
|
116
|
+
* - `fetch(` — when `'fetch'` is not in the allowlist
|
|
117
|
+
* - `fs.*` — when `'fs.readFile'` is not in the allowlist
|
|
118
|
+
* - `crypto.*` — when `'crypto'` is not in the allowlist
|
|
119
|
+
*
|
|
120
|
+
* @param code - The raw source code string to validate.
|
|
121
|
+
* @param allowlist - The set of APIs the code is permitted to use.
|
|
122
|
+
* @returns An object with `valid: true` if no violations were found, or
|
|
123
|
+
* `valid: false` with a `violations` array describing each flagged pattern.
|
|
124
|
+
*
|
|
125
|
+
* @example
|
|
126
|
+
* ```ts
|
|
127
|
+
* const forge = new SandboxedToolForge();
|
|
128
|
+
* const result = forge.validateCode('eval("exploit")', []);
|
|
129
|
+
* // result.valid === false
|
|
130
|
+
* // result.violations === ['eval() is forbidden']
|
|
131
|
+
* ```
|
|
132
|
+
*/
|
|
133
|
+
validateCode(code, allowlist) {
|
|
134
|
+
const violations = [];
|
|
135
|
+
// Check always-banned patterns.
|
|
136
|
+
for (const [pattern, message] of ALWAYS_BANNED) {
|
|
137
|
+
if (pattern.test(code)) {
|
|
138
|
+
violations.push(message);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Conditionally ban `fetch(` when not allowed.
|
|
142
|
+
if (!allowlist.includes('fetch') && /\bfetch\s*\(/.test(code)) {
|
|
143
|
+
violations.push('fetch() is not in the allowlist');
|
|
144
|
+
}
|
|
145
|
+
// Conditionally ban all `fs.*` when fs.readFile is not allowed.
|
|
146
|
+
// We already caught write/unlink/rm above, but if fs.readFile is not in
|
|
147
|
+
// the allowlist, ban any fs reference.
|
|
148
|
+
if (!allowlist.includes('fs.readFile') && /\bfs\s*\./.test(code)) {
|
|
149
|
+
// Only add if we haven't already flagged a more specific fs violation.
|
|
150
|
+
const hasFsViolation = violations.some((v) => v.startsWith('fs.'));
|
|
151
|
+
if (!hasFsViolation) {
|
|
152
|
+
violations.push('fs access is not in the allowlist');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
// Conditionally ban `crypto` when not allowed.
|
|
156
|
+
if (!allowlist.includes('crypto') && /\bcrypto\s*\./.test(code)) {
|
|
157
|
+
violations.push('crypto access is not in the allowlist');
|
|
158
|
+
}
|
|
159
|
+
return violations.length === 0
|
|
160
|
+
? { valid: true, violations: [] }
|
|
161
|
+
: { valid: false, violations };
|
|
162
|
+
}
|
|
163
|
+
// --------------------------------------------------------------------------
|
|
164
|
+
// PUBLIC: execute
|
|
165
|
+
// --------------------------------------------------------------------------
|
|
166
|
+
/**
|
|
167
|
+
* Execute agent-generated code in the sandbox.
|
|
168
|
+
*
|
|
169
|
+
* The code must define a function named `execute` that accepts a single
|
|
170
|
+
* argument and returns the output:
|
|
171
|
+
*
|
|
172
|
+
* ```js
|
|
173
|
+
* function execute(input) { return input.a + input.b; }
|
|
174
|
+
* ```
|
|
175
|
+
*
|
|
176
|
+
* Execution flow:
|
|
177
|
+
* 1. Run {@link validateCode} — reject immediately if violations are found.
|
|
178
|
+
* 2. Wrap the agent's code into a self-contained expression that calls `execute`.
|
|
179
|
+
* 3. Run in a Node.js `vm` sandbox with a restricted global context.
|
|
180
|
+
* 4. Parse the output, measure execution time, and return the result.
|
|
181
|
+
*
|
|
182
|
+
* @param request - The execution request containing code, input, allowlist,
|
|
183
|
+
* and resource limits.
|
|
184
|
+
* @returns A {@link SandboxExecutionResult} with the output (on success) or
|
|
185
|
+
* error description (on failure), plus execution time telemetry.
|
|
186
|
+
*
|
|
187
|
+
* @example
|
|
188
|
+
* ```ts
|
|
189
|
+
* const result = await forge.execute({
|
|
190
|
+
* code: 'function execute(input) { return { sum: input.a + input.b }; }',
|
|
191
|
+
* input: { a: 10, b: 20 },
|
|
192
|
+
* allowlist: [],
|
|
193
|
+
* memoryMB: 128,
|
|
194
|
+
* timeoutMs: 5000,
|
|
195
|
+
* });
|
|
196
|
+
* // result.success === true
|
|
197
|
+
* // result.output === { sum: 30 }
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
async execute(request) {
|
|
201
|
+
const timeout = request.timeoutMs ?? this.timeoutMs;
|
|
202
|
+
const startTime = performance.now();
|
|
203
|
+
// Step 1: Static validation.
|
|
204
|
+
const validation = this.validateCode(request.code, request.allowlist);
|
|
205
|
+
if (!validation.valid) {
|
|
206
|
+
return {
|
|
207
|
+
success: false,
|
|
208
|
+
error: `Code validation failed: ${validation.violations.join('; ')}`,
|
|
209
|
+
executionTimeMs: Math.round(performance.now() - startTime),
|
|
210
|
+
memoryUsedBytes: 0,
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
// Step 2: Build sandbox context with only safe globals + allowlisted APIs.
|
|
214
|
+
const sandboxGlobals = this.buildSandboxContext(request.allowlist);
|
|
215
|
+
// Step 3: Wrap the code so it supports either `execute(input)` or
|
|
216
|
+
// `run(input)` and always resolves async work before serializing the result.
|
|
217
|
+
const wrappedCode = `
|
|
218
|
+
(async () => {
|
|
219
|
+
${request.code};
|
|
220
|
+
const __entry =
|
|
221
|
+
typeof execute === 'function'
|
|
222
|
+
? execute
|
|
223
|
+
: (typeof run === 'function' ? run : null);
|
|
224
|
+
if (!__entry) {
|
|
225
|
+
throw new Error('Sandboxed tool must define execute(input) or run(input).');
|
|
226
|
+
}
|
|
227
|
+
return JSON.stringify(await __entry(${JSON.stringify(request.input)}));
|
|
228
|
+
})();
|
|
229
|
+
`;
|
|
230
|
+
// Step 4: Execute in VM with timeout.
|
|
231
|
+
try {
|
|
232
|
+
const ctx = createContext(sandboxGlobals);
|
|
233
|
+
const rawResult = runInContext(wrappedCode, ctx, {
|
|
234
|
+
timeout,
|
|
235
|
+
// Prevent breakOnSigint from leaking.
|
|
236
|
+
breakOnSigint: false,
|
|
237
|
+
});
|
|
238
|
+
const settledResult = rawResult &&
|
|
239
|
+
typeof rawResult === 'object' &&
|
|
240
|
+
typeof rawResult.then === 'function'
|
|
241
|
+
? await Promise.race([
|
|
242
|
+
rawResult,
|
|
243
|
+
new Promise((_, reject) => {
|
|
244
|
+
setTimeout(() => {
|
|
245
|
+
reject(new Error(`Execution timed out after ${timeout}ms`));
|
|
246
|
+
}, timeout);
|
|
247
|
+
}),
|
|
248
|
+
])
|
|
249
|
+
: rawResult;
|
|
250
|
+
const executionTimeMs = Math.round(performance.now() - startTime);
|
|
251
|
+
// Parse the JSON-serialized output.
|
|
252
|
+
let output;
|
|
253
|
+
try {
|
|
254
|
+
output =
|
|
255
|
+
typeof settledResult === 'string'
|
|
256
|
+
? JSON.parse(settledResult)
|
|
257
|
+
: settledResult;
|
|
258
|
+
}
|
|
259
|
+
catch {
|
|
260
|
+
// If JSON.parse fails, use the raw result.
|
|
261
|
+
output = settledResult;
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
success: true,
|
|
265
|
+
output,
|
|
266
|
+
executionTimeMs,
|
|
267
|
+
memoryUsedBytes: 0,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
const executionTimeMs = Math.round(performance.now() - startTime);
|
|
272
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
273
|
+
// Detect timeout errors from the vm module.
|
|
274
|
+
const isTimeout = message.includes('Script execution timed out') ||
|
|
275
|
+
message.includes('timed out');
|
|
276
|
+
return {
|
|
277
|
+
success: false,
|
|
278
|
+
error: isTimeout
|
|
279
|
+
? `Execution timed out after ${timeout}ms`
|
|
280
|
+
: `Execution error: ${message}`,
|
|
281
|
+
executionTimeMs,
|
|
282
|
+
memoryUsedBytes: 0,
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
// --------------------------------------------------------------------------
|
|
287
|
+
// PRIVATE: buildSandboxContext
|
|
288
|
+
// --------------------------------------------------------------------------
|
|
289
|
+
/**
|
|
290
|
+
* Build the global context object for the VM sandbox.
|
|
291
|
+
*
|
|
292
|
+
* Provides a minimal set of safe built-ins (JSON, Math, Date, TextEncoder,
|
|
293
|
+
* TextDecoder) and conditionally injects allowlisted APIs.
|
|
294
|
+
*
|
|
295
|
+
* @param allowlist - The set of APIs to inject into the sandbox.
|
|
296
|
+
* @returns A plain object suitable for {@link createContext}.
|
|
297
|
+
*/
|
|
298
|
+
buildSandboxContext(allowlist) {
|
|
299
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
300
|
+
const globals = {
|
|
301
|
+
// Safe built-ins always available.
|
|
302
|
+
JSON,
|
|
303
|
+
Math,
|
|
304
|
+
Date,
|
|
305
|
+
parseInt,
|
|
306
|
+
parseFloat,
|
|
307
|
+
isNaN,
|
|
308
|
+
isFinite,
|
|
309
|
+
Number,
|
|
310
|
+
String,
|
|
311
|
+
Boolean,
|
|
312
|
+
Array,
|
|
313
|
+
Object,
|
|
314
|
+
Map,
|
|
315
|
+
Set,
|
|
316
|
+
RegExp,
|
|
317
|
+
Error,
|
|
318
|
+
TypeError,
|
|
319
|
+
RangeError,
|
|
320
|
+
TextEncoder,
|
|
321
|
+
TextDecoder,
|
|
322
|
+
// Minimal crypto for randomUUID.
|
|
323
|
+
crypto: { randomUUID: () => randomUUID() },
|
|
324
|
+
// Console stub that silently discards output.
|
|
325
|
+
console: {
|
|
326
|
+
log: () => { },
|
|
327
|
+
warn: () => { },
|
|
328
|
+
error: () => { },
|
|
329
|
+
info: () => { },
|
|
330
|
+
debug: () => { },
|
|
331
|
+
},
|
|
332
|
+
};
|
|
333
|
+
// --- Allowlisted: fetch ---
|
|
334
|
+
if (allowlist.includes('fetch')) {
|
|
335
|
+
const domainAllowlist = this.fetchDomainAllowlist;
|
|
336
|
+
globals.fetch = async (urlOrRequest, init) => {
|
|
337
|
+
const urlStr = typeof urlOrRequest === 'string'
|
|
338
|
+
? urlOrRequest
|
|
339
|
+
: urlOrRequest.url;
|
|
340
|
+
const url = new URL(urlStr);
|
|
341
|
+
const host = url.hostname.toLowerCase();
|
|
342
|
+
// Enforce domain allowlist if configured.
|
|
343
|
+
if (domainAllowlist.length > 0 &&
|
|
344
|
+
!domainAllowlist.includes(host)) {
|
|
345
|
+
throw new Error(`fetch blocked: domain "${host}" is not in the allowlist`);
|
|
346
|
+
}
|
|
347
|
+
// Delegate to the real global fetch.
|
|
348
|
+
return globalThis.fetch(urlStr, init);
|
|
349
|
+
};
|
|
350
|
+
}
|
|
351
|
+
// --- Allowlisted: fs.readFile ---
|
|
352
|
+
if (allowlist.includes('fs.readFile')) {
|
|
353
|
+
globals.fs = {
|
|
354
|
+
readFile: async (filePath) => {
|
|
355
|
+
const resolvedPath = path.resolve(filePath);
|
|
356
|
+
const allowed = this.fsReadRoots.some((root) => {
|
|
357
|
+
return (resolvedPath === root ||
|
|
358
|
+
resolvedPath.startsWith(`${root}${path.sep}`));
|
|
359
|
+
});
|
|
360
|
+
if (!allowed) {
|
|
361
|
+
throw new Error(`fs.readFile blocked: path "${resolvedPath}" is outside the allowed roots`);
|
|
362
|
+
}
|
|
363
|
+
const data = await readFile(filePath);
|
|
364
|
+
// Enforce 1 MB size limit.
|
|
365
|
+
if (data.byteLength > 1048576) {
|
|
366
|
+
throw new Error(`fs.readFile blocked: file exceeds 1 MB limit (${data.byteLength} bytes)`);
|
|
367
|
+
}
|
|
368
|
+
return data.toString('utf-8');
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
}
|
|
372
|
+
// --- Allowlisted: crypto ---
|
|
373
|
+
if (allowlist.includes('crypto')) {
|
|
374
|
+
globals.crypto = {
|
|
375
|
+
randomUUID: () => randomUUID(),
|
|
376
|
+
createHash: (algorithm) => createHash(algorithm),
|
|
377
|
+
createHmac: (algorithm, key) => createHmac(algorithm, key),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
return globals;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=SandboxedToolForge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SandboxedToolForge.js","sourceRoot":"","sources":["../../src/emergent/SandboxedToolForge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AA8ClC,+EAA+E;AAC/E,6BAA6B;AAC7B,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,aAAa,GAAoC;IACrD,CAAC,aAAa,EAAE,qBAAqB,CAAC;IACtC,CAAC,iBAAiB,EAAE,yBAAyB,CAAC;IAC9C,CAAC,uBAAuB,EAAE,6BAA6B,CAAC;IACxD,CAAC,gBAAgB,EAAE,wBAAwB,CAAC;IAC5C,CAAC,aAAa,EAAE,iCAAiC,CAAC;IAClD,CAAC,eAAe,EAAE,+BAA+B,CAAC;IAClD,CAAC,gBAAgB,EAAE,6BAA6B,CAAC;IACjD,CAAC,mBAAmB,EAAE,mCAAmC,CAAC;IAC1D,CAAC,mBAAmB,EAAE,wBAAwB,CAAC;IAC/C,CAAC,oBAAoB,EAAE,wBAAwB,CAAC;IAChD,CAAC,kBAAkB,EAAE,oBAAoB,CAAC;IAC1C,CAAC,mBAAmB,EAAE,uBAAuB,CAAC;IAC9C,CAAC,wBAAwB,EAAE,4BAA4B,CAAC;IACxD,CAAC,sBAAsB,EAAE,0BAA0B,CAAC;CACrD,CAAC;AAEF,+EAA+E;AAC/E,uBAAuB;AACvB,+EAA+E;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,OAAO,kBAAkB;IAa7B;;;;;OAKG;IACH,YAAY,MAAiC;QAC3C,IAAI,CAAC,QAAQ,GAAG,MAAM,EAAE,QAAQ,IAAI,GAAG,CAAC;QACxC,IAAI,CAAC,SAAS,GAAG,MAAM,EAAE,SAAS,IAAI,IAAI,CAAC;QAC3C,IAAI,CAAC,oBAAoB,GAAG,CAAC,MAAM,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACzE,CAAC,CAAC,WAAW,EAAE,CAChB,CAAC;QACF,IAAI,CAAC,WAAW,GAAG,CAAC,MAAM,EAAE,WAAW,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACvE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CACnB,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,uBAAuB;IACvB,6EAA6E;IAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,YAAY,CACV,IAAY,EACZ,SAAuB;QAEvB,MAAM,UAAU,GAAa,EAAE,CAAC;QAEhC,gCAAgC;QAChC,KAAK,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,IAAI,aAAa,EAAE,CAAC;YAC/C,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACvB,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3B,CAAC;QACH,CAAC;QAED,+CAA+C;QAC/C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9D,UAAU,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QAED,gEAAgE;QAChE,wEAAwE;QACxE,uCAAuC;QACvC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACjE,uEAAuE;YACvE,MAAM,cAAc,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;YACnE,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,UAAU,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;YACvD,CAAC;QACH,CAAC;QAED,+CAA+C;QAC/C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAChE,UAAU,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,KAAK,CAAC;YAC5B,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;YACjC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC;IACnC,CAAC;IAED,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAE7E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,KAAK,CAAC,OAAO,CACX,OAAgC;QAEhC,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,CAAC;QACpD,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAEpC,6BAA6B;QAC7B,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;QACtE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,2BAA2B,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACpE,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAC1D,eAAe,EAAE,CAAC;aACnB,CAAC;QACJ,CAAC;QAED,2EAA2E;QAC3E,MAAM,cAAc,GAAG,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAEnE,kEAAkE;QAClE,6EAA6E;QAC7E,MAAM,WAAW,GAAG;;UAEd,OAAO,CAAC,IAAI;;;;;;;;8CAQwB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC;;KAEtE,CAAC;QAEF,sCAAsC;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;YAC1C,MAAM,SAAS,GAAG,YAAY,CAAC,WAAW,EAAE,GAAG,EAAE;gBAC/C,OAAO;gBACP,sCAAsC;gBACtC,aAAa,EAAE,KAAK;aACrB,CAAC,CAAC;YACH,MAAM,aAAa,GACjB,SAAS;gBACT,OAAO,SAAS,KAAK,QAAQ;gBAC7B,OAAQ,SAA8B,CAAC,IAAI,KAAK,UAAU;gBACxD,CAAC,CAAC,MAAM,OAAO,CAAC,IAAI,CAAC;oBACjB,SAA6B;oBAC7B,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;wBAC/B,UAAU,CAAC,GAAG,EAAE;4BACd,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,OAAO,IAAI,CAAC,CAAC,CAAC;wBAC9D,CAAC,EAAE,OAAO,CAAC,CAAC;oBACd,CAAC,CAAC;iBACH,CAAC;gBACJ,CAAC,CAAC,SAAS,CAAC;YAEhB,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YAElE,oCAAoC;YACpC,IAAI,MAAe,CAAC;YACpB,IAAI,CAAC;gBACH,MAAM;oBACJ,OAAO,aAAa,KAAK,QAAQ;wBAC/B,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;wBAC3B,CAAC,CAAC,aAAa,CAAC;YACtB,CAAC;YAAC,MAAM,CAAC;gBACP,2CAA2C;gBAC3C,MAAM,GAAG,aAAa,CAAC;YACzB,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM;gBACN,eAAe;gBACf,eAAe,EAAE,CAAC;aACnB,CAAC;QACJ,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACtB,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,CAAC;YAClE,MAAM,OAAO,GACX,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAEnD,4CAA4C;YAC5C,MAAM,SAAS,GACb,OAAO,CAAC,QAAQ,CAAC,4BAA4B,CAAC;gBAC9C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YAEhC,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,SAAS;oBACd,CAAC,CAAC,6BAA6B,OAAO,IAAI;oBAC1C,CAAC,CAAC,oBAAoB,OAAO,EAAE;gBACjC,eAAe;gBACf,eAAe,EAAE,CAAC;aACnB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,+BAA+B;IAC/B,6EAA6E;IAE7E;;;;;;;;OAQG;IACK,mBAAmB,CACzB,SAAuB;QAEvB,uDAAuD;QACvD,MAAM,OAAO,GAA4B;YACvC,mCAAmC;YACnC,IAAI;YACJ,IAAI;YACJ,IAAI;YACJ,QAAQ;YACR,UAAU;YACV,KAAK;YACL,QAAQ;YACR,MAAM;YACN,MAAM;YACN,OAAO;YACP,KAAK;YACL,MAAM;YACN,GAAG;YACH,GAAG;YACH,MAAM;YACN,KAAK;YACL,SAAS;YACT,UAAU;YACV,WAAW;YACX,WAAW;YACX,iCAAiC;YACjC,MAAM,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE,EAAE;YAC1C,8CAA8C;YAC9C,OAAO,EAAE;gBACP,GAAG,EAAE,GAAG,EAAE,GAAE,CAAC;gBACb,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;gBACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;gBACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;gBACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;aAChB;SACF,CAAC;QAEF,6BAA6B;QAC7B,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,MAAM,eAAe,GAAG,IAAI,CAAC,oBAAoB,CAAC;YAClD,OAAO,CAAC,KAAK,GAAG,KAAK,EACnB,YAAsC,EACtC,IAA8B,EAC9B,EAAE;gBACF,MAAM,MAAM,GACV,OAAO,YAAY,KAAK,QAAQ;oBAC9B,CAAC,CAAC,YAAY;oBACd,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC;gBACvB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC;gBAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;gBAExC,0CAA0C;gBAC1C,IACE,eAAe,CAAC,MAAM,GAAG,CAAC;oBAC1B,CAAC,eAAe,CAAC,QAAQ,CAAC,IAAI,CAAC,EAC/B,CAAC;oBACD,MAAM,IAAI,KAAK,CACb,0BAA0B,IAAI,2BAA2B,CAC1D,CAAC;gBACJ,CAAC;gBAED,qCAAqC;gBACrC,OAAO,UAAU,CAAC,KAAK,CAAC,MAAM,EAAE,IAAW,CAAC,CAAC;YAC/C,CAAC,CAAC;QACJ,CAAC;QAED,mCAAmC;QACnC,IAAI,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;YACtC,OAAO,CAAC,EAAE,GAAG;gBACX,QAAQ,EAAE,KAAK,EAAE,QAAgB,EAAE,EAAE;oBACnC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;oBAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;wBAC7C,OAAO,CACL,YAAY,KAAK,IAAI;4BACrB,YAAY,CAAC,UAAU,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAC9C,CAAC;oBACJ,CAAC,CAAC,CAAC;oBACH,IAAI,CAAC,OAAO,EAAE,CAAC;wBACb,MAAM,IAAI,KAAK,CACb,8BAA8B,YAAY,gCAAgC,CAC3E,CAAC;oBACJ,CAAC;oBACD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;oBACtC,2BAA2B;oBAC3B,IAAI,IAAI,CAAC,UAAU,GAAG,OAAS,EAAE,CAAC;wBAChC,MAAM,IAAI,KAAK,CACb,iDAAiD,IAAI,CAAC,UAAU,SAAS,CAC1E,CAAC;oBACJ,CAAC;oBACD,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;aACF,CAAC;QACJ,CAAC;QAED,8BAA8B;QAC9B,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,OAAO,CAAC,MAAM,GAAG;gBACf,UAAU,EAAE,GAAG,EAAE,CAAC,UAAU,EAAE;gBAC9B,UAAU,EAAE,CAAC,SAAiB,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;gBACxD,UAAU,EAAE,CAAC,SAAiB,EAAE,GAAW,EAAE,EAAE,CAC7C,UAAU,CAAC,SAAS,EAAE,GAAG,CAAC;aAC7B,CAAC;QACJ,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Emergent Capability Engine — public API barrel.
|
|
3
|
+
* @module @framers/agentos/emergent
|
|
4
|
+
*
|
|
5
|
+
* Re-exports all types, interfaces, and constants from the emergent module.
|
|
6
|
+
* Import from this barrel to avoid deep path coupling to internal files.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import type { EmergentTool, ForgeToolRequest, DEFAULT_EMERGENT_CONFIG } from '../emergent';
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export * from './types.js';
|
|
14
|
+
export { ComposableToolBuilder } from './ComposableToolBuilder.js';
|
|
15
|
+
export { SandboxedToolForge } from './SandboxedToolForge.js';
|
|
16
|
+
export type { SandboxedToolForgeConfig } from './SandboxedToolForge.js';
|
|
17
|
+
export { EmergentToolRegistry } from './EmergentToolRegistry.js';
|
|
18
|
+
export type { IStorageAdapter as EmergentRegistryStorageAdapter, AuditEntry, } from './EmergentToolRegistry.js';
|
|
19
|
+
export { EmergentJudge } from './EmergentJudge.js';
|
|
20
|
+
export type { ToolCandidate, EmergentJudgeConfig } from './EmergentJudge.js';
|
|
21
|
+
export { EmergentCapabilityEngine } from './EmergentCapabilityEngine.js';
|
|
22
|
+
export type { EmergentCapabilityEngineDeps } from './EmergentCapabilityEngine.js';
|
|
23
|
+
export { ForgeToolMetaTool } from './ForgeToolMetaTool.js';
|
|
24
|
+
export type { ForgeToolInput } from './ForgeToolMetaTool.js';
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/emergent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,YAAY,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACxE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,YAAY,EACV,eAAe,IAAI,8BAA8B,EACjD,UAAU,GACX,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,YAAY,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC7E,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AACzE,YAAY,EAAE,4BAA4B,EAAE,MAAM,+BAA+B,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAC3D,YAAY,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Emergent Capability Engine — public API barrel.
|
|
3
|
+
* @module @framers/agentos/emergent
|
|
4
|
+
*
|
|
5
|
+
* Re-exports all types, interfaces, and constants from the emergent module.
|
|
6
|
+
* Import from this barrel to avoid deep path coupling to internal files.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* import type { EmergentTool, ForgeToolRequest, DEFAULT_EMERGENT_CONFIG } from '../emergent/index.js';
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
export * from './types.js';
|
|
14
|
+
export { ComposableToolBuilder } from './ComposableToolBuilder.js';
|
|
15
|
+
export { SandboxedToolForge } from './SandboxedToolForge.js';
|
|
16
|
+
export { EmergentToolRegistry } from './EmergentToolRegistry.js';
|
|
17
|
+
export { EmergentJudge } from './EmergentJudge.js';
|
|
18
|
+
export { EmergentCapabilityEngine } from './EmergentCapabilityEngine.js';
|
|
19
|
+
export { ForgeToolMetaTool } from './ForgeToolMetaTool.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/emergent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AAKjE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAEzE,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC"}
|