@bunny-agent/runner-cli 0.9.29-beta.0 → 0.9.29-beta.11

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.
@@ -1 +1 @@
1
- {"version":3,"file":"build-image.d.ts","sourceRoot":"","sources":["../src/build-image.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,IAAI,EAAE,OAAO,CAAC;CACf;AA2ED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EvE"}
1
+ {"version":3,"file":"build-image.d.ts","sourceRoot":"","sources":["../src/build-image.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,iBAAiB;IAChC,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,mDAAmD;IACnD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,IAAI,EAAE,OAAO,CAAC;CACf;AA6ED,wBAAsB,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EvE"}
@@ -13,10 +13,12 @@ function getShippedDockerfile() {
13
13
  // Look for Dockerfile in several locations:
14
14
  // 1. Package root (apps/runner-cli/Dockerfile) — shipped with npm package
15
15
  // 2. docker/bunny-agent-claude/Dockerfile — monorepo development
16
+ // 3. CWD-relative docker/bunny-agent-claude/Dockerfile — global install invoked from repo root
16
17
  const packageRoot = getPackageRoot();
17
18
  const candidates = [
18
19
  join(packageRoot, "Dockerfile"),
19
20
  resolve(packageRoot, "..", "..", "docker", "bunny-agent-claude", "Dockerfile"),
21
+ resolve(process.cwd(), "docker", "bunny-agent-claude", "Dockerfile"),
20
22
  ];
21
23
  for (const p of candidates) {
22
24
  if (existsSync(p))
@@ -1 +1 @@
1
- {"version":3,"file":"build-image.js","sourceRoot":"","sources":["../src/build-image.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"build-image.js","sourceRoot":"","sources":["../src/build-image.ts"],"names":[],"mappings":"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"}
package/dist/bundle.mjs CHANGED
@@ -33,7 +33,8 @@ function getShippedDockerfile() {
33
33
  "docker",
34
34
  "bunny-agent-claude",
35
35
  "Dockerfile"
36
- )
36
+ ),
37
+ resolve(process.cwd(), "docker", "bunny-agent-claude", "Dockerfile")
37
38
  ];
38
39
  for (const p of candidates) {
39
40
  if (existsSync(p)) return p;
@@ -1273,9 +1274,9 @@ function createOpenCodeRunner(options = {}) {
1273
1274
 
1274
1275
  // ../../packages/runner-pi/dist/pi-runner.js
1275
1276
  import { appendFileSync as appendFileSync2, existsSync as existsSync5, unlinkSync as unlinkSync3 } from "node:fs";
1276
- import { join as join7 } from "node:path";
1277
+ import { join as join8 } from "node:path";
1277
1278
  import { getModel } from "@mariozechner/pi-ai";
1278
- import { AuthStorage, createAgentSession, ModelRegistry, SessionManager } from "@mariozechner/pi-coding-agent";
1279
+ import { AuthStorage, createAgentSession, ModelRegistry, SessionManager as SessionManager2 } from "@mariozechner/pi-coding-agent";
1279
1280
 
1280
1281
  // ../../packages/runner-pi/dist/bunny-agent-resource-loader.js
1281
1282
  import { existsSync as existsSync4 } from "node:fs";
@@ -1399,8 +1400,8 @@ var generateImageSchema = {
1399
1400
  },
1400
1401
  quality: {
1401
1402
  type: "string",
1402
- enum: ["standard", "hd"],
1403
- description: "Image quality (OpenAI only). Defaults to standard."
1403
+ enum: ["low", "medium", "high", "auto"],
1404
+ description: "Image quality. Defaults to auto."
1404
1405
  }
1405
1406
  },
1406
1407
  required: ["prompt"],
@@ -1558,11 +1559,11 @@ function buildImageGenerateTool(cwd, imageModelId, baseUrl, apiKey) {
1558
1559
  ],
1559
1560
  // biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
1560
1561
  parameters: generateImageSchema,
1561
- async execute(_toolCallId, params, _signal, _onUpdate) {
1562
+ async execute(_toolCallId, params, signal, _onUpdate) {
1562
1563
  const p = params;
1563
1564
  const prompt = p.prompt;
1564
1565
  const size = p.size ?? "1024x1024";
1565
- const quality = p.quality ?? "standard";
1566
+ const quality = p.quality ?? "auto";
1566
1567
  const rawFilename = p.filename;
1567
1568
  const filename = rawFilename ? extname(rawFilename) ? rawFilename : `${rawFilename}.png` : `image_${Date.now()}.png`;
1568
1569
  const filePath = join6(cwd, filename.replace(/[^a-zA-Z0-9_\-./]/g, "_"));
@@ -1582,7 +1583,8 @@ function buildImageGenerateTool(cwd, imageModelId, baseUrl, apiKey) {
1582
1583
  quality,
1583
1584
  response_format: "b64_json",
1584
1585
  output_format: "png"
1585
- })
1586
+ }),
1587
+ signal
1586
1588
  });
1587
1589
  if (!res.ok) {
1588
1590
  throw new Error(`Image generation failed (${res.status}): ${await res.text()}`);
@@ -1599,6 +1601,7 @@ function buildImageGenerateTool(cwd, imageModelId, baseUrl, apiKey) {
1599
1601
  ],
1600
1602
  details: {
1601
1603
  filePath: savedPath,
1604
+ ...json.usage != null ? { usage: { raw: { [imageModelId]: json.usage } } } : {},
1602
1605
  response: json
1603
1606
  }
1604
1607
  };
@@ -1687,7 +1690,7 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
1687
1690
  ],
1688
1691
  // biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
1689
1692
  parameters: editImageSchema,
1690
- async execute(_toolCallId, params, _signal, _onUpdate) {
1693
+ async execute(_toolCallId, params, signal, _onUpdate) {
1691
1694
  const { readFileSync: readFileSync4, existsSync: existsSync8 } = await import("node:fs");
1692
1695
  const { resolve: resolve4, basename: basename2 } = await import("node:path");
1693
1696
  const p = params;
@@ -1755,7 +1758,8 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
1755
1758
  "Content-Type": type,
1756
1759
  Authorization: `Bearer ${apiKey}`
1757
1760
  },
1758
- body
1761
+ body,
1762
+ signal
1759
1763
  });
1760
1764
  if (!res.ok) {
1761
1765
  throw new Error(`Image edit failed (${res.status}): ${await res.text()}`);
@@ -1785,6 +1789,7 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
1785
1789
  ],
1786
1790
  details: {
1787
1791
  filePath: savedPath,
1792
+ ...json.usage != null ? { usage: { raw: { [imageModelId]: json.usage } } } : {},
1788
1793
  response: json
1789
1794
  }
1790
1795
  };
@@ -1801,6 +1806,310 @@ function buildImageEditTool(cwd, imageModelId, baseUrl, apiKey) {
1801
1806
  };
1802
1807
  }
1803
1808
 
1809
+ // ../../packages/runner-pi/dist/session-utils.js
1810
+ import { closeSync, fstatSync, openSync, readdirSync as readdirSync2, readSync, statSync as statSync2 } from "node:fs";
1811
+ import { join as join7 } from "node:path";
1812
+ import { SessionManager } from "@mariozechner/pi-coding-agent";
1813
+ var MAX_SESSION_FILE_BYTES = Number(process.env.SANDAGENT_MAX_SESSION_BYTES) || 10 * 1024 * 1024;
1814
+ function resolveSessionPathById(cwd, sessionId) {
1815
+ const tempMgr = SessionManager.create(cwd);
1816
+ const sessionsDir = tempMgr.getSessionDir();
1817
+ try {
1818
+ const suffix = `_${sessionId}.jsonl`;
1819
+ const match = readdirSync2(sessionsDir).find((f) => f.endsWith(suffix));
1820
+ return match ? join7(sessionsDir, match) : void 0;
1821
+ } catch {
1822
+ return void 0;
1823
+ }
1824
+ }
1825
+ function isSessionFileTooLarge(sessionPath2) {
1826
+ try {
1827
+ return statSync2(sessionPath2).size > MAX_SESSION_FILE_BYTES;
1828
+ } catch {
1829
+ return false;
1830
+ }
1831
+ }
1832
+ function readTailEntries(sessionPath2, tailBytes = 1024 * 1024) {
1833
+ let fd;
1834
+ try {
1835
+ fd = openSync(sessionPath2, "r");
1836
+ } catch {
1837
+ return [];
1838
+ }
1839
+ try {
1840
+ const fileSize = fstatSync(fd).size;
1841
+ const readStart = Math.max(0, fileSize - tailBytes);
1842
+ const readLen = fileSize - readStart;
1843
+ const buf = Buffer.alloc(readLen);
1844
+ readSync(fd, buf, 0, readLen, readStart);
1845
+ const tail = buf.toString("utf8");
1846
+ const entries = [];
1847
+ for (const line of tail.split("\n")) {
1848
+ const trimmed = line.trim();
1849
+ if (!trimmed)
1850
+ continue;
1851
+ try {
1852
+ entries.push(JSON.parse(trimmed));
1853
+ } catch {
1854
+ }
1855
+ }
1856
+ return entries;
1857
+ } finally {
1858
+ closeSync(fd);
1859
+ }
1860
+ }
1861
+ function extractSessionContext(sessionPath2) {
1862
+ const entries = readTailEntries(sessionPath2);
1863
+ if (entries.length === 0)
1864
+ return void 0;
1865
+ for (let i = entries.length - 1; i >= 0; i--) {
1866
+ const e = entries[i];
1867
+ if (e.type === "compaction" && typeof e.summary === "string") {
1868
+ return e.summary;
1869
+ }
1870
+ }
1871
+ const recentMessages = [];
1872
+ const MAX_MESSAGES = 6;
1873
+ for (let i = entries.length - 1; i >= 0 && recentMessages.length < MAX_MESSAGES; i--) {
1874
+ const e = entries[i];
1875
+ if (e.type !== "message")
1876
+ continue;
1877
+ const msg = e.message;
1878
+ if (!msg)
1879
+ continue;
1880
+ if (msg.role !== "user" && msg.role !== "assistant")
1881
+ continue;
1882
+ let text = "";
1883
+ if (typeof msg.content === "string") {
1884
+ text = msg.content;
1885
+ } else if (Array.isArray(msg.content)) {
1886
+ text = msg.content.filter((c) => c.type === "text" && c.text).map((c) => c.text).join("\n");
1887
+ }
1888
+ if (text) {
1889
+ recentMessages.unshift(`[${msg.role}]: ${text}`);
1890
+ }
1891
+ }
1892
+ if (recentMessages.length === 0)
1893
+ return void 0;
1894
+ return "## Previous Session Context (auto-extracted)\n\nThe following is the tail of the previous conversation:\n\n" + recentMessages.join("\n\n");
1895
+ }
1896
+
1897
+ // ../../packages/runner-pi/dist/usage-metadata.js
1898
+ function usageToMessageMetadata(usage) {
1899
+ return {
1900
+ input_tokens: usage.input,
1901
+ output_tokens: usage.output,
1902
+ cache_read_input_tokens: usage.cacheRead,
1903
+ cache_creation_input_tokens: usage.cacheWrite
1904
+ };
1905
+ }
1906
+ function accumulateToolUsage(tally, raw) {
1907
+ for (const [key, row] of Object.entries(raw)) {
1908
+ const existing = tally[key];
1909
+ if (existing) {
1910
+ for (const [field, val] of Object.entries(row)) {
1911
+ if (typeof val === "number")
1912
+ existing[field] = (existing[field] ?? 0) + val;
1913
+ }
1914
+ } else {
1915
+ const nums = {};
1916
+ for (const [field, val] of Object.entries(row)) {
1917
+ if (typeof val === "number")
1918
+ nums[field] = val;
1919
+ }
1920
+ tally[key] = nums;
1921
+ }
1922
+ }
1923
+ }
1924
+ function getUsageFromAgentEndMessages(messages) {
1925
+ for (let i = messages.length - 1; i >= 0; i--) {
1926
+ const m = messages[i];
1927
+ if (m.role === "assistant" && m.usage != null)
1928
+ return m.usage;
1929
+ }
1930
+ return void 0;
1931
+ }
1932
+
1933
+ // ../../packages/runner-pi/dist/stream-converter.js
1934
+ function emitStreamError(errorText) {
1935
+ const errorLine = "data: " + JSON.stringify({ type: "error", errorText }) + "\n\n";
1936
+ const finishLine = "data: " + JSON.stringify({ type: "finish", finishReason: "error" }) + "\n\n";
1937
+ return [errorLine, finishLine, "data: [DONE]\n\n"];
1938
+ }
1939
+ function extractToolResultText(result) {
1940
+ if (result !== null && typeof result === "object") {
1941
+ const r = result;
1942
+ if (Array.isArray(r.content) && r.content.length > 0) {
1943
+ const text = r.content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join("\n");
1944
+ if (text.length > 0)
1945
+ return text;
1946
+ }
1947
+ }
1948
+ if (typeof result === "string")
1949
+ return result;
1950
+ try {
1951
+ return JSON.stringify(result);
1952
+ } catch {
1953
+ return String(result);
1954
+ }
1955
+ }
1956
+ function sseData(obj) {
1957
+ return "data: " + JSON.stringify(obj) + "\n\n";
1958
+ }
1959
+ var PiAISDKStreamConverter = class {
1960
+ constructor(options) {
1961
+ this.options = options;
1962
+ this.messageId = "msg_" + Date.now() + "_" + Math.random().toString(36).slice(2);
1963
+ this.toolUsageTally = {};
1964
+ this.activeTextPartId = null;
1965
+ this.hasStarted = false;
1966
+ this.hasFinished = false;
1967
+ }
1968
+ get finished() {
1969
+ return this.hasFinished;
1970
+ }
1971
+ forceError(errorText) {
1972
+ if (this.hasFinished)
1973
+ return [];
1974
+ return [...this.ensureStart(), ...this.finishError(errorText)];
1975
+ }
1976
+ handleEvent(event, aborted) {
1977
+ if (this.hasFinished)
1978
+ return [];
1979
+ const chunks = [...this.ensureStart()];
1980
+ if (event.type === "message_start") {
1981
+ const msg = event.message;
1982
+ if (msg?.role === "assistant")
1983
+ chunks.push(...this.endTextStreamIfOpen());
1984
+ return chunks;
1985
+ }
1986
+ if (event.type === "message_end")
1987
+ return chunks;
1988
+ if (event.type === "message_update") {
1989
+ const sub = event.assistantMessageEvent;
1990
+ if (sub.type === "text_start")
1991
+ chunks.push(...this.endTextStreamIfOpen(), ...this.openTextStream());
1992
+ else if (sub.type === "text_delta")
1993
+ chunks.push(...this.emitTextDelta(sub.delta));
1994
+ else if (sub.type === "toolcall_start")
1995
+ chunks.push(...this.endTextStreamIfOpen());
1996
+ return chunks;
1997
+ }
1998
+ if (event.type === "tool_execution_start") {
1999
+ chunks.push(...this.endTextStreamIfOpen());
2000
+ chunks.push(sseData({
2001
+ type: "tool-input-start",
2002
+ toolCallId: event.toolCallId,
2003
+ toolName: event.toolName,
2004
+ dynamic: true,
2005
+ providerExecuted: true
2006
+ }), sseData({
2007
+ type: "tool-input-available",
2008
+ toolCallId: event.toolCallId,
2009
+ toolName: event.toolName,
2010
+ input: event.args,
2011
+ dynamic: true,
2012
+ providerExecuted: true
2013
+ }));
2014
+ return chunks;
2015
+ }
2016
+ if (event.type === "tool_execution_end") {
2017
+ const output = this.options.redactText(this.options.normalizeToolOutput(event.result));
2018
+ const raw = event.result?.details?.usage?.raw;
2019
+ if (raw != null)
2020
+ accumulateToolUsage(this.toolUsageTally, raw);
2021
+ chunks.push(sseData({
2022
+ type: "tool-output-available",
2023
+ toolCallId: event.toolCallId,
2024
+ output,
2025
+ isError: event.isError,
2026
+ dynamic: true,
2027
+ providerExecuted: true
2028
+ }));
2029
+ return chunks;
2030
+ }
2031
+ if (event.type === "agent_end") {
2032
+ if (aborted) {
2033
+ chunks.push(...this.finishError("Run aborted by signal."));
2034
+ } else {
2035
+ const errorMsg = this.options.getErrorFromAgentEndMessages(event.messages);
2036
+ if (errorMsg)
2037
+ chunks.push(...this.finishError(errorMsg));
2038
+ else
2039
+ chunks.push(...this.finishSuccess(this.options.getUsageFromAgentEndMessages(event.messages)));
2040
+ }
2041
+ return chunks;
2042
+ }
2043
+ return chunks;
2044
+ }
2045
+ ensureStart() {
2046
+ if (this.hasStarted)
2047
+ return [];
2048
+ this.hasStarted = true;
2049
+ return [
2050
+ sseData({ type: "start", messageId: this.messageId }),
2051
+ sseData({
2052
+ type: "message-metadata",
2053
+ messageMetadata: { sessionId: this.options.sessionId }
2054
+ })
2055
+ ];
2056
+ }
2057
+ newTextPartId() {
2058
+ return "text_" + Date.now() + "_" + Math.random().toString(36).slice(2) + "_" + Math.random().toString(36).slice(2);
2059
+ }
2060
+ openTextStream() {
2061
+ this.activeTextPartId = this.newTextPartId();
2062
+ return [sseData({ type: "text-start", id: this.activeTextPartId })];
2063
+ }
2064
+ emitTextDelta(rawDelta) {
2065
+ const delta = rawDelta ? this.options.redactText(rawDelta) : void 0;
2066
+ if (!delta)
2067
+ return [];
2068
+ const startChunk = this.activeTextPartId == null ? this.openTextStream() : [];
2069
+ return [
2070
+ ...startChunk,
2071
+ sseData({ type: "text-delta", id: this.activeTextPartId, delta })
2072
+ ];
2073
+ }
2074
+ endTextStreamIfOpen() {
2075
+ if (this.activeTextPartId == null)
2076
+ return [];
2077
+ const id = this.activeTextPartId;
2078
+ this.activeTextPartId = null;
2079
+ return [sseData({ type: "text-end", id })];
2080
+ }
2081
+ finishSuccess(usage) {
2082
+ const chunks = [...this.endTextStreamIfOpen()];
2083
+ const raw = {};
2084
+ let chatUsage;
2085
+ if (usage) {
2086
+ const { id } = this.options.model;
2087
+ chatUsage = {
2088
+ type: "chat",
2089
+ ...usageToMessageMetadata(usage)
2090
+ };
2091
+ raw[id] = chatUsage;
2092
+ }
2093
+ for (const [key, tally] of Object.entries(this.toolUsageTally)) {
2094
+ raw[key] = { ...tally };
2095
+ }
2096
+ const finishPayload = {
2097
+ type: "finish",
2098
+ finishReason: "stop"
2099
+ };
2100
+ if (usage) {
2101
+ finishPayload.messageMetadata = { usage: { ...chatUsage, raw } };
2102
+ }
2103
+ chunks.push(sseData(finishPayload), "data: [DONE]\n\n");
2104
+ this.hasFinished = true;
2105
+ return chunks;
2106
+ }
2107
+ finishError(errorText) {
2108
+ this.hasFinished = true;
2109
+ return emitStreamError(errorText);
2110
+ }
2111
+ };
2112
+
1804
2113
  // ../../packages/runner-pi/dist/tool-overrides.js
1805
2114
  import { createBashTool, createReadTool } from "@mariozechner/pi-coding-agent";
1806
2115
 
@@ -1809,7 +2118,7 @@ var braveProvider = {
1809
2118
  id: "brave",
1810
2119
  label: "Brave Search",
1811
2120
  envKeys: ["BRAVE_API_KEY"],
1812
- async search({ apiKey, query, count, country, freshness }) {
2121
+ async search({ apiKey, query, count, country, freshness, signal }) {
1813
2122
  const params = new URLSearchParams({
1814
2123
  q: query,
1815
2124
  count: String(Math.min(count, 20))
@@ -1823,7 +2132,8 @@ var braveProvider = {
1823
2132
  Accept: "application/json",
1824
2133
  "Accept-Encoding": "gzip",
1825
2134
  "X-Subscription-Token": apiKey
1826
- }
2135
+ },
2136
+ signal
1827
2137
  });
1828
2138
  if (!res.ok) {
1829
2139
  const body = await res.text().catch(() => "");
@@ -1844,14 +2154,14 @@ ${body}`);
1844
2154
  });
1845
2155
  }
1846
2156
  }
1847
- return results;
2157
+ return { results };
1848
2158
  }
1849
2159
  };
1850
2160
  var tavilyProvider = {
1851
2161
  id: "tavily",
1852
2162
  label: "Tavily",
1853
2163
  envKeys: ["TAVILY_API_KEY"],
1854
- async search({ apiKey, query, count }) {
2164
+ async search({ apiKey, query, count, signal }) {
1855
2165
  const res = await fetch("https://api.tavily.com/search", {
1856
2166
  method: "POST",
1857
2167
  headers: { "Content-Type": "application/json" },
@@ -1860,7 +2170,8 @@ var tavilyProvider = {
1860
2170
  query,
1861
2171
  max_results: Math.min(count, 10),
1862
2172
  include_answer: false
1863
- })
2173
+ }),
2174
+ signal
1864
2175
  });
1865
2176
  if (!res.ok) {
1866
2177
  const body = await res.text().catch(() => "");
@@ -1878,7 +2189,7 @@ ${body}`);
1878
2189
  });
1879
2190
  }
1880
2191
  }
1881
- return results;
2192
+ return { results };
1882
2193
  }
1883
2194
  };
1884
2195
  var AUTO_DETECT_ORDER = [braveProvider, tavilyProvider];
@@ -1913,9 +2224,12 @@ var BROWSER_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/53
1913
2224
  function htmlToText(html) {
1914
2225
  return html.replace(/<(script|style|noscript)[^>]*>[\s\S]*?<\/\1>/gi, "").replace(/<br\s*\/?>/gi, "\n").replace(/<\/(p|div|h[1-6]|li|tr)>/gi, "\n").replace(/<(p|div|h[1-6]|li|tr)[^>]*>/gi, "\n").replace(/<[^>]+>/g, "").replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/g, " ").replace(/[ \t]+/g, " ").replace(/\n{3,}/g, "\n\n").trim();
1915
2226
  }
1916
- async function fetchPageContent(url) {
2227
+ async function fetchPageContent(url, externalSignal) {
1917
2228
  const controller = new AbortController();
1918
2229
  const timeout = setTimeout(() => controller.abort(), 15e3);
2230
+ externalSignal?.addEventListener("abort", () => controller.abort(), {
2231
+ once: true
2232
+ });
1919
2233
  try {
1920
2234
  const res = await fetch(url, {
1921
2235
  headers: {
@@ -2012,7 +2326,7 @@ function buildWebSearchTool(env) {
2012
2326
  ],
2013
2327
  // biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
2014
2328
  parameters: webSearchSchema,
2015
- async execute(_toolCallId, params, _signal, _onUpdate) {
2329
+ async execute(_toolCallId, params, signal, _onUpdate) {
2016
2330
  const p = params;
2017
2331
  const query = p.query;
2018
2332
  const count = p.count ?? 5;
@@ -2022,18 +2336,29 @@ function buildWebSearchTool(env) {
2022
2336
  let lastError;
2023
2337
  for (const { provider, apiKey } of providers) {
2024
2338
  try {
2025
- const results = await provider.search({
2339
+ const { results } = await provider.search({
2026
2340
  apiKey,
2027
2341
  query,
2028
2342
  count,
2029
2343
  country,
2030
- freshness
2344
+ freshness,
2345
+ signal
2031
2346
  });
2347
+ let fetchedPages = 0;
2032
2348
  if (shouldFetchContent) {
2033
2349
  for (const r of results) {
2034
- r.content = await fetchPageContent(r.link);
2350
+ r.content = await fetchPageContent(r.link, signal);
2351
+ fetchedPages += 1;
2035
2352
  }
2036
2353
  }
2354
+ const usage = {
2355
+ raw: {
2356
+ [provider.id]: {
2357
+ requests: 1,
2358
+ fetchedPages
2359
+ }
2360
+ }
2361
+ };
2037
2362
  return {
2038
2363
  content: [
2039
2364
  {
@@ -2041,7 +2366,9 @@ function buildWebSearchTool(env) {
2041
2366
  text: formatSearchResults(results, provider.label)
2042
2367
  }
2043
2368
  ],
2044
- details: void 0
2369
+ details: {
2370
+ usage
2371
+ }
2045
2372
  };
2046
2373
  } catch (e) {
2047
2374
  lastError = e;
@@ -2077,11 +2404,11 @@ function buildWebFetchTool() {
2077
2404
  ],
2078
2405
  // biome-ignore lint/suspicious/noExplicitAny: plain JSON Schema compatible with TypeBox TSchema
2079
2406
  parameters: webFetchSchema,
2080
- async execute(_toolCallId, params, _signal, _onUpdate) {
2407
+ async execute(_toolCallId, params, signal, _onUpdate) {
2081
2408
  const p = params;
2082
2409
  const url = p.url;
2083
2410
  try {
2084
- const content = await fetchPageContent(url);
2411
+ const content = await fetchPageContent(url, signal);
2085
2412
  return {
2086
2413
  content: [{ type: "text", text: content }],
2087
2414
  details: void 0
@@ -2224,52 +2551,6 @@ function applyModelOverrides(model, provider, optionsEnv) {
2224
2551
  model.baseUrl = anthropicBaseUrl;
2225
2552
  }
2226
2553
  }
2227
- function emitStreamError(errorText) {
2228
- return [
2229
- `data: ${JSON.stringify({ type: "error", errorText })}
2230
-
2231
- `,
2232
- `data: ${JSON.stringify({ type: "finish", finishReason: "error" })}
2233
-
2234
- `,
2235
- "data: [DONE]\n\n"
2236
- ];
2237
- }
2238
- function extractToolResultText(result) {
2239
- if (result !== null && typeof result === "object") {
2240
- const r = result;
2241
- if (Array.isArray(r.content) && r.content.length > 0) {
2242
- const text = r.content.filter((c) => c.type === "text" && typeof c.text === "string").map((c) => c.text).join("\n");
2243
- if (text.length > 0) {
2244
- return text;
2245
- }
2246
- }
2247
- }
2248
- if (typeof result === "string")
2249
- return result;
2250
- try {
2251
- return JSON.stringify(result);
2252
- } catch {
2253
- return String(result);
2254
- }
2255
- }
2256
- function usageToMessageMetadata(usage) {
2257
- return {
2258
- input_tokens: usage.input,
2259
- output_tokens: usage.output,
2260
- cache_read_input_tokens: usage.cacheRead,
2261
- cache_creation_input_tokens: usage.cacheWrite
2262
- };
2263
- }
2264
- function getUsageFromAgentEndMessages(messages) {
2265
- for (let i = messages.length - 1; i >= 0; i--) {
2266
- const m = messages[i];
2267
- if (m.role === "assistant" && m.usage != null) {
2268
- return m.usage;
2269
- }
2270
- }
2271
- return void 0;
2272
- }
2273
2554
  function getErrorFromAgentEndMessages(messages) {
2274
2555
  for (let i = messages.length - 1; i >= 0; i--) {
2275
2556
  const m = messages[i];
@@ -2285,7 +2566,7 @@ function traceRawMessage(debugCwd, data, reset = false, optionsEnv) {
2285
2566
  if (!enabled)
2286
2567
  return;
2287
2568
  try {
2288
- const file = join7(debugCwd, "pi-message-stream-debug.json");
2569
+ const file = join8(debugCwd, "pi-message-stream-debug.json");
2289
2570
  if (reset && existsSync5(file))
2290
2571
  unlinkSync3(file);
2291
2572
  const type = data !== null && typeof data === "object" ? data.type : void 0;
@@ -2352,13 +2633,26 @@ function createPiRunner(options = {}) {
2352
2633
  const sessionManager = await (async () => {
2353
2634
  if (resume !== void 0 && resume !== "") {
2354
2635
  if (resume.includes("/")) {
2355
- return SessionManager.open(resume);
2636
+ return SessionManager2.open(resume);
2356
2637
  }
2357
- const sessions = await SessionManager.list(cwd);
2358
- const found = sessions.find((s) => s.id === resume);
2359
- return found ? SessionManager.open(found.path) : SessionManager.create(cwd);
2638
+ const sessionPath2 = resolveSessionPathById(cwd, resume);
2639
+ console.error(`${LOG_PREFIX2} resume: id=${resume} path=${sessionPath2 ?? "(not found)"}`);
2640
+ if (sessionPath2) {
2641
+ if (isSessionFileTooLarge(sessionPath2)) {
2642
+ const context = extractSessionContext(sessionPath2);
2643
+ console.error(`${LOG_PREFIX2} session file too large, starting fresh${context ? " (with context)" : ""}`);
2644
+ const newMgr = SessionManager2.create(cwd);
2645
+ if (context) {
2646
+ const firstId = newMgr.getEntries()[0]?.id ?? "";
2647
+ newMgr.appendCompaction(context, firstId, 0);
2648
+ }
2649
+ return newMgr;
2650
+ }
2651
+ return SessionManager2.open(sessionPath2);
2652
+ }
2653
+ return SessionManager2.create(cwd);
2360
2654
  }
2361
- return SessionManager.create(cwd);
2655
+ return SessionManager2.create(cwd);
2362
2656
  })();
2363
2657
  const resourceLoader = options.skillPaths ? new BunnyAgentResourceLoader({
2364
2658
  cwd,
@@ -2414,165 +2708,34 @@ function createPiRunner(options = {}) {
2414
2708
  }
2415
2709
  try {
2416
2710
  traceRawMessage(cwd, null, true, options.env);
2417
- let promptText = userInput;
2418
- let images;
2419
- try {
2420
- if (userInput.startsWith("[") && userInput.endsWith("]")) {
2421
- const parsed = JSON.parse(userInput);
2422
- if (Array.isArray(parsed)) {
2423
- promptText = parsed.filter((p) => p.type === "text").map((p) => p.text).join("\n");
2424
- const imageParts = parsed.filter((p) => p.type === "image");
2425
- if (imageParts.length > 0) {
2426
- images = imageParts.map((p) => ({
2427
- type: "image",
2428
- data: p.data,
2429
- mimeType: p.mimeType
2430
- }));
2431
- }
2711
+ const promptText = userInput;
2712
+ const promptPromise = session.prompt(promptText);
2713
+ const streamConverter = new PiAISDKStreamConverter({
2714
+ sessionId: session.sessionId,
2715
+ model,
2716
+ redactText: (value) => {
2717
+ if (options.env && Object.keys(options.env).length > 0) {
2718
+ return redactSecrets(value, options.env);
2432
2719
  }
2433
- }
2434
- } catch (_e) {
2435
- }
2436
- const promptPromise = session.prompt(promptText, images ? { images } : void 0);
2437
- const messageId = `msg_${Date.now()}_${Math.random().toString(36).slice(2)}`;
2438
- let hasStarted = false;
2439
- let hasFinished = false;
2440
- const imageToolUsage = { input_tokens: 0, output_tokens: 0 };
2441
- const newTextPartId = () => `text_${Date.now()}_${Math.random().toString(36).slice(2)}_${Math.random().toString(36).slice(2)}`;
2442
- let activeTextPartId = null;
2443
- let textStreamOpen = false;
2444
- const endTextStreamIfOpen = function* () {
2445
- if (textStreamOpen && activeTextPartId != null) {
2446
- yield `data: ${JSON.stringify({ type: "text-end", id: activeTextPartId })}
2447
-
2448
- `;
2449
- textStreamOpen = false;
2450
- activeTextPartId = null;
2451
- }
2452
- };
2453
- const beginTextStream = function* () {
2454
- activeTextPartId = newTextPartId();
2455
- yield `data: ${JSON.stringify({ type: "text-start", id: activeTextPartId })}
2456
-
2457
- `;
2458
- textStreamOpen = true;
2459
- };
2460
- const ensureStartEvent = async function* () {
2461
- if (!hasStarted) {
2462
- yield `data: ${JSON.stringify({ type: "start", messageId })}
2463
-
2464
- `;
2465
- yield `data: ${JSON.stringify({
2466
- type: "message-metadata",
2467
- messageMetadata: { sessionId: session.sessionId }
2468
- })}
2469
-
2470
- `;
2471
- hasStarted = true;
2472
- }
2473
- };
2474
- const finishSuccess = async function* (usage) {
2475
- yield* endTextStreamIfOpen();
2476
- const finishPayload = { type: "finish", finishReason: "stop" };
2477
- const hasImageUsage = imageToolUsage.input_tokens > 0 || imageToolUsage.output_tokens > 0;
2478
- if (usage != null || hasImageUsage) {
2479
- const base = usage != null ? usageToMessageMetadata(usage) : {};
2480
- finishPayload.messageMetadata = {
2481
- usage: {
2482
- ...base,
2483
- input_tokens: (base.input_tokens ?? 0) + imageToolUsage.input_tokens,
2484
- output_tokens: (base.output_tokens ?? 0) + imageToolUsage.output_tokens
2485
- }
2486
- };
2487
- }
2488
- yield `data: ${JSON.stringify(finishPayload)}
2489
-
2490
- `;
2491
- yield "data: [DONE]\n\n";
2492
- hasFinished = true;
2493
- };
2494
- const finishError = async function* (errorText) {
2495
- for (const chunk of emitStreamError(errorText)) {
2496
- yield chunk;
2497
- }
2498
- hasFinished = true;
2499
- };
2720
+ return value;
2721
+ },
2722
+ normalizeToolOutput: extractToolResultText,
2723
+ getUsageFromAgentEndMessages,
2724
+ getErrorFromAgentEndMessages
2725
+ });
2500
2726
  while (!isComplete || eventQueue.length > 0) {
2501
2727
  while (eventQueue.length > 0) {
2502
2728
  const event = eventQueue.shift();
2503
2729
  traceRawMessage(cwd, event, false, options.env);
2504
- yield* ensureStartEvent();
2505
- if (event.type === "message_start") {
2506
- const msg = event.message;
2507
- if (msg?.role === "assistant") {
2508
- yield* endTextStreamIfOpen();
2509
- }
2510
- } else if (event.type === "message_update") {
2511
- const sub = event.assistantMessageEvent;
2512
- if (sub.type === "text_start") {
2513
- yield* endTextStreamIfOpen();
2514
- yield* beginTextStream();
2515
- } else if (sub.type === "text_delta") {
2516
- let delta = sub.delta;
2517
- if (delta) {
2518
- if (options.env && Object.keys(options.env).length > 0) {
2519
- delta = redactSecrets(delta, options.env);
2520
- }
2521
- if (!textStreamOpen) {
2522
- yield* beginTextStream();
2523
- }
2524
- yield `data: ${JSON.stringify({
2525
- type: "text-delta",
2526
- id: activeTextPartId,
2527
- delta
2528
- })}
2529
-
2530
- `;
2531
- }
2532
- } else if (sub.type === "toolcall_start") {
2533
- yield* endTextStreamIfOpen();
2534
- }
2535
- } else if (event.type === "tool_execution_start") {
2536
- yield* endTextStreamIfOpen();
2537
- yield `data: ${JSON.stringify({ type: "tool-input-start", toolCallId: event.toolCallId, toolName: event.toolName, dynamic: true, providerExecuted: true })}
2538
-
2539
- `;
2540
- yield `data: ${JSON.stringify({ type: "tool-input-available", toolCallId: event.toolCallId, toolName: event.toolName, input: event.args, dynamic: true, providerExecuted: true })}
2541
-
2542
- `;
2543
- } else if (event.type === "tool_execution_end") {
2544
- let output = extractToolResultText(event.result);
2545
- if (options.env && Object.keys(options.env).length > 0) {
2546
- output = redactSecrets(output, options.env);
2547
- }
2548
- if ((event.toolName === "generate_image" || event.toolName === "edit_image") && event.result !== null && typeof event.result === "object") {
2549
- const details = event.result.details;
2550
- const u = details?.response?.usage;
2551
- if (u) {
2552
- imageToolUsage.input_tokens += u.input_tokens ?? 0;
2553
- imageToolUsage.output_tokens += u.output_tokens ?? 0;
2554
- }
2555
- }
2556
- yield `data: ${JSON.stringify({ type: "tool-output-available", toolCallId: event.toolCallId, output, isError: event.isError, dynamic: true, providerExecuted: true })}
2557
-
2558
- `;
2559
- } else if (event.type === "agent_end") {
2560
- if (aborted) {
2561
- yield* finishError("Run aborted by signal.");
2562
- } else {
2563
- const errorMsg = getErrorFromAgentEndMessages(event.messages);
2564
- if (errorMsg) {
2565
- yield* finishError(errorMsg);
2566
- } else {
2567
- const usage = getUsageFromAgentEndMessages(event.messages);
2568
- yield* finishSuccess(usage);
2569
- }
2570
- }
2730
+ const chunks = streamConverter.handleEvent(event, aborted);
2731
+ for (const chunk of chunks) {
2732
+ yield chunk;
2571
2733
  }
2572
2734
  }
2573
- if (aborted && !hasFinished) {
2574
- yield* ensureStartEvent();
2575
- yield* finishError("Run aborted by signal.");
2735
+ if (aborted && !streamConverter.finished) {
2736
+ for (const chunk of streamConverter.forceError("Run aborted by signal.")) {
2737
+ yield chunk;
2738
+ }
2576
2739
  break;
2577
2740
  }
2578
2741
  if (!isComplete && eventQueue.length === 0) {
@@ -2581,22 +2744,24 @@ function createPiRunner(options = {}) {
2581
2744
  });
2582
2745
  }
2583
2746
  }
2584
- if (hasFinished) {
2747
+ if (streamConverter.finished) {
2585
2748
  return;
2586
2749
  }
2587
2750
  try {
2588
2751
  await promptPromise;
2589
2752
  } catch (error) {
2590
- if (!hasFinished) {
2591
- yield* ensureStartEvent();
2753
+ if (!streamConverter.finished) {
2592
2754
  const message = error instanceof Error ? error.message : "Pi agent run failed.";
2593
- yield* finishError(message);
2755
+ for (const chunk of streamConverter.forceError(message)) {
2756
+ yield chunk;
2757
+ }
2594
2758
  }
2595
2759
  return;
2596
2760
  }
2597
- if (!hasFinished && session.agent.state.error) {
2598
- yield* ensureStartEvent();
2599
- yield* finishError(session.agent.state.error);
2761
+ if (!streamConverter.finished && session.agent.state.error) {
2762
+ for (const chunk of streamConverter.forceError(session.agent.state.error)) {
2763
+ yield chunk;
2764
+ }
2600
2765
  }
2601
2766
  } finally {
2602
2767
  if (abortSignal) {
@@ -2616,11 +2781,11 @@ function createPiRunner(options = {}) {
2616
2781
 
2617
2782
  // ../../packages/runner-harness/dist/session.js
2618
2783
  import { existsSync as existsSync6, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync4 } from "node:fs";
2619
- import { join as join8 } from "node:path";
2784
+ import { join as join9 } from "node:path";
2620
2785
  var DIR = ".bunny-agent";
2621
2786
  var FILE = "session-id";
2622
2787
  function sessionPath(cwd) {
2623
- return join8(cwd, DIR, FILE);
2788
+ return join9(cwd, DIR, FILE);
2624
2789
  }
2625
2790
  function readSessionId(cwd) {
2626
2791
  try {
@@ -2634,28 +2799,28 @@ function readSessionId(cwd) {
2634
2799
  }
2635
2800
  function writeSessionId(cwd, id) {
2636
2801
  try {
2637
- mkdirSync3(join8(cwd, DIR), { recursive: true });
2802
+ mkdirSync3(join9(cwd, DIR), { recursive: true });
2638
2803
  writeFileSync4(sessionPath(cwd), id, "utf8");
2639
2804
  } catch {
2640
2805
  }
2641
2806
  }
2642
2807
 
2643
2808
  // ../../packages/runner-harness/dist/skills.js
2644
- import { existsSync as existsSync7, readdirSync as readdirSync2, statSync as statSync2 } from "node:fs";
2809
+ import { existsSync as existsSync7, readdirSync as readdirSync3, statSync as statSync3 } from "node:fs";
2645
2810
  import { homedir as homedir2 } from "node:os";
2646
- import { join as join9 } from "node:path";
2811
+ import { join as join10 } from "node:path";
2647
2812
  function discoverSkillPaths(cwd) {
2648
2813
  const paths = [];
2649
2814
  for (const base of [
2650
- join9(cwd, "skills"),
2651
- join9(homedir2(), ".bunny-agent", "skills")
2815
+ join10(cwd, "skills"),
2816
+ join10(homedir2(), ".bunny-agent", "skills")
2652
2817
  ]) {
2653
2818
  if (!existsSync7(base))
2654
2819
  continue;
2655
2820
  try {
2656
- for (const entry of readdirSync2(base)) {
2657
- const full = join9(base, entry);
2658
- if (statSync2(full).isDirectory() && existsSync7(join9(full, "SKILL.md"))) {
2821
+ for (const entry of readdirSync3(base)) {
2822
+ const full = join10(base, entry);
2823
+ if (statSync3(full).isDirectory() && existsSync7(join10(full, "SKILL.md"))) {
2659
2824
  paths.push(full);
2660
2825
  }
2661
2826
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bunny-agent/runner-cli",
3
- "version": "0.9.29-beta.0",
3
+ "version": "0.9.29-beta.11",
4
4
  "description": "BunnyAgent Runner CLI - Like gemini-cli or claude-code, runs in your local terminal with AI SDK UI streaming",
5
5
  "type": "module",
6
6
  "bin": {
@@ -53,12 +53,12 @@
53
53
  "esbuild": "^0.27.2",
54
54
  "typescript": "^5.3.0",
55
55
  "vitest": "^1.6.1",
56
- "@bunny-agent/runner-claude": "0.6.2",
57
- "@bunny-agent/runner-codex": "0.6.2",
58
56
  "@bunny-agent/runner-harness": "0.1.1-beta.0",
59
- "@bunny-agent/runner-opencode": "0.6.2",
57
+ "@bunny-agent/runner-claude": "0.6.2",
58
+ "@bunny-agent/runner-gemini": "0.6.2",
60
59
  "@bunny-agent/runner-pi": "0.6.4-beta.0",
61
- "@bunny-agent/runner-gemini": "0.6.2"
60
+ "@bunny-agent/runner-opencode": "0.6.2",
61
+ "@bunny-agent/runner-codex": "0.6.2"
62
62
  },
63
63
  "scripts": {
64
64
  "build": "tsc && pnpm bundle",