@sandagent/manager 0.1.0-beta.0

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 ADDED
@@ -0,0 +1,191 @@
1
+ # @sandagent/manager
2
+
3
+ Core manager package for SandAgent - manages sandbox and runner lifecycle, defines core interfaces.
4
+
5
+ ## Overview
6
+
7
+ `@sandagent/manager` is the foundational package that provides:
8
+
9
+ - **SandAgent**: Main class for managing sandboxed agent instances
10
+ - **Core Interfaces**: `SandboxAdapter`, `SandboxHandle`, `RunnerSpec`, etc.
11
+ - **Transcript Writers**: Tools for logging agent execution (JSONL, Memory, Console, Multi)
12
+ - **Type Definitions**: Shared types for messages, streams, and sandbox operations
13
+
14
+ This package is typically used as a dependency by higher-level packages like `@sandagent/ai-provider` and sandbox adapters.
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @sandagent/manager
20
+ ```
21
+
22
+ ## Usage
23
+
24
+ ### Basic Usage
25
+
26
+ ```typescript
27
+ import { SandAgent } from '@sandagent/manager';
28
+ import { E2BSandbox } from '@sandagent/sandbox-e2b';
29
+
30
+ const agent = new SandAgent({
31
+ sandbox: new E2BSandbox({ apiKey: 'xxx' }),
32
+ runner: {
33
+ kind: 'claude-agent-sdk',
34
+ model: 'claude-sonnet-4-20250514',
35
+ outputFormat: 'stream',
36
+ },
37
+ env: {
38
+ ANTHROPIC_API_KEY: process.env.ANTHROPIC_API_KEY!,
39
+ },
40
+ });
41
+
42
+ // Stream a task
43
+ const stream = await agent.stream({
44
+ messages: [
45
+ { role: 'user', content: 'Create a hello world program' }
46
+ ],
47
+ workspace: {
48
+ path: '/workspace',
49
+ },
50
+ });
51
+
52
+ // Read the stream
53
+ const reader = stream.getReader();
54
+ while (true) {
55
+ const { done, value } = await reader.read();
56
+ if (done) break;
57
+ process.stdout.write(value);
58
+ }
59
+
60
+ // Cleanup
61
+ await agent.destroy();
62
+ ```
63
+
64
+ ### With Transcript Logging
65
+
66
+ ```typescript
67
+ import { SandAgent, JsonlTranscriptWriter } from '@sandagent/manager';
68
+
69
+ const transcriptWriter = new JsonlTranscriptWriter('./transcript.jsonl');
70
+
71
+ const stream = await agent.stream({
72
+ messages: [{ role: 'user', content: 'Do something' }],
73
+ workspace: { path: '/workspace' },
74
+ transcriptWriter,
75
+ });
76
+ ```
77
+
78
+ ### Upload Files
79
+
80
+ ```typescript
81
+ await agent.uploadFiles([
82
+ { path: 'hello.txt', content: 'Hello World!' },
83
+ { path: 'data.json', content: JSON.stringify({ key: 'value' }) },
84
+ ], '/workspace');
85
+ ```
86
+
87
+ ## Core Interfaces
88
+
89
+ ### SandboxAdapter
90
+
91
+ Interface that sandbox implementations must follow:
92
+
93
+ ```typescript
94
+ interface SandboxAdapter {
95
+ attach(): Promise<SandboxHandle>;
96
+ getHandle(): SandboxHandle | null;
97
+ getEnv?(): Record<string, string>;
98
+ getWorkdir?(): string;
99
+ }
100
+ ```
101
+
102
+ ### SandboxHandle
103
+
104
+ Interface for interacting with an attached sandbox:
105
+
106
+ ```typescript
107
+ interface SandboxHandle {
108
+ exec(command: string[], opts?: ExecOptions): AsyncIterable<Uint8Array>;
109
+ upload(files: Array<{ path: string; content: Uint8Array | string }>, targetDir: string): Promise<void>;
110
+ readFile?(filePath: string): Promise<string>;
111
+ runCommand?(command: string): Promise<{ stdout: string; stderr: string; exitCode: number }>;
112
+ destroy(): Promise<void>;
113
+ getWorkdir?(): string;
114
+ }
115
+ ```
116
+
117
+ ### RunnerSpec
118
+
119
+ Specification for the runner to execute inside the sandbox:
120
+
121
+ ```typescript
122
+ interface RunnerSpec {
123
+ kind: 'claude-agent-sdk' | string;
124
+ model: string;
125
+ systemPrompt?: string;
126
+ maxTurns?: number;
127
+ allowedTools?: string[];
128
+ approvalDir?: string;
129
+ outputFormat?: 'stream' | 'json';
130
+ }
131
+ ```
132
+
133
+ ## Transcript Writers
134
+
135
+ Available transcript writers:
136
+
137
+ - **JsonlTranscriptWriter**: Write to JSONL file
138
+ - **MemoryTranscriptWriter**: Store in memory
139
+ - **ConsoleTranscriptWriter**: Log to console
140
+ - **MultiTranscriptWriter**: Write to multiple writers
141
+
142
+ ```typescript
143
+ import {
144
+ JsonlTranscriptWriter,
145
+ MemoryTranscriptWriter,
146
+ MultiTranscriptWriter
147
+ } from '@sandagent/manager';
148
+
149
+ const transcriptWriter = new MultiTranscriptWriter([
150
+ new JsonlTranscriptWriter('./transcript.jsonl'),
151
+ new ConsoleTranscriptWriter(),
152
+ ]);
153
+ ```
154
+
155
+ ## API Reference
156
+
157
+ ### SandAgent
158
+
159
+ #### Constructor
160
+
161
+ ```typescript
162
+ new SandAgent(options: SandAgentOptions)
163
+ ```
164
+
165
+ **Options:**
166
+ - `sandbox` (required): A SandboxAdapter instance
167
+ - `runner` (required): RunnerSpec configuration
168
+ - `env`: Environment variables for the sandbox
169
+
170
+ #### Methods
171
+
172
+ **stream(input: StreamInput): Promise<ReadableStream<Uint8Array>>**
173
+
174
+ Stream a task through the agent. Returns a ReadableStream of AI SDK UI messages.
175
+
176
+ **uploadFiles(files: Array<{ path: string; content: Uint8Array | string }>, targetDir?: string): Promise<void>**
177
+
178
+ Upload files to the agent's workspace.
179
+
180
+ **destroy(): Promise<void>**
181
+
182
+ Destroy the sandbox and release resources.
183
+
184
+ ## Requirements
185
+
186
+ - Node.js 20+
187
+ - A sandbox adapter (@sandagent/sandbox-e2b, @sandagent/sandbox-local, etc.)
188
+
189
+ ## License
190
+
191
+ Apache-2.0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=sand-agent.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sand-agent.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/sand-agent.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,284 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ import { SandAgent } from "../sand-agent.js";
3
+ /**
4
+ * Create an async iterable from data
5
+ */
6
+ function createAsyncIterable(data) {
7
+ return {
8
+ [Symbol.asyncIterator]: () => {
9
+ let index = 0;
10
+ return {
11
+ async next() {
12
+ if (index < data.length) {
13
+ return { value: data[index++], done: false };
14
+ }
15
+ return { value: undefined, done: true };
16
+ },
17
+ };
18
+ },
19
+ };
20
+ }
21
+ /**
22
+ * Mock sandbox adapter for testing
23
+ */
24
+ function createMockSandbox() {
25
+ const handle = {
26
+ exec: vi
27
+ .fn()
28
+ .mockReturnValue(createAsyncIterable([new TextEncoder().encode("test output")])),
29
+ upload: vi.fn().mockResolvedValue(undefined),
30
+ readFile: vi.fn().mockResolvedValue(""),
31
+ destroy: vi.fn().mockResolvedValue(undefined),
32
+ };
33
+ const adapter = {
34
+ attach: vi.fn().mockResolvedValue(handle),
35
+ getHandle: vi.fn().mockReturnValue(handle),
36
+ handle,
37
+ };
38
+ return adapter;
39
+ }
40
+ describe("SandAgent", () => {
41
+ describe("stream", () => {
42
+ it("should attach to sandbox and execute command", async () => {
43
+ const sandbox = createMockSandbox();
44
+ const agent = new SandAgent({
45
+ sandbox,
46
+ runner: {
47
+ kind: "claude-agent-sdk",
48
+ model: "claude-sonnet-4-20250514",
49
+ },
50
+ });
51
+ const stream = await agent.stream({
52
+ messages: [{ role: "user", content: "Hello" }],
53
+ });
54
+ expect(sandbox.attach).toHaveBeenCalledWith();
55
+ expect(stream).toBeInstanceOf(ReadableStream);
56
+ });
57
+ it("should use default workspace path", async () => {
58
+ const sandbox = createMockSandbox();
59
+ const agent = new SandAgent({
60
+ sandbox,
61
+ runner: {
62
+ kind: "claude-agent-sdk",
63
+ model: "claude-sonnet-4-20250514",
64
+ },
65
+ });
66
+ await agent.stream({
67
+ messages: [{ role: "user", content: "Hello" }],
68
+ });
69
+ expect(sandbox.handle.exec).toHaveBeenCalledWith(expect.arrayContaining(["--cwd", "/workspace"]), expect.objectContaining({ cwd: "/workspace" }));
70
+ });
71
+ it("should use custom workspace path", async () => {
72
+ const sandbox = createMockSandbox();
73
+ const agent = new SandAgent({
74
+ sandbox,
75
+ runner: {
76
+ kind: "claude-agent-sdk",
77
+ model: "claude-sonnet-4-20250514",
78
+ },
79
+ });
80
+ await agent.stream({
81
+ messages: [{ role: "user", content: "Hello" }],
82
+ workspace: { path: "/custom/path" },
83
+ });
84
+ expect(sandbox.handle.exec).toHaveBeenCalledWith(expect.arrayContaining(["--cwd", "/custom/path"]), expect.objectContaining({ cwd: "/custom/path" }));
85
+ });
86
+ it("should include user message in command", async () => {
87
+ const sandbox = createMockSandbox();
88
+ const agent = new SandAgent({
89
+ sandbox,
90
+ runner: {
91
+ kind: "claude-agent-sdk",
92
+ model: "claude-sonnet-4-20250514",
93
+ },
94
+ });
95
+ await agent.stream({
96
+ messages: [{ role: "user", content: "Create a file" }],
97
+ });
98
+ expect(sandbox.handle.exec).toHaveBeenCalledWith(expect.arrayContaining(["Create a file"]), expect.any(Object));
99
+ });
100
+ it("should pass through stdout without modification", async () => {
101
+ const testData = "test streaming data";
102
+ const sandbox = createMockSandbox();
103
+ // Override exec to return test data using proper async iterable
104
+ sandbox.handle.exec = vi
105
+ .fn()
106
+ .mockReturnValue(createAsyncIterable([new TextEncoder().encode(testData)]));
107
+ const agent = new SandAgent({
108
+ sandbox,
109
+ runner: {
110
+ kind: "claude-agent-sdk",
111
+ model: "claude-sonnet-4-20250514",
112
+ },
113
+ });
114
+ const stream = await agent.stream({
115
+ messages: [{ role: "user", content: "Hello" }],
116
+ });
117
+ const reader = stream.getReader();
118
+ const { value } = await reader.read();
119
+ const text = new TextDecoder().decode(value);
120
+ expect(text).toBe(testData);
121
+ });
122
+ });
123
+ describe("uploadFiles", () => {
124
+ it("should upload files to the sandbox", async () => {
125
+ const sandbox = createMockSandbox();
126
+ const agent = new SandAgent({
127
+ sandbox,
128
+ runner: {
129
+ kind: "claude-agent-sdk",
130
+ model: "claude-sonnet-4-20250514",
131
+ },
132
+ });
133
+ await agent.uploadFiles([{ path: "test.txt", content: "Hello, World!" }]);
134
+ expect(sandbox.handle.upload).toHaveBeenCalledWith([{ path: "test.txt", content: "Hello, World!" }], "/workspace");
135
+ });
136
+ it("should upload files to custom directory", async () => {
137
+ const sandbox = createMockSandbox();
138
+ const agent = new SandAgent({
139
+ sandbox,
140
+ runner: {
141
+ kind: "claude-agent-sdk",
142
+ model: "claude-sonnet-4-20250514",
143
+ },
144
+ });
145
+ await agent.uploadFiles([{ path: "test.txt", content: "Hello, World!" }], "/custom/dir");
146
+ expect(sandbox.handle.upload).toHaveBeenCalledWith([{ path: "test.txt", content: "Hello, World!" }], "/custom/dir");
147
+ });
148
+ });
149
+ describe("destroy", () => {
150
+ it("should destroy the sandbox", async () => {
151
+ const sandbox = createMockSandbox();
152
+ const agent = new SandAgent({
153
+ sandbox,
154
+ runner: {
155
+ kind: "claude-agent-sdk",
156
+ model: "claude-sonnet-4-20250514",
157
+ },
158
+ });
159
+ // First attach to sandbox
160
+ await agent.stream({
161
+ messages: [{ role: "user", content: "Hello" }],
162
+ });
163
+ // Then destroy
164
+ await agent.destroy();
165
+ expect(sandbox.handle.destroy).toHaveBeenCalled();
166
+ });
167
+ it("should do nothing if not attached", async () => {
168
+ const sandbox = createMockSandbox();
169
+ const agent = new SandAgent({
170
+ sandbox,
171
+ runner: {
172
+ kind: "claude-agent-sdk",
173
+ model: "claude-sonnet-4-20250514",
174
+ },
175
+ });
176
+ // Destroy without attaching first
177
+ await agent.destroy();
178
+ expect(sandbox.handle.destroy).not.toHaveBeenCalled();
179
+ });
180
+ });
181
+ describe("AbortSignal support", () => {
182
+ it("should pass signal to exec()", async () => {
183
+ const sandbox = createMockSandbox();
184
+ const agent = new SandAgent({
185
+ sandbox,
186
+ runner: {
187
+ kind: "claude-agent-sdk",
188
+ model: "claude-sonnet-4-20250514",
189
+ },
190
+ });
191
+ const controller = new AbortController();
192
+ const signal = controller.signal;
193
+ await agent.stream({
194
+ messages: [{ role: "user", content: "Hello" }],
195
+ signal,
196
+ });
197
+ expect(sandbox.handle.exec).toHaveBeenCalledWith(expect.any(Array), expect.objectContaining({ signal }));
198
+ });
199
+ it("should throw error if signal is already aborted", async () => {
200
+ const sandbox = createMockSandbox();
201
+ const agent = new SandAgent({
202
+ sandbox,
203
+ runner: {
204
+ kind: "claude-agent-sdk",
205
+ model: "claude-sonnet-4-20250514",
206
+ },
207
+ });
208
+ const controller = new AbortController();
209
+ controller.abort();
210
+ const signal = controller.signal;
211
+ await expect(agent.stream({
212
+ messages: [{ role: "user", content: "Hello" }],
213
+ signal,
214
+ })).rejects.toThrow("Operation was aborted");
215
+ });
216
+ it("should pass signal to exec()", async () => {
217
+ const sandbox = createMockSandbox();
218
+ const controller = new AbortController();
219
+ sandbox.handle.exec = vi
220
+ .fn()
221
+ .mockReturnValue(createAsyncIterable([new TextEncoder().encode("test output")]));
222
+ const agent = new SandAgent({
223
+ sandbox,
224
+ runner: {
225
+ kind: "claude-agent-sdk",
226
+ model: "claude-sonnet-4-20250514",
227
+ },
228
+ });
229
+ await agent.stream({
230
+ messages: [{ role: "user", content: "Hello" }],
231
+ signal: controller.signal,
232
+ });
233
+ // Verify signal was passed to exec
234
+ expect(sandbox.handle.exec).toHaveBeenCalledWith(expect.any(Array), expect.objectContaining({
235
+ signal: controller.signal,
236
+ }));
237
+ });
238
+ it("should handle AbortError from exec() gracefully", async () => {
239
+ const sandbox = createMockSandbox();
240
+ const transcriptEntries = [];
241
+ const mockTranscriptWriter = {
242
+ write: vi.fn().mockImplementation((entry) => {
243
+ transcriptEntries.push(entry);
244
+ return Promise.resolve();
245
+ }),
246
+ };
247
+ // Create a mock that throws AbortError
248
+ sandbox.handle.exec = vi.fn().mockReturnValue({
249
+ [Symbol.asyncIterator]: async function* () {
250
+ yield new TextEncoder().encode("chunk1");
251
+ const error = new Error("The operation was aborted");
252
+ error.name = "AbortError";
253
+ throw error;
254
+ },
255
+ });
256
+ const agent = new SandAgent({
257
+ sandbox,
258
+ runner: {
259
+ kind: "claude-agent-sdk",
260
+ model: "claude-sonnet-4-20250514",
261
+ },
262
+ });
263
+ const stream = await agent.stream({
264
+ messages: [{ role: "user", content: "Hello" }],
265
+ transcriptWriter: mockTranscriptWriter,
266
+ });
267
+ const reader = stream.getReader();
268
+ // Read first chunk
269
+ await reader.read();
270
+ // Try to read next chunk - should throw
271
+ await expect(reader.read()).rejects.toThrow();
272
+ // Check that start entry was written
273
+ const startEntry = transcriptEntries.find((entry) => entry.type === "start");
274
+ expect(startEntry).toBeDefined();
275
+ // Check that at least one chunk was written
276
+ const chunkEntry = transcriptEntries.find((entry) => entry.type === "chunk");
277
+ expect(chunkEntry).toBeDefined();
278
+ // AbortError should NOT create an error entry - just stops cleanly
279
+ const errorEntry = transcriptEntries.find((entry) => entry.type === "error");
280
+ expect(errorEntry).toBeUndefined();
281
+ });
282
+ });
283
+ });
284
+ //# sourceMappingURL=sand-agent.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sand-agent.test.js","sourceRoot":"","sources":["../../src/__tests__/sand-agent.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=signal-integration.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-integration.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/signal-integration.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,136 @@
1
+ import { beforeEach, describe, expect, it, vi } from "vitest";
2
+ import { SandAgent } from "../sand-agent.js";
3
+ describe("Signal Integration Tests", () => {
4
+ let mockSandbox;
5
+ let mockHandle;
6
+ let execSignalReceived;
7
+ beforeEach(() => {
8
+ execSignalReceived = undefined;
9
+ mockHandle = {
10
+ exec: vi.fn((command, opts) => {
11
+ // Capture the signal that was passed
12
+ execSignalReceived = opts?.signal;
13
+ // Return an async iterable that respects the signal
14
+ return {
15
+ async *[Symbol.asyncIterator]() {
16
+ const chunks = [
17
+ new TextEncoder().encode("chunk1"),
18
+ new TextEncoder().encode("chunk2"),
19
+ new TextEncoder().encode("chunk3"),
20
+ ];
21
+ for (const chunk of chunks) {
22
+ // Check if signal was aborted
23
+ if (opts?.signal?.aborted) {
24
+ break;
25
+ }
26
+ yield chunk;
27
+ // Small delay to allow abort to happen
28
+ await new Promise((resolve) => setTimeout(resolve, 10));
29
+ }
30
+ },
31
+ };
32
+ }),
33
+ upload: vi.fn(),
34
+ readFile: vi.fn(),
35
+ destroy: vi.fn(),
36
+ };
37
+ mockSandbox = {
38
+ attach: vi.fn(async () => mockHandle),
39
+ getHandle: vi.fn(() => mockHandle),
40
+ };
41
+ });
42
+ it("should pass signal from StreamInput to sandbox exec", async () => {
43
+ const agent = new SandAgent({
44
+ sandbox: mockSandbox,
45
+ runner: {
46
+ kind: "claude-agent-sdk",
47
+ model: "claude-3-5-sonnet-20241022",
48
+ },
49
+ });
50
+ const controller = new AbortController();
51
+ const input = {
52
+ messages: [{ role: "user", content: "test" }],
53
+ signal: controller.signal,
54
+ };
55
+ const stream = await agent.stream(input);
56
+ expect(stream).toBeInstanceOf(ReadableStream);
57
+ // Verify that the signal was passed to exec
58
+ expect(execSignalReceived).toBe(controller.signal);
59
+ });
60
+ it("should stop streaming when signal is aborted", async () => {
61
+ const agent = new SandAgent({
62
+ sandbox: mockSandbox,
63
+ runner: {
64
+ kind: "claude-agent-sdk",
65
+ model: "claude-3-5-sonnet-20241022",
66
+ },
67
+ });
68
+ const controller = new AbortController();
69
+ const input = {
70
+ messages: [{ role: "user", content: "test" }],
71
+ signal: controller.signal,
72
+ };
73
+ const stream = await agent.stream(input);
74
+ const reader = stream.getReader();
75
+ expect(reader).toBeDefined();
76
+ // Read first chunk
77
+ const chunk1 = await reader.read();
78
+ expect(chunk1.done).toBe(false);
79
+ // Abort the signal
80
+ controller.abort();
81
+ // Try to read more - should complete quickly
82
+ const chunks = [];
83
+ while (true) {
84
+ const result = await reader.read();
85
+ if (result.done)
86
+ break;
87
+ chunks.push(result.value);
88
+ }
89
+ // Should have received fewer than all 3 chunks
90
+ expect(chunks.length).toBeLessThan(2);
91
+ });
92
+ it("should handle pre-aborted signal", async () => {
93
+ const agent = new SandAgent({
94
+ sandbox: mockSandbox,
95
+ runner: {
96
+ kind: "claude-agent-sdk",
97
+ model: "claude-3-5-sonnet-20241022",
98
+ },
99
+ });
100
+ const controller = new AbortController();
101
+ controller.abort(); // Abort before streaming
102
+ const input = {
103
+ messages: [{ role: "user", content: "test" }],
104
+ signal: controller.signal,
105
+ };
106
+ await expect(agent.stream(input)).rejects.toThrow("Operation was aborted");
107
+ });
108
+ it("should work without signal (backward compatibility)", async () => {
109
+ const agent = new SandAgent({
110
+ sandbox: mockSandbox,
111
+ runner: {
112
+ kind: "claude-agent-sdk",
113
+ model: "claude-3-5-sonnet-20241022",
114
+ },
115
+ });
116
+ const input = {
117
+ messages: [{ role: "user", content: "test" }],
118
+ // No signal provided
119
+ };
120
+ const stream = await agent.stream(input);
121
+ expect(stream).toBeInstanceOf(ReadableStream);
122
+ // Verify that exec was called without signal
123
+ expect(execSignalReceived).toBeUndefined();
124
+ // Should be able to read all chunks
125
+ const reader = stream.getReader();
126
+ const chunks = [];
127
+ while (true) {
128
+ const result = await reader.read();
129
+ if (result.done)
130
+ break;
131
+ chunks.push(result.value);
132
+ }
133
+ expect(chunks.length).toBe(3);
134
+ });
135
+ });
136
+ //# sourceMappingURL=signal-integration.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"signal-integration.test.js","sourceRoot":"","sources":["../../src/__tests__/signal-integration.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=transcript.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/transcript.test.ts"],"names":[],"mappings":""}