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

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.14"}${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-07T07:10:57.155Z").getTime();
244438
244623
  if (isNaN(buildTime))
244439
244624
  return;
244440
244625
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -264902,49 +265087,36 @@ assistant: Still waiting on the audit — that's one of the things it's checking
264902
265087
 
264903
265088
  <example>
264904
265089
  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>
265090
+ assistant: <thinking>Forking this review keeps the detailed audit out of my context while I keep steering the work.</thinking>
264906
265091
  <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.
265092
+ 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
265093
  </commentary>
264909
265094
  ${AGENT_TOOL_NAME2}({
264910
265095
  name: "migration-review",
264911
265096
  description: "Independent migration review",
264912
- subagent_type: "code-reviewer",
264913
265097
  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
265098
  })
264915
265099
  </example>
264916
265100
  `;
264917
265101
  const currentExamples = `Example usage:
264918
265102
 
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
265103
  <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>
265104
+ user: "Hello"
264936
265105
  <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
265106
+ Do not use the ${AGENT_TOOL_NAME2} tool for a simple greeting or a short reply. Answer directly.
264938
265107
  </commentary>
264939
- assistant: Uses the ${AGENT_TOOL_NAME2} tool to launch the test-runner agent
265108
+ assistant: "Hi! Nice to see you. What shall we work on today?"
264940
265109
  </example>
264941
265110
 
264942
265111
  <example>
264943
- user: "Hello"
265112
+ user: "Can you investigate whether this migration is safe?"
264944
265113
  <commentary>
264945
- Since the user is greeting, use the greeting-responder agent to respond with a friendly joke
265114
+ 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
265115
  </commentary>
264947
- assistant: "I'm going to use the ${AGENT_TOOL_NAME2} tool to launch the greeting-responder agent"
265116
+ ${AGENT_TOOL_NAME2}({
265117
+ description: "Review migration safety",
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. Check whether the backfill approach is safe under concurrent writes. Report: is this safe, and if not, what specifically breaks?"
265119
+ })
264948
265120
  </example>
264949
265121
  `;
264950
265122
  const listViaAttachment = shouldInjectAgentListInMessages();
@@ -264957,7 +265129,7 @@ The ${AGENT_TOOL_NAME2} tool launches specialized agents (subprocesses) that aut
264957
265129
 
264958
265130
  ${agentListSection}
264959
265131
 
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.`}`;
265132
+ ${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
265133
  if (isCoordinator) {
264962
265134
  return shared2;
264963
265135
  }
@@ -264985,7 +265157,7 @@ Usage notes:
264985
265157
  - The agent's outputs should generally be trusted
264986
265158
  - 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
265159
  - 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.
265160
+ - 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
265161
  - 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
265162
  - 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
265163
  - The run_in_background, name, team_name, and mode parameters are not available in this context. Only synchronous subagents are supported.` : isTeammate() ? `
@@ -265000,7 +265172,6 @@ var init_prompt8 = __esm(() => {
265000
265172
  init_teammate();
265001
265173
  init_teammateContext();
265002
265174
  init_prompt();
265003
- init_prompt2();
265004
265175
  init_constants4();
265005
265176
  init_forkSubagent();
265006
265177
  init_state2();
@@ -288417,7 +288588,7 @@ async function loadPluginSettings(pluginPath, manifest) {
288417
288588
  try {
288418
288589
  const content = await getFsImplementation().readFile(settingsJsonPath, { encoding: "utf-8" });
288419
288590
  const parsed = jsonParse(content);
288420
- if (isRecord(parsed)) {
288591
+ if (isRecord2(parsed)) {
288421
288592
  const filtered = parsePluginSettings(parsed);
288422
288593
  if (filtered) {
288423
288594
  logForDebugging2(`Loaded settings from settings.json for plugin ${manifest.name}`);
@@ -289107,7 +289278,7 @@ function cachePluginSettings(plugins) {
289107
289278
  logForDebugging2(`Cached plugin settings with keys: ${Object.keys(settings).join(", ")}`);
289108
289279
  }
289109
289280
  }
289110
- function isRecord(value) {
289281
+ function isRecord2(value) {
289111
289282
  return typeof value === "object" && value !== null && !Array.isArray(value);
289112
289283
  }
289113
289284
  var PluginSettingsSchema, loadAllPlugins, loadAllPluginsCacheOnly;
@@ -305345,6 +305516,11 @@ var init_toolSearch = __esm(() => {
305345
305516
  });
305346
305517
 
305347
305518
  // src/providers/shared/tokenCount.ts
305519
+ function headersForBetas2(betas) {
305520
+ if (!betas || betas.length === 0)
305521
+ return;
305522
+ return { "anthropic-beta": betas.join(",") };
305523
+ }
305348
305524
  function hasThinkingBlocks(messages) {
305349
305525
  for (const message of messages) {
305350
305526
  if (message.role === "assistant" && Array.isArray(message.content)) {
@@ -305419,17 +305595,18 @@ async function countMessagesTokensWithAPI(messages, tools) {
305419
305595
  model,
305420
305596
  source: "count_tokens"
305421
305597
  });
305422
- const response = await anthropic.beta.messages.countTokens({
305598
+ const response = await anthropic.messages.countTokens({
305423
305599
  model: normalizeModelStringForAPI(model),
305424
305600
  messages: messages.length > 0 ? messages : [{ role: "user", content: "foo" }],
305425
305601
  tools,
305426
- ...betas.length > 0 && { betas },
305427
305602
  ...containsThinking && {
305428
305603
  thinking: {
305429
305604
  type: "enabled",
305430
305605
  budget_tokens: TOKEN_COUNT_THINKING_BUDGET
305431
305606
  }
305432
305607
  }
305608
+ }, {
305609
+ ...betas.length > 0 ? { headers: headersForBetas2(betas) } : {}
305433
305610
  });
305434
305611
  if (typeof response.input_tokens !== "number") {
305435
305612
  return null;
@@ -305468,12 +305645,11 @@ async function countTokensViaHaikuFallback(messages, tools) {
305468
305645
  const normalizedMessages = stripToolSearchFieldsFromMessages(messages);
305469
305646
  const messagesToSend = normalizedMessages.length > 0 ? normalizedMessages : [{ role: "user", content: "count" }];
305470
305647
  const betas = getModelBetas(model);
305471
- const response = await anthropic.beta.messages.create({
305648
+ const response = await anthropic.messages.create({
305472
305649
  model: normalizeModelStringForAPI(model),
305473
305650
  max_tokens: containsThinking ? TOKEN_COUNT_MAX_TOKENS : 1,
305474
305651
  messages: messagesToSend,
305475
305652
  tools: tools.length > 0 ? tools : undefined,
305476
- ...betas.length > 0 && { betas },
305477
305653
  metadata: getAPIMetadata(),
305478
305654
  ...getExtraBodyParams(),
305479
305655
  ...containsThinking && {
@@ -305482,6 +305658,8 @@ async function countTokensViaHaikuFallback(messages, tools) {
305482
305658
  budget_tokens: TOKEN_COUNT_THINKING_BUDGET
305483
305659
  }
305484
305660
  }
305661
+ }, {
305662
+ ...betas.length > 0 ? { headers: headersForBetas2(betas) } : {}
305485
305663
  });
305486
305664
  const usage = response.usage;
305487
305665
  const inputTokens = usage.input_tokens;
@@ -307282,6 +307460,11 @@ var init_apiMicrocompact = __esm(() => {
307282
307460
 
307283
307461
  // src/controller/loop.ts
307284
307462
  import { randomUUID as randomUUID17 } from "crypto";
307463
+ function headersForBetas3(betas) {
307464
+ if (!betas || betas.length === 0)
307465
+ return;
307466
+ return { "anthropic-beta": betas.join(",") };
307467
+ }
307285
307468
  function adjustParamsForNonStreaming(params, maxTokensCap) {
307286
307469
  const cappedMaxTokens = Math.min(params.max_tokens, maxTokensCap);
307287
307470
  const adjustedParams = { ...params };
@@ -307359,13 +307542,16 @@ async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFr
307359
307542
  captureRequest(retryParams);
307360
307543
  onAttempt(attempt, start, retryParams.max_tokens);
307361
307544
  const adjustedParams = adjustParamsForNonStreaming(retryParams, MAX_NON_STREAMING_TOKENS);
307545
+ const { betas: requestBetas, ...standardParams } = adjustedParams;
307546
+ const headers = headersForBetas3(requestBetas);
307362
307547
  try {
307363
- return await anthropic.beta.messages.create({
307364
- ...adjustedParams,
307365
- model: normalizeModelStringForAPI(adjustedParams.model)
307548
+ return await anthropic.messages.create({
307549
+ ...standardParams,
307550
+ model: normalizeModelStringForAPI(standardParams.model)
307366
307551
  }, {
307367
307552
  signal: retryOptions.signal,
307368
- timeout: fallbackTimeoutMs
307553
+ timeout: fallbackTimeoutMs,
307554
+ ...headers ? { headers } : {}
307369
307555
  });
307370
307556
  } catch (err2) {
307371
307557
  if (err2 instanceof APIUserAbortError)
@@ -307847,11 +308033,19 @@ ${deferredToolList}
307847
308033
  headlessProfilerCheckpoint("api_request_sent");
307848
308034
  }
307849
308035
  clientRequestId = shouldSendClientRequestId() ? randomUUID17() : undefined;
307850
- const result = await anthropic.beta.messages.create({ ...params, stream: true }, {
307851
- signal,
308036
+ const { betas: requestBetas, ...standardParams } = params;
308037
+ const headers = {
308038
+ ...headersForBetas3(requestBetas) ?? {},
307852
308039
  ...clientRequestId && {
307853
- headers: { [CLIENT_REQUEST_ID_HEADER]: clientRequestId }
308040
+ [CLIENT_REQUEST_ID_HEADER]: clientRequestId
307854
308041
  }
308042
+ };
308043
+ const result = await anthropic.messages.create({
308044
+ ...standardParams,
308045
+ stream: true
308046
+ }, {
308047
+ signal,
308048
+ ...Object.keys(headers).length > 0 ? { headers } : {}
307855
308049
  }).withResponse();
307856
308050
  queryCheckpoint("query_response_headers_received");
307857
308051
  streamRequestId = result.request_id;
@@ -312164,6 +312358,11 @@ function stripToolReferenceBlocksFromUserMessage(message) {
312164
312358
  }
312165
312359
  };
312166
312360
  }
312361
+ function omitToolSearchCaller(block2) {
312362
+ const blockWithoutCaller = { ...block2 };
312363
+ delete blockWithoutCaller.caller;
312364
+ return blockWithoutCaller;
312365
+ }
312167
312366
  function stripCallerFieldFromAssistantMessage(message) {
312168
312367
  const hasCallerField = message.message.content.some((block2) => block2.type === "tool_use" && ("caller" in block2) && block2.caller !== null);
312169
312368
  if (!hasCallerField) {
@@ -312177,12 +312376,7 @@ function stripCallerFieldFromAssistantMessage(message) {
312177
312376
  if (block2.type !== "tool_use") {
312178
312377
  return block2;
312179
312378
  }
312180
- return {
312181
- type: "tool_use",
312182
- id: block2.id,
312183
- name: block2.name,
312184
- input: block2.input
312185
- };
312379
+ return omitToolSearchCaller(block2);
312186
312380
  })
312187
312381
  }
312188
312382
  };
@@ -312459,9 +312653,9 @@ function normalizeMessagesForAPI(messages, tools = []) {
312459
312653
  input: normalizedInput
312460
312654
  };
312461
312655
  }
312656
+ const blockWithoutCaller = omitToolSearchCaller(block2);
312462
312657
  return {
312463
- type: "tool_use",
312464
- id: block2.id,
312658
+ ...blockWithoutCaller,
312465
312659
  name: canonicalName,
312466
312660
  input: normalizedInput
312467
312661
  };
@@ -312658,6 +312852,15 @@ function mergeUserContentBlocks(a2, b) {
312658
312852
  }
312659
312853
  return [...a2.slice(0, -1), smooshed, ...toolResults];
312660
312854
  }
312855
+ function normalizeToolUseIdFromAPI(contentBlock) {
312856
+ if (typeof contentBlock.id === "string" && contentBlock.id.trim().length > 0) {
312857
+ return contentBlock.id;
312858
+ }
312859
+ logEvent("tengu_tool_use_missing_id_repaired", {
312860
+ toolName: sanitizeToolNameForAnalytics(contentBlock.name)
312861
+ });
312862
+ return `toolu_${randomUUID18().replace(/-/g, "")}`;
312863
+ }
312661
312864
  function normalizeContentFromAPI(contentBlocks, tools, agentId) {
312662
312865
  if (!contentBlocks) {
312663
312866
  return [];
@@ -312696,6 +312899,7 @@ function normalizeContentFromAPI(contentBlocks, tools, agentId) {
312696
312899
  }
312697
312900
  return {
312698
312901
  ...contentBlock,
312902
+ id: normalizeToolUseIdFromAPI(contentBlock),
312699
312903
  input: normalizedInput
312700
312904
  };
312701
312905
  }
@@ -458202,6 +458406,11 @@ var init_useDeferredHookMessages = __esm(() => {
458202
458406
  });
458203
458407
 
458204
458408
  // src/providers/anthropic/verifyApiKey.ts
458409
+ function headersForBetas4(betas) {
458410
+ if (!betas || betas.length === 0)
458411
+ return;
458412
+ return { "anthropic-beta": betas.join(",") };
458413
+ }
458205
458414
  async function verifyApiKey(apiKey, isNonInteractiveSession) {
458206
458415
  if (isNonInteractiveSession) {
458207
458416
  return true;
@@ -458216,14 +458425,15 @@ async function verifyApiKey(apiKey, isNonInteractiveSession) {
458216
458425
  source: "verify_api_key"
458217
458426
  }), async (anthropic) => {
458218
458427
  const messages = [{ role: "user", content: "test" }];
458219
- await anthropic.beta.messages.create({
458428
+ await anthropic.messages.create({
458220
458429
  model,
458221
458430
  max_tokens: 1,
458222
458431
  messages,
458223
458432
  temperature: 1,
458224
- ...betas.length > 0 && { betas },
458225
458433
  metadata: getAPIMetadata(),
458226
458434
  ...getExtraBodyParams()
458435
+ }, {
458436
+ ...betas.length > 0 ? { headers: headersForBetas4(betas) } : {}
458227
458437
  });
458228
458438
  return true;
458229
458439
  }, { maxRetries: 2, model, thinkingConfig: { type: "disabled" } }));
@@ -468433,21 +468643,21 @@ function extractLspInfoFromManifest(lspServers) {
468433
468643
  }
468434
468644
  return extractFromServerConfigRecord(lspServers);
468435
468645
  }
468436
- function isRecord2(value) {
468646
+ function isRecord3(value) {
468437
468647
  return typeof value === "object" && value !== null;
468438
468648
  }
468439
468649
  function extractFromServerConfigRecord(serverConfigs) {
468440
468650
  const extensions = new Set;
468441
468651
  let command = null;
468442
468652
  for (const [_serverName, config2] of Object.entries(serverConfigs)) {
468443
- if (!isRecord2(config2)) {
468653
+ if (!isRecord3(config2)) {
468444
468654
  continue;
468445
468655
  }
468446
468656
  if (!command && typeof config2.command === "string") {
468447
468657
  command = config2.command;
468448
468658
  }
468449
468659
  const extMapping = config2.extensionToLanguage;
468450
- if (isRecord2(extMapping)) {
468660
+ if (isRecord3(extMapping)) {
468451
468661
  for (const ext of Object.keys(extMapping)) {
468452
468662
  extensions.add(ext.toLowerCase());
468453
468663
  }
@@ -479844,7 +480054,7 @@ function buildPrimarySection() {
479844
480054
  }, undefined, false, undefined, this);
479845
480055
  return [{
479846
480056
  label: "Version",
479847
- value: "0.4.13"
480057
+ value: "0.4.14"
479848
480058
  }, {
479849
480059
  label: "Session name",
479850
480060
  value: nameValue
@@ -483125,7 +483335,7 @@ var init_OverageCreditUpsell = __esm(() => {
483125
483335
  });
483126
483336
 
483127
483337
  // src/providers/codex/usage.ts
483128
- function isRecord3(value) {
483338
+ function isRecord4(value) {
483129
483339
  return typeof value === "object" && value !== null;
483130
483340
  }
483131
483341
  function asString(value) {
@@ -483144,7 +483354,7 @@ function toIsoFromUnixSeconds(value) {
483144
483354
  return new Date(seconds * 1000).toISOString();
483145
483355
  }
483146
483356
  function normalizeWindow(value) {
483147
- if (!isRecord3(value))
483357
+ if (!isRecord4(value))
483148
483358
  return;
483149
483359
  const usedPercent = asNumber(value.used_percent) ?? asNumber(value.usedPercent);
483150
483360
  if (usedPercent === undefined)
@@ -483161,7 +483371,7 @@ function normalizeWindow(value) {
483161
483371
  };
483162
483372
  }
483163
483373
  function normalizeCredits(value) {
483164
- if (!isRecord3(value))
483374
+ if (!isRecord4(value))
483165
483375
  return;
483166
483376
  const hasCredits = asBoolean(value.has_credits) ?? asBoolean(value.hasCredits) ?? false;
483167
483377
  const unlimited = asBoolean(value.unlimited) ?? false;
@@ -483176,7 +483386,7 @@ function normalizeCredits(value) {
483176
483386
  };
483177
483387
  }
483178
483388
  function normalizeSnapshot(value, fallbackLimitName) {
483179
- if (!isRecord3(value))
483389
+ if (!isRecord4(value))
483180
483390
  return;
483181
483391
  const limitName = asString(value.limit_name) ?? asString(value.limitName) ?? asString(value.limit_id) ?? asString(value.limitId) ?? fallbackLimitName;
483182
483392
  const primary = normalizeWindow(value.primary) ?? normalizeWindow(value.primary_window);
@@ -483196,7 +483406,7 @@ function normalizeSnapshotsFromCollection(value, defaultLimitName = "codex") {
483196
483406
  if (Array.isArray(value)) {
483197
483407
  return value.map((item, index) => normalizeSnapshot(item, index === 0 ? defaultLimitName : `${defaultLimitName}-${index + 1}`)).filter((item) => item !== undefined);
483198
483408
  }
483199
- if (!isRecord3(value))
483409
+ if (!isRecord4(value))
483200
483410
  return [];
483201
483411
  return Object.entries(value).map(([key, entry]) => normalizeSnapshot(entry, key)).filter((item) => item !== undefined);
483202
483412
  }
@@ -483230,7 +483440,7 @@ function normalizeCodexUsagePayload(payload) {
483230
483440
  snapshots: normalizeSnapshotsFromCollection(payload)
483231
483441
  };
483232
483442
  }
483233
- if (!isRecord3(payload)) {
483443
+ if (!isRecord4(payload)) {
483234
483444
  return { snapshots: [] };
483235
483445
  }
483236
483446
  if ("rate_limit" in payload || "code_review_rate_limit" in payload || "additional_rate_limits" in payload || "credits" in payload) {
@@ -533163,8 +533373,8 @@ var AGENT_CREATION_SYSTEM_PROMPT, AGENT_MEMORY_INSTRUCTIONS = `
533163
533373
  - [domain-specific item 3]"
533164
533374
 
533165
533375
  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."
533376
+ - For a code review agent: "Update your agent memory as you discover code patterns, style conventions, common issues, and architectural decisions in this codebase."
533377
+ - For a test investigation agent: "Update your agent memory as you discover test patterns, common failure modes, flaky tests, and testing best practices."
533168
533378
  - For an architect: "Update your agent memory as you discover codepaths, library locations, key architectural decisions, and component relationships."
533169
533379
  - For a documentation writer: "Update your agent memory as you discover documentation patterns, API structures, and terminology conventions."
533170
533380
 
@@ -533213,29 +533423,30 @@ When a user describes what they want an agent to do, you will:
533213
533423
  - in the 'whenToUse' field of the JSON object, you should include examples of when this agent should be used.
533214
533424
  - examples should be of the form:
533215
533425
  - <example>
533216
- Context: The user is creating a test-runner agent that should be called after a logical chunk of code is written.
533426
+ Context: The user is creating an agent that should review recently changed code after a logical chunk of implementation work.
533217
533427
  user: "Please write a function that checks if a number is prime"
533218
533428
  assistant: "Here is the relevant function: "
533219
533429
  <function call omitted for brevity only for this example>
533220
533430
  <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.
533431
+ 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
533432
  </commentary>
533223
- assistant: "Now let me use the test-runner agent to run the tests"
533433
+ assistant: "Now let me use the review agent to inspect the change."
533224
533434
  </example>
533225
533435
  - <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"
533436
+ Context: The user is creating an agent that should investigate flaky CI failures.
533437
+ user: "The integration test failed again, can you look into the pattern?"
533438
+ 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
533439
  <commentary>
533230
- Since the user is greeting, use the greeting-responder agent to respond with a friendly joke.
533440
+ Since the request matches the new agent's investigation scope, delegate the focused analysis to that exact agent type.
533231
533441
  </commentary>
533232
533442
  </example>
533443
+ - 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
533444
  - If the user mentioned or implied that the agent should be used proactively, you should include examples of this.
533234
533445
  - NOTE: Ensure that in the examples, you are making the assistant use the Agent tool and not simply respond directly to the task.
533235
533446
 
533236
533447
  Your output must be a valid JSON object with exactly these fields:
533237
533448
  {
533238
- "identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens (e.g., 'test-runner', 'api-docs-writer', 'code-formatter')",
533449
+ "identifier": "A unique, descriptive identifier using lowercase letters, numbers, and hyphens. Use an identifier that matches the agent being created.",
533239
533450
  "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
533451
  "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
533452
  }
@@ -536166,7 +536377,7 @@ var init_bridge_kick = __esm(() => {
536166
536377
  var call58 = async () => {
536167
536378
  return {
536168
536379
  type: "text",
536169
- value: `${"99.0.0"} (built ${"2026-06-25T12:29:02.938Z"})`
536380
+ value: `${"99.0.0"} (built ${"2026-07-07T07:10:57.155Z"})`
536170
536381
  };
536171
536382
  }, version2, version_default;
536172
536383
  var init_version = __esm(() => {
@@ -558276,7 +558487,7 @@ function WelcomeV2() {
558276
558487
  dimColor: true,
558277
558488
  children: [
558278
558489
  "v",
558279
- "0.4.13",
558490
+ "0.4.14",
558280
558491
  " "
558281
558492
  ]
558282
558493
  }, undefined, true, undefined, this)
@@ -558476,7 +558687,7 @@ function WelcomeV2() {
558476
558687
  dimColor: true,
558477
558688
  children: [
558478
558689
  "v",
558479
- "0.4.13",
558690
+ "0.4.14",
558480
558691
  " "
558481
558692
  ]
558482
558693
  }, undefined, true, undefined, this)
@@ -558702,7 +558913,7 @@ function AppleTerminalWelcomeV2(t0) {
558702
558913
  dimColor: true,
558703
558914
  children: [
558704
558915
  "v",
558705
- "0.4.13",
558916
+ "0.4.14",
558706
558917
  " "
558707
558918
  ]
558708
558919
  }, undefined, true, undefined, this);
@@ -558956,7 +559167,7 @@ function AppleTerminalWelcomeV2(t0) {
558956
559167
  dimColor: true,
558957
559168
  children: [
558958
559169
  "v",
558959
- "0.4.13",
559170
+ "0.4.14",
558960
559171
  " "
558961
559172
  ]
558962
559173
  }, undefined, true, undefined, this);
@@ -579824,7 +580035,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
579824
580035
  pendingHookMessages
579825
580036
  }, renderAndRun);
579826
580037
  }
579827
- }).version("0.4.13 (OpenCow)", "-v, --version", "Output the version number");
580038
+ }).version("0.4.14 (OpenCow)", "-v, --version", "Output the version number");
579828
580039
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
579829
580040
  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
580041
  if (canUserConfigureAdvisor()) {
@@ -580470,7 +580681,7 @@ if (false) {}
580470
580681
  async function main2() {
580471
580682
  const args = process.argv.slice(2);
580472
580683
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
580473
- console.log(`${"0.4.13"} (OpenCow)`);
580684
+ console.log(`${"0.4.14"} (OpenCow)`);
580474
580685
  return;
580475
580686
  }
580476
580687
  if (args.includes("--provider")) {
@@ -580588,4 +580799,4 @@ async function main2() {
580588
580799
  }
580589
580800
  main2();
580590
580801
 
580591
- //# debugId=D1D0071A1FA049F864756E2164756E21
580802
+ //# debugId=C329783BF76928B664756E2164756E21