@bunny-agent/manager 0.9.28
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/LICENSE +201 -0
- package/README.md +198 -0
- package/dist/__tests__/bunny-agent.test.d.ts +2 -0
- package/dist/__tests__/bunny-agent.test.d.ts.map +1 -0
- package/dist/__tests__/bunny-agent.test.js +274 -0
- package/dist/__tests__/bunny-agent.test.js.map +1 -0
- package/dist/__tests__/coding-run.test.d.ts +2 -0
- package/dist/__tests__/coding-run.test.d.ts.map +1 -0
- package/dist/__tests__/coding-run.test.js +27 -0
- package/dist/__tests__/coding-run.test.js.map +1 -0
- package/dist/__tests__/daemon-health.test.d.ts +2 -0
- package/dist/__tests__/daemon-health.test.d.ts.map +1 -0
- package/dist/__tests__/daemon-health.test.js +113 -0
- package/dist/__tests__/daemon-health.test.js.map +1 -0
- package/dist/__tests__/env.test.d.ts +2 -0
- package/dist/__tests__/env.test.d.ts.map +1 -0
- package/dist/__tests__/env.test.js +82 -0
- package/dist/__tests__/env.test.js.map +1 -0
- package/dist/__tests__/local-sandbox.test.d.ts +2 -0
- package/dist/__tests__/local-sandbox.test.d.ts.map +1 -0
- package/dist/__tests__/local-sandbox.test.js +274 -0
- package/dist/__tests__/local-sandbox.test.js.map +1 -0
- package/dist/__tests__/signal-integration.test.d.ts +2 -0
- package/dist/__tests__/signal-integration.test.d.ts.map +1 -0
- package/dist/__tests__/signal-integration.test.js +135 -0
- package/dist/__tests__/signal-integration.test.js.map +1 -0
- package/dist/__tests__/transcript.test.d.ts +2 -0
- package/dist/__tests__/transcript.test.d.ts.map +1 -0
- package/dist/__tests__/transcript.test.js +144 -0
- package/dist/__tests__/transcript.test.js.map +1 -0
- package/dist/__tests__/types.test.d.ts +2 -0
- package/dist/__tests__/types.test.d.ts.map +1 -0
- package/dist/__tests__/types.test.js +148 -0
- package/dist/__tests__/types.test.js.map +1 -0
- package/dist/bunny-agent.d.ts +50 -0
- package/dist/bunny-agent.d.ts.map +1 -0
- package/dist/bunny-agent.js +206 -0
- package/dist/bunny-agent.js.map +1 -0
- package/dist/coding-run.d.ts +40 -0
- package/dist/coding-run.d.ts.map +1 -0
- package/dist/coding-run.js +111 -0
- package/dist/coding-run.js.map +1 -0
- package/dist/constants.d.ts +7 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +7 -0
- package/dist/constants.js.map +1 -0
- package/dist/daemon-health.d.ts +16 -0
- package/dist/daemon-health.d.ts.map +1 -0
- package/dist/daemon-health.js +66 -0
- package/dist/daemon-health.js.map +1 -0
- package/dist/env.d.ts +55 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +113 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/local-sandbox.d.ts +83 -0
- package/dist/local-sandbox.d.ts.map +1 -0
- package/dist/local-sandbox.js +364 -0
- package/dist/local-sandbox.js.map +1 -0
- package/dist/transcript.d.ts +112 -0
- package/dist/transcript.d.ts.map +1 -0
- package/dist/transcript.js +176 -0
- package/dist/transcript.js.map +1 -0
- package/dist/types.d.ts +249 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +50 -0
package/dist/env.js
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build a sanitised env record for spawning a runner child process.
|
|
3
|
+
*
|
|
4
|
+
* Responsibilities:
|
|
5
|
+
* 1. Differentiate env by runner type (Claude vs Pi vs others).
|
|
6
|
+
* 2. Claude: map Anthropic/Bedrock/LiteLLM credentials.
|
|
7
|
+
* 3. Pi: map OpenAI/Gemini/Anthropic credentials and base URLs.
|
|
8
|
+
* 4. Strip host-only vars (e.g. CLAUDE_CODE_SSE_PORT) that would make the SDK
|
|
9
|
+
* connect to the parent Claude Code instead of calling the API directly.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Env vars that must NOT be forwarded to the runner child process.
|
|
13
|
+
*/
|
|
14
|
+
const STRIP_FROM_CHILD = new Set([
|
|
15
|
+
"CLAUDE_CODE_SSE_PORT",
|
|
16
|
+
"CLAUDE_CODE_SSE_SESSION_ID",
|
|
17
|
+
]);
|
|
18
|
+
function applyInherit(inherit, env) {
|
|
19
|
+
for (const [key, val] of Object.entries(inherit)) {
|
|
20
|
+
if (val == null)
|
|
21
|
+
continue;
|
|
22
|
+
if (STRIP_FROM_CHILD.has(key))
|
|
23
|
+
continue;
|
|
24
|
+
env[key] = String(val);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Env vars for Claude runner (Anthropic Agent SDK, Bedrock, LiteLLM).
|
|
29
|
+
*/
|
|
30
|
+
function applyClaudeRunnerEnv(params, env) {
|
|
31
|
+
const { ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL, AWS_BEARER_TOKEN_BEDROCK, ANTHROPIC_AUTH_TOKEN, LITELLM_MASTER_KEY, ANTHROPIC_BEDROCK_BASE_URL, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_SKIP_BEDROCK_AUTH, } = params;
|
|
32
|
+
if (ANTHROPIC_API_KEY)
|
|
33
|
+
env.ANTHROPIC_API_KEY = ANTHROPIC_API_KEY;
|
|
34
|
+
if (ANTHROPIC_BASE_URL)
|
|
35
|
+
env.ANTHROPIC_BASE_URL = ANTHROPIC_BASE_URL;
|
|
36
|
+
if (AWS_BEARER_TOKEN_BEDROCK) {
|
|
37
|
+
env.AWS_BEARER_TOKEN_BEDROCK = AWS_BEARER_TOKEN_BEDROCK;
|
|
38
|
+
env.CLAUDE_CODE_USE_BEDROCK = "1";
|
|
39
|
+
}
|
|
40
|
+
if (ANTHROPIC_AUTH_TOKEN)
|
|
41
|
+
env.ANTHROPIC_AUTH_TOKEN = ANTHROPIC_AUTH_TOKEN;
|
|
42
|
+
if (LITELLM_MASTER_KEY)
|
|
43
|
+
env.LITELLM_MASTER_KEY = LITELLM_MASTER_KEY;
|
|
44
|
+
if (ANTHROPIC_BEDROCK_BASE_URL) {
|
|
45
|
+
env.ANTHROPIC_BEDROCK_BASE_URL = ANTHROPIC_BEDROCK_BASE_URL;
|
|
46
|
+
env.CLAUDE_CODE_USE_BEDROCK = CLAUDE_CODE_USE_BEDROCK || "1";
|
|
47
|
+
env.CLAUDE_CODE_SKIP_BEDROCK_AUTH = CLAUDE_CODE_SKIP_BEDROCK_AUTH || "1";
|
|
48
|
+
if (!env.AWS_BEARER_TOKEN_BEDROCK) {
|
|
49
|
+
const proxyKey = ANTHROPIC_AUTH_TOKEN || LITELLM_MASTER_KEY;
|
|
50
|
+
if (proxyKey)
|
|
51
|
+
env.AWS_BEARER_TOKEN_BEDROCK = proxyKey;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Env vars for Pi runner (OpenAI, Gemini, Anthropic providers; base URLs).
|
|
57
|
+
*/
|
|
58
|
+
function applyPiRunnerEnv(params, env) {
|
|
59
|
+
const { ANTHROPIC_API_KEY, ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, LITELLM_MASTER_KEY, ANTHROPIC_BEDROCK_BASE_URL, OPENAI_API_KEY, OPENAI_BASE_URL, GEMINI_API_KEY, GEMINI_BASE_URL, } = params;
|
|
60
|
+
if (OPENAI_API_KEY)
|
|
61
|
+
env.OPENAI_API_KEY = OPENAI_API_KEY;
|
|
62
|
+
if (OPENAI_BASE_URL)
|
|
63
|
+
env.OPENAI_BASE_URL = OPENAI_BASE_URL;
|
|
64
|
+
if (GEMINI_API_KEY)
|
|
65
|
+
env.GEMINI_API_KEY = GEMINI_API_KEY;
|
|
66
|
+
if (GEMINI_BASE_URL)
|
|
67
|
+
env.GEMINI_BASE_URL = GEMINI_BASE_URL;
|
|
68
|
+
if (ANTHROPIC_API_KEY)
|
|
69
|
+
env.ANTHROPIC_API_KEY = ANTHROPIC_API_KEY;
|
|
70
|
+
if (ANTHROPIC_BASE_URL)
|
|
71
|
+
env.ANTHROPIC_BASE_URL = ANTHROPIC_BASE_URL;
|
|
72
|
+
if (!env.ANTHROPIC_API_KEY && (ANTHROPIC_AUTH_TOKEN || LITELLM_MASTER_KEY)) {
|
|
73
|
+
env.ANTHROPIC_API_KEY = ANTHROPIC_AUTH_TOKEN || LITELLM_MASTER_KEY || "";
|
|
74
|
+
}
|
|
75
|
+
if (ANTHROPIC_BEDROCK_BASE_URL && !env.ANTHROPIC_BASE_URL) {
|
|
76
|
+
env.ANTHROPIC_BASE_URL = ANTHROPIC_BEDROCK_BASE_URL;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Build the env record that should be passed to a runner child process.
|
|
81
|
+
*
|
|
82
|
+
* Applies inherit (stripped) first, then runner-specific credential vars.
|
|
83
|
+
* Unknown runner types default to Claude for backward compatibility.
|
|
84
|
+
*
|
|
85
|
+
* @param params - Credential / proxy configuration and runner type.
|
|
86
|
+
* @returns A plain `Record<string, string>` safe for child process env.
|
|
87
|
+
*/
|
|
88
|
+
export function buildRunnerEnv(params) {
|
|
89
|
+
const { runnerType = "claude", inherit = {} } = params;
|
|
90
|
+
const env = {};
|
|
91
|
+
applyInherit(inherit, env);
|
|
92
|
+
switch (runnerType) {
|
|
93
|
+
case "pi":
|
|
94
|
+
applyPiRunnerEnv(params, env);
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
applyClaudeRunnerEnv(params, env);
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
// Web search keys (all runners) — params override process.env
|
|
101
|
+
const braveKey = params.BRAVE_API_KEY || process.env.BRAVE_API_KEY;
|
|
102
|
+
const tavilyKey = params.TAVILY_API_KEY || process.env.TAVILY_API_KEY;
|
|
103
|
+
if (braveKey)
|
|
104
|
+
env.BRAVE_API_KEY = braveKey;
|
|
105
|
+
if (tavilyKey)
|
|
106
|
+
env.TAVILY_API_KEY = tavilyKey;
|
|
107
|
+
const imageModel = params.IMAGE_GENERATION_MODEL || process.env.IMAGE_GENERATION_MODEL;
|
|
108
|
+
if (imageModel) {
|
|
109
|
+
env.IMAGE_GENERATION_MODEL = imageModel;
|
|
110
|
+
}
|
|
111
|
+
return env;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=env.js.map
|
package/dist/env.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.js","sourceRoot":"","sources":["../src/env.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export { BunnyAgent } from "./bunny-agent.js";
|
|
2
|
+
export type { DaemonCodingRunExecParams } from "./coding-run.js";
|
|
3
|
+
export { buildCodingRunShellScript, buildDefaultCodingRunExec, buildDefaultDaemonCodingRunExecCommand, SANDBOX_CODING_RUN_TMP_DIR, streamCodingRunFromSandbox, } from "./coding-run.js";
|
|
4
|
+
export { DEFAULT_BUNNY_AGENT_DAEMON_URL } from "./constants.js";
|
|
5
|
+
export type { IsBunnyAgentDaemonHealthyOptions } from "./daemon-health.js";
|
|
6
|
+
export { isBunnyAgentDaemonHealthy } from "./daemon-health.js";
|
|
7
|
+
export type { RunnerEnvParams, RunnerType } from "./env.js";
|
|
8
|
+
export { buildRunnerEnv } from "./env.js";
|
|
9
|
+
export type { LocalSandboxOptions } from "./local-sandbox.js";
|
|
10
|
+
export { LocalSandbox } from "./local-sandbox.js";
|
|
11
|
+
export { ConsoleTranscriptWriter, JsonlTranscriptWriter, MemoryTranscriptWriter, MultiTranscriptWriter, } from "./transcript.js";
|
|
12
|
+
export type { BunnyAgentCodingRunBody, BunnyAgentOptions, ExecOptions, Message, RunnerSpec, SandboxAdapter, SandboxHandle, StreamInput, TranscriptEntry, TranscriptWriter, Volume, } from "./types.js";
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,YAAY,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,sCAAsC,EACtC,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAChE,YAAY,EAAE,gCAAgC,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,WAAW,EACX,OAAO,EACP,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,MAAM,GACP,MAAM,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { BunnyAgent } from "./bunny-agent.js";
|
|
2
|
+
export { buildCodingRunShellScript, buildDefaultCodingRunExec, buildDefaultDaemonCodingRunExecCommand, SANDBOX_CODING_RUN_TMP_DIR, streamCodingRunFromSandbox, } from "./coding-run.js";
|
|
3
|
+
export { DEFAULT_BUNNY_AGENT_DAEMON_URL } from "./constants.js";
|
|
4
|
+
export { isBunnyAgentDaemonHealthy } from "./daemon-health.js";
|
|
5
|
+
// Env helpers
|
|
6
|
+
export { buildRunnerEnv } from "./env.js";
|
|
7
|
+
// Default sandbox adapter (built-in)
|
|
8
|
+
export { LocalSandbox } from "./local-sandbox.js";
|
|
9
|
+
export { ConsoleTranscriptWriter, JsonlTranscriptWriter, MemoryTranscriptWriter, MultiTranscriptWriter, } from "./transcript.js";
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,OAAO,EACL,yBAAyB,EACzB,yBAAyB,EACzB,sCAAsC,EACtC,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,8BAA8B,EAAE,MAAM,gBAAgB,CAAC;AAEhE,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAE/D,cAAc;AACd,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { SandboxAdapter, SandboxHandle } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Options for creating a LocalSandbox instance
|
|
4
|
+
*/
|
|
5
|
+
export interface LocalSandboxOptions {
|
|
6
|
+
/** Working directory for all operations (defaults to process.cwd()) */
|
|
7
|
+
workdir?: string;
|
|
8
|
+
/** Path to the agent template directory to copy into the sandbox workdir */
|
|
9
|
+
templatesPath?: string;
|
|
10
|
+
/** Default timeout for commands in milliseconds (default: 300000 = 5 min) */
|
|
11
|
+
defaultTimeout?: number;
|
|
12
|
+
/** Environment variables to pass to all commands */
|
|
13
|
+
env?: Record<string, string>;
|
|
14
|
+
/** Runner command to execute in the sandbox (default: ["bunny-agent", "run"]) */
|
|
15
|
+
runnerCommand?: string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Local sandbox implementation that runs commands on the local machine.
|
|
19
|
+
*
|
|
20
|
+
* This adapter is useful for:
|
|
21
|
+
* - Development and testing
|
|
22
|
+
* - Running agents locally without cloud dependencies
|
|
23
|
+
* - Quick prototyping
|
|
24
|
+
*
|
|
25
|
+
* Warning: This runs commands directly on your local machine with your user's
|
|
26
|
+
* permissions. Use with caution and only with trusted code.
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```typescript
|
|
30
|
+
* import { LocalSandbox, BunnyAgent } from "@bunny-agent/manager";
|
|
31
|
+
*
|
|
32
|
+
* // Create sandbox with template
|
|
33
|
+
* const sandbox = new LocalSandbox({
|
|
34
|
+
* workdir: "/tmp/my-sandbox",
|
|
35
|
+
* templatesPath: "/path/to/agent-template",
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* const agent = new BunnyAgent({
|
|
39
|
+
* sandbox,
|
|
40
|
+
* runner: {
|
|
41
|
+
* model: "claude-sonnet-4-20250514",
|
|
42
|
+
* },
|
|
43
|
+
* });
|
|
44
|
+
*
|
|
45
|
+
* // Attach copies template files to workdir and returns handle
|
|
46
|
+
* const handle = await sandbox.attach();
|
|
47
|
+
* const result = await handle.runCommand("ls -la");
|
|
48
|
+
* console.log(result.stdout);
|
|
49
|
+
* ```
|
|
50
|
+
*/
|
|
51
|
+
export declare class LocalSandbox implements SandboxAdapter {
|
|
52
|
+
private readonly workdir;
|
|
53
|
+
private readonly templatesPath;
|
|
54
|
+
private readonly defaultTimeout;
|
|
55
|
+
private readonly env;
|
|
56
|
+
private readonly runnerCommand;
|
|
57
|
+
/** Current handle for the sandbox instance */
|
|
58
|
+
private currentHandle;
|
|
59
|
+
constructor(options?: LocalSandboxOptions);
|
|
60
|
+
getHandle(): SandboxHandle | null;
|
|
61
|
+
/**
|
|
62
|
+
* Get the environment variables configured for this sandbox.
|
|
63
|
+
*/
|
|
64
|
+
getEnv(): Record<string, string>;
|
|
65
|
+
/**
|
|
66
|
+
* Get the working directory configured for this sandbox.
|
|
67
|
+
*/
|
|
68
|
+
getWorkdir(): string;
|
|
69
|
+
/**
|
|
70
|
+
* Get the runner command to execute in the sandbox.
|
|
71
|
+
*/
|
|
72
|
+
getRunnerCommand(): string[];
|
|
73
|
+
attach(): Promise<SandboxHandle>;
|
|
74
|
+
/**
|
|
75
|
+
* Recursively copy a directory
|
|
76
|
+
*/
|
|
77
|
+
private copyDir;
|
|
78
|
+
/**
|
|
79
|
+
* Reset the sandbox, clearing the current handle.
|
|
80
|
+
*/
|
|
81
|
+
reset(): void;
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=local-sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-sandbox.d.ts","sourceRoot":"","sources":["../src/local-sandbox.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAe,cAAc,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAE7E;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4EAA4E;IAC5E,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,oDAAoD;IACpD,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAAa,YAAa,YAAW,cAAc;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAqB;IACnD,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAW;IAEzC,8CAA8C;IAC9C,OAAO,CAAC,aAAa,CAAmC;gBAE5C,OAAO,GAAE,mBAAwB;IAQ7C,SAAS,IAAI,aAAa,GAAG,IAAI;IAIjC;;OAEG;IACH,MAAM,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC;IAIhC;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE;IAItB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;IA0DtC;;OAEG;YACW,OAAO;IAcrB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd"}
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs/promises";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import { buildRunnerEnv } from "./env.js";
|
|
5
|
+
/**
|
|
6
|
+
* Local sandbox implementation that runs commands on the local machine.
|
|
7
|
+
*
|
|
8
|
+
* This adapter is useful for:
|
|
9
|
+
* - Development and testing
|
|
10
|
+
* - Running agents locally without cloud dependencies
|
|
11
|
+
* - Quick prototyping
|
|
12
|
+
*
|
|
13
|
+
* Warning: This runs commands directly on your local machine with your user's
|
|
14
|
+
* permissions. Use with caution and only with trusted code.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* import { LocalSandbox, BunnyAgent } from "@bunny-agent/manager";
|
|
19
|
+
*
|
|
20
|
+
* // Create sandbox with template
|
|
21
|
+
* const sandbox = new LocalSandbox({
|
|
22
|
+
* workdir: "/tmp/my-sandbox",
|
|
23
|
+
* templatesPath: "/path/to/agent-template",
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* const agent = new BunnyAgent({
|
|
27
|
+
* sandbox,
|
|
28
|
+
* runner: {
|
|
29
|
+
* model: "claude-sonnet-4-20250514",
|
|
30
|
+
* },
|
|
31
|
+
* });
|
|
32
|
+
*
|
|
33
|
+
* // Attach copies template files to workdir and returns handle
|
|
34
|
+
* const handle = await sandbox.attach();
|
|
35
|
+
* const result = await handle.runCommand("ls -la");
|
|
36
|
+
* console.log(result.stdout);
|
|
37
|
+
* ```
|
|
38
|
+
*/
|
|
39
|
+
export class LocalSandbox {
|
|
40
|
+
workdir;
|
|
41
|
+
templatesPath;
|
|
42
|
+
defaultTimeout;
|
|
43
|
+
env;
|
|
44
|
+
runnerCommand;
|
|
45
|
+
/** Current handle for the sandbox instance */
|
|
46
|
+
currentHandle = null;
|
|
47
|
+
constructor(options = {}) {
|
|
48
|
+
this.workdir = options.workdir ?? process.cwd();
|
|
49
|
+
this.templatesPath = options.templatesPath;
|
|
50
|
+
this.defaultTimeout = options.defaultTimeout ?? 300000; // 5 min for agent runs
|
|
51
|
+
this.env = options.env ?? {};
|
|
52
|
+
this.runnerCommand = options.runnerCommand ?? ["bunny-agent", "run"];
|
|
53
|
+
}
|
|
54
|
+
getHandle() {
|
|
55
|
+
return this.currentHandle;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the environment variables configured for this sandbox.
|
|
59
|
+
*/
|
|
60
|
+
getEnv() {
|
|
61
|
+
return { ...this.env };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the working directory configured for this sandbox.
|
|
65
|
+
*/
|
|
66
|
+
getWorkdir() {
|
|
67
|
+
return this.currentHandle?.getWorkdir() ?? this.workdir;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Get the runner command to execute in the sandbox.
|
|
71
|
+
*/
|
|
72
|
+
getRunnerCommand() {
|
|
73
|
+
return [...this.runnerCommand];
|
|
74
|
+
}
|
|
75
|
+
async attach() {
|
|
76
|
+
// Return existing handle if already attached
|
|
77
|
+
if (this.currentHandle) {
|
|
78
|
+
return this.currentHandle;
|
|
79
|
+
}
|
|
80
|
+
// Use workdir as the working directory
|
|
81
|
+
const workdir = this.workdir;
|
|
82
|
+
// Clear template files before copying (only .claude dir and CLAUDE.md)
|
|
83
|
+
if (this.templatesPath) {
|
|
84
|
+
const claudeDir = path.join(workdir, ".claude");
|
|
85
|
+
const claudeMd = path.join(workdir, "CLAUDE.md");
|
|
86
|
+
await fs.rm(claudeDir, { recursive: true, force: true }).catch(() => { });
|
|
87
|
+
await fs.rm(claudeMd, { force: true }).catch(() => { });
|
|
88
|
+
console.log(`[LocalSandbox] Cleared template files: .claude, CLAUDE.md`);
|
|
89
|
+
}
|
|
90
|
+
// Create the directory if it doesn't exist
|
|
91
|
+
await fs.mkdir(workdir, { recursive: true });
|
|
92
|
+
console.log(`[LocalSandbox] Using directory: ${workdir}`);
|
|
93
|
+
// Copy all files from templatesPath to workdir if specified
|
|
94
|
+
if (this.templatesPath) {
|
|
95
|
+
try {
|
|
96
|
+
const stat = await fs.stat(this.templatesPath);
|
|
97
|
+
if (stat.isDirectory()) {
|
|
98
|
+
await this.copyDir(this.templatesPath, workdir);
|
|
99
|
+
console.log(`[LocalSandbox] Copied template directory: ${this.templatesPath} -> ${workdir}`);
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
console.warn(`[LocalSandbox] templatesPath is not a directory: ${this.templatesPath}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (err) {
|
|
106
|
+
console.warn(`[LocalSandbox] Failed to copy template directory: ${this.templatesPath}`, err);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
const handle = new LocalSandboxHandle(workdir, this.defaultTimeout, this.env);
|
|
110
|
+
// Store the handle
|
|
111
|
+
this.currentHandle = handle;
|
|
112
|
+
return handle;
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Recursively copy a directory
|
|
116
|
+
*/
|
|
117
|
+
async copyDir(src, dest) {
|
|
118
|
+
await fs.mkdir(dest, { recursive: true });
|
|
119
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
120
|
+
for (const entry of entries) {
|
|
121
|
+
const srcPath = path.join(src, entry.name);
|
|
122
|
+
const destPath = path.join(dest, entry.name);
|
|
123
|
+
if (entry.isDirectory()) {
|
|
124
|
+
await this.copyDir(srcPath, destPath);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
await fs.copyFile(srcPath, destPath);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Reset the sandbox, clearing the current handle.
|
|
133
|
+
*/
|
|
134
|
+
reset() {
|
|
135
|
+
this.currentHandle = null;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Handle for a local sandbox instance
|
|
140
|
+
*/
|
|
141
|
+
class LocalSandboxHandle {
|
|
142
|
+
workDir;
|
|
143
|
+
defaultTimeout;
|
|
144
|
+
env;
|
|
145
|
+
_sandboxId;
|
|
146
|
+
constructor(workDir, defaultTimeout, env) {
|
|
147
|
+
this.workDir = workDir;
|
|
148
|
+
this.defaultTimeout = defaultTimeout;
|
|
149
|
+
this.env = env;
|
|
150
|
+
this._sandboxId = `local-${crypto.randomUUID()}`;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Get the sandbox instance ID.
|
|
154
|
+
*/
|
|
155
|
+
getSandboxId() {
|
|
156
|
+
return this._sandboxId;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Local sandbox has no volumes.
|
|
160
|
+
*/
|
|
161
|
+
getVolumes() {
|
|
162
|
+
return null;
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Get the working directory for this sandbox handle
|
|
166
|
+
*/
|
|
167
|
+
getWorkdir() {
|
|
168
|
+
return this.workDir;
|
|
169
|
+
}
|
|
170
|
+
async *exec(command, opts = {}) {
|
|
171
|
+
if (command.length === 0) {
|
|
172
|
+
throw new Error("Command cannot be empty");
|
|
173
|
+
}
|
|
174
|
+
const cwd = opts.cwd ? path.resolve(this.workDir, opts.cwd) : this.workDir;
|
|
175
|
+
const timeout = opts.timeout ?? this.defaultTimeout;
|
|
176
|
+
const baseInherit = { ...process.env, ...this.env, ...opts.env };
|
|
177
|
+
const env = buildRunnerEnv({
|
|
178
|
+
inherit: baseInherit,
|
|
179
|
+
});
|
|
180
|
+
console.log(`[LocalSandbox] Executing command: ${command.join(" ")}`);
|
|
181
|
+
console.log(`[LocalSandbox] Working directory: ${cwd}`);
|
|
182
|
+
console.log(`[LocalSandbox] ENV AWS_BEARER_TOKEN_BEDROCK: ${env.AWS_BEARER_TOKEN_BEDROCK ? "SET" : "NOT SET"}`);
|
|
183
|
+
console.log(`[LocalSandbox] ENV CLAUDE_CODE_USE_BEDROCK: ${env.CLAUDE_CODE_USE_BEDROCK || "NOT SET"}`);
|
|
184
|
+
console.log(`[LocalSandbox] ENV ANTHROPIC_API_KEY: ${env.ANTHROPIC_API_KEY ? "SET" : "NOT SET"}`);
|
|
185
|
+
// Ensure the working directory exists
|
|
186
|
+
await fs.mkdir(cwd, { recursive: true });
|
|
187
|
+
const [cmd, ...args] = command;
|
|
188
|
+
const child = spawn(cmd, args, {
|
|
189
|
+
cwd,
|
|
190
|
+
env,
|
|
191
|
+
shell: false,
|
|
192
|
+
});
|
|
193
|
+
let timeoutId;
|
|
194
|
+
let isTimedOut = false;
|
|
195
|
+
let isAborted = false;
|
|
196
|
+
// Set up timeout if specified
|
|
197
|
+
if (timeout > 0) {
|
|
198
|
+
timeoutId = setTimeout(() => {
|
|
199
|
+
isTimedOut = true;
|
|
200
|
+
child.kill("SIGTERM");
|
|
201
|
+
// Force kill after 5 seconds if still running
|
|
202
|
+
setTimeout(() => {
|
|
203
|
+
if (!child.killed) {
|
|
204
|
+
child.kill("SIGKILL");
|
|
205
|
+
}
|
|
206
|
+
}, 5000);
|
|
207
|
+
}, timeout);
|
|
208
|
+
}
|
|
209
|
+
// Set up abort signal if provided
|
|
210
|
+
const abortHandler = () => {
|
|
211
|
+
isAborted = true;
|
|
212
|
+
child.kill("SIGTERM");
|
|
213
|
+
setTimeout(() => {
|
|
214
|
+
if (!child.killed) {
|
|
215
|
+
child.kill("SIGKILL");
|
|
216
|
+
}
|
|
217
|
+
}, 5000);
|
|
218
|
+
};
|
|
219
|
+
if (opts.signal) {
|
|
220
|
+
opts.signal.addEventListener("abort", abortHandler);
|
|
221
|
+
}
|
|
222
|
+
// Handle spawn errors (e.g., command not found)
|
|
223
|
+
const spawnError = await new Promise((resolve) => {
|
|
224
|
+
child.once("error", resolve);
|
|
225
|
+
child.once("spawn", () => resolve(null));
|
|
226
|
+
});
|
|
227
|
+
if (spawnError) {
|
|
228
|
+
if (timeoutId) {
|
|
229
|
+
clearTimeout(timeoutId);
|
|
230
|
+
}
|
|
231
|
+
if (opts.signal) {
|
|
232
|
+
opts.signal.removeEventListener("abort", abortHandler);
|
|
233
|
+
}
|
|
234
|
+
throw spawnError;
|
|
235
|
+
}
|
|
236
|
+
// Buffer stderr for error reporting; also mirror to the parent process so
|
|
237
|
+
// subprocess diagnostics (e.g. [bunny-agent:pi] skill load) are visible on success.
|
|
238
|
+
const stderrChunks = [];
|
|
239
|
+
child.stderr.on("data", (chunk) => {
|
|
240
|
+
stderrChunks.push(chunk);
|
|
241
|
+
process.stderr.write(chunk);
|
|
242
|
+
});
|
|
243
|
+
try {
|
|
244
|
+
// Yield stdout chunks
|
|
245
|
+
for await (const chunk of child.stdout) {
|
|
246
|
+
yield chunk;
|
|
247
|
+
}
|
|
248
|
+
// Wait for the process to complete
|
|
249
|
+
const exitCode = await new Promise((resolve, reject) => {
|
|
250
|
+
child.on("error", reject);
|
|
251
|
+
child.on("close", (code) => resolve(code ?? 0));
|
|
252
|
+
});
|
|
253
|
+
if (timeoutId) {
|
|
254
|
+
clearTimeout(timeoutId);
|
|
255
|
+
}
|
|
256
|
+
if (isAborted) {
|
|
257
|
+
throw new Error("Command was aborted");
|
|
258
|
+
}
|
|
259
|
+
if (isTimedOut) {
|
|
260
|
+
throw new Error(`Command timed out after ${timeout}ms`);
|
|
261
|
+
}
|
|
262
|
+
if (exitCode !== 0) {
|
|
263
|
+
const stderr = stderrChunks.length
|
|
264
|
+
? Buffer.concat(stderrChunks).toString("utf-8").trim()
|
|
265
|
+
: "";
|
|
266
|
+
if (stderr) {
|
|
267
|
+
console.error(`[LocalSandbox] Command failed (exit ${exitCode}) stderr:\n${stderr}`);
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
console.error(`[LocalSandbox] Command failed with exit ${exitCode} (no stderr). Run manually to see output: ${command.join(" ")}`);
|
|
271
|
+
}
|
|
272
|
+
// User-facing message: show the actual error from stderr (where it failed)
|
|
273
|
+
const lines = stderr
|
|
274
|
+
.split(/\n/)
|
|
275
|
+
.map((l) => l.trim())
|
|
276
|
+
.filter(Boolean);
|
|
277
|
+
const lastLine = lines.length > 0 ? lines[lines.length - 1] : "";
|
|
278
|
+
const hasErrorLike = (s) => /error|Error|Fatal|TypeError|SyntaxError|Exception/i.test(s);
|
|
279
|
+
const errorLine = lines.filter(hasErrorLike).pop() ?? lastLine;
|
|
280
|
+
const userMessage = errorLine
|
|
281
|
+
? errorLine.replace(/\s+/g, " ").slice(0, 500)
|
|
282
|
+
: stderr
|
|
283
|
+
? `Command failed (exit ${exitCode}). See server logs for stderr.`
|
|
284
|
+
: `Command failed with exit ${exitCode}.`;
|
|
285
|
+
throw new Error(userMessage);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
catch (error) {
|
|
289
|
+
if (timeoutId) {
|
|
290
|
+
clearTimeout(timeoutId);
|
|
291
|
+
}
|
|
292
|
+
throw error;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
async upload(files, targetDir) {
|
|
296
|
+
const resolvedTargetDir = path.resolve(this.workDir, targetDir);
|
|
297
|
+
console.log(`[LocalSandbox] Uploading ${files.length} file(s) to ${resolvedTargetDir}`);
|
|
298
|
+
// Create target directory
|
|
299
|
+
await fs.mkdir(resolvedTargetDir, { recursive: true });
|
|
300
|
+
// Write each file
|
|
301
|
+
for (const file of files) {
|
|
302
|
+
const filePath = path.join(resolvedTargetDir, file.path);
|
|
303
|
+
const fileDir = path.dirname(filePath);
|
|
304
|
+
// Ensure the file's directory exists
|
|
305
|
+
await fs.mkdir(fileDir, { recursive: true });
|
|
306
|
+
// Write the file
|
|
307
|
+
const content = typeof file.content === "string"
|
|
308
|
+
? Buffer.from(file.content, "utf-8")
|
|
309
|
+
: file.content;
|
|
310
|
+
await fs.writeFile(filePath, content);
|
|
311
|
+
console.log(`[LocalSandbox] Wrote file: ${filePath}`);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
async readFile(filePath) {
|
|
315
|
+
const resolvedPath = path.resolve(this.workDir, filePath);
|
|
316
|
+
const content = await fs.readFile(resolvedPath, "utf-8");
|
|
317
|
+
return content;
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Execute a command and wait for completion, returning stdout, stderr, and exit code
|
|
321
|
+
*/
|
|
322
|
+
async runCommand(command) {
|
|
323
|
+
console.log(`[LocalSandbox] Running command: ${command}`);
|
|
324
|
+
return new Promise((resolve, reject) => {
|
|
325
|
+
// Use sh -c to execute the command
|
|
326
|
+
const child = spawn("sh", ["-c", command], {
|
|
327
|
+
cwd: this.workDir,
|
|
328
|
+
env: { ...process.env, ...this.env }, // Use instance env
|
|
329
|
+
stdio: "pipe",
|
|
330
|
+
});
|
|
331
|
+
let stdout = "";
|
|
332
|
+
let stderr = "";
|
|
333
|
+
child.stdout?.on("data", (data) => {
|
|
334
|
+
stdout += data.toString();
|
|
335
|
+
});
|
|
336
|
+
child.stderr?.on("data", (data) => {
|
|
337
|
+
stderr += data.toString();
|
|
338
|
+
});
|
|
339
|
+
child.on("close", (code) => {
|
|
340
|
+
resolve({
|
|
341
|
+
stdout,
|
|
342
|
+
stderr,
|
|
343
|
+
exitCode: code ?? 0,
|
|
344
|
+
});
|
|
345
|
+
});
|
|
346
|
+
child.on("error", reject);
|
|
347
|
+
// Timeout handling
|
|
348
|
+
const timeout = this.defaultTimeout;
|
|
349
|
+
const timeoutId = setTimeout(() => {
|
|
350
|
+
child.kill();
|
|
351
|
+
reject(new Error(`Command timed out after ${timeout}ms`));
|
|
352
|
+
}, timeout);
|
|
353
|
+
child.on("close", () => {
|
|
354
|
+
clearTimeout(timeoutId);
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
async destroy() {
|
|
359
|
+
console.log(`[LocalSandbox] Cleanup complete for: ${this.workDir}`);
|
|
360
|
+
// Note: We don't delete the directory by default to preserve work
|
|
361
|
+
// Users can manually delete it if needed
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
//# sourceMappingURL=local-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"local-sandbox.js","sourceRoot":"","sources":["../src/local-sandbox.ts"],"names":[],"mappings":"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"}
|