@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
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { BunnyAgent } from "../bunny-agent.js";
|
|
3
|
+
describe("Signal Integration Tests", () => {
|
|
4
|
+
let mockSandbox;
|
|
5
|
+
let mockHandle;
|
|
6
|
+
let execSignalReceived;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
execSignalReceived = undefined;
|
|
9
|
+
mockHandle = {
|
|
10
|
+
getWorkdir: vi.fn().mockReturnValue("/workspace"),
|
|
11
|
+
getSandboxId: vi.fn().mockReturnValue(null),
|
|
12
|
+
getVolumes: vi.fn().mockReturnValue(null),
|
|
13
|
+
exec: vi.fn((_command, opts) => {
|
|
14
|
+
// Capture the signal that was passed
|
|
15
|
+
execSignalReceived = opts?.signal;
|
|
16
|
+
// Return an async iterable that respects the signal
|
|
17
|
+
return {
|
|
18
|
+
async *[Symbol.asyncIterator]() {
|
|
19
|
+
const chunks = [
|
|
20
|
+
new TextEncoder().encode("chunk1"),
|
|
21
|
+
new TextEncoder().encode("chunk2"),
|
|
22
|
+
new TextEncoder().encode("chunk3"),
|
|
23
|
+
];
|
|
24
|
+
for (const chunk of chunks) {
|
|
25
|
+
// Check if signal was aborted
|
|
26
|
+
if (opts?.signal?.aborted) {
|
|
27
|
+
break;
|
|
28
|
+
}
|
|
29
|
+
yield chunk;
|
|
30
|
+
// Small delay to allow abort to happen
|
|
31
|
+
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}),
|
|
36
|
+
upload: vi.fn(),
|
|
37
|
+
readFile: vi.fn(),
|
|
38
|
+
destroy: vi.fn(),
|
|
39
|
+
};
|
|
40
|
+
mockSandbox = {
|
|
41
|
+
attach: vi.fn(async () => mockHandle),
|
|
42
|
+
getHandle: vi.fn(() => mockHandle),
|
|
43
|
+
};
|
|
44
|
+
});
|
|
45
|
+
it("should pass signal from StreamInput to sandbox exec", async () => {
|
|
46
|
+
const agent = new BunnyAgent({
|
|
47
|
+
sandbox: mockSandbox,
|
|
48
|
+
runner: {
|
|
49
|
+
model: "claude-3-5-sonnet-20241022",
|
|
50
|
+
},
|
|
51
|
+
});
|
|
52
|
+
const controller = new AbortController();
|
|
53
|
+
const input = {
|
|
54
|
+
messages: [{ role: "user", content: "test" }],
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
};
|
|
57
|
+
const stream = await agent.stream(input);
|
|
58
|
+
expect(stream).toBeInstanceOf(ReadableStream);
|
|
59
|
+
// Verify that the signal was passed to exec
|
|
60
|
+
expect(execSignalReceived).toBe(controller.signal);
|
|
61
|
+
});
|
|
62
|
+
it("should stop streaming when signal is aborted", async () => {
|
|
63
|
+
const agent = new BunnyAgent({
|
|
64
|
+
sandbox: mockSandbox,
|
|
65
|
+
runner: {
|
|
66
|
+
model: "claude-3-5-sonnet-20241022",
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
const controller = new AbortController();
|
|
70
|
+
const input = {
|
|
71
|
+
messages: [{ role: "user", content: "test" }],
|
|
72
|
+
signal: controller.signal,
|
|
73
|
+
};
|
|
74
|
+
const stream = await agent.stream(input);
|
|
75
|
+
const reader = stream.getReader();
|
|
76
|
+
expect(reader).toBeDefined();
|
|
77
|
+
// Read first chunk
|
|
78
|
+
const chunk1 = await reader.read();
|
|
79
|
+
expect(chunk1.done).toBe(false);
|
|
80
|
+
// Abort the signal
|
|
81
|
+
controller.abort();
|
|
82
|
+
// Try to read more - should complete quickly
|
|
83
|
+
const chunks = [];
|
|
84
|
+
while (true) {
|
|
85
|
+
const result = await reader.read();
|
|
86
|
+
if (result.done)
|
|
87
|
+
break;
|
|
88
|
+
chunks.push(result.value);
|
|
89
|
+
}
|
|
90
|
+
// Should have received fewer than all 3 chunks
|
|
91
|
+
expect(chunks.length).toBeLessThan(2);
|
|
92
|
+
});
|
|
93
|
+
it("should handle pre-aborted signal", async () => {
|
|
94
|
+
const agent = new BunnyAgent({
|
|
95
|
+
sandbox: mockSandbox,
|
|
96
|
+
runner: {
|
|
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 BunnyAgent({
|
|
110
|
+
sandbox: mockSandbox,
|
|
111
|
+
runner: {
|
|
112
|
+
model: "claude-3-5-sonnet-20241022",
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
const input = {
|
|
116
|
+
messages: [{ role: "user", content: "test" }],
|
|
117
|
+
// No signal provided
|
|
118
|
+
};
|
|
119
|
+
const stream = await agent.stream(input);
|
|
120
|
+
expect(stream).toBeInstanceOf(ReadableStream);
|
|
121
|
+
// Verify that exec was called without signal
|
|
122
|
+
expect(execSignalReceived).toBeUndefined();
|
|
123
|
+
// Should be able to read all chunks
|
|
124
|
+
const reader = stream.getReader();
|
|
125
|
+
const chunks = [];
|
|
126
|
+
while (true) {
|
|
127
|
+
const result = await reader.read();
|
|
128
|
+
if (result.done)
|
|
129
|
+
break;
|
|
130
|
+
chunks.push(result.value);
|
|
131
|
+
}
|
|
132
|
+
expect(chunks.length).toBe(3);
|
|
133
|
+
});
|
|
134
|
+
});
|
|
135
|
+
//# 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 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/transcript.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { ConsoleTranscriptWriter, MemoryTranscriptWriter, MultiTranscriptWriter, } from "../transcript.js";
|
|
3
|
+
describe("Transcript Writers", () => {
|
|
4
|
+
describe("MemoryTranscriptWriter", () => {
|
|
5
|
+
let writer;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
writer = new MemoryTranscriptWriter();
|
|
8
|
+
});
|
|
9
|
+
it("should store entries in memory", () => {
|
|
10
|
+
const entry = {
|
|
11
|
+
timestamp: new Date().toISOString(),
|
|
12
|
+
type: "chunk",
|
|
13
|
+
text: "Hello, world!",
|
|
14
|
+
};
|
|
15
|
+
writer.write(entry);
|
|
16
|
+
const entries = writer.getEntries();
|
|
17
|
+
expect(entries).toHaveLength(1);
|
|
18
|
+
expect(entries[0]).toEqual(entry);
|
|
19
|
+
});
|
|
20
|
+
it("should return chunks as strings", () => {
|
|
21
|
+
writer.write({
|
|
22
|
+
timestamp: new Date().toISOString(),
|
|
23
|
+
type: "chunk",
|
|
24
|
+
text: "Hello, ",
|
|
25
|
+
});
|
|
26
|
+
writer.write({
|
|
27
|
+
timestamp: new Date().toISOString(),
|
|
28
|
+
type: "chunk",
|
|
29
|
+
text: "world!",
|
|
30
|
+
});
|
|
31
|
+
expect(writer.getChunks()).toEqual(["Hello, ", "world!"]);
|
|
32
|
+
});
|
|
33
|
+
it("should return full output as single string", () => {
|
|
34
|
+
writer.write({
|
|
35
|
+
timestamp: new Date().toISOString(),
|
|
36
|
+
type: "chunk",
|
|
37
|
+
text: "Hello, ",
|
|
38
|
+
});
|
|
39
|
+
writer.write({
|
|
40
|
+
timestamp: new Date().toISOString(),
|
|
41
|
+
type: "chunk",
|
|
42
|
+
text: "world!",
|
|
43
|
+
});
|
|
44
|
+
expect(writer.getFullOutput()).toBe("Hello, world!");
|
|
45
|
+
});
|
|
46
|
+
it("should generate valid JSONL output", () => {
|
|
47
|
+
writer.write({
|
|
48
|
+
timestamp: "2024-01-01T00:00:00.000Z",
|
|
49
|
+
type: "start",
|
|
50
|
+
});
|
|
51
|
+
writer.write({
|
|
52
|
+
timestamp: "2024-01-01T00:00:01.000Z",
|
|
53
|
+
type: "chunk",
|
|
54
|
+
text: "test",
|
|
55
|
+
});
|
|
56
|
+
const jsonl = writer.toJsonl();
|
|
57
|
+
const lines = jsonl.trim().split("\n");
|
|
58
|
+
expect(lines).toHaveLength(2);
|
|
59
|
+
const parsed0 = JSON.parse(lines[0]);
|
|
60
|
+
expect(parsed0.type).toBe("start");
|
|
61
|
+
const parsed1 = JSON.parse(lines[1]);
|
|
62
|
+
expect(parsed1.type).toBe("chunk");
|
|
63
|
+
expect(parsed1.text).toBe("test");
|
|
64
|
+
});
|
|
65
|
+
it("should clear all entries", () => {
|
|
66
|
+
writer.write({
|
|
67
|
+
timestamp: new Date().toISOString(),
|
|
68
|
+
type: "chunk",
|
|
69
|
+
text: "test",
|
|
70
|
+
});
|
|
71
|
+
expect(writer.getEntries()).toHaveLength(1);
|
|
72
|
+
writer.clear();
|
|
73
|
+
expect(writer.getEntries()).toHaveLength(0);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe("ConsoleTranscriptWriter", () => {
|
|
77
|
+
it("should write to console", () => {
|
|
78
|
+
const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
79
|
+
const writer = new ConsoleTranscriptWriter();
|
|
80
|
+
writer.write({
|
|
81
|
+
timestamp: "2024-01-01T00:00:00.000Z",
|
|
82
|
+
type: "chunk",
|
|
83
|
+
text: "Hello",
|
|
84
|
+
});
|
|
85
|
+
expect(consoleSpy).toHaveBeenCalled();
|
|
86
|
+
const call = consoleSpy.mock.calls[0][0];
|
|
87
|
+
expect(call).toContain("[Transcript]");
|
|
88
|
+
expect(call).toContain("CHUNK");
|
|
89
|
+
expect(call).toContain("Hello");
|
|
90
|
+
consoleSpy.mockRestore();
|
|
91
|
+
});
|
|
92
|
+
it("should use custom prefix", () => {
|
|
93
|
+
const consoleSpy = vi.spyOn(console, "log").mockImplementation(() => { });
|
|
94
|
+
const writer = new ConsoleTranscriptWriter("[TEST]");
|
|
95
|
+
writer.write({
|
|
96
|
+
timestamp: "2024-01-01T00:00:00.000Z",
|
|
97
|
+
type: "start",
|
|
98
|
+
});
|
|
99
|
+
const call = consoleSpy.mock.calls[0][0];
|
|
100
|
+
expect(call).toContain("[TEST]");
|
|
101
|
+
consoleSpy.mockRestore();
|
|
102
|
+
});
|
|
103
|
+
it("should log errors to console.error", () => {
|
|
104
|
+
const errorSpy = vi.spyOn(console, "error").mockImplementation(() => { });
|
|
105
|
+
const writer = new ConsoleTranscriptWriter();
|
|
106
|
+
writer.write({
|
|
107
|
+
timestamp: "2024-01-01T00:00:00.000Z",
|
|
108
|
+
type: "error",
|
|
109
|
+
text: "Something went wrong",
|
|
110
|
+
});
|
|
111
|
+
expect(errorSpy).toHaveBeenCalled();
|
|
112
|
+
const call = errorSpy.mock.calls[0][0];
|
|
113
|
+
expect(call).toContain("ERROR");
|
|
114
|
+
expect(call).toContain("Something went wrong");
|
|
115
|
+
errorSpy.mockRestore();
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
describe("MultiTranscriptWriter", () => {
|
|
119
|
+
it("should write to multiple writers", async () => {
|
|
120
|
+
const writer1 = new MemoryTranscriptWriter();
|
|
121
|
+
const writer2 = new MemoryTranscriptWriter();
|
|
122
|
+
const multiWriter = new MultiTranscriptWriter([writer1, writer2]);
|
|
123
|
+
const entry = {
|
|
124
|
+
timestamp: new Date().toISOString(),
|
|
125
|
+
type: "chunk",
|
|
126
|
+
text: "test",
|
|
127
|
+
};
|
|
128
|
+
await multiWriter.write(entry);
|
|
129
|
+
expect(writer1.getEntries()).toHaveLength(1);
|
|
130
|
+
expect(writer2.getEntries()).toHaveLength(1);
|
|
131
|
+
expect(writer1.getEntries()[0]).toEqual(entry);
|
|
132
|
+
expect(writer2.getEntries()[0]).toEqual(entry);
|
|
133
|
+
});
|
|
134
|
+
it("should close all writers", async () => {
|
|
135
|
+
const closeFn = vi.fn();
|
|
136
|
+
const writer1 = { write: vi.fn(), close: closeFn };
|
|
137
|
+
const writer2 = { write: vi.fn(), close: closeFn };
|
|
138
|
+
const multiWriter = new MultiTranscriptWriter([writer1, writer2]);
|
|
139
|
+
await multiWriter.close();
|
|
140
|
+
expect(closeFn).toHaveBeenCalledTimes(2);
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
//# sourceMappingURL=transcript.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript.test.js","sourceRoot":"","sources":["../../src/__tests__/transcript.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
describe("Type Definitions", () => {
|
|
3
|
+
describe("ExecOptions", () => {
|
|
4
|
+
it("should accept signal parameter", () => {
|
|
5
|
+
const controller = new AbortController();
|
|
6
|
+
const options = {
|
|
7
|
+
signal: controller.signal,
|
|
8
|
+
};
|
|
9
|
+
expect(options.signal).toBeDefined();
|
|
10
|
+
expect(options.signal).toBe(controller.signal);
|
|
11
|
+
});
|
|
12
|
+
it("should accept signal with other options", () => {
|
|
13
|
+
const controller = new AbortController();
|
|
14
|
+
const options = {
|
|
15
|
+
cwd: "/workspace",
|
|
16
|
+
env: { NODE_ENV: "test" },
|
|
17
|
+
timeout: 5000,
|
|
18
|
+
signal: controller.signal,
|
|
19
|
+
};
|
|
20
|
+
expect(options.signal).toBe(controller.signal);
|
|
21
|
+
expect(options.cwd).toBe("/workspace");
|
|
22
|
+
expect(options.env).toEqual({ NODE_ENV: "test" });
|
|
23
|
+
expect(options.timeout).toBe(5000);
|
|
24
|
+
});
|
|
25
|
+
it("should allow signal to be undefined", () => {
|
|
26
|
+
const options = {
|
|
27
|
+
cwd: "/workspace",
|
|
28
|
+
};
|
|
29
|
+
expect(options.signal).toBeUndefined();
|
|
30
|
+
});
|
|
31
|
+
it("should allow empty options object", () => {
|
|
32
|
+
const options = {};
|
|
33
|
+
expect(options.signal).toBeUndefined();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
36
|
+
describe("StreamInput", () => {
|
|
37
|
+
it("should accept signal parameter", () => {
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const input = {
|
|
40
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
41
|
+
signal: controller.signal,
|
|
42
|
+
};
|
|
43
|
+
expect(input.signal).toBeDefined();
|
|
44
|
+
expect(input.signal).toBe(controller.signal);
|
|
45
|
+
});
|
|
46
|
+
it("should accept signal with other options", () => {
|
|
47
|
+
const controller = new AbortController();
|
|
48
|
+
const input = {
|
|
49
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
50
|
+
workspace: { path: "/workspace" },
|
|
51
|
+
contentType: "text/event-stream",
|
|
52
|
+
resume: "session-123",
|
|
53
|
+
signal: controller.signal,
|
|
54
|
+
};
|
|
55
|
+
expect(input.signal).toBe(controller.signal);
|
|
56
|
+
expect(input.workspace?.path).toBe("/workspace");
|
|
57
|
+
expect(input.contentType).toBe("text/event-stream");
|
|
58
|
+
expect(input.resume).toBe("session-123");
|
|
59
|
+
});
|
|
60
|
+
it("should allow signal to be undefined", () => {
|
|
61
|
+
const input = {
|
|
62
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
63
|
+
};
|
|
64
|
+
expect(input.signal).toBeUndefined();
|
|
65
|
+
});
|
|
66
|
+
it("should require messages even with signal", () => {
|
|
67
|
+
const controller = new AbortController();
|
|
68
|
+
const input = {
|
|
69
|
+
messages: [],
|
|
70
|
+
signal: controller.signal,
|
|
71
|
+
};
|
|
72
|
+
expect(input.messages).toEqual([]);
|
|
73
|
+
expect(input.signal).toBe(controller.signal);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe("Signal Type Inference", () => {
|
|
77
|
+
it("should infer AbortSignal type correctly", () => {
|
|
78
|
+
const controller = new AbortController();
|
|
79
|
+
const options = {
|
|
80
|
+
signal: controller.signal,
|
|
81
|
+
};
|
|
82
|
+
// TypeScript should infer the type correctly
|
|
83
|
+
const signal = options.signal;
|
|
84
|
+
expect(signal).toBe(controller.signal);
|
|
85
|
+
});
|
|
86
|
+
it("should allow AbortSignal methods to be called", () => {
|
|
87
|
+
const controller = new AbortController();
|
|
88
|
+
const options = {
|
|
89
|
+
signal: controller.signal,
|
|
90
|
+
};
|
|
91
|
+
if (options.signal) {
|
|
92
|
+
// These should compile without errors
|
|
93
|
+
expect(typeof options.signal.aborted).toBe("boolean");
|
|
94
|
+
expect(typeof options.signal.addEventListener).toBe("function");
|
|
95
|
+
expect(typeof options.signal.removeEventListener).toBe("function");
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
it("should handle pre-aborted signal", () => {
|
|
99
|
+
const controller = new AbortController();
|
|
100
|
+
controller.abort();
|
|
101
|
+
const options = {
|
|
102
|
+
signal: controller.signal,
|
|
103
|
+
};
|
|
104
|
+
expect(options.signal?.aborted).toBe(true);
|
|
105
|
+
});
|
|
106
|
+
it("should handle signal abort event", () => {
|
|
107
|
+
const controller = new AbortController();
|
|
108
|
+
const options = {
|
|
109
|
+
signal: controller.signal,
|
|
110
|
+
};
|
|
111
|
+
let aborted = false;
|
|
112
|
+
options.signal?.addEventListener("abort", () => {
|
|
113
|
+
aborted = true;
|
|
114
|
+
});
|
|
115
|
+
controller.abort();
|
|
116
|
+
expect(aborted).toBe(true);
|
|
117
|
+
expect(options.signal?.aborted).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
describe("Type Compatibility", () => {
|
|
121
|
+
it("should accept signal from Request object", () => {
|
|
122
|
+
// Simulate a Request object's signal
|
|
123
|
+
const controller = new AbortController();
|
|
124
|
+
const mockRequest = {
|
|
125
|
+
signal: controller.signal,
|
|
126
|
+
};
|
|
127
|
+
const input = {
|
|
128
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
129
|
+
signal: mockRequest.signal,
|
|
130
|
+
};
|
|
131
|
+
expect(input.signal).toBe(mockRequest.signal);
|
|
132
|
+
});
|
|
133
|
+
it("should work with signal passed through multiple layers", () => {
|
|
134
|
+
const controller = new AbortController();
|
|
135
|
+
// Simulate passing signal through layers
|
|
136
|
+
const streamInput = {
|
|
137
|
+
messages: [{ role: "user", content: "Hello" }],
|
|
138
|
+
signal: controller.signal,
|
|
139
|
+
};
|
|
140
|
+
const execOptions = {
|
|
141
|
+
signal: streamInput.signal,
|
|
142
|
+
};
|
|
143
|
+
expect(execOptions.signal).toBe(controller.signal);
|
|
144
|
+
expect(streamInput.signal).toBe(controller.signal);
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
});
|
|
148
|
+
//# sourceMappingURL=types.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.test.js","sourceRoot":"","sources":["../../src/__tests__/types.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { BunnyAgentOptions, StreamInput } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* BunnyAgent - A sandboxed agent runtime that speaks AI SDK UI natively.
|
|
4
|
+
*
|
|
5
|
+
* Represents one persistent agent instance with:
|
|
6
|
+
* - An isolated sandbox
|
|
7
|
+
* - A dedicated filesystem volume
|
|
8
|
+
* - Direct passthrough of AI SDK UI messages
|
|
9
|
+
*/
|
|
10
|
+
export declare class BunnyAgent {
|
|
11
|
+
private readonly sandbox;
|
|
12
|
+
private readonly runner;
|
|
13
|
+
private readonly env;
|
|
14
|
+
private handle;
|
|
15
|
+
constructor(options: BunnyAgentOptions);
|
|
16
|
+
/**
|
|
17
|
+
* Attach to the sandbox if not already attached
|
|
18
|
+
*/
|
|
19
|
+
private ensureAttached;
|
|
20
|
+
/**
|
|
21
|
+
* Build the CLI command to execute
|
|
22
|
+
*/
|
|
23
|
+
private buildCommand;
|
|
24
|
+
/**
|
|
25
|
+
* Stream a task through the agent.
|
|
26
|
+
*
|
|
27
|
+
* This method:
|
|
28
|
+
* 1. Attaches to the sandbox
|
|
29
|
+
* 2. Executes the CLI runner inside the sandbox
|
|
30
|
+
* 3. Returns a ReadableStream of AI SDK UI messages from stdout
|
|
31
|
+
*
|
|
32
|
+
* The server NEVER parses or modifies the stream.
|
|
33
|
+
*
|
|
34
|
+
* @param input - Stream input including messages and optional transcript writer
|
|
35
|
+
* @returns ReadableStream of AI SDK UI messages
|
|
36
|
+
*/
|
|
37
|
+
stream(input: StreamInput): Promise<ReadableStream<Uint8Array>>;
|
|
38
|
+
/**
|
|
39
|
+
* Upload files to the agent's workspace
|
|
40
|
+
*/
|
|
41
|
+
uploadFiles(files: Array<{
|
|
42
|
+
path: string;
|
|
43
|
+
content: Uint8Array | string;
|
|
44
|
+
}>, targetDir?: string): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* Destroy the sandbox and release resources
|
|
47
|
+
*/
|
|
48
|
+
destroy(): Promise<void>;
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=bunny-agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bunny-agent.d.ts","sourceRoot":"","sources":["../src/bunny-agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EAKjB,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAa;IACpC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAyB;IAC7C,OAAO,CAAC,MAAM,CAA8B;gBAEhC,OAAO,EAAE,iBAAiB;IAMtC;;OAEG;YACW,cAAc;IAO5B;;OAEG;IACH,OAAO,CAAC,YAAY;IAsEpB;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAwGrE;;OAEG;IACG,WAAW,CACf,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAAA;KAAE,CAAC,EAC5D,SAAS,SAAe,GACvB,OAAO,CAAC,IAAI,CAAC;IAKhB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B"}
|