@opencow-ai/opencow-agent-sdk 0.4.28 → 0.4.30

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/cli.mjs CHANGED
@@ -20054,10 +20054,20 @@ function isEssentialTrafficOnly() {
20054
20054
  return getPrivacyLevel() === "essential-traffic";
20055
20055
  }
20056
20056
  function getEssentialTrafficOnlyReason() {
20057
- if (resolveEnvVar("DISABLE_NONESSENTIAL_TRAFFIC")) {
20058
- return "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC";
20057
+ if (!resolveEnvVar("DISABLE_NONESSENTIAL_TRAFFIC")) {
20058
+ return null;
20059
20059
  }
20060
- return null;
20060
+ const primaryName = "OPENCOW_DISABLE_NONESSENTIAL_TRAFFIC";
20061
+ const legacyName = "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC";
20062
+ const primaryValue = getQueryEnvVar(primaryName);
20063
+ const legacyValue = getQueryEnvVar(legacyName);
20064
+ if (primaryValue && legacyValue) {
20065
+ return `${primaryName} and ${legacyName}`;
20066
+ }
20067
+ if (legacyValue) {
20068
+ return legacyName;
20069
+ }
20070
+ return primaryName;
20061
20071
  }
20062
20072
  var init_privacyLevel = __esm(() => {
20063
20073
  init_state();
@@ -86008,6 +86018,7 @@ var init_managedEnvConstants = __esm(() => {
86008
86018
  "MAX_THINKING_TOKENS",
86009
86019
  "MCP_TIMEOUT",
86010
86020
  "MCP_TOOL_TIMEOUT",
86021
+ "OPENCOW_DISABLE_NONESSENTIAL_TRAFFIC",
86011
86022
  "OTEL_EXPORTER_OTLP_HEADERS",
86012
86023
  "OTEL_EXPORTER_OTLP_LOGS_HEADERS",
86013
86024
  "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL",
@@ -86726,7 +86737,7 @@ function printStartupScreen() {
86726
86737
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
86727
86738
  out.push(boxRow(sRow, W, sLen));
86728
86739
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W - 2)}╝${RESET}`);
86729
- out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.28"}${RESET}`);
86740
+ out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.30"}${RESET}`);
86730
86741
  out.push("");
86731
86742
  process.stdout.write(out.join(`
86732
86743
  `) + `
@@ -138398,16 +138409,17 @@ function getAssistantMessageFromError(error, model, options) {
138398
138409
  error: "rate_limit"
138399
138410
  });
138400
138411
  }
138401
- if (error instanceof APIError && error.status === 429 && shouldProcessRateLimits(isClaudeAISubscriber())) {
138402
- const rateLimitType = error.headers?.get?.("anthropic-ratelimit-unified-representative-claim");
138403
- const overageStatus = error.headers?.get?.("anthropic-ratelimit-unified-overage-status");
138412
+ if (error instanceof APIError && error.status === 429) {
138413
+ const quotaHeaders = shouldProcessRateLimits(isClaudeAISubscriber()) ? error.headers : undefined;
138414
+ const rateLimitType = quotaHeaders?.get?.("anthropic-ratelimit-unified-representative-claim");
138415
+ const overageStatus = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-status");
138404
138416
  if (rateLimitType || overageStatus) {
138405
138417
  const limits = {
138406
138418
  status: "rejected",
138407
138419
  unifiedRateLimitFallbackAvailable: false,
138408
138420
  isUsingOverage: false
138409
138421
  };
138410
- const resetHeader = error.headers?.get?.("anthropic-ratelimit-unified-reset");
138422
+ const resetHeader = quotaHeaders?.get?.("anthropic-ratelimit-unified-reset");
138411
138423
  if (resetHeader) {
138412
138424
  limits.resetsAt = Number(resetHeader);
138413
138425
  }
@@ -138417,11 +138429,11 @@ function getAssistantMessageFromError(error, model, options) {
138417
138429
  if (overageStatus) {
138418
138430
  limits.overageStatus = overageStatus;
138419
138431
  }
138420
- const overageResetHeader = error.headers?.get?.("anthropic-ratelimit-unified-overage-reset");
138432
+ const overageResetHeader = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-reset");
138421
138433
  if (overageResetHeader) {
138422
138434
  limits.overageResetsAt = Number(overageResetHeader);
138423
138435
  }
138424
- const overageDisabledReason = error.headers?.get?.("anthropic-ratelimit-unified-overage-disabled-reason");
138436
+ const overageDisabledReason = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-disabled-reason");
138425
138437
  if (overageDisabledReason) {
138426
138438
  limits.overageDisabledReason = overageDisabledReason;
138427
138439
  }
@@ -138562,6 +138574,13 @@ Run /share and post the JSON file to ${MACRO.FEEDBACK_CHANNEL}.`;
138562
138574
  error: "billing_error"
138563
138575
  });
138564
138576
  }
138577
+ if (error instanceof APIError && (error.status === 402 || error.message.includes('"type":"billing_error"'))) {
138578
+ const detail = error.message.match(/"message"\s*:\s*"([^"]*)"/)?.[1];
138579
+ return createAssistantAPIErrorMessage({
138580
+ content: `${API_ERROR_MESSAGE_PREFIX}: ${detail || error.message}`,
138581
+ error: "billing_error"
138582
+ });
138583
+ }
138565
138584
  if (error instanceof APIError && error.status === 400 && error.message.toLowerCase().includes("organization has been disabled")) {
138566
138585
  const { source } = getAnthropicApiKeyWithSource();
138567
138586
  if (source === "ANTHROPIC_API_KEY" && process.env.ANTHROPIC_API_KEY && !isClaudeAISubscriber()) {
@@ -234406,7 +234425,6 @@ async function* queryLoop(params, consumedCommandUuids) {
234406
234425
  exceeds200kTokens: permissionMode === "plan" && doesMostRecentAssistantMessageExceed200k(messagesForQuery)
234407
234426
  });
234408
234427
  queryCheckpoint("query_setup_end");
234409
- const dumpPromptsFetch = undefined;
234410
234428
  let collapseOwnsIt = false;
234411
234429
  if (false) {}
234412
234430
  const mediaRecoveryEnabled = reactiveCompact?.isReactiveCompactEnabled() ?? false;
@@ -234459,7 +234477,7 @@ async function* queryLoop(params, consumedCommandUuids) {
234459
234477
  hasAppendSystemPrompt: !!toolUseContext.options.appendSystemPrompt,
234460
234478
  maxOutputTokensOverride,
234461
234479
  maxOutputTokensLimitOverride: params.maxOutputTokensLimitOverride,
234462
- fetchOverride: dumpPromptsFetch,
234480
+ fetchOverride: toolUseContext.options.fetchOverride,
234463
234481
  mcpTools: appState.mcp.tools,
234464
234482
  hasPendingMcpServers: appState.mcp.clients.some((c) => c.type === "pending"),
234465
234483
  queryTracking,
@@ -235172,7 +235190,7 @@ function getAnthropicEnvMetadata() {
235172
235190
  function getBuildAgeMinutes() {
235173
235191
  if (false)
235174
235192
  ;
235175
- const buildTime = new Date("2026-10-24T12:55:52.344Z").getTime();
235193
+ const buildTime = new Date("2026-11-04T12:30:46.458Z").getTime();
235176
235194
  if (isNaN(buildTime))
235177
235195
  return;
235178
235196
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -239045,6 +239063,7 @@ async function* runAgent({
239045
239063
  mcpResources: toolUseContext.options.mcpResources,
239046
239064
  agentDefinitions: toolUseContext.options.agentDefinitions,
239047
239065
  subagentDisallowedTools: toolUseContext.options.subagentDisallowedTools,
239066
+ fetchOverride: toolUseContext.options.fetchOverride,
239048
239067
  ...useExactTools && { querySource }
239049
239068
  };
239050
239069
  agentToolRuntimeContext = createSubagentContext(toolUseContext, {
@@ -480205,7 +480224,7 @@ function buildPrimarySection() {
480205
480224
  }, undefined, false, undefined, this);
480206
480225
  return [{
480207
480226
  label: "Version",
480208
- value: "0.4.28"
480227
+ value: "0.4.30"
480209
480228
  }, {
480210
480229
  label: "Session name",
480211
480230
  value: nameValue
@@ -528285,7 +528304,7 @@ var init_bridge_kick = __esm(() => {
528285
528304
  var call58 = async () => {
528286
528305
  return {
528287
528306
  type: "text",
528288
- value: `${"99.0.0"} (built ${"2026-10-24T12:55:52.344Z"})`
528307
+ value: `${"99.0.0"} (built ${"2026-11-04T12:30:46.458Z"})`
528289
528308
  };
528290
528309
  }, version2, version_default;
528291
528310
  var init_version = __esm(() => {
@@ -545964,7 +545983,7 @@ function WelcomeV2() {
545964
545983
  dimColor: true,
545965
545984
  children: [
545966
545985
  "v",
545967
- "0.4.28",
545986
+ "0.4.30",
545968
545987
  " "
545969
545988
  ]
545970
545989
  }, undefined, true, undefined, this)
@@ -546164,7 +546183,7 @@ function WelcomeV2() {
546164
546183
  dimColor: true,
546165
546184
  children: [
546166
546185
  "v",
546167
- "0.4.28",
546186
+ "0.4.30",
546168
546187
  " "
546169
546188
  ]
546170
546189
  }, undefined, true, undefined, this)
@@ -546390,7 +546409,7 @@ function AppleTerminalWelcomeV2(t0) {
546390
546409
  dimColor: true,
546391
546410
  children: [
546392
546411
  "v",
546393
- "0.4.28",
546412
+ "0.4.30",
546394
546413
  " "
546395
546414
  ]
546396
546415
  }, undefined, true, undefined, this);
@@ -546644,7 +546663,7 @@ function AppleTerminalWelcomeV2(t0) {
546644
546663
  dimColor: true,
546645
546664
  children: [
546646
546665
  "v",
546647
- "0.4.28",
546666
+ "0.4.30",
546648
546667
  " "
546649
546668
  ]
546650
546669
  }, undefined, true, undefined, this);
@@ -557376,6 +557395,7 @@ class QueryEngine {
557376
557395
  maxOutputTokensLimit,
557377
557396
  contextWindow,
557378
557397
  modelProviders: this.config.modelProviders,
557398
+ fetchOverride: this.config.fetchOverride,
557379
557399
  subagentDisallowedTools: this.config.subagentDisallowedTools,
557380
557400
  preDecidePermissions
557381
557401
  },
@@ -557475,6 +557495,7 @@ class QueryEngine {
557475
557495
  maxOutputTokensLimit,
557476
557496
  contextWindow,
557477
557497
  modelProviders: this.config.modelProviders,
557498
+ fetchOverride: this.config.fetchOverride,
557478
557499
  subagentDisallowedTools: this.config.subagentDisallowedTools,
557479
557500
  preDecidePermissions
557480
557501
  },
@@ -557984,6 +558005,7 @@ async function* ask({
557984
558005
  userSpecifiedModel,
557985
558006
  fallbackModel,
557986
558007
  modelProviders,
558008
+ fetchOverride,
557987
558009
  jsonSchema,
557988
558010
  getAppState,
557989
558011
  setAppState,
@@ -558014,6 +558036,7 @@ async function* ask({
558014
558036
  userSpecifiedModel,
558015
558037
  fallbackModel,
558016
558038
  modelProviders,
558039
+ fetchOverride,
558017
558040
  thinkingConfig,
558018
558041
  maxTurns,
558019
558042
  maxBudgetUsd,
@@ -567401,7 +567424,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
567401
567424
  pendingHookMessages
567402
567425
  }, renderAndRun);
567403
567426
  }
567404
- }).version("0.4.28 (OpenCow)", "-v, --version", "Output the version number");
567427
+ }).version("0.4.30 (OpenCow)", "-v, --version", "Output the version number");
567405
567428
  program.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
567406
567429
  program.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
567407
567430
  if (canUserConfigureAdvisor()) {
@@ -567996,7 +568019,7 @@ if (false) {}
567996
568019
  async function main2() {
567997
568020
  const args = process.argv.slice(2);
567998
568021
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
567999
- console.log(`${"0.4.28"} (OpenCow)`);
568022
+ console.log(`${"0.4.30"} (OpenCow)`);
568000
568023
  return;
568001
568024
  }
568002
568025
  if (args.includes("--provider")) {
@@ -568096,4 +568119,4 @@ async function main2() {
568096
568119
  }
568097
568120
  main2();
568098
568121
 
568099
- //# debugId=9998D5AD757C65B264756E2164756E21
568122
+ //# debugId=350424289A5BE31764756E2164756E21
package/dist/client.js CHANGED
@@ -122191,16 +122191,17 @@ function getAssistantMessageFromError(error, model, options) {
122191
122191
  error: "rate_limit"
122192
122192
  });
122193
122193
  }
122194
- if (error instanceof APIError && error.status === 429 && shouldProcessRateLimits(isClaudeAISubscriber())) {
122195
- const rateLimitType = error.headers?.get?.("anthropic-ratelimit-unified-representative-claim");
122196
- const overageStatus = error.headers?.get?.("anthropic-ratelimit-unified-overage-status");
122194
+ if (error instanceof APIError && error.status === 429) {
122195
+ const quotaHeaders = shouldProcessRateLimits(isClaudeAISubscriber()) ? error.headers : undefined;
122196
+ const rateLimitType = quotaHeaders?.get?.("anthropic-ratelimit-unified-representative-claim");
122197
+ const overageStatus = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-status");
122197
122198
  if (rateLimitType || overageStatus) {
122198
122199
  const limits = {
122199
122200
  status: "rejected",
122200
122201
  unifiedRateLimitFallbackAvailable: false,
122201
122202
  isUsingOverage: false
122202
122203
  };
122203
- const resetHeader = error.headers?.get?.("anthropic-ratelimit-unified-reset");
122204
+ const resetHeader = quotaHeaders?.get?.("anthropic-ratelimit-unified-reset");
122204
122205
  if (resetHeader) {
122205
122206
  limits.resetsAt = Number(resetHeader);
122206
122207
  }
@@ -122210,11 +122211,11 @@ function getAssistantMessageFromError(error, model, options) {
122210
122211
  if (overageStatus) {
122211
122212
  limits.overageStatus = overageStatus;
122212
122213
  }
122213
- const overageResetHeader = error.headers?.get?.("anthropic-ratelimit-unified-overage-reset");
122214
+ const overageResetHeader = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-reset");
122214
122215
  if (overageResetHeader) {
122215
122216
  limits.overageResetsAt = Number(overageResetHeader);
122216
122217
  }
122217
- const overageDisabledReason = error.headers?.get?.("anthropic-ratelimit-unified-overage-disabled-reason");
122218
+ const overageDisabledReason = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-disabled-reason");
122218
122219
  if (overageDisabledReason) {
122219
122220
  limits.overageDisabledReason = overageDisabledReason;
122220
122221
  }
@@ -122355,6 +122356,13 @@ Run /share and post the JSON file to ${MACRO.FEEDBACK_CHANNEL}.`;
122355
122356
  error: "billing_error"
122356
122357
  });
122357
122358
  }
122359
+ if (error instanceof APIError && (error.status === 402 || error.message.includes('"type":"billing_error"'))) {
122360
+ const detail = error.message.match(/"message"\s*:\s*"([^"]*)"/)?.[1];
122361
+ return createAssistantAPIErrorMessage({
122362
+ content: `${API_ERROR_MESSAGE_PREFIX}: ${detail || error.message}`,
122363
+ error: "billing_error"
122364
+ });
122365
+ }
122358
122366
  if (error instanceof APIError && error.status === 400 && error.message.toLowerCase().includes("organization has been disabled")) {
122359
122367
  const { source } = getAnthropicApiKeyWithSource();
122360
122368
  if (source === "ANTHROPIC_API_KEY" && process.env.ANTHROPIC_API_KEY && !isClaudeAISubscriber()) {
@@ -176405,6 +176413,7 @@ async function* runAgent({
176405
176413
  mcpResources: toolUseContext.options.mcpResources,
176406
176414
  agentDefinitions: toolUseContext.options.agentDefinitions,
176407
176415
  subagentDisallowedTools: toolUseContext.options.subagentDisallowedTools,
176416
+ fetchOverride: toolUseContext.options.fetchOverride,
176408
176417
  ...useExactTools && { querySource }
176409
176418
  };
176410
176419
  agentToolRuntimeContext = createSubagentContext(toolUseContext, {
@@ -226651,7 +226660,6 @@ async function* queryLoop(params, consumedCommandUuids) {
226651
226660
  exceeds200kTokens: permissionMode === "plan" && doesMostRecentAssistantMessageExceed200k(messagesForQuery)
226652
226661
  });
226653
226662
  queryCheckpoint("query_setup_end");
226654
- const dumpPromptsFetch = undefined;
226655
226663
  let collapseOwnsIt = false;
226656
226664
  if (false) {}
226657
226665
  const mediaRecoveryEnabled = reactiveCompact?.isReactiveCompactEnabled() ?? false;
@@ -226704,7 +226712,7 @@ async function* queryLoop(params, consumedCommandUuids) {
226704
226712
  hasAppendSystemPrompt: !!toolUseContext.options.appendSystemPrompt,
226705
226713
  maxOutputTokensOverride,
226706
226714
  maxOutputTokensLimitOverride: params.maxOutputTokensLimitOverride,
226707
- fetchOverride: dumpPromptsFetch,
226715
+ fetchOverride: toolUseContext.options.fetchOverride,
226708
226716
  mcpTools: appState.mcp.tools,
226709
226717
  hasPendingMcpServers: appState.mcp.clients.some((c) => c.type === "pending"),
226710
226718
  queryTracking,
@@ -227383,7 +227391,7 @@ function getAnthropicEnvMetadata() {
227383
227391
  function getBuildAgeMinutes() {
227384
227392
  if (false)
227385
227393
  ;
227386
- const buildTime = new Date("2026-10-24T12:55:52.344Z").getTime();
227394
+ const buildTime = new Date("2026-11-04T12:30:46.458Z").getTime();
227387
227395
  if (isNaN(buildTime))
227388
227396
  return;
227389
227397
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -271008,6 +271016,7 @@ class QueryEngine {
271008
271016
  maxOutputTokensLimit,
271009
271017
  contextWindow,
271010
271018
  modelProviders: this.config.modelProviders,
271019
+ fetchOverride: this.config.fetchOverride,
271011
271020
  subagentDisallowedTools: this.config.subagentDisallowedTools,
271012
271021
  preDecidePermissions
271013
271022
  },
@@ -271107,6 +271116,7 @@ class QueryEngine {
271107
271116
  maxOutputTokensLimit,
271108
271117
  contextWindow,
271109
271118
  modelProviders: this.config.modelProviders,
271119
+ fetchOverride: this.config.fetchOverride,
271110
271120
  subagentDisallowedTools: this.config.subagentDisallowedTools,
271111
271121
  preDecidePermissions
271112
271122
  },
@@ -271616,6 +271626,7 @@ async function* ask({
271616
271626
  userSpecifiedModel,
271617
271627
  fallbackModel,
271618
271628
  modelProviders,
271629
+ fetchOverride,
271619
271630
  jsonSchema,
271620
271631
  getAppState,
271621
271632
  setAppState,
@@ -271646,6 +271657,7 @@ async function* ask({
271646
271657
  userSpecifiedModel,
271647
271658
  fallbackModel,
271648
271659
  modelProviders,
271660
+ fetchOverride,
271649
271661
  thinkingConfig,
271650
271662
  maxTurns,
271651
271663
  maxBudgetUsd,
@@ -279288,6 +279300,7 @@ function runSdkQueryRuntime(params) {
279288
279300
  fallbackModel: typeof options.fallbackModel === "string" && options.fallbackModel.length > 0 ? options.fallbackModel : undefined,
279289
279301
  jsonSchema: options.jsonSchema && typeof options.jsonSchema === "object" ? options.jsonSchema : undefined,
279290
279302
  modelProviders: options.modelProviders && typeof options.modelProviders === "object" ? options.modelProviders : undefined,
279303
+ fetchOverride: typeof options.fetchOverride === "function" ? options.fetchOverride : undefined,
279291
279304
  getAppState: appStateStore.getAppState,
279292
279305
  setAppState: appStateStore.setAppState,
279293
279306
  abortController: runtimeState.abortController,
@@ -280615,4 +280628,4 @@ export {
280615
280628
  watchScheduledTasks
280616
280629
  };
280617
280630
 
280618
- //# debugId=E18A4788D5E5D36064756E2164756E21
280631
+ //# debugId=B13AF4A366BF432D64756E2164756E21
@@ -483,6 +483,13 @@ export type Options = {
483
483
  * the catalog use the session provider config as before.
484
484
  */
485
485
  modelProviders?: ModelProviders;
486
+ /**
487
+ * Host fetch for this session's model requests (main loop and subagents).
488
+ * Lets the host attach per-request headers or observe responses (e.g. surface
489
+ * a billing rejection in its own UI). Return the response unchanged unless the
490
+ * host deliberately alters retry semantics. Absent → global fetch.
491
+ */
492
+ fetchOverride?: typeof globalThis.fetch;
486
493
  /**
487
494
  * Per-protocol passthrough channel for fields the wire supports but the
488
495
  * SDK does not surface as first-class options. The shim merges these
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Privacy level controls how much nonessential network traffic and telemetry
3
- * Claude Code generates.
3
+ * OpenCow generates.
4
4
  *
5
5
  * Levels are ordered by restrictiveness:
6
6
  * default < no-telemetry < essential-traffic
@@ -11,8 +11,8 @@
11
11
  * (telemetry + auto-updates, grove, release notes, model capabilities, etc.).
12
12
  *
13
13
  * The resolved level is the most restrictive signal from:
14
- * CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC → essential-traffic
15
- * DISABLE_TELEMETRY → no-telemetry
14
+ * OPENCOW_DISABLE_NONESSENTIAL_TRAFFIC → essential-traffic
15
+ * DISABLE_TELEMETRY → no-telemetry
16
16
  */
17
17
  type PrivacyLevel = 'default' | 'no-telemetry' | 'essential-traffic';
18
18
  export declare function getPrivacyLevel(): PrivacyLevel;
@@ -27,7 +27,7 @@ export declare function isEssentialTrafficOnly(): boolean;
27
27
  */
28
28
  export declare function isTelemetryDisabled(): boolean;
29
29
  /**
30
- * Returns the env var name responsible for the current essential-traffic restriction,
30
+ * Returns the env var name(s) responsible for the current essential-traffic restriction,
31
31
  * or null if unrestricted. Used for user-facing "unset X to re-enable" messages.
32
32
  */
33
33
  export declare function getEssentialTrafficOnlyReason(): string | null;
package/dist/sdk.js CHANGED
@@ -122191,16 +122191,17 @@ function getAssistantMessageFromError(error, model, options) {
122191
122191
  error: "rate_limit"
122192
122192
  });
122193
122193
  }
122194
- if (error instanceof APIError && error.status === 429 && shouldProcessRateLimits(isClaudeAISubscriber())) {
122195
- const rateLimitType = error.headers?.get?.("anthropic-ratelimit-unified-representative-claim");
122196
- const overageStatus = error.headers?.get?.("anthropic-ratelimit-unified-overage-status");
122194
+ if (error instanceof APIError && error.status === 429) {
122195
+ const quotaHeaders = shouldProcessRateLimits(isClaudeAISubscriber()) ? error.headers : undefined;
122196
+ const rateLimitType = quotaHeaders?.get?.("anthropic-ratelimit-unified-representative-claim");
122197
+ const overageStatus = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-status");
122197
122198
  if (rateLimitType || overageStatus) {
122198
122199
  const limits = {
122199
122200
  status: "rejected",
122200
122201
  unifiedRateLimitFallbackAvailable: false,
122201
122202
  isUsingOverage: false
122202
122203
  };
122203
- const resetHeader = error.headers?.get?.("anthropic-ratelimit-unified-reset");
122204
+ const resetHeader = quotaHeaders?.get?.("anthropic-ratelimit-unified-reset");
122204
122205
  if (resetHeader) {
122205
122206
  limits.resetsAt = Number(resetHeader);
122206
122207
  }
@@ -122210,11 +122211,11 @@ function getAssistantMessageFromError(error, model, options) {
122210
122211
  if (overageStatus) {
122211
122212
  limits.overageStatus = overageStatus;
122212
122213
  }
122213
- const overageResetHeader = error.headers?.get?.("anthropic-ratelimit-unified-overage-reset");
122214
+ const overageResetHeader = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-reset");
122214
122215
  if (overageResetHeader) {
122215
122216
  limits.overageResetsAt = Number(overageResetHeader);
122216
122217
  }
122217
- const overageDisabledReason = error.headers?.get?.("anthropic-ratelimit-unified-overage-disabled-reason");
122218
+ const overageDisabledReason = quotaHeaders?.get?.("anthropic-ratelimit-unified-overage-disabled-reason");
122218
122219
  if (overageDisabledReason) {
122219
122220
  limits.overageDisabledReason = overageDisabledReason;
122220
122221
  }
@@ -122355,6 +122356,13 @@ Run /share and post the JSON file to ${MACRO.FEEDBACK_CHANNEL}.`;
122355
122356
  error: "billing_error"
122356
122357
  });
122357
122358
  }
122359
+ if (error instanceof APIError && (error.status === 402 || error.message.includes('"type":"billing_error"'))) {
122360
+ const detail = error.message.match(/"message"\s*:\s*"([^"]*)"/)?.[1];
122361
+ return createAssistantAPIErrorMessage({
122362
+ content: `${API_ERROR_MESSAGE_PREFIX}: ${detail || error.message}`,
122363
+ error: "billing_error"
122364
+ });
122365
+ }
122358
122366
  if (error instanceof APIError && error.status === 400 && error.message.toLowerCase().includes("organization has been disabled")) {
122359
122367
  const { source } = getAnthropicApiKeyWithSource();
122360
122368
  if (source === "ANTHROPIC_API_KEY" && process.env.ANTHROPIC_API_KEY && !isClaudeAISubscriber()) {
@@ -176405,6 +176413,7 @@ async function* runAgent({
176405
176413
  mcpResources: toolUseContext.options.mcpResources,
176406
176414
  agentDefinitions: toolUseContext.options.agentDefinitions,
176407
176415
  subagentDisallowedTools: toolUseContext.options.subagentDisallowedTools,
176416
+ fetchOverride: toolUseContext.options.fetchOverride,
176408
176417
  ...useExactTools && { querySource }
176409
176418
  };
176410
176419
  agentToolRuntimeContext = createSubagentContext(toolUseContext, {
@@ -226651,7 +226660,6 @@ async function* queryLoop(params, consumedCommandUuids) {
226651
226660
  exceeds200kTokens: permissionMode === "plan" && doesMostRecentAssistantMessageExceed200k(messagesForQuery)
226652
226661
  });
226653
226662
  queryCheckpoint("query_setup_end");
226654
- const dumpPromptsFetch = undefined;
226655
226663
  let collapseOwnsIt = false;
226656
226664
  if (false) {}
226657
226665
  const mediaRecoveryEnabled = reactiveCompact?.isReactiveCompactEnabled() ?? false;
@@ -226704,7 +226712,7 @@ async function* queryLoop(params, consumedCommandUuids) {
226704
226712
  hasAppendSystemPrompt: !!toolUseContext.options.appendSystemPrompt,
226705
226713
  maxOutputTokensOverride,
226706
226714
  maxOutputTokensLimitOverride: params.maxOutputTokensLimitOverride,
226707
- fetchOverride: dumpPromptsFetch,
226715
+ fetchOverride: toolUseContext.options.fetchOverride,
226708
226716
  mcpTools: appState.mcp.tools,
226709
226717
  hasPendingMcpServers: appState.mcp.clients.some((c) => c.type === "pending"),
226710
226718
  queryTracking,
@@ -227383,7 +227391,7 @@ function getAnthropicEnvMetadata() {
227383
227391
  function getBuildAgeMinutes() {
227384
227392
  if (false)
227385
227393
  ;
227386
- const buildTime = new Date("2026-10-24T12:55:52.344Z").getTime();
227394
+ const buildTime = new Date("2026-11-04T12:30:46.458Z").getTime();
227387
227395
  if (isNaN(buildTime))
227388
227396
  return;
227389
227397
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -271008,6 +271016,7 @@ class QueryEngine {
271008
271016
  maxOutputTokensLimit,
271009
271017
  contextWindow,
271010
271018
  modelProviders: this.config.modelProviders,
271019
+ fetchOverride: this.config.fetchOverride,
271011
271020
  subagentDisallowedTools: this.config.subagentDisallowedTools,
271012
271021
  preDecidePermissions
271013
271022
  },
@@ -271107,6 +271116,7 @@ class QueryEngine {
271107
271116
  maxOutputTokensLimit,
271108
271117
  contextWindow,
271109
271118
  modelProviders: this.config.modelProviders,
271119
+ fetchOverride: this.config.fetchOverride,
271110
271120
  subagentDisallowedTools: this.config.subagentDisallowedTools,
271111
271121
  preDecidePermissions
271112
271122
  },
@@ -271616,6 +271626,7 @@ async function* ask({
271616
271626
  userSpecifiedModel,
271617
271627
  fallbackModel,
271618
271628
  modelProviders,
271629
+ fetchOverride,
271619
271630
  jsonSchema,
271620
271631
  getAppState,
271621
271632
  setAppState,
@@ -271646,6 +271657,7 @@ async function* ask({
271646
271657
  userSpecifiedModel,
271647
271658
  fallbackModel,
271648
271659
  modelProviders,
271660
+ fetchOverride,
271649
271661
  thinkingConfig,
271650
271662
  maxTurns,
271651
271663
  maxBudgetUsd,
@@ -279288,6 +279300,7 @@ function runSdkQueryRuntime(params) {
279288
279300
  fallbackModel: typeof options.fallbackModel === "string" && options.fallbackModel.length > 0 ? options.fallbackModel : undefined,
279289
279301
  jsonSchema: options.jsonSchema && typeof options.jsonSchema === "object" ? options.jsonSchema : undefined,
279290
279302
  modelProviders: options.modelProviders && typeof options.modelProviders === "object" ? options.modelProviders : undefined,
279303
+ fetchOverride: typeof options.fetchOverride === "function" ? options.fetchOverride : undefined,
279291
279304
  getAppState: appStateStore.getAppState,
279292
279305
  setAppState: appStateStore.setAppState,
279293
279306
  abortController: runtimeState.abortController,
@@ -280615,4 +280628,4 @@ export {
280615
280628
  watchScheduledTasks
280616
280629
  };
280617
280630
 
280618
- //# debugId=FB4FE49FF3A1776C64756E2164756E21
280631
+ //# debugId=12B4F50CE40DB29164756E2164756E21
@@ -124,6 +124,8 @@ export type ToolRuntimeContext = {
124
124
  * wire/endpoint than the main session gets its own provider override.
125
125
  */
126
126
  modelProviders?: ModelProviders;
127
+ /** Host fetch for model requests (see Options.fetchOverride); propagated to subagents. */
128
+ fetchOverride?: typeof globalThis.fetch;
127
129
  /**
128
130
  * Tool names excluded from sub-agents only (see Options.subagentDisallowedTools).
129
131
  * Applied by runAgent via filterSubagentDisallowedTools and propagated to
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opencow-ai/opencow-agent-sdk",
3
- "version": "0.4.28",
3
+ "version": "0.4.30",
4
4
  "description": "Claude Code opened to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models",
5
5
  "type": "module",
6
6
  "main": "./dist/sdk.js",