@opencow-ai/opencow-agent-sdk 0.4.13 → 0.4.15

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
@@ -83882,6 +83882,48 @@ var init_proxy = __esm(() => {
83882
83882
  });
83883
83883
  });
83884
83884
 
83885
+ // src/providers/shared/httpObservability.ts
83886
+ function classifyModelHttpEndpoint(url3) {
83887
+ try {
83888
+ const pathname = new URL(url3).pathname.replace(/\/+$/, "");
83889
+ if (pathname.endsWith("/messages/count_tokens"))
83890
+ return "count_tokens";
83891
+ if (pathname.endsWith("/chat/completions"))
83892
+ return "messages";
83893
+ if (pathname.endsWith("/messages"))
83894
+ return "messages";
83895
+ if (pathname.endsWith("/responses"))
83896
+ return "responses";
83897
+ return pathname || "unknown";
83898
+ } catch {
83899
+ return "unknown";
83900
+ }
83901
+ }
83902
+ function errorToFailureReason(error41) {
83903
+ if (error41 instanceof Error)
83904
+ return error41.message;
83905
+ return String(error41);
83906
+ }
83907
+ function responseBodyToFailureReason(status, body) {
83908
+ let detail = body.trim();
83909
+ try {
83910
+ const parsed = JSON.parse(body);
83911
+ const message = typeof parsed.error?.message === "string" ? parsed.error.message : typeof parsed.message === "string" ? parsed.message : undefined;
83912
+ const code = typeof parsed.error?.code === "string" ? parsed.error.code : typeof parsed.error?.type === "string" ? parsed.error.type : undefined;
83913
+ detail = [code, message].filter(Boolean).join(": ") || detail;
83914
+ } catch {}
83915
+ const compact = detail.replace(/\s+/g, " ").slice(0, 240);
83916
+ return compact ? `HTTP ${status}: ${compact}` : `HTTP ${status}`;
83917
+ }
83918
+ function emitSdkHttp(event) {
83919
+ try {
83920
+ emitHttp(event);
83921
+ } catch {}
83922
+ }
83923
+ var init_httpObservability = __esm(() => {
83924
+ init_observer();
83925
+ });
83926
+
83885
83927
  // src/providers/shared/geminiAuth.ts
83886
83928
  import { homedir as homedir10 } from "node:os";
83887
83929
  import { join as join23 } from "node:path";
@@ -84582,6 +84624,44 @@ var init_capabilities2 = __esm(() => {
84582
84624
  ]);
84583
84625
  });
84584
84626
 
84627
+ // src/providers/shared/requestSideChannels.ts
84628
+ function isRecord(value) {
84629
+ return typeof value === "object" && value !== null && !Array.isArray(value);
84630
+ }
84631
+ function parseJsonObject(raw) {
84632
+ if (!raw)
84633
+ return;
84634
+ try {
84635
+ const parsed = JSON.parse(raw);
84636
+ return isRecord(parsed) ? parsed : undefined;
84637
+ } catch {
84638
+ return;
84639
+ }
84640
+ }
84641
+ function readExplicitExtraBodyParams() {
84642
+ return parseJsonObject(getQueryEnvVar(QUERY_ENV_KEY_EXTRA_BODY)) ?? parseJsonObject(resolveEnvVar("EXTRA_BODY"));
84643
+ }
84644
+ function mergeOpenAICompatibleExtraBodyParams(body, params) {
84645
+ const extra = {};
84646
+ const shouldMerge = (key, value) => value !== undefined && !(key in body);
84647
+ const explicitExtraBody = readExplicitExtraBodyParams();
84648
+ if (explicitExtraBody) {
84649
+ Object.assign(extra, explicitExtraBody);
84650
+ }
84651
+ const nestedExtraBody = params.extra_body;
84652
+ if (isRecord(nestedExtraBody)) {
84653
+ Object.assign(extra, nestedExtraBody);
84654
+ }
84655
+ for (const [key, value] of Object.entries(extra)) {
84656
+ if (shouldMerge(key, value))
84657
+ body[key] = value;
84658
+ }
84659
+ }
84660
+ var init_requestSideChannels = __esm(() => {
84661
+ init_state2();
84662
+ init_config3();
84663
+ });
84664
+
84585
84665
  // src/providers/codex/shim.ts
84586
84666
  function parseSseChunk(chunk) {
84587
84667
  const lines = chunk.split(`
@@ -84930,6 +85010,7 @@ async function performCodexRequest(options) {
84930
85010
  body.top_p = options.params.top_p;
84931
85011
  }
84932
85012
  }
85013
+ mergeOpenAICompatibleExtraBodyParams(body, options.params);
84933
85014
  const headers = {
84934
85015
  "Content-Type": "application/json",
84935
85016
  ...options.defaultHeaders,
@@ -85301,6 +85382,7 @@ var init_shim = __esm(() => {
85301
85382
  init_sdk();
85302
85383
  init_schema();
85303
85384
  init_capabilities2();
85385
+ init_requestSideChannels();
85304
85386
  init_canonical();
85305
85387
  });
85306
85388
 
@@ -85423,7 +85505,7 @@ function convertContentBlocks(content) {
85423
85505
  return parts[0].text ?? "";
85424
85506
  return parts;
85425
85507
  }
85426
- function convertMessages(messages, system) {
85508
+ function convertMessages(messages, system, options = {}) {
85427
85509
  const result = [];
85428
85510
  const sysText = convertSystemPrompt2(system);
85429
85511
  if (sysText) {
@@ -85486,7 +85568,7 @@ function convertMessages(messages, system) {
85486
85568
  return text || null;
85487
85569
  })()
85488
85570
  };
85489
- if (thinkingBlocks.length > 0) {
85571
+ if (options.replayReasoningContent !== false && thinkingBlocks.length > 0) {
85490
85572
  const reasoningText = thinkingBlocks.map((b) => b.thinking ?? "").filter(Boolean).join(`
85491
85573
  `);
85492
85574
  if (reasoningText) {
@@ -85619,7 +85701,8 @@ function serializeParallelToolCalls(messages, capabilities) {
85619
85701
  }
85620
85702
  function buildOpenAIRequestBody(params, ctx) {
85621
85703
  const capabilities = getOpenAIChatProviderCapabilities(ctx.resolvedModel);
85622
- const openaiMessages = serializeParallelToolCalls(convertMessages(params.messages, params.system), capabilities);
85704
+ const replayReasoningContent = !isGeminiTarget(ctx.resolvedModel);
85705
+ const openaiMessages = serializeParallelToolCalls(convertMessages(params.messages, params.system, { replayReasoningContent }), capabilities);
85623
85706
  const body = {
85624
85707
  model: ctx.resolvedModel,
85625
85708
  messages: openaiMessages,
@@ -85670,6 +85753,7 @@ function buildOpenAIRequestBody(params, ctx) {
85670
85753
  }
85671
85754
  }
85672
85755
  }
85756
+ mergeOpenAICompatibleExtraBodyParams(body, params);
85673
85757
  return body;
85674
85758
  }
85675
85759
  async function* openaiStreamToAnthropic(response, model) {
@@ -85996,10 +86080,12 @@ class OpenAIShimMessages {
85996
86080
  defaultHeaders;
85997
86081
  reasoningEffort;
85998
86082
  providerOverride;
85999
- constructor(defaultHeaders, reasoningEffort, providerOverride) {
86083
+ source;
86084
+ constructor(defaultHeaders, reasoningEffort, providerOverride, source) {
86000
86085
  this.defaultHeaders = defaultHeaders;
86001
86086
  this.reasoningEffort = reasoningEffort;
86002
86087
  this.providerOverride = providerOverride;
86088
+ this.source = source;
86003
86089
  }
86004
86090
  create(params, options) {
86005
86091
  const self2 = this;
@@ -86134,28 +86220,93 @@ class OpenAIShimMessages {
86134
86220
  signal: options?.signal
86135
86221
  };
86136
86222
  const maxAttempts = isGithub ? GITHUB_429_MAX_RETRIES : 1;
86223
+ const endpoint = classifyModelHttpEndpoint(chatCompletionsUrl);
86137
86224
  let response;
86138
86225
  for (let attempt = 0;attempt < maxAttempts; attempt++) {
86226
+ const attemptNumber = attempt + 1;
86227
+ const requestId = `req_${crypto.randomUUID().replace(/-/g, "")}`;
86228
+ const requestStartedAt = Date.now();
86229
+ emitSdkHttp({
86230
+ type: "request_start",
86231
+ requestId,
86232
+ method: fetchInit.method,
86233
+ url: chatCompletionsUrl,
86234
+ source: this.source,
86235
+ endpoint,
86236
+ attempt: attemptNumber,
86237
+ maxAttempts,
86238
+ timestamp: requestStartedAt
86239
+ });
86139
86240
  try {
86140
86241
  response = await fetch(chatCompletionsUrl, fetchInit);
86141
86242
  } catch (fetchErr) {
86142
86243
  const msg = fetchErr instanceof Error ? `${fetchErr.message}${fetchErr.cause ? ` (${fetchErr.cause?.code ?? fetchErr.cause?.message ?? ""})` : ""}` : String(fetchErr);
86244
+ emitSdkHttp({
86245
+ type: "error",
86246
+ requestId,
86247
+ error: fetchErr instanceof Error ? fetchErr : new Error(String(fetchErr)),
86248
+ durationMs: Date.now() - requestStartedAt,
86249
+ source: this.source,
86250
+ endpoint,
86251
+ attempt: attemptNumber,
86252
+ maxAttempts,
86253
+ failureReason: msg,
86254
+ timestamp: Date.now()
86255
+ });
86143
86256
  throw new APIConnectionError({
86144
86257
  message: `OpenAI-compat connection failed: ${msg}`,
86145
86258
  cause: fetchErr
86146
86259
  });
86147
86260
  }
86148
86261
  if (response.ok) {
86262
+ emitSdkHttp({
86263
+ type: "response_start",
86264
+ requestId,
86265
+ status: response.status,
86266
+ durationMs: Date.now() - requestStartedAt,
86267
+ source: this.source,
86268
+ endpoint,
86269
+ attempt: attemptNumber,
86270
+ maxAttempts,
86271
+ timestamp: Date.now()
86272
+ });
86149
86273
  return response;
86150
86274
  }
86151
86275
  if (isGithub && response.status === 429 && attempt < maxAttempts - 1) {
86152
86276
  await response.text().catch(() => {});
86153
86277
  const delaySec = Math.min(GITHUB_429_BASE_DELAY_SEC * 2 ** attempt, GITHUB_429_MAX_DELAY_SEC);
86278
+ emitSdkHttp({
86279
+ type: "response_start",
86280
+ requestId,
86281
+ status: response.status,
86282
+ durationMs: Date.now() - requestStartedAt,
86283
+ source: this.source,
86284
+ endpoint,
86285
+ attempt: attemptNumber,
86286
+ maxAttempts,
86287
+ willRetry: true,
86288
+ retryDelayMs: delaySec * 1000,
86289
+ failureReason: `HTTP ${response.status}${formatRetryAfterHint(response)}`,
86290
+ timestamp: Date.now()
86291
+ });
86154
86292
  await sleepMs(delaySec * 1000);
86155
86293
  continue;
86156
86294
  }
86157
86295
  const errorBody = await response.text().catch(() => "unknown error");
86158
86296
  const rateHint = isGithub && response.status === 429 ? formatRetryAfterHint(response) : "";
86297
+ const failureReason = `${responseBodyToFailureReason(response.status, errorBody)}${rateHint}`;
86298
+ emitSdkHttp({
86299
+ type: "response_start",
86300
+ requestId,
86301
+ status: response.status,
86302
+ durationMs: Date.now() - requestStartedAt,
86303
+ source: this.source,
86304
+ endpoint,
86305
+ attempt: attemptNumber,
86306
+ maxAttempts,
86307
+ failureReason,
86308
+ timestamp: Date.now()
86309
+ });
86159
86310
  let errorResponse;
86160
86311
  try {
86161
86312
  errorResponse = JSON.parse(errorBody);
@@ -86244,8 +86395,8 @@ function convertOpenAIResponseToAnthropic(data, model) {
86244
86395
  class OpenAIShimBeta {
86245
86396
  messages;
86246
86397
  reasoningEffort;
86247
- constructor(defaultHeaders, reasoningEffort, providerOverride) {
86248
- this.messages = new OpenAIShimMessages(defaultHeaders, reasoningEffort, providerOverride);
86398
+ constructor(defaultHeaders, reasoningEffort, providerOverride, source) {
86399
+ this.messages = new OpenAIShimMessages(defaultHeaders, reasoningEffort, providerOverride, source);
86249
86400
  this.reasoningEffort = reasoningEffort;
86250
86401
  }
86251
86402
  }
@@ -86267,7 +86418,7 @@ function createOpenAIShimClient(options) {
86267
86418
  }
86268
86419
  const beta = new OpenAIShimBeta({
86269
86420
  ...options.defaultHeaders ?? {}
86270
- }, options.reasoningEffort, options.providerOverride);
86421
+ }, options.reasoningEffort, options.providerOverride, options.source);
86271
86422
  return {
86272
86423
  beta,
86273
86424
  messages: beta.messages
@@ -86286,7 +86437,9 @@ var init_shim2 = __esm(() => {
86286
86437
  init_schemaSanitizer();
86287
86438
  init_providerProfile();
86288
86439
  init_capabilities2();
86440
+ init_httpObservability();
86289
86441
  init_canonical();
86442
+ init_requestSideChannels();
86290
86443
  OpenAIShimStream = class OpenAIShimStream {
86291
86444
  generator;
86292
86445
  controller = new AbortController;
@@ -86383,7 +86536,8 @@ async function getNormalizedClient({
86383
86536
  defaultHeaders: safeHeaders,
86384
86537
  maxRetries,
86385
86538
  timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10),
86386
- providerOverride
86539
+ providerOverride,
86540
+ source
86387
86541
  });
86388
86542
  }
86389
86543
  const transportOverride = getQueryEnvVar(QUERY_ENV_KEY_TRANSPORT_OVERRIDE);
@@ -86393,7 +86547,8 @@ async function getNormalizedClient({
86393
86547
  return createOpenAIShimClient2({
86394
86548
  defaultHeaders,
86395
86549
  maxRetries,
86396
- timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10)
86550
+ timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10),
86551
+ source
86397
86552
  });
86398
86553
  }
86399
86554
  const stagingOauthBaseUrl = process.env.USER_TYPE === "ant" && isEnvTruthy(process.env.USE_STAGING_OAUTH) ? getOauthConfig().BASE_API_URL : undefined;
@@ -86445,42 +86600,49 @@ function buildFetch(fetchOverride, source) {
86445
86600
  const url3 = input instanceof Request ? input.url : String(input);
86446
86601
  const method = init?.method ?? (input instanceof Request ? input.method : "GET");
86447
86602
  const requestId = headers.get(CLIENT_REQUEST_ID_HEADER) ?? randomUUID();
86603
+ const endpoint = classifyModelHttpEndpoint(url3);
86448
86604
  try {
86449
86605
  logForDebugging2(`[API REQUEST] ${new URL(url3).pathname} ${CLIENT_REQUEST_ID_HEADER}=${requestId} source=${source ?? "unknown"}`);
86450
86606
  } catch {}
86451
86607
  const requestStartedAt = Date.now();
86608
+ emitSdkHttp({
86609
+ type: "request_start",
86610
+ requestId,
86611
+ method,
86612
+ url: url3,
86613
+ source,
86614
+ endpoint,
86615
+ attempt: 1,
86616
+ maxAttempts: 1,
86617
+ timestamp: requestStartedAt
86618
+ });
86452
86619
  try {
86453
- emitHttp({
86454
- type: "request_start",
86620
+ const response = await inner(input, { ...init, headers });
86621
+ emitSdkHttp({
86622
+ type: "response_start",
86455
86623
  requestId,
86456
- method,
86457
- url: url3,
86624
+ status: response.status,
86625
+ durationMs: Date.now() - requestStartedAt,
86458
86626
  source,
86459
- timestamp: requestStartedAt
86627
+ endpoint,
86628
+ attempt: 1,
86629
+ maxAttempts: 1,
86630
+ timestamp: Date.now()
86460
86631
  });
86461
- } catch {}
86462
- try {
86463
- const response = await inner(input, { ...init, headers });
86464
- try {
86465
- emitHttp({
86466
- type: "response_start",
86467
- requestId,
86468
- status: response.status,
86469
- durationMs: Date.now() - requestStartedAt,
86470
- timestamp: Date.now()
86471
- });
86472
- } catch {}
86473
86632
  return response;
86474
86633
  } catch (err) {
86475
- try {
86476
- emitHttp({
86477
- type: "error",
86478
- requestId,
86479
- error: err instanceof Error ? err : new Error(String(err)),
86480
- durationMs: Date.now() - requestStartedAt,
86481
- timestamp: Date.now()
86482
- });
86483
- } catch {}
86634
+ emitSdkHttp({
86635
+ type: "error",
86636
+ requestId,
86637
+ error: err instanceof Error ? err : new Error(String(err)),
86638
+ durationMs: Date.now() - requestStartedAt,
86639
+ source,
86640
+ endpoint,
86641
+ attempt: 1,
86642
+ maxAttempts: 1,
86643
+ failureReason: errorToFailureReason(err),
86644
+ timestamp: Date.now()
86645
+ });
86484
86646
  throw err;
86485
86647
  }
86486
86648
  };
@@ -86499,7 +86661,7 @@ var init_clientFactory = __esm(() => {
86499
86661
  init_oauth();
86500
86662
  init_debug();
86501
86663
  init_envUtils();
86502
- init_observer();
86664
+ init_httpObservability();
86503
86665
  });
86504
86666
 
86505
86667
  // src/providers/anthropic/index.ts
@@ -92725,7 +92887,8 @@ function normalizeGithubModelsApiModel(requestedModel) {
92725
92887
  return segment;
92726
92888
  }
92727
92889
  function resolveProviderTransport(options) {
92728
- const rawBaseUrl = asEnvUrl(options?.baseUrl) ?? asEnvUrl(getQueryEnvVar("OPENAI_BASE_URL")) ?? asEnvUrl(getQueryEnvVar("OPENAI_API_BASE"));
92890
+ const optionBaseUrl = asEnvUrl(options?.baseUrl);
92891
+ const rawBaseUrl = optionBaseUrl ?? asEnvUrl(getQueryEnvVar("OPENAI_BASE_URL")) ?? asEnvUrl(getQueryEnvVar("OPENAI_API_BASE"));
92729
92892
  const envOverride = options?.transportOverride ?? getQueryEnvVar(QUERY_ENV_KEY_TRANSPORT_OVERRIDE);
92730
92893
  if (envOverride && envOverride !== "auto") {
92731
92894
  let normalized;
@@ -92735,7 +92898,8 @@ function resolveProviderTransport(options) {
92735
92898
  } else {
92736
92899
  normalized = envOverride;
92737
92900
  }
92738
- const baseUrl2 = (rawBaseUrl ?? (normalized === "openai_responses" ? DEFAULT_CODEX_BASE_URL : DEFAULT_OPENAI_BASE_URL)).replace(/\/+$/, "");
92901
+ const baseUrlSource = rawBaseUrl ?? (normalized === "openai_responses" ? DEFAULT_CODEX_BASE_URL : DEFAULT_OPENAI_BASE_URL);
92902
+ const baseUrl2 = baseUrlSource.replace(/\/+$/, "");
92739
92903
  return { transport: normalized, baseUrl: baseUrl2 };
92740
92904
  }
92741
92905
  const modelForDetection = options?.model?.trim() ?? "";
@@ -92870,7 +93034,7 @@ function getReasoningEffortForModel(model) {
92870
93034
  const aliasConfig = CODEX_ALIAS_MODELS[alias];
92871
93035
  return aliasConfig?.reasoningEffort;
92872
93036
  }
92873
- var DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1", DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex", DEFAULT_GITHUB_MODELS_API_MODEL = "openai/gpt-4.1", CODEX_ALIAS_MODELS, QUERY_ENV_KEY_TRANSPORT_OVERRIDE = "__OPENCOW_TRANSPORT_OVERRIDE", QUERY_ENV_KEY_REASONING_EFFORT_OVERRIDE = "__OPENCOW_REASONING_EFFORT_OVERRIDE", QUERY_ENV_VALUE_REASONING_EFFORT_CLEAR = "__OPENCOW_CLEAR_REASONING_EFFORT__", QUERY_ENV_KEY_PROVIDER_SPECIFIC_OPENAI_RESPONSES = "__OPENCOW_PROVIDER_SPECIFIC_OPENAI_RESPONSES", LOCALHOST_HOSTNAMES, warnedCodexAliasOnce = false, MissingProviderModelError;
93037
+ var DEFAULT_OPENAI_BASE_URL = "https://api.openai.com/v1", DEFAULT_CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex", DEFAULT_GITHUB_MODELS_API_MODEL = "openai/gpt-4.1", CODEX_ALIAS_MODELS, QUERY_ENV_KEY_TRANSPORT_OVERRIDE = "__OPENCOW_TRANSPORT_OVERRIDE", QUERY_ENV_KEY_REASONING_EFFORT_OVERRIDE = "__OPENCOW_REASONING_EFFORT_OVERRIDE", QUERY_ENV_VALUE_REASONING_EFFORT_CLEAR = "__OPENCOW_CLEAR_REASONING_EFFORT__", QUERY_ENV_KEY_PROVIDER_SPECIFIC_OPENAI_RESPONSES = "__OPENCOW_PROVIDER_SPECIFIC_OPENAI_RESPONSES", QUERY_ENV_KEY_EXTRA_BODY = "__OPENCOW_EXTRA_BODY", LOCALHOST_HOSTNAMES, warnedCodexAliasOnce = false, MissingProviderModelError;
92874
93038
  var init_config3 = __esm(() => {
92875
93039
  init_envUtils();
92876
93040
  init_state2();
@@ -94534,7 +94698,7 @@ function printStartupScreen() {
94534
94698
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
94535
94699
  out.push(boxRow(sRow, W2, sLen));
94536
94700
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
94537
- out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.13"}${RESET}`);
94701
+ out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.15"}${RESET}`);
94538
94702
  out.push("");
94539
94703
  process.stdout.write(out.join(`
94540
94704
  `) + `
@@ -96200,6 +96364,11 @@ var FINGERPRINT_SALT = "59cf53e54c78";
96200
96364
  var init_fingerprint = () => {};
96201
96365
 
96202
96366
  // src/session/sideQuery.ts
96367
+ function headersForBetas(betas) {
96368
+ if (!betas || betas.length === 0)
96369
+ return;
96370
+ return { "anthropic-beta": betas.join(",") };
96371
+ }
96203
96372
  function extractFirstUserMessageText(messages) {
96204
96373
  const firstUserMessage = messages.find((m) => m.role === "user");
96205
96374
  if (!firstUserMessage)
@@ -96262,7 +96431,7 @@ async function sideQuery(opts) {
96262
96431
  }
96263
96432
  const normalizedModel = normalizeModelStringForAPI(model);
96264
96433
  const start = Date.now();
96265
- const response = await client.beta.messages.create({
96434
+ const response = await client.messages.create({
96266
96435
  model: normalizedModel,
96267
96436
  max_tokens,
96268
96437
  system: systemBlocks,
@@ -96273,9 +96442,12 @@ async function sideQuery(opts) {
96273
96442
  ...temperature !== undefined && { temperature },
96274
96443
  ...stop_sequences && { stop_sequences },
96275
96444
  ...thinkingConfig && { thinking: thinkingConfig },
96276
- ...betas.length > 0 && { betas },
96277
- metadata: getAPIMetadata()
96278
- }, { signal });
96445
+ metadata: getAPIMetadata(),
96446
+ ...getExtraBodyParams()
96447
+ }, {
96448
+ signal,
96449
+ ...betas.length > 0 ? { headers: headersForBetas(betas) } : {}
96450
+ });
96279
96451
  const requestId = response._request_id ?? undefined;
96280
96452
  const now = Date.now();
96281
96453
  const lastCompletion = getLastApiCompletionTimestamp();
@@ -147253,12 +147425,13 @@ async function makeTestQuery() {
147253
147425
  });
147254
147426
  const messages = [{ role: "user", content: "quota" }];
147255
147427
  const betas = getModelBetas(model);
147256
- return anthropic.beta.messages.create({
147428
+ return anthropic.messages.create({
147257
147429
  model,
147258
147430
  max_tokens: 1,
147259
147431
  messages,
147260
- metadata: getAPIMetadata(),
147261
- ...betas.length > 0 ? { betas } : {}
147432
+ metadata: getAPIMetadata()
147433
+ }, {
147434
+ ...betas.length > 0 ? { headers: { "anthropic-beta": betas.join(",") } } : {}
147262
147435
  }).asResponse();
147263
147436
  }
147264
147437
  async function checkQuotaStatus() {
@@ -148415,6 +148588,17 @@ async function* withRetry(getClient, operation, options2) {
148415
148588
  status: error41.status,
148416
148589
  provider: getAPIProviderForStatsig()
148417
148590
  });
148591
+ emitSdkHttp({
148592
+ type: "retry",
148593
+ source: options2.querySource,
148594
+ endpoint: "messages",
148595
+ attempt: reportedAttempt,
148596
+ ...persistent ? {} : { maxAttempts: maxRetries + 1 },
148597
+ retryDelayMs: delayMs,
148598
+ status: error41 instanceof APIError ? error41.status : undefined,
148599
+ failureReason: errorToFailureReason(error41),
148600
+ timestamp: Date.now()
148601
+ });
148418
148602
  if (persistent) {
148419
148603
  if (delayMs > 60000) {
148420
148604
  logEvent("tengu_api_persistent_retry_wait", {
@@ -148668,6 +148852,7 @@ var init_retry = __esm(() => {
148668
148852
  init_mocking();
148669
148853
  init_errors8();
148670
148854
  init_errorUtils();
148855
+ init_httpObservability();
148671
148856
  FOREGROUND_529_RETRY_SOURCES = new Set([
148672
148857
  "repl_main_thread",
148673
148858
  "repl_main_thread:outputStyle:custom",
@@ -244434,7 +244619,7 @@ function getAnthropicEnvMetadata() {
244434
244619
  function getBuildAgeMinutes() {
244435
244620
  if (false)
244436
244621
  ;
244437
- const buildTime = new Date("2026-06-25T12:29:02.938Z").getTime();
244622
+ const buildTime = new Date("2026-07-07T09:41:37.769Z").getTime();
244438
244623
  if (isNaN(buildTime))
244439
244624
  return;
244440
244625
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -246008,6 +246193,27 @@ function isResultSuccessful(message, stopReason = null) {
246008
246193
  }
246009
246194
  return stopReason === "end_turn";
246010
246195
  }
246196
+ function buildErrorDuringExecutionDiagnostic({
246197
+ resultType,
246198
+ lastContentType,
246199
+ stopReason
246200
+ }) {
246201
+ return `${ERROR_DURING_EXECUTION_DIAGNOSTIC_PREFIX} result_type=${resultType} last_content_type=${lastContentType} stop_reason=${stopReason}`;
246202
+ }
246203
+ function buildErrorDuringExecutionErrors({
246204
+ recentErrors,
246205
+ stopReason
246206
+ }) {
246207
+ const visibleErrors = recentErrors.filter((error41) => !error41.startsWith(ERROR_DURING_EXECUTION_DIAGNOSTIC_PREFIX));
246208
+ if (visibleErrors.length > 0)
246209
+ return visibleErrors;
246210
+ if (stopReason === "tool_use") {
246211
+ return [
246212
+ "The upstream model requested a tool but did not produce a final assistant response after the tool result."
246213
+ ];
246214
+ }
246215
+ return ["The upstream model stopped before producing a final assistant response."];
246216
+ }
246011
246217
  function normalizeUserMessageForSdk(message) {
246012
246218
  const content = message.content;
246013
246219
  if (!Array.isArray(content))
@@ -246312,7 +246518,7 @@ function extractCliName(command) {
246312
246518
  }
246313
246519
  return;
246314
246520
  }
246315
- var ASK_READ_FILE_STATE_CACHE_SIZE = 10, MAX_TOOL_PROGRESS_TRACKING_ENTRIES = 100, TOOL_PROGRESS_THROTTLE_MS = 30000, toolProgressLastSentTime, STRIPPED_COMMANDS;
246521
+ var ASK_READ_FILE_STATE_CACHE_SIZE = 10, ERROR_DURING_EXECUTION_DIAGNOSTIC_PREFIX = "[ede_diagnostic]", MAX_TOOL_PROGRESS_TRACKING_ENTRIES = 100, TOOL_PROGRESS_THROTTLE_MS = 30000, toolProgressLastSentTime, STRIPPED_COMMANDS;
246316
246522
  var init_queryHelpers = __esm(() => {
246317
246523
  init_last();
246318
246524
  init_state();
@@ -264902,49 +265108,36 @@ assistant: Still waiting on the audit — that's one of the things it's checking
264902
265108
 
264903
265109
  <example>
264904
265110
  user: "Can you get a second opinion on whether this migration is safe?"
264905
- assistant: <thinking>I'll ask the code-reviewer agent it won't see my analysis, so it can give an independent read.</thinking>
265111
+ assistant: <thinking>Forking this review keeps the detailed audit out of my context while I keep steering the work.</thinking>
264906
265112
  <commentary>
264907
- A subagent_type is specified, so the agent starts fresh. It needs full context in the prompt. The briefing explains what to assess and why.
265113
+ No subagent_type is specified, so this uses the fork path. If you do specify subagent_type, copy an exact type from the available agent list; never invent one from an example.
264908
265114
  </commentary>
264909
265115
  ${AGENT_TOOL_NAME2}({
264910
265116
  name: "migration-review",
264911
265117
  description: "Independent migration review",
264912
- subagent_type: "code-reviewer",
264913
265118
  prompt: "Review migration 0042_user_schema.sql for safety. Context: we're adding a NOT NULL column to a 50M-row table. Existing rows get a backfill default. I want a second opinion on whether the backfill approach is safe under concurrent writes — I've checked locking behavior but want independent verification. Report: is this safe, and if not, what specifically breaks?"
264914
265119
  })
264915
265120
  </example>
264916
265121
  `;
264917
265122
  const currentExamples = `Example usage:
264918
265123
 
264919
- <example_agent_descriptions>
264920
- "test-runner": use this agent after you are done writing code to run tests
264921
- "greeting-responder": use this agent to respond to user greetings with a friendly joke
264922
- </example_agent_descriptions>
264923
-
264924
265124
  <example>
264925
- user: "Please write a function that checks if a number is prime"
264926
- assistant: I'm going to use the ${FILE_WRITE_TOOL_NAME2} tool to write the following code:
264927
- <code>
264928
- function isPrime(n) {
264929
- if (n <= 1) return false
264930
- for (let i = 2; i * i <= n; i++) {
264931
- if (n % i === 0) return false
264932
- }
264933
- return true
264934
- }
264935
- </code>
265125
+ user: "Hello"
264936
265126
  <commentary>
264937
- Since a significant piece of code was written and the task was completed, now use the test-runner agent to run the tests
265127
+ Do not use the ${AGENT_TOOL_NAME2} tool for a simple greeting or a short reply. Answer directly.
264938
265128
  </commentary>
264939
- assistant: Uses the ${AGENT_TOOL_NAME2} tool to launch the test-runner agent
265129
+ assistant: "Hi! Nice to see you. What shall we work on today?"
264940
265130
  </example>
264941
265131
 
264942
265132
  <example>
264943
- user: "Hello"
265133
+ user: "Can you investigate whether this migration is safe?"
264944
265134
  <commentary>
264945
- Since the user is greeting, use the greeting-responder agent to respond with a friendly joke
265135
+ This is a multi-step review, so the ${AGENT_TOOL_NAME2} tool can help. Omit subagent_type to use the default general-purpose agent, or specify a subagent_type only by copying an exact type from the available agent list.
264946
265136
  </commentary>
264947
- assistant: "I'm going to use the ${AGENT_TOOL_NAME2} tool to launch the greeting-responder agent"
265137
+ ${AGENT_TOOL_NAME2}({
265138
+ description: "Review migration safety",
265139
+ prompt: "Review migration 0042_user_schema.sql for safety. Context: we're adding a NOT NULL column to a 50M-row table. Existing rows get a backfill default. Check whether the backfill approach is safe under concurrent writes. Report: is this safe, and if not, what specifically breaks?"
265140
+ })
264948
265141
  </example>
264949
265142
  `;
264950
265143
  const listViaAttachment = shouldInjectAgentListInMessages();
@@ -264957,7 +265150,7 @@ The ${AGENT_TOOL_NAME2} tool launches specialized agents (subprocesses) that aut
264957
265150
 
264958
265151
  ${agentListSection}
264959
265152
 
264960
- ${forkEnabled ? `When using the ${AGENT_TOOL_NAME2} tool, specify a subagent_type to use a specialized agent, or omit it to fork yourself — a fork inherits your full conversation context.` : `When using the ${AGENT_TOOL_NAME2} tool, specify a subagent_type parameter to select which agent type to use. If omitted, the general-purpose agent is used.`}`;
265153
+ ${forkEnabled ? `When using the ${AGENT_TOOL_NAME2} tool, specify a subagent_type to use a specialized agent, or omit it to fork yourself — a fork inherits your full conversation context. Only use subagent_type values that appear in the available agent types; never invent an agent type from an example.` : `When using the ${AGENT_TOOL_NAME2} tool, specify a subagent_type parameter to select which agent type to use. If omitted, the general-purpose agent is used. Only use subagent_type values that appear in the available agent types; never invent an agent type from an example.`}`;
264961
265154
  if (isCoordinator) {
264962
265155
  return shared2;
264963
265156
  }
@@ -264985,7 +265178,7 @@ Usage notes:
264985
265178
  - The agent's outputs should generally be trusted
264986
265179
  - Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.)${forkEnabled ? "" : ", since it is not aware of the user's intent"}
264987
265180
  - If the agent description mentions that it should be used proactively, then you should try your best to use it without the user having to ask for it first. Use your judgement.
264988
- - If the user specifies that they want you to run agents "in parallel", you MUST send a single message with multiple ${AGENT_TOOL_NAME2} tool use content blocks. For example, if you need to launch both a build-validator agent and a test-runner agent in parallel, send a single message with both tool calls.
265181
+ - If the user specifies that they want you to run agents "in parallel", you MUST send a single message with multiple ${AGENT_TOOL_NAME2} tool use content blocks. Each call must either omit subagent_type or use an exact type from the available agent list.
264989
265182
  - You can optionally set \`isolation: "worktree"\` to run the agent in a temporary git worktree, giving it an isolated copy of the repository. The worktree is automatically cleaned up if the agent makes no changes; if changes are made, the worktree path and branch are returned in the result.${process.env.USER_TYPE === "ant" ? `
264990
265183
  - You can set \`isolation: "remote"\` to run the agent in a remote CCR environment. This is always a background task; you'll be notified when it completes. Use for long-running tasks that need a fresh sandbox.` : ""}${isInProcessTeammate() ? `
264991
265184
  - The run_in_background, name, team_name, and mode parameters are not available in this context. Only synchronous subagents are supported.` : isTeammate() ? `
@@ -265000,7 +265193,6 @@ var init_prompt8 = __esm(() => {
265000
265193
  init_teammate();
265001
265194
  init_teammateContext();
265002
265195
  init_prompt();
265003
- init_prompt2();
265004
265196
  init_constants4();
265005
265197
  init_forkSubagent();
265006
265198
  init_state2();
@@ -288417,7 +288609,7 @@ async function loadPluginSettings(pluginPath, manifest) {
288417
288609
  try {
288418
288610
  const content = await getFsImplementation().readFile(settingsJsonPath, { encoding: "utf-8" });
288419
288611
  const parsed = jsonParse(content);
288420
- if (isRecord(parsed)) {
288612
+ if (isRecord2(parsed)) {
288421
288613
  const filtered = parsePluginSettings(parsed);
288422
288614
  if (filtered) {
288423
288615
  logForDebugging2(`Loaded settings from settings.json for plugin ${manifest.name}`);
@@ -289107,7 +289299,7 @@ function cachePluginSettings(plugins) {
289107
289299
  logForDebugging2(`Cached plugin settings with keys: ${Object.keys(settings).join(", ")}`);
289108
289300
  }
289109
289301
  }
289110
- function isRecord(value) {
289302
+ function isRecord2(value) {
289111
289303
  return typeof value === "object" && value !== null && !Array.isArray(value);
289112
289304
  }
289113
289305
  var PluginSettingsSchema, loadAllPlugins, loadAllPluginsCacheOnly;
@@ -305345,6 +305537,11 @@ var init_toolSearch = __esm(() => {
305345
305537
  });
305346
305538
 
305347
305539
  // src/providers/shared/tokenCount.ts
305540
+ function headersForBetas2(betas) {
305541
+ if (!betas || betas.length === 0)
305542
+ return;
305543
+ return { "anthropic-beta": betas.join(",") };
305544
+ }
305348
305545
  function hasThinkingBlocks(messages) {
305349
305546
  for (const message of messages) {
305350
305547
  if (message.role === "assistant" && Array.isArray(message.content)) {
@@ -305419,17 +305616,18 @@ async function countMessagesTokensWithAPI(messages, tools) {
305419
305616
  model,
305420
305617
  source: "count_tokens"
305421
305618
  });
305422
- const response = await anthropic.beta.messages.countTokens({
305619
+ const response = await anthropic.messages.countTokens({
305423
305620
  model: normalizeModelStringForAPI(model),
305424
305621
  messages: messages.length > 0 ? messages : [{ role: "user", content: "foo" }],
305425
305622
  tools,
305426
- ...betas.length > 0 && { betas },
305427
305623
  ...containsThinking && {
305428
305624
  thinking: {
305429
305625
  type: "enabled",
305430
305626
  budget_tokens: TOKEN_COUNT_THINKING_BUDGET
305431
305627
  }
305432
305628
  }
305629
+ }, {
305630
+ ...betas.length > 0 ? { headers: headersForBetas2(betas) } : {}
305433
305631
  });
305434
305632
  if (typeof response.input_tokens !== "number") {
305435
305633
  return null;
@@ -305468,12 +305666,11 @@ async function countTokensViaHaikuFallback(messages, tools) {
305468
305666
  const normalizedMessages = stripToolSearchFieldsFromMessages(messages);
305469
305667
  const messagesToSend = normalizedMessages.length > 0 ? normalizedMessages : [{ role: "user", content: "count" }];
305470
305668
  const betas = getModelBetas(model);
305471
- const response = await anthropic.beta.messages.create({
305669
+ const response = await anthropic.messages.create({
305472
305670
  model: normalizeModelStringForAPI(model),
305473
305671
  max_tokens: containsThinking ? TOKEN_COUNT_MAX_TOKENS : 1,
305474
305672
  messages: messagesToSend,
305475
305673
  tools: tools.length > 0 ? tools : undefined,
305476
- ...betas.length > 0 && { betas },
305477
305674
  metadata: getAPIMetadata(),
305478
305675
  ...getExtraBodyParams(),
305479
305676
  ...containsThinking && {
@@ -305482,6 +305679,8 @@ async function countTokensViaHaikuFallback(messages, tools) {
305482
305679
  budget_tokens: TOKEN_COUNT_THINKING_BUDGET
305483
305680
  }
305484
305681
  }
305682
+ }, {
305683
+ ...betas.length > 0 ? { headers: headersForBetas2(betas) } : {}
305485
305684
  });
305486
305685
  const usage = response.usage;
305487
305686
  const inputTokens = usage.input_tokens;
@@ -307282,6 +307481,11 @@ var init_apiMicrocompact = __esm(() => {
307282
307481
 
307283
307482
  // src/controller/loop.ts
307284
307483
  import { randomUUID as randomUUID17 } from "crypto";
307484
+ function headersForBetas3(betas) {
307485
+ if (!betas || betas.length === 0)
307486
+ return;
307487
+ return { "anthropic-beta": betas.join(",") };
307488
+ }
307285
307489
  function adjustParamsForNonStreaming(params, maxTokensCap) {
307286
307490
  const cappedMaxTokens = Math.min(params.max_tokens, maxTokensCap);
307287
307491
  const adjustedParams = { ...params };
@@ -307359,13 +307563,16 @@ async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFr
307359
307563
  captureRequest(retryParams);
307360
307564
  onAttempt(attempt, start, retryParams.max_tokens);
307361
307565
  const adjustedParams = adjustParamsForNonStreaming(retryParams, MAX_NON_STREAMING_TOKENS);
307566
+ const { betas: requestBetas, ...standardParams } = adjustedParams;
307567
+ const headers = headersForBetas3(requestBetas);
307362
307568
  try {
307363
- return await anthropic.beta.messages.create({
307364
- ...adjustedParams,
307365
- model: normalizeModelStringForAPI(adjustedParams.model)
307569
+ return await anthropic.messages.create({
307570
+ ...standardParams,
307571
+ model: normalizeModelStringForAPI(standardParams.model)
307366
307572
  }, {
307367
307573
  signal: retryOptions.signal,
307368
- timeout: fallbackTimeoutMs
307574
+ timeout: fallbackTimeoutMs,
307575
+ ...headers ? { headers } : {}
307369
307576
  });
307370
307577
  } catch (err2) {
307371
307578
  if (err2 instanceof APIUserAbortError)
@@ -307847,11 +308054,19 @@ ${deferredToolList}
307847
308054
  headlessProfilerCheckpoint("api_request_sent");
307848
308055
  }
307849
308056
  clientRequestId = shouldSendClientRequestId() ? randomUUID17() : undefined;
307850
- const result = await anthropic.beta.messages.create({ ...params, stream: true }, {
307851
- signal,
308057
+ const { betas: requestBetas, ...standardParams } = params;
308058
+ const headers = {
308059
+ ...headersForBetas3(requestBetas) ?? {},
307852
308060
  ...clientRequestId && {
307853
- headers: { [CLIENT_REQUEST_ID_HEADER]: clientRequestId }
308061
+ [CLIENT_REQUEST_ID_HEADER]: clientRequestId
307854
308062
  }
308063
+ };
308064
+ const result = await anthropic.messages.create({
308065
+ ...standardParams,
308066
+ stream: true
308067
+ }, {
308068
+ signal,
308069
+ ...Object.keys(headers).length > 0 ? { headers } : {}
307855
308070
  }).withResponse();
307856
308071
  queryCheckpoint("query_response_headers_received");
307857
308072
  streamRequestId = result.request_id;
@@ -312164,6 +312379,11 @@ function stripToolReferenceBlocksFromUserMessage(message) {
312164
312379
  }
312165
312380
  };
312166
312381
  }
312382
+ function omitToolSearchCaller(block2) {
312383
+ const blockWithoutCaller = { ...block2 };
312384
+ delete blockWithoutCaller.caller;
312385
+ return blockWithoutCaller;
312386
+ }
312167
312387
  function stripCallerFieldFromAssistantMessage(message) {
312168
312388
  const hasCallerField = message.message.content.some((block2) => block2.type === "tool_use" && ("caller" in block2) && block2.caller !== null);
312169
312389
  if (!hasCallerField) {
@@ -312177,12 +312397,7 @@ function stripCallerFieldFromAssistantMessage(message) {
312177
312397
  if (block2.type !== "tool_use") {
312178
312398
  return block2;
312179
312399
  }
312180
- return {
312181
- type: "tool_use",
312182
- id: block2.id,
312183
- name: block2.name,
312184
- input: block2.input
312185
- };
312400
+ return omitToolSearchCaller(block2);
312186
312401
  })
312187
312402
  }
312188
312403
  };
@@ -312459,9 +312674,9 @@ function normalizeMessagesForAPI(messages, tools = []) {
312459
312674
  input: normalizedInput
312460
312675
  };
312461
312676
  }
312677
+ const blockWithoutCaller = omitToolSearchCaller(block2);
312462
312678
  return {
312463
- type: "tool_use",
312464
- id: block2.id,
312679
+ ...blockWithoutCaller,
312465
312680
  name: canonicalName,
312466
312681
  input: normalizedInput
312467
312682
  };
@@ -312658,6 +312873,15 @@ function mergeUserContentBlocks(a2, b) {
312658
312873
  }
312659
312874
  return [...a2.slice(0, -1), smooshed, ...toolResults];
312660
312875
  }
312876
+ function normalizeToolUseIdFromAPI(contentBlock) {
312877
+ if (typeof contentBlock.id === "string" && contentBlock.id.trim().length > 0) {
312878
+ return contentBlock.id;
312879
+ }
312880
+ logEvent("tengu_tool_use_missing_id_repaired", {
312881
+ toolName: sanitizeToolNameForAnalytics(contentBlock.name)
312882
+ });
312883
+ return `toolu_${randomUUID18().replace(/-/g, "")}`;
312884
+ }
312661
312885
  function normalizeContentFromAPI(contentBlocks, tools, agentId) {
312662
312886
  if (!contentBlocks) {
312663
312887
  return [];
@@ -312696,6 +312920,7 @@ function normalizeContentFromAPI(contentBlocks, tools, agentId) {
312696
312920
  }
312697
312921
  return {
312698
312922
  ...contentBlock,
312923
+ id: normalizeToolUseIdFromAPI(contentBlock),
312699
312924
  input: normalizedInput
312700
312925
  };
312701
312926
  }
@@ -458202,6 +458427,11 @@ var init_useDeferredHookMessages = __esm(() => {
458202
458427
  });
458203
458428
 
458204
458429
  // src/providers/anthropic/verifyApiKey.ts
458430
+ function headersForBetas4(betas) {
458431
+ if (!betas || betas.length === 0)
458432
+ return;
458433
+ return { "anthropic-beta": betas.join(",") };
458434
+ }
458205
458435
  async function verifyApiKey(apiKey, isNonInteractiveSession) {
458206
458436
  if (isNonInteractiveSession) {
458207
458437
  return true;
@@ -458216,14 +458446,15 @@ async function verifyApiKey(apiKey, isNonInteractiveSession) {
458216
458446
  source: "verify_api_key"
458217
458447
  }), async (anthropic) => {
458218
458448
  const messages = [{ role: "user", content: "test" }];
458219
- await anthropic.beta.messages.create({
458449
+ await anthropic.messages.create({
458220
458450
  model,
458221
458451
  max_tokens: 1,
458222
458452
  messages,
458223
458453
  temperature: 1,
458224
- ...betas.length > 0 && { betas },
458225
458454
  metadata: getAPIMetadata(),
458226
458455
  ...getExtraBodyParams()
458456
+ }, {
458457
+ ...betas.length > 0 ? { headers: headersForBetas4(betas) } : {}
458227
458458
  });
458228
458459
  return true;
458229
458460
  }, { maxRetries: 2, model, thinkingConfig: { type: "disabled" } }));
@@ -468433,21 +468664,21 @@ function extractLspInfoFromManifest(lspServers) {
468433
468664
  }
468434
468665
  return extractFromServerConfigRecord(lspServers);
468435
468666
  }
468436
- function isRecord2(value) {
468667
+ function isRecord3(value) {
468437
468668
  return typeof value === "object" && value !== null;
468438
468669
  }
468439
468670
  function extractFromServerConfigRecord(serverConfigs) {
468440
468671
  const extensions = new Set;
468441
468672
  let command = null;
468442
468673
  for (const [_serverName, config2] of Object.entries(serverConfigs)) {
468443
- if (!isRecord2(config2)) {
468674
+ if (!isRecord3(config2)) {
468444
468675
  continue;
468445
468676
  }
468446
468677
  if (!command && typeof config2.command === "string") {
468447
468678
  command = config2.command;
468448
468679
  }
468449
468680
  const extMapping = config2.extensionToLanguage;
468450
- if (isRecord2(extMapping)) {
468681
+ if (isRecord3(extMapping)) {
468451
468682
  for (const ext of Object.keys(extMapping)) {
468452
468683
  extensions.add(ext.toLowerCase());
468453
468684
  }
@@ -479844,7 +480075,7 @@ function buildPrimarySection() {
479844
480075
  }, undefined, false, undefined, this);
479845
480076
  return [{
479846
480077
  label: "Version",
479847
- value: "0.4.13"
480078
+ value: "0.4.15"
479848
480079
  }, {
479849
480080
  label: "Session name",
479850
480081
  value: nameValue
@@ -483125,7 +483356,7 @@ var init_OverageCreditUpsell = __esm(() => {
483125
483356
  });
483126
483357
 
483127
483358
  // src/providers/codex/usage.ts
483128
- function isRecord3(value) {
483359
+ function isRecord4(value) {
483129
483360
  return typeof value === "object" && value !== null;
483130
483361
  }
483131
483362
  function asString(value) {
@@ -483144,7 +483375,7 @@ function toIsoFromUnixSeconds(value) {
483144
483375
  return new Date(seconds * 1000).toISOString();
483145
483376
  }
483146
483377
  function normalizeWindow(value) {
483147
- if (!isRecord3(value))
483378
+ if (!isRecord4(value))
483148
483379
  return;
483149
483380
  const usedPercent = asNumber(value.used_percent) ?? asNumber(value.usedPercent);
483150
483381
  if (usedPercent === undefined)
@@ -483161,7 +483392,7 @@ function normalizeWindow(value) {
483161
483392
  };
483162
483393
  }
483163
483394
  function normalizeCredits(value) {
483164
- if (!isRecord3(value))
483395
+ if (!isRecord4(value))
483165
483396
  return;
483166
483397
  const hasCredits = asBoolean(value.has_credits) ?? asBoolean(value.hasCredits) ?? false;
483167
483398
  const unlimited = asBoolean(value.unlimited) ?? false;
@@ -483176,7 +483407,7 @@ function normalizeCredits(value) {
483176
483407
  };
483177
483408
  }
483178
483409
  function normalizeSnapshot(value, fallbackLimitName) {
483179
- if (!isRecord3(value))
483410
+ if (!isRecord4(value))
483180
483411
  return;
483181
483412
  const limitName = asString(value.limit_name) ?? asString(value.limitName) ?? asString(value.limit_id) ?? asString(value.limitId) ?? fallbackLimitName;
483182
483413
  const primary = normalizeWindow(value.primary) ?? normalizeWindow(value.primary_window);
@@ -483196,7 +483427,7 @@ function normalizeSnapshotsFromCollection(value, defaultLimitName = "codex") {
483196
483427
  if (Array.isArray(value)) {
483197
483428
  return value.map((item, index) => normalizeSnapshot(item, index === 0 ? defaultLimitName : `${defaultLimitName}-${index + 1}`)).filter((item) => item !== undefined);
483198
483429
  }
483199
- if (!isRecord3(value))
483430
+ if (!isRecord4(value))
483200
483431
  return [];
483201
483432
  return Object.entries(value).map(([key, entry]) => normalizeSnapshot(entry, key)).filter((item) => item !== undefined);
483202
483433
  }
@@ -483230,7 +483461,7 @@ function normalizeCodexUsagePayload(payload) {
483230
483461
  snapshots: normalizeSnapshotsFromCollection(payload)
483231
483462
  };
483232
483463
  }
483233
- if (!isRecord3(payload)) {
483464
+ if (!isRecord4(payload)) {
483234
483465
  return { snapshots: [] };
483235
483466
  }
483236
483467
  if ("rate_limit" in payload || "code_review_rate_limit" in payload || "additional_rate_limits" in payload || "credits" in payload) {
@@ -533163,8 +533394,8 @@ var AGENT_CREATION_SYSTEM_PROMPT, AGENT_MEMORY_INSTRUCTIONS = `
533163
533394
  - [domain-specific item 3]"
533164
533395
 
533165
533396
  Examples of domain-specific memory instructions:
533166
- - For a code-reviewer: "Update your agent memory as you discover code patterns, style conventions, common issues, and architectural decisions in this codebase."
533167
- - For a test-runner: "Update your agent memory as you discover test patterns, common failure modes, flaky tests, and testing best practices."
533397
+ - For a code review agent: "Update your agent memory as you discover code patterns, style conventions, common issues, and architectural decisions in this codebase."
533398
+ - For a test investigation agent: "Update your agent memory as you discover test patterns, common failure modes, flaky tests, and testing best practices."
533168
533399
  - For an architect: "Update your agent memory as you discover codepaths, library locations, key architectural decisions, and component relationships."
533169
533400
  - For a documentation writer: "Update your agent memory as you discover documentation patterns, API structures, and terminology conventions."
533170
533401
 
@@ -533213,29 +533444,30 @@ When a user describes what they want an agent to do, you will:
533213
533444
  - in the 'whenToUse' field of the JSON object, you should include examples of when this agent should be used.
533214
533445
  - examples should be of the form:
533215
533446
  - <example>
533216
- Context: The user is creating a test-runner agent that should be called after a logical chunk of code is written.
533447
+ Context: The user is creating an agent that should review recently changed code after a logical chunk of implementation work.
533217
533448
  user: "Please write a function that checks if a number is prime"
533218
533449
  assistant: "Here is the relevant function: "
533219
533450
  <function call omitted for brevity only for this example>
533220
533451
  <commentary>
533221
- Since a significant piece of code was written, use the ${AGENT_TOOL_NAME} tool to launch the test-runner agent to run the tests.
533452
+ Since a significant piece of code was written, use the ${AGENT_TOOL_NAME} tool with this newly created agent's exact identifier to review the change.
533222
533453
  </commentary>
533223
- assistant: "Now let me use the test-runner agent to run the tests"
533454
+ assistant: "Now let me use the review agent to inspect the change."
533224
533455
  </example>
533225
533456
  - <example>
533226
- Context: User is creating an agent to respond to the word "hello" with a friendly jok.
533227
- user: "Hello"
533228
- assistant: "I'm going to use the ${AGENT_TOOL_NAME} tool to launch the greeting-responder agent to respond with a friendly joke"
533457
+ Context: The user is creating an agent that should investigate flaky CI failures.
533458
+ user: "The integration test failed again, can you look into the pattern?"
533459
+ assistant: "I'm going to use the ${AGENT_TOOL_NAME} tool with this newly created agent's exact identifier to investigate the flaky CI failure pattern."
533229
533460
  <commentary>
533230
- Since the user is greeting, use the greeting-responder agent to respond with a friendly joke.
533461
+ Since the request matches the new agent's investigation scope, delegate the focused analysis to that exact agent type.
533231
533462
  </commentary>
533232
533463
  </example>
533464
+ - Do not use fictional agent names in examples. Refer to "this newly created agent's exact identifier" or to the actual identifier you output in the JSON.
533233
533465
  - If the user mentioned or implied that the agent should be used proactively, you should include examples of this.
533234
533466
  - NOTE: Ensure that in the examples, you are making the assistant use the Agent tool and not simply respond directly to the task.
533235
533467
 
533236
533468
  Your output must be a valid JSON object with exactly these fields:
533237
533469
  {
533238
- "identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens (e.g., 'test-runner', 'api-docs-writer', 'code-formatter')",
533470
+ "identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens. Use an identifier that matches the agent being created.",
533239
533471
  "whenToUse": "A precise, actionable description starting with 'Use this agent when...' that clearly defines the triggering conditions and use cases. Ensure you include examples as described above.",
533240
533472
  "systemPrompt": "The complete system prompt that will govern the agent's behavior, written in second person ('You are...', 'You will...') and structured for maximum clarity and effectiveness"
533241
533473
  }
@@ -536166,7 +536398,7 @@ var init_bridge_kick = __esm(() => {
536166
536398
  var call58 = async () => {
536167
536399
  return {
536168
536400
  type: "text",
536169
- value: `${"99.0.0"} (built ${"2026-06-25T12:29:02.938Z"})`
536401
+ value: `${"99.0.0"} (built ${"2026-07-07T09:41:37.769Z"})`
536170
536402
  };
536171
536403
  }, version2, version_default;
536172
536404
  var init_version = __esm(() => {
@@ -558276,7 +558508,7 @@ function WelcomeV2() {
558276
558508
  dimColor: true,
558277
558509
  children: [
558278
558510
  "v",
558279
- "0.4.13",
558511
+ "0.4.15",
558280
558512
  " "
558281
558513
  ]
558282
558514
  }, undefined, true, undefined, this)
@@ -558476,7 +558708,7 @@ function WelcomeV2() {
558476
558708
  dimColor: true,
558477
558709
  children: [
558478
558710
  "v",
558479
- "0.4.13",
558711
+ "0.4.15",
558480
558712
  " "
558481
558713
  ]
558482
558714
  }, undefined, true, undefined, this)
@@ -558702,7 +558934,7 @@ function AppleTerminalWelcomeV2(t0) {
558702
558934
  dimColor: true,
558703
558935
  children: [
558704
558936
  "v",
558705
- "0.4.13",
558937
+ "0.4.15",
558706
558938
  " "
558707
558939
  ]
558708
558940
  }, undefined, true, undefined, this);
@@ -558956,7 +559188,7 @@ function AppleTerminalWelcomeV2(t0) {
558956
559188
  dimColor: true,
558957
559189
  children: [
558958
559190
  "v",
558959
- "0.4.13",
559191
+ "0.4.15",
558960
559192
  " "
558961
559193
  ]
558962
559194
  }, undefined, true, undefined, this);
@@ -570179,6 +570411,17 @@ class QueryEngine {
570179
570411
  };
570180
570412
  return;
570181
570413
  }
570414
+ const recentErrors = (() => {
570415
+ const all4 = getInMemoryErrors();
570416
+ const start = errorLogWatermark ? all4.lastIndexOf(errorLogWatermark) + 1 : 0;
570417
+ return all4.slice(start).map((_) => _.error);
570418
+ })();
570419
+ const edeDiagnostic = buildErrorDuringExecutionDiagnostic({
570420
+ resultType: edeResultType,
570421
+ lastContentType: edeLastContentType,
570422
+ stopReason: lastStopReason
570423
+ });
570424
+ logForDebugging2(edeDiagnostic, { level: "warn" });
570182
570425
  yield {
570183
570426
  type: "result",
570184
570427
  subtype: "error_during_execution",
@@ -570194,14 +570437,10 @@ class QueryEngine {
570194
570437
  permission_denials: this.permissionDenials,
570195
570438
  fast_mode_state: getFastModeState(mainLoopModel, initialAppState.fastMode),
570196
570439
  uuid: randomUUID46(),
570197
- errors: (() => {
570198
- const all4 = getInMemoryErrors();
570199
- const start = errorLogWatermark ? all4.lastIndexOf(errorLogWatermark) + 1 : 0;
570200
- return [
570201
- `[ede_diagnostic] result_type=${edeResultType} last_content_type=${edeLastContentType} stop_reason=${lastStopReason}`,
570202
- ...all4.slice(start).map((_) => _.error)
570203
- ];
570204
- })()
570440
+ errors: buildErrorDuringExecutionErrors({
570441
+ recentErrors,
570442
+ stopReason: lastStopReason
570443
+ })
570205
570444
  };
570206
570445
  return;
570207
570446
  }
@@ -579824,7 +580063,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
579824
580063
  pendingHookMessages
579825
580064
  }, renderAndRun);
579826
580065
  }
579827
- }).version("0.4.13 (OpenCow)", "-v, --version", "Output the version number");
580066
+ }).version("0.4.15 (OpenCow)", "-v, --version", "Output the version number");
579828
580067
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
579829
580068
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
579830
580069
  if (canUserConfigureAdvisor()) {
@@ -580470,7 +580709,7 @@ if (false) {}
580470
580709
  async function main2() {
580471
580710
  const args = process.argv.slice(2);
580472
580711
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
580473
- console.log(`${"0.4.13"} (OpenCow)`);
580712
+ console.log(`${"0.4.15"} (OpenCow)`);
580474
580713
  return;
580475
580714
  }
580476
580715
  if (args.includes("--provider")) {
@@ -580588,4 +580827,4 @@ async function main2() {
580588
580827
  }
580589
580828
  main2();
580590
580829
 
580591
- //# debugId=D1D0071A1FA049F864756E2164756E21
580830
+ //# debugId=B3DC484465E4B22564756E2164756E21