@bunny-agent/runner-cli 0.9.53 → 0.9.56
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/dist/bundle.mjs +100 -7
- package/package.json +4 -4
package/dist/bundle.mjs
CHANGED
|
@@ -2483,6 +2483,92 @@ function isRateLimitError(err) {
|
|
|
2483
2483
|
const msg = err.message;
|
|
2484
2484
|
return msg.includes("429") || msg.includes("rate") || msg.includes("quota") || msg.includes("limit");
|
|
2485
2485
|
}
|
|
2486
|
+
var RETRYABLE_NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
2487
|
+
"EAI_AGAIN",
|
|
2488
|
+
"ECONNREFUSED",
|
|
2489
|
+
"ECONNRESET",
|
|
2490
|
+
"EHOSTUNREACH",
|
|
2491
|
+
"ENETUNREACH",
|
|
2492
|
+
"ENOTFOUND",
|
|
2493
|
+
"ETIMEDOUT",
|
|
2494
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
2495
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
2496
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
2497
|
+
"UND_ERR_SOCKET"
|
|
2498
|
+
]);
|
|
2499
|
+
function hasRetryableNetworkCode(error, seen = /* @__PURE__ */ new Set()) {
|
|
2500
|
+
if (error === null || typeof error !== "object" || seen.has(error))
|
|
2501
|
+
return false;
|
|
2502
|
+
seen.add(error);
|
|
2503
|
+
const code = getErrorField(error, "code");
|
|
2504
|
+
if (code && RETRYABLE_NETWORK_ERROR_CODES.has(code))
|
|
2505
|
+
return true;
|
|
2506
|
+
const nestedErrors = [];
|
|
2507
|
+
if ("cause" in error)
|
|
2508
|
+
nestedErrors.push(error.cause);
|
|
2509
|
+
if ("errors" in error && Array.isArray(error.errors)) {
|
|
2510
|
+
nestedErrors.push(...error.errors);
|
|
2511
|
+
}
|
|
2512
|
+
return nestedErrors.some((nested) => hasRetryableNetworkCode(nested, seen));
|
|
2513
|
+
}
|
|
2514
|
+
function isRetryableNetworkError(err) {
|
|
2515
|
+
if (hasRetryableNetworkCode(err))
|
|
2516
|
+
return true;
|
|
2517
|
+
return err instanceof TypeError && err.message === "fetch failed";
|
|
2518
|
+
}
|
|
2519
|
+
function getFallbackReason(err) {
|
|
2520
|
+
if (isRateLimitError(err))
|
|
2521
|
+
return "rate limit";
|
|
2522
|
+
if (isRetryableNetworkError(err))
|
|
2523
|
+
return "network error";
|
|
2524
|
+
return null;
|
|
2525
|
+
}
|
|
2526
|
+
function getErrorField(error, key) {
|
|
2527
|
+
if (!(key in error))
|
|
2528
|
+
return void 0;
|
|
2529
|
+
const value = error[key];
|
|
2530
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
2531
|
+
return String(value);
|
|
2532
|
+
}
|
|
2533
|
+
return void 0;
|
|
2534
|
+
}
|
|
2535
|
+
function formatErrorCause(cause) {
|
|
2536
|
+
if (cause === null || cause === void 0)
|
|
2537
|
+
return "unknown";
|
|
2538
|
+
if (typeof cause !== "object")
|
|
2539
|
+
return String(cause);
|
|
2540
|
+
const details = [
|
|
2541
|
+
["code", getErrorField(cause, "code")],
|
|
2542
|
+
[
|
|
2543
|
+
"message",
|
|
2544
|
+
cause instanceof Error ? cause.message : getErrorField(cause, "message")
|
|
2545
|
+
],
|
|
2546
|
+
["errno", getErrorField(cause, "errno")],
|
|
2547
|
+
["syscall", getErrorField(cause, "syscall")],
|
|
2548
|
+
["hostname", getErrorField(cause, "hostname")],
|
|
2549
|
+
["address", getErrorField(cause, "address")],
|
|
2550
|
+
["port", getErrorField(cause, "port")]
|
|
2551
|
+
].filter((entry) => Boolean(entry[1])).map(([key, value]) => `${key}=${value}`);
|
|
2552
|
+
const nestedErrors = "errors" in cause && Array.isArray(cause.errors) ? cause.errors : [];
|
|
2553
|
+
if (nestedErrors.length > 0) {
|
|
2554
|
+
const nested = nestedErrors.slice(0, 3).map(formatErrorCause).join("; ");
|
|
2555
|
+
details.push(`errors=[${nested}]`);
|
|
2556
|
+
}
|
|
2557
|
+
return details.length > 0 ? details.join(", ") : String(cause);
|
|
2558
|
+
}
|
|
2559
|
+
function formatWebToolError(error) {
|
|
2560
|
+
if (!(error instanceof Error))
|
|
2561
|
+
return String(error);
|
|
2562
|
+
const cause = "cause" in error ? error.cause : void 0;
|
|
2563
|
+
return cause === void 0 ? error.message : `${error.name}: ${error.message} (cause: ${formatErrorCause(cause)})`;
|
|
2564
|
+
}
|
|
2565
|
+
function getSafeTarget(url) {
|
|
2566
|
+
try {
|
|
2567
|
+
return new URL(url).origin;
|
|
2568
|
+
} catch {
|
|
2569
|
+
return "invalid-url";
|
|
2570
|
+
}
|
|
2571
|
+
}
|
|
2486
2572
|
var BROWSER_UA = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
|
|
2487
2573
|
function stripNullBytes(s) {
|
|
2488
2574
|
return s.replace(/\0/g, "");
|
|
@@ -2513,7 +2599,8 @@ async function fetchPageContent(url, externalSignal) {
|
|
|
2513
2599
|
|
|
2514
2600
|
[Truncated]` : text;
|
|
2515
2601
|
} catch (e) {
|
|
2516
|
-
const msg =
|
|
2602
|
+
const msg = formatWebToolError(e);
|
|
2603
|
+
console.error(`[bunny-agent:pi] web_fetch failed target=${getSafeTarget(url)}: ${msg}`);
|
|
2517
2604
|
return `(Error fetching ${url}: ${msg})`;
|
|
2518
2605
|
} finally {
|
|
2519
2606
|
clearTimeout(timeout);
|
|
@@ -2600,7 +2687,9 @@ function buildWebSearchTool(env) {
|
|
|
2600
2687
|
const freshness = p.freshness;
|
|
2601
2688
|
const shouldFetchContent = p.fetch_content ?? false;
|
|
2602
2689
|
let lastError;
|
|
2603
|
-
|
|
2690
|
+
let lastProviderLabel = "unknown provider";
|
|
2691
|
+
for (const [providerIndex, { provider, apiKey }] of providers.entries()) {
|
|
2692
|
+
lastProviderLabel = provider.label;
|
|
2604
2693
|
try {
|
|
2605
2694
|
const { results } = await provider.search({
|
|
2606
2695
|
apiKey,
|
|
@@ -2638,19 +2727,23 @@ function buildWebSearchTool(env) {
|
|
|
2638
2727
|
};
|
|
2639
2728
|
} catch (e) {
|
|
2640
2729
|
lastError = e;
|
|
2641
|
-
|
|
2642
|
-
|
|
2730
|
+
const diagnostic = formatWebToolError(e);
|
|
2731
|
+
console.error(`[bunny-agent:pi] ${provider.label} web_search failed: ${diagnostic}`);
|
|
2732
|
+
const fallbackReason = getFallbackReason(e);
|
|
2733
|
+
const nextProvider = providers[providerIndex + 1];
|
|
2734
|
+
if (fallbackReason && nextProvider) {
|
|
2735
|
+
console.error(`[bunny-agent:pi] ${provider.label} ${fallbackReason}, trying ${nextProvider.provider.label}...`);
|
|
2643
2736
|
continue;
|
|
2644
2737
|
}
|
|
2645
2738
|
break;
|
|
2646
2739
|
}
|
|
2647
2740
|
}
|
|
2648
|
-
const msg =
|
|
2741
|
+
const msg = formatWebToolError(lastError);
|
|
2649
2742
|
return {
|
|
2650
2743
|
content: [
|
|
2651
2744
|
{
|
|
2652
2745
|
type: "text",
|
|
2653
|
-
text: `Web search error: ${msg}`
|
|
2746
|
+
text: `Web search error (${lastProviderLabel}): ${msg}`
|
|
2654
2747
|
}
|
|
2655
2748
|
],
|
|
2656
2749
|
details: void 0
|
|
@@ -2680,7 +2773,7 @@ function buildWebFetchTool() {
|
|
|
2680
2773
|
details: void 0
|
|
2681
2774
|
};
|
|
2682
2775
|
} catch (e) {
|
|
2683
|
-
const msg =
|
|
2776
|
+
const msg = formatWebToolError(e);
|
|
2684
2777
|
return {
|
|
2685
2778
|
content: [
|
|
2686
2779
|
{ type: "text", text: `Error fetching URL: ${msg}` }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bunny-agent/runner-cli",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.56",
|
|
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": {
|
|
@@ -55,10 +55,10 @@
|
|
|
55
55
|
"typescript": "^5.3.0",
|
|
56
56
|
"vitest": "^1.6.1",
|
|
57
57
|
"@bunny-agent/runner-claude": "0.6.2",
|
|
58
|
-
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
59
|
-
"@bunny-agent/runner-pi": "0.6.4-beta.0",
|
|
60
|
-
"@bunny-agent/runner-opencode": "0.6.2",
|
|
61
58
|
"@bunny-agent/runner-codex": "0.6.2",
|
|
59
|
+
"@bunny-agent/runner-opencode": "0.6.2",
|
|
60
|
+
"@bunny-agent/runner-pi": "0.6.4-beta.0",
|
|
61
|
+
"@bunny-agent/runner-harness": "0.1.1-beta.0",
|
|
62
62
|
"@bunny-agent/runner-gemini": "0.6.2"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|