@bunny-agent/manager 0.9.61-release.9 → 0.9.62-release.1

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=tool-output.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-output.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/tool-output.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,77 @@
1
+ import { mkdtemp, readdir, readFile, rm, stat, writeFile, } from "node:fs/promises";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
5
+ import { guardToolOutput, TOOL_OUTPUT_MAX_BYTES, TOOL_OUTPUT_MAX_LINES, } from "../tool-output.js";
6
+ vi.mock("node:os", async (importOriginal) => {
7
+ const actual = await importOriginal();
8
+ return { ...actual, tmpdir: vi.fn(actual.tmpdir) };
9
+ });
10
+ const systemTempDirectory = tmpdir();
11
+ describe("guardToolOutput", () => {
12
+ let tempDirectory;
13
+ beforeEach(async () => {
14
+ tempDirectory = await mkdtemp(join(systemTempDirectory, "bunny-tool-output-test-"));
15
+ vi.mocked(tmpdir).mockReturnValue(tempDirectory);
16
+ });
17
+ afterEach(async () => {
18
+ vi.restoreAllMocks();
19
+ await rm(tempDirectory, { recursive: true, force: true });
20
+ });
21
+ it.each([
22
+ "",
23
+ " unchanged\n",
24
+ "x".repeat(TOOL_OUTPUT_MAX_BYTES),
25
+ "\n".repeat(TOOL_OUTPUT_MAX_LINES - 1),
26
+ ])("leaves outputs within both limits unchanged without writing files (%#)", async (text) => {
27
+ expect(await guardToolOutput(text)).toEqual({ text });
28
+ expect(await readdir(tempDirectory)).toEqual([]);
29
+ });
30
+ it.each([
31
+ "x".repeat(TOOL_OUTPUT_MAX_BYTES + 1),
32
+ "event\n".repeat(TOOL_OUTPUT_MAX_LINES),
33
+ "\u4e2d\u6587\ud83d\ude42".repeat(20_000),
34
+ JSON.stringify({
35
+ content: [
36
+ {
37
+ type: "text",
38
+ text: JSON.stringify({ report: "work log\\n".repeat(400_000) }),
39
+ },
40
+ ],
41
+ }),
42
+ ])("bounds previews and saves the entire original response (%#)", async (text) => {
43
+ const result = await guardToolOutput(text);
44
+ expect(Buffer.byteLength(result.text)).toBeLessThanOrEqual(TOOL_OUTPUT_MAX_BYTES);
45
+ expect(result.text.split("\n").length).toBeLessThanOrEqual(TOOL_OUTPUT_MAX_LINES);
46
+ expect(result.text).not.toContain("\ufffd");
47
+ expect(result.text).toContain("Tool output truncated:");
48
+ expect(result.text).toContain("Use read with offset/limit");
49
+ expect(result.outputGuard).toMatchObject({
50
+ truncated: true,
51
+ originalBytes: Buffer.byteLength(text),
52
+ originalLines: text.split("\n").length,
53
+ });
54
+ const path = result.outputGuard.fullOutputPath;
55
+ expect(path.startsWith(join(tempDirectory, "bunny-tool-output-"))).toBe(true);
56
+ expect(result.text).toContain(JSON.stringify(path));
57
+ expect(await readFile(path, "utf8")).toBe(text);
58
+ expect((await stat(path)).mode & 0o777).toBe(0o600);
59
+ });
60
+ it("keeps concurrent responses in distinct files", async () => {
61
+ const texts = Array.from({ length: 5 }, (_, index) => `${index}:${"x".repeat(100_000)}`);
62
+ const results = await Promise.all(texts.map((text) => guardToolOutput(text)));
63
+ const paths = results.map((result) => result.outputGuard.fullOutputPath);
64
+ expect(new Set(paths).size).toBe(5);
65
+ expect(await Promise.all(paths.map((path) => readFile(path, "utf8")))).toEqual(texts);
66
+ });
67
+ it("still bounds output and reports when the temporary directory cannot store the full response", async () => {
68
+ const blocked = join(tempDirectory, "blocked");
69
+ await writeFile(blocked, "not a directory");
70
+ vi.mocked(tmpdir).mockReturnValue(blocked);
71
+ const result = await guardToolOutput("x".repeat(100_000));
72
+ expect(Buffer.byteLength(result.text)).toBeLessThanOrEqual(TOOL_OUTPUT_MAX_BYTES);
73
+ expect(result.text).toContain("Full output could not be saved");
74
+ expect(result.outputGuard).not.toHaveProperty("fullOutputPath");
75
+ });
76
+ });
77
+ //# sourceMappingURL=tool-output.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-output.test.js","sourceRoot":"","sources":["../../src/__tests__/tool-output.test.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -11,6 +11,8 @@ export { buildRunnerEnv } from "./env.js";
11
11
  export type { SandboxExecErrorCode } from "./sandbox-exec-error.js";
12
12
  export { ExecDiagnostics, SandboxExecError, validateExecInput, } from "./sandbox-exec-error.js";
13
13
  export { posixShellQuote } from "./shell-escape.js";
14
+ export type { GuardedToolOutput, ToolOutputGuardDetails, } from "./tool-output.js";
15
+ export { guardToolOutput, TOOL_OUTPUT_MAX_BYTES, TOOL_OUTPUT_MAX_LINES, } from "./tool-output.js";
14
16
  export { ConsoleTranscriptWriter, JsonlTranscriptWriter, MemoryTranscriptWriter, MultiTranscriptWriter, } from "./transcript.js";
15
17
  export type { BunnyAgentCodingRunBody, BunnyAgentOptions, ExecOptions, McpConfig, McpHttpServerConfig, McpLifecycle, McpServerConfig, McpServerOptions, McpSettings, McpStdioServerConfig, Message, RunnerSpec, SandboxAdapter, SandboxHandle, StreamInput, ToolInputSchema, ToolRef, ToolRuntime, TranscriptEntry, TranscriptWriter, Volume, } from "./types.js";
16
18
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,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,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAMpD,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,OAAO,EACP,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EACf,OAAO,EACP,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,MAAM,GACP,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,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,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,YAAY,EACV,iBAAiB,EACjB,sBAAsB,GACvB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAM1B,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,uBAAuB,EACvB,iBAAiB,EACjB,WAAW,EACX,SAAS,EACT,mBAAmB,EACnB,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,WAAW,EACX,oBAAoB,EACpB,OAAO,EACP,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,EACf,OAAO,EACP,WAAW,EACX,eAAe,EACf,gBAAgB,EAChB,MAAM,GACP,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -10,6 +10,7 @@ export { ExecDiagnostics, SandboxExecError, validateExecInput, } from "./sandbox
10
10
  // Shared POSIX shell quoting for adapters that must build a shell command
11
11
  // string instead of using independent argv/env channels.
12
12
  export { posixShellQuote } from "./shell-escape.js";
13
+ export { guardToolOutput, TOOL_OUTPUT_MAX_BYTES, TOOL_OUTPUT_MAX_LINES, } from "./tool-output.js";
13
14
  // Local adapters live in their own packages, mirroring the cloud adapters:
14
15
  // @bunny-agent/sandbox-local (LocalMachine — NO isolation) and
15
16
  // @bunny-agent/sandbox-srt (SrtSandbox — OS-level isolation via
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,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,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,0EAA0E;AAC1E,yDAAyD;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,2EAA2E;AAC3E,+DAA+D;AAC/D,gEAAgE;AAChE,iEAAiE;AACjE,oCAAoC;AACpC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,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,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,yBAAyB,CAAC;AACjC,0EAA0E;AAC1E,yDAAyD;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAKpD,OAAO,EACL,eAAe,EACf,qBAAqB,EACrB,qBAAqB,GACtB,MAAM,kBAAkB,CAAC;AAC1B,2EAA2E;AAC3E,+DAA+D;AAC/D,gEAAgE;AAChE,iEAAiE;AACjE,oCAAoC;AACpC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,22 @@
1
+ export declare const TOOL_OUTPUT_MAX_BYTES: number;
2
+ export declare const TOOL_OUTPUT_MAX_LINES = 2000;
3
+ /** Size and retrieval information for a truncated external tool response. */
4
+ export interface ToolOutputGuardDetails {
5
+ truncated: true;
6
+ originalBytes: number;
7
+ originalLines: number;
8
+ fullOutputPath?: string;
9
+ }
10
+ /** Model-visible text and optional metadata; never contains the full spilled response. */
11
+ export interface GuardedToolOutput {
12
+ text: string;
13
+ outputGuard?: ToolOutputGuardDetails;
14
+ }
15
+ /**
16
+ * Bound external tool text to 50 KiB / 2,000 lines, including the retrieval notice.
17
+ * Oversized responses are saved verbatim in the OS temporary directory, matching
18
+ * Pi's native output-file lifecycle. Storage failures still return bounded text
19
+ * and explicitly report that the full output could not be saved.
20
+ */
21
+ export declare function guardToolOutput(text: string): Promise<GuardedToolOutput>;
22
+ //# sourceMappingURL=tool-output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-output.d.ts","sourceRoot":"","sources":["../src/tool-output.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,qBAAqB,QAAY,CAAC;AAC/C,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAE3C,6EAA6E;AAC7E,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,IAAI,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,0FAA0F;AAC1F,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,sBAAsB,CAAC;CACtC;AA2BD;;;;;GAKG;AACH,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,CAAC,CAyC5B"}
@@ -0,0 +1,68 @@
1
+ import { randomBytes } from "node:crypto";
2
+ import { writeFile } from "node:fs/promises";
3
+ import { tmpdir } from "node:os";
4
+ import { join } from "node:path";
5
+ export const TOOL_OUTPUT_MAX_BYTES = 50 * 1024;
6
+ export const TOOL_OUTPUT_MAX_LINES = 2_000;
7
+ function countLines(text) {
8
+ let lines = 1;
9
+ for (let index = 0; index < text.length; index++) {
10
+ if (text[index] === "\n")
11
+ lines++;
12
+ }
13
+ return lines;
14
+ }
15
+ function previewText(text, maxBytes, maxLines) {
16
+ // Slice before encoding to avoid allocating another copy of a multi-MB response.
17
+ const buffer = Buffer.from(text.slice(0, maxBytes), "utf8");
18
+ let end = Math.min(buffer.length, maxBytes);
19
+ while (end > 0 && end < buffer.length && (buffer[end] & 0xc0) === 0x80) {
20
+ end--;
21
+ }
22
+ const prefix = buffer.subarray(0, end).toString("utf8");
23
+ let lines = 1;
24
+ for (let index = 0; index < prefix.length; index++) {
25
+ if (prefix[index] === "\n" && ++lines > maxLines) {
26
+ return prefix.slice(0, index);
27
+ }
28
+ }
29
+ return prefix;
30
+ }
31
+ /**
32
+ * Bound external tool text to 50 KiB / 2,000 lines, including the retrieval notice.
33
+ * Oversized responses are saved verbatim in the OS temporary directory, matching
34
+ * Pi's native output-file lifecycle. Storage failures still return bounded text
35
+ * and explicitly report that the full output could not be saved.
36
+ */
37
+ export async function guardToolOutput(text) {
38
+ const originalBytes = Buffer.byteLength(text, "utf8");
39
+ const originalLines = countLines(text);
40
+ if (originalBytes <= TOOL_OUTPUT_MAX_BYTES &&
41
+ originalLines <= TOOL_OUTPUT_MAX_LINES) {
42
+ return { text };
43
+ }
44
+ let fullOutputPath;
45
+ try {
46
+ const path = join(tmpdir(), `bunny-tool-output-${randomBytes(8).toString("hex")}.txt`);
47
+ await writeFile(path, text, { encoding: "utf8", mode: 0o600, flag: "wx" });
48
+ fullOutputPath = path;
49
+ }
50
+ catch {
51
+ // A storage error must not let the original oversized response reach the model.
52
+ }
53
+ const retrieval = fullOutputPath
54
+ ? `Full output saved to: ${JSON.stringify(fullOutputPath)}. Use read with offset/limit or bash to extract a bounded fragment.`
55
+ : "Full output could not be saved. Retry with a narrower query or fewer fields.";
56
+ const notice = `\n\n[Tool output truncated: original ${originalBytes} bytes / ${originalLines} lines; preview limit ${TOOL_OUTPUT_MAX_BYTES} bytes / ${TOOL_OUTPUT_MAX_LINES} lines. ${retrieval}]`;
57
+ const preview = previewText(text, TOOL_OUTPUT_MAX_BYTES - Buffer.byteLength(notice, "utf8"), TOOL_OUTPUT_MAX_LINES - countLines(notice) + 1);
58
+ return {
59
+ text: `${preview}${notice}`,
60
+ outputGuard: {
61
+ truncated: true,
62
+ originalBytes,
63
+ originalLines,
64
+ ...(fullOutputPath ? { fullOutputPath } : {}),
65
+ },
66
+ };
67
+ }
68
+ //# sourceMappingURL=tool-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-output.js","sourceRoot":"","sources":["../src/tool-output.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunny-agent/manager",
3
- "version": "0.9.61-release.9",
3
+ "version": "0.9.62-release.1",
4
4
  "description": "BunnyAgent Manager - Manages sandbox and runner lifecycle, defines core interfaces",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",