@opencow-ai/opencow-agent-sdk 0.4.12 → 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) {
@@ -85561,7 +85643,7 @@ function convertChunkUsage(usage) {
85561
85643
  return openaiUsageToAnthropicUsage(usage);
85562
85644
  }
85563
85645
  function toOpenAIChatReasoningEffort(effort) {
85564
- return effort === "xhigh" ? "high" : effort;
85646
+ return effort;
85565
85647
  }
85566
85648
  function getOpenAIChatProviderCapabilities(model) {
85567
85649
  return {
@@ -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,17 +86080,26 @@ 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;
86006
86092
  let httpResponse;
86007
86093
  const promise2 = (async () => {
86008
86094
  const overrideTransport = self2.providerOverride?.transport === "anthropic" ? undefined : self2.providerOverride?.transport;
86009
- const request = resolveProviderRequest({ model: self2.providerOverride?.model ?? params.model, baseUrl: self2.providerOverride?.baseURL, reasoningEffortOverride: self2.reasoningEffort, transportOverride: overrideTransport });
86095
+ const hasProviderReasoningEffortOverride = !!self2.providerOverride && Object.prototype.hasOwnProperty.call(self2.providerOverride, "reasoningEffort");
86096
+ const reasoningEffortOverride = hasProviderReasoningEffortOverride ? self2.providerOverride?.reasoningEffort ?? null : self2.reasoningEffort;
86097
+ const request = resolveProviderRequest({
86098
+ model: self2.providerOverride?.model ?? params.model,
86099
+ baseUrl: self2.providerOverride?.baseURL,
86100
+ ...reasoningEffortOverride !== undefined ? { reasoningEffortOverride } : {},
86101
+ transportOverride: overrideTransport
86102
+ });
86010
86103
  const response = await self2._doRequest(request, params, options);
86011
86104
  httpResponse = response;
86012
86105
  if (params.stream) {
@@ -86127,28 +86220,93 @@ class OpenAIShimMessages {
86127
86220
  signal: options?.signal
86128
86221
  };
86129
86222
  const maxAttempts = isGithub ? GITHUB_429_MAX_RETRIES : 1;
86223
+ const endpoint = classifyModelHttpEndpoint(chatCompletionsUrl);
86130
86224
  let response;
86131
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
+ });
86132
86240
  try {
86133
86241
  response = await fetch(chatCompletionsUrl, fetchInit);
86134
86242
  } catch (fetchErr) {
86135
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
+ });
86136
86256
  throw new APIConnectionError({
86137
86257
  message: `OpenAI-compat connection failed: ${msg}`,
86138
86258
  cause: fetchErr
86139
86259
  });
86140
86260
  }
86141
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
+ });
86142
86273
  return response;
86143
86274
  }
86144
86275
  if (isGithub && response.status === 429 && attempt < maxAttempts - 1) {
86145
86276
  await response.text().catch(() => {});
86146
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
+ });
86147
86292
  await sleepMs(delaySec * 1000);
86148
86293
  continue;
86149
86294
  }
86150
86295
  const errorBody = await response.text().catch(() => "unknown error");
86151
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
+ });
86152
86310
  let errorResponse;
86153
86311
  try {
86154
86312
  errorResponse = JSON.parse(errorBody);
@@ -86237,8 +86395,8 @@ function convertOpenAIResponseToAnthropic(data, model) {
86237
86395
  class OpenAIShimBeta {
86238
86396
  messages;
86239
86397
  reasoningEffort;
86240
- constructor(defaultHeaders, reasoningEffort, providerOverride) {
86241
- this.messages = new OpenAIShimMessages(defaultHeaders, reasoningEffort, providerOverride);
86398
+ constructor(defaultHeaders, reasoningEffort, providerOverride, source) {
86399
+ this.messages = new OpenAIShimMessages(defaultHeaders, reasoningEffort, providerOverride, source);
86242
86400
  this.reasoningEffort = reasoningEffort;
86243
86401
  }
86244
86402
  }
@@ -86260,7 +86418,7 @@ function createOpenAIShimClient(options) {
86260
86418
  }
86261
86419
  const beta = new OpenAIShimBeta({
86262
86420
  ...options.defaultHeaders ?? {}
86263
- }, options.reasoningEffort, options.providerOverride);
86421
+ }, options.reasoningEffort, options.providerOverride, options.source);
86264
86422
  return {
86265
86423
  beta,
86266
86424
  messages: beta.messages
@@ -86279,7 +86437,9 @@ var init_shim2 = __esm(() => {
86279
86437
  init_schemaSanitizer();
86280
86438
  init_providerProfile();
86281
86439
  init_capabilities2();
86440
+ init_httpObservability();
86282
86441
  init_canonical();
86442
+ init_requestSideChannels();
86283
86443
  OpenAIShimStream = class OpenAIShimStream {
86284
86444
  generator;
86285
86445
  controller = new AbortController;
@@ -86376,7 +86536,8 @@ async function getNormalizedClient({
86376
86536
  defaultHeaders: safeHeaders,
86377
86537
  maxRetries,
86378
86538
  timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10),
86379
- providerOverride
86539
+ providerOverride,
86540
+ source
86380
86541
  });
86381
86542
  }
86382
86543
  const transportOverride = getQueryEnvVar(QUERY_ENV_KEY_TRANSPORT_OVERRIDE);
@@ -86386,7 +86547,8 @@ async function getNormalizedClient({
86386
86547
  return createOpenAIShimClient2({
86387
86548
  defaultHeaders,
86388
86549
  maxRetries,
86389
- timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10)
86550
+ timeout: parseInt(process.env.API_TIMEOUT_MS || String(600000), 10),
86551
+ source
86390
86552
  });
86391
86553
  }
86392
86554
  const stagingOauthBaseUrl = process.env.USER_TYPE === "ant" && isEnvTruthy(process.env.USE_STAGING_OAUTH) ? getOauthConfig().BASE_API_URL : undefined;
@@ -86438,42 +86600,49 @@ function buildFetch(fetchOverride, source) {
86438
86600
  const url3 = input instanceof Request ? input.url : String(input);
86439
86601
  const method = init?.method ?? (input instanceof Request ? input.method : "GET");
86440
86602
  const requestId = headers.get(CLIENT_REQUEST_ID_HEADER) ?? randomUUID();
86603
+ const endpoint = classifyModelHttpEndpoint(url3);
86441
86604
  try {
86442
86605
  logForDebugging2(`[API REQUEST] ${new URL(url3).pathname} ${CLIENT_REQUEST_ID_HEADER}=${requestId} source=${source ?? "unknown"}`);
86443
86606
  } catch {}
86444
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
+ });
86445
86619
  try {
86446
- emitHttp({
86447
- type: "request_start",
86620
+ const response = await inner(input, { ...init, headers });
86621
+ emitSdkHttp({
86622
+ type: "response_start",
86448
86623
  requestId,
86449
- method,
86450
- url: url3,
86624
+ status: response.status,
86625
+ durationMs: Date.now() - requestStartedAt,
86451
86626
  source,
86452
- timestamp: requestStartedAt
86627
+ endpoint,
86628
+ attempt: 1,
86629
+ maxAttempts: 1,
86630
+ timestamp: Date.now()
86453
86631
  });
86454
- } catch {}
86455
- try {
86456
- const response = await inner(input, { ...init, headers });
86457
- try {
86458
- emitHttp({
86459
- type: "response_start",
86460
- requestId,
86461
- status: response.status,
86462
- durationMs: Date.now() - requestStartedAt,
86463
- timestamp: Date.now()
86464
- });
86465
- } catch {}
86466
86632
  return response;
86467
86633
  } catch (err) {
86468
- try {
86469
- emitHttp({
86470
- type: "error",
86471
- requestId,
86472
- error: err instanceof Error ? err : new Error(String(err)),
86473
- durationMs: Date.now() - requestStartedAt,
86474
- timestamp: Date.now()
86475
- });
86476
- } 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
+ });
86477
86646
  throw err;
86478
86647
  }
86479
86648
  };
@@ -86492,7 +86661,7 @@ var init_clientFactory = __esm(() => {
86492
86661
  init_oauth();
86493
86662
  init_debug();
86494
86663
  init_envUtils();
86495
- init_observer();
86664
+ init_httpObservability();
86496
86665
  });
86497
86666
 
86498
86667
  // src/providers/anthropic/index.ts
@@ -92628,7 +92797,7 @@ function parseReasoningEffort(value) {
92628
92797
  if (!value)
92629
92798
  return;
92630
92799
  const normalized = value.trim().toLowerCase();
92631
- if (normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "xhigh") {
92800
+ if (normalized === "none" || normalized === "minimal" || normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "xhigh") {
92632
92801
  return normalized;
92633
92802
  }
92634
92803
  return;
@@ -92718,7 +92887,8 @@ function normalizeGithubModelsApiModel(requestedModel) {
92718
92887
  return segment;
92719
92888
  }
92720
92889
  function resolveProviderTransport(options) {
92721
- 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"));
92722
92892
  const envOverride = options?.transportOverride ?? getQueryEnvVar(QUERY_ENV_KEY_TRANSPORT_OVERRIDE);
92723
92893
  if (envOverride && envOverride !== "auto") {
92724
92894
  let normalized;
@@ -92728,7 +92898,8 @@ function resolveProviderTransport(options) {
92728
92898
  } else {
92729
92899
  normalized = envOverride;
92730
92900
  }
92731
- 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(/\/+$/, "");
92732
92903
  return { transport: normalized, baseUrl: baseUrl2 };
92733
92904
  }
92734
92905
  const modelForDetection = options?.model?.trim() ?? "";
@@ -92749,7 +92920,10 @@ function resolveProviderRequest(options) {
92749
92920
  transportOverride: options?.transportOverride
92750
92921
  });
92751
92922
  const resolvedModel = transport === "chat_completions" && isEnvTruthy(getQueryEnvVar("CLAUDE_CODE_USE_GITHUB")) ? normalizeGithubModelsApiModel(requestedModel) : descriptor.baseModel;
92752
- const reasoning = options?.reasoningEffortOverride ? { effort: options.reasoningEffortOverride } : descriptor.reasoning;
92923
+ const hasReasoningEffortOverride = !!options && Object.prototype.hasOwnProperty.call(options, "reasoningEffortOverride");
92924
+ const rawEnvReasoningEffortOverride = getQueryEnvVar(QUERY_ENV_KEY_REASONING_EFFORT_OVERRIDE);
92925
+ const envReasoningEffortOverride = parseReasoningEffort(rawEnvReasoningEffortOverride);
92926
+ const reasoning = hasReasoningEffortOverride ? options?.reasoningEffortOverride ? { effort: options.reasoningEffortOverride } : undefined : rawEnvReasoningEffortOverride === QUERY_ENV_VALUE_REASONING_EFFORT_CLEAR ? undefined : envReasoningEffortOverride ? { effort: envReasoningEffortOverride } : descriptor.reasoning;
92753
92927
  return {
92754
92928
  transport,
92755
92929
  requestedModel,
@@ -92860,7 +93034,7 @@ function getReasoningEffortForModel(model) {
92860
93034
  const aliasConfig = CODEX_ALIAS_MODELS[alias];
92861
93035
  return aliasConfig?.reasoningEffort;
92862
93036
  }
92863
- 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_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;
92864
93038
  var init_config3 = __esm(() => {
92865
93039
  init_envUtils();
92866
93040
  init_state2();
@@ -94524,7 +94698,7 @@ function printStartupScreen() {
94524
94698
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
94525
94699
  out.push(boxRow(sRow, W2, sLen));
94526
94700
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
94527
- out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.12"}${RESET}`);
94701
+ out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.14"}${RESET}`);
94528
94702
  out.push("");
94529
94703
  process.stdout.write(out.join(`
94530
94704
  `) + `
@@ -96190,6 +96364,11 @@ var FINGERPRINT_SALT = "59cf53e54c78";
96190
96364
  var init_fingerprint = () => {};
96191
96365
 
96192
96366
  // src/session/sideQuery.ts
96367
+ function headersForBetas(betas) {
96368
+ if (!betas || betas.length === 0)
96369
+ return;
96370
+ return { "anthropic-beta": betas.join(",") };
96371
+ }
96193
96372
  function extractFirstUserMessageText(messages) {
96194
96373
  const firstUserMessage = messages.find((m) => m.role === "user");
96195
96374
  if (!firstUserMessage)
@@ -96252,7 +96431,7 @@ async function sideQuery(opts) {
96252
96431
  }
96253
96432
  const normalizedModel = normalizeModelStringForAPI(model);
96254
96433
  const start = Date.now();
96255
- const response = await client.beta.messages.create({
96434
+ const response = await client.messages.create({
96256
96435
  model: normalizedModel,
96257
96436
  max_tokens,
96258
96437
  system: systemBlocks,
@@ -96263,9 +96442,12 @@ async function sideQuery(opts) {
96263
96442
  ...temperature !== undefined && { temperature },
96264
96443
  ...stop_sequences && { stop_sequences },
96265
96444
  ...thinkingConfig && { thinking: thinkingConfig },
96266
- ...betas.length > 0 && { betas },
96267
- metadata: getAPIMetadata()
96268
- }, { signal });
96445
+ metadata: getAPIMetadata(),
96446
+ ...getExtraBodyParams()
96447
+ }, {
96448
+ signal,
96449
+ ...betas.length > 0 ? { headers: headersForBetas(betas) } : {}
96450
+ });
96269
96451
  const requestId = response._request_id ?? undefined;
96270
96452
  const now = Date.now();
96271
96453
  const lastCompletion = getLastApiCompletionTimestamp();
@@ -113069,15 +113251,16 @@ function isMaxTokensCapEnabled() {
113069
113251
  }
113070
113252
  function getMaxOutputTokensForModel(model, opts) {
113071
113253
  const maxOutputTokens = getModelMaxOutputTokens(model);
113072
- const defaultTokens = isMaxTokensCapEnabled() ? Math.min(maxOutputTokens.default, CAPPED_DEFAULT_MAX_TOKENS) : maxOutputTokens.default;
113254
+ const upperLimit = opts?.upperLimitOverride !== undefined && Number.isFinite(opts.upperLimitOverride) && opts.upperLimitOverride >= 1 ? Math.floor(opts.upperLimitOverride) : maxOutputTokens.upperLimit;
113255
+ const defaultTokens = isMaxTokensCapEnabled() ? Math.min(maxOutputTokens.default, CAPPED_DEFAULT_MAX_TOKENS, upperLimit) : Math.min(maxOutputTokens.default, upperLimit);
113073
113256
  if (opts?.override !== undefined) {
113074
- if (!Number.isFinite(opts.override) || opts.override < 1 || opts.override > maxOutputTokens.upperLimit) {
113075
- console.warn(`[opencow] Options.maxOutputTokens=${opts.override} out of range ` + `[1, ${maxOutputTokens.upperLimit}] for model ${model}; clamping.`);
113257
+ if (!Number.isFinite(opts.override) || opts.override < 1 || opts.override > upperLimit) {
113258
+ console.warn(`[opencow] Options.maxOutputTokens=${opts.override} out of range ` + `[1, ${upperLimit}] for model ${model}; clamping.`);
113076
113259
  }
113077
- const clamped = Math.min(Math.max(1, Math.floor(opts.override)), maxOutputTokens.upperLimit);
113260
+ const clamped = Math.min(Math.max(1, Math.floor(opts.override)), upperLimit);
113078
113261
  return clamped;
113079
113262
  }
113080
- const result = validateBoundedIntEnvVar("CLAUDE_CODE_MAX_OUTPUT_TOKENS", resolveEnvVar("MAX_OUTPUT_TOKENS"), defaultTokens, maxOutputTokens.upperLimit);
113263
+ const result = validateBoundedIntEnvVar("CLAUDE_CODE_MAX_OUTPUT_TOKENS", resolveEnvVar("MAX_OUTPUT_TOKENS"), defaultTokens, upperLimit);
113081
113264
  return result.effective;
113082
113265
  }
113083
113266
  var init_maxTokens = __esm(() => {
@@ -118590,6 +118773,13 @@ function getDisableExtglobCommand(shellPath) {
118590
118773
  }
118591
118774
  return null;
118592
118775
  }
118776
+ function getHostProvidedPathCommand() {
118777
+ const path11 = getHostProvidedEnvVar("PATH");
118778
+ if (!path11) {
118779
+ return null;
118780
+ }
118781
+ return `export PATH=${quote([path11])}`;
118782
+ }
118593
118783
  async function createBashShellProvider(shellPath, options2) {
118594
118784
  let currentSandboxTmpDir;
118595
118785
  const snapshotPromise = options2?.skipSnapshot ? Promise.resolve(undefined) : createAndSaveSnapshot(shellPath).catch((error41) => {
@@ -118630,6 +118820,10 @@ async function createBashShellProvider(shellPath, options2) {
118630
118820
  const finalPath = getPlatform() === "windows" ? windowsPathToPosixPath(snapshotFilePath) : snapshotFilePath;
118631
118821
  commandParts.push(`source ${quote([finalPath])} 2>/dev/null || true`);
118632
118822
  }
118823
+ const hostPathCommand = getHostProvidedPathCommand();
118824
+ if (hostPathCommand) {
118825
+ commandParts.push(hostPathCommand);
118826
+ }
118633
118827
  const sessionEnvScript2 = await getSessionEnvironmentScript();
118634
118828
  if (sessionEnvScript2) {
118635
118829
  commandParts.push(sessionEnvScript2);
@@ -147231,12 +147425,13 @@ async function makeTestQuery() {
147231
147425
  });
147232
147426
  const messages = [{ role: "user", content: "quota" }];
147233
147427
  const betas = getModelBetas(model);
147234
- return anthropic.beta.messages.create({
147428
+ return anthropic.messages.create({
147235
147429
  model,
147236
147430
  max_tokens: 1,
147237
147431
  messages,
147238
- metadata: getAPIMetadata(),
147239
- ...betas.length > 0 ? { betas } : {}
147432
+ metadata: getAPIMetadata()
147433
+ }, {
147434
+ ...betas.length > 0 ? { headers: { "anthropic-beta": betas.join(",") } } : {}
147240
147435
  }).asResponse();
147241
147436
  }
147242
147437
  async function checkQuotaStatus() {
@@ -148393,6 +148588,17 @@ async function* withRetry(getClient, operation, options2) {
148393
148588
  status: error41.status,
148394
148589
  provider: getAPIProviderForStatsig()
148395
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
+ });
148396
148602
  if (persistent) {
148397
148603
  if (delayMs > 60000) {
148398
148604
  logEvent("tengu_api_persistent_retry_wait", {
@@ -148646,6 +148852,7 @@ var init_retry = __esm(() => {
148646
148852
  init_mocking();
148647
148853
  init_errors8();
148648
148854
  init_errorUtils();
148855
+ init_httpObservability();
148649
148856
  FOREGROUND_529_RETRY_SOURCES = new Set([
148650
148857
  "repl_main_thread",
148651
148858
  "repl_main_thread:outputStyle:custom",
@@ -243655,7 +243862,11 @@ async function* queryLoop(params, consumedCommandUuids) {
243655
243862
  if (false) {}
243656
243863
  const mediaRecoveryEnabled = reactiveCompact?.isReactiveCompactEnabled() ?? false;
243657
243864
  if (!compactionResult && querySource !== "compact" && querySource !== "session_memory" && !(reactiveCompact?.isReactiveCompactEnabled() && isAutoCompactEnabled()) && !collapseOwnsIt) {
243658
- const { isAtBlockingLimit } = calculateTokenWarningState(tokenCountWithEstimation(messagesForQuery) - snipTokensFreed, toolUseContext.options.mainLoopModel);
243865
+ const { isAtBlockingLimit } = calculateTokenWarningState(tokenCountWithEstimation(messagesForQuery) - snipTokensFreed, toolUseContext.options.mainLoopModel, {
243866
+ contextWindow: toolUseContext.options.contextWindow,
243867
+ maxOutputTokens: toolUseContext.options.maxOutputTokens,
243868
+ maxOutputTokensLimit: toolUseContext.options.maxOutputTokensLimit
243869
+ });
243659
243870
  if (isAtBlockingLimit) {
243660
243871
  yield createAssistantAPIErrorMessage({
243661
243872
  content: PROMPT_TOO_LONG_ERROR_MESSAGE,
@@ -243698,6 +243909,7 @@ async function* queryLoop(params, consumedCommandUuids) {
243698
243909
  allowedAgentTypes: toolUseContext.options.agentDefinitions.allowedAgentTypes,
243699
243910
  hasAppendSystemPrompt: !!toolUseContext.options.appendSystemPrompt,
243700
243911
  maxOutputTokensOverride,
243912
+ maxOutputTokensLimitOverride: params.maxOutputTokensLimitOverride,
243701
243913
  fetchOverride: dumpPromptsFetch,
243702
243914
  mcpTools: appState.mcp.tools,
243703
243915
  hasPendingMcpServers: appState.mcp.clients.some((c6) => c6.type === "pending"),
@@ -244407,7 +244619,7 @@ function getAnthropicEnvMetadata() {
244407
244619
  function getBuildAgeMinutes() {
244408
244620
  if (false)
244409
244621
  ;
244410
- const buildTime = new Date("2026-06-24T10:02:32.669Z").getTime();
244622
+ const buildTime = new Date("2026-07-07T07:10:57.155Z").getTime();
244411
244623
  if (isNaN(buildTime))
244412
244624
  return;
244413
244625
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -245008,6 +245220,7 @@ async function runForkedAgent({
245008
245220
  toolUseContext: isolatedToolUseContext,
245009
245221
  querySource,
245010
245222
  maxOutputTokensOverride: maxOutputTokens,
245223
+ maxOutputTokensLimitOverride: isolatedToolUseContext.options.maxOutputTokensLimit,
245011
245224
  maxTurns,
245012
245225
  skipCacheWrite
245013
245226
  })) {
@@ -264874,49 +265087,36 @@ assistant: Still waiting on the audit — that's one of the things it's checking
264874
265087
 
264875
265088
  <example>
264876
265089
  user: "Can you get a second opinion on whether this migration is safe?"
264877
- 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>
264878
265091
  <commentary>
264879
- 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.
264880
265093
  </commentary>
264881
265094
  ${AGENT_TOOL_NAME2}({
264882
265095
  name: "migration-review",
264883
265096
  description: "Independent migration review",
264884
- subagent_type: "code-reviewer",
264885
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?"
264886
265098
  })
264887
265099
  </example>
264888
265100
  `;
264889
265101
  const currentExamples = `Example usage:
264890
265102
 
264891
- <example_agent_descriptions>
264892
- "test-runner": use this agent after you are done writing code to run tests
264893
- "greeting-responder": use this agent to respond to user greetings with a friendly joke
264894
- </example_agent_descriptions>
264895
-
264896
265103
  <example>
264897
- user: "Please write a function that checks if a number is prime"
264898
- assistant: I'm going to use the ${FILE_WRITE_TOOL_NAME2} tool to write the following code:
264899
- <code>
264900
- function isPrime(n) {
264901
- if (n <= 1) return false
264902
- for (let i = 2; i * i <= n; i++) {
264903
- if (n % i === 0) return false
264904
- }
264905
- return true
264906
- }
264907
- </code>
265104
+ user: "Hello"
264908
265105
  <commentary>
264909
- 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.
264910
265107
  </commentary>
264911
- 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?"
264912
265109
  </example>
264913
265110
 
264914
265111
  <example>
264915
- user: "Hello"
265112
+ user: "Can you investigate whether this migration is safe?"
264916
265113
  <commentary>
264917
- 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.
264918
265115
  </commentary>
264919
- 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
+ })
264920
265120
  </example>
264921
265121
  `;
264922
265122
  const listViaAttachment = shouldInjectAgentListInMessages();
@@ -264929,7 +265129,7 @@ The ${AGENT_TOOL_NAME2} tool launches specialized agents (subprocesses) that aut
264929
265129
 
264930
265130
  ${agentListSection}
264931
265131
 
264932
- ${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.`}`;
264933
265133
  if (isCoordinator) {
264934
265134
  return shared2;
264935
265135
  }
@@ -264957,7 +265157,7 @@ Usage notes:
264957
265157
  - The agent's outputs should generally be trusted
264958
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"}
264959
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.
264960
- - 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.
264961
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" ? `
264962
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() ? `
264963
265163
  - The run_in_background, name, team_name, and mode parameters are not available in this context. Only synchronous subagents are supported.` : isTeammate() ? `
@@ -264972,7 +265172,6 @@ var init_prompt8 = __esm(() => {
264972
265172
  init_teammate();
264973
265173
  init_teammateContext();
264974
265174
  init_prompt();
264975
- init_prompt2();
264976
265175
  init_constants4();
264977
265176
  init_forkSubagent();
264978
265177
  init_state2();
@@ -288389,7 +288588,7 @@ async function loadPluginSettings(pluginPath, manifest) {
288389
288588
  try {
288390
288589
  const content = await getFsImplementation().readFile(settingsJsonPath, { encoding: "utf-8" });
288391
288590
  const parsed = jsonParse(content);
288392
- if (isRecord(parsed)) {
288591
+ if (isRecord2(parsed)) {
288393
288592
  const filtered = parsePluginSettings(parsed);
288394
288593
  if (filtered) {
288395
288594
  logForDebugging2(`Loaded settings from settings.json for plugin ${manifest.name}`);
@@ -289079,7 +289278,7 @@ function cachePluginSettings(plugins) {
289079
289278
  logForDebugging2(`Cached plugin settings with keys: ${Object.keys(settings).join(", ")}`);
289080
289279
  }
289081
289280
  }
289082
- function isRecord(value) {
289281
+ function isRecord2(value) {
289083
289282
  return typeof value === "object" && value !== null && !Array.isArray(value);
289084
289283
  }
289085
289284
  var PluginSettingsSchema, loadAllPlugins, loadAllPluginsCacheOnly;
@@ -302297,7 +302496,17 @@ ${formattedSummary}`;
302297
302496
  if (transcriptPath) {
302298
302497
  baseSummary += `
302299
302498
 
302300
- If you need specific details from before compaction (like exact code snippets, error messages, or content you generated), read the full transcript at: ${transcriptPath}`;
302499
+ IMPORTANT Transcript recovery protocol:
302500
+ The full pre-compaction conversation is preserved at: ${transcriptPath}
302501
+ When you encounter ANY of these situations, you MUST use the Read tool to search the transcript for the missing context BEFORE responding:
302502
+ - You are unsure about a specific detail (file path, function name, error message, code snippet, user preference)
302503
+ - The user references something you cannot find in the summary above
302504
+ - You need exact code that was previously read or written
302505
+ - You are about to make a decision but feel uncertain whether the user already gave guidance on it
302506
+ - A tool name, skill name, or configuration was discussed but is not in the summary
302507
+
302508
+ The transcript is a JSONL file. Read its tail (last 500–2000 lines) first for the most recent context; if that doesn't resolve the gap, read earlier sections.
302509
+ Do NOT guess or hallucinate details that might have been discussed — read the transcript instead.`;
302301
302510
  }
302302
302511
  if (recentMessagesPreserved) {
302303
302512
  baseSummary += `
@@ -302364,6 +302573,7 @@ Your summary should include the following sections:
302364
302573
  8. Current Work: Describe in detail precisely what was being worked on immediately before this summary request, paying special attention to the most recent messages from both user and assistant. Include file names and code snippets where applicable.
302365
302574
  9. Optional Next Step: List the next step that you will take that is related to the most recent work you were doing. IMPORTANT: ensure that this step is DIRECTLY in line with the user's most recent explicit requests, and the task you were working on immediately before this summary request. If your last task was concluded, then only list next steps if they are explicitly in line with the users request. Do not start on tangential requests or really old requests that were already completed without confirming with the user first.
302366
302575
  If there is a next step, include direct quotes from the most recent conversation showing exactly what task you were working on and where you left off. This should be verbatim to ensure there's no drift in task interpretation.
302576
+ 10. Uncertain or Incomplete Context: List any items where you are not fully confident in the details — e.g., a tool/skill name you vaguely recall but cannot confirm, a user preference you think was stated but cannot pinpoint, or a decision whose rationale is unclear. Mark each with [NEEDS_TRANSCRIPT_LOOKUP] so the post-compaction assistant knows to read the transcript file for these specific items before acting on them.
302367
302577
 
302368
302578
  Here's an example of how your output should be structured:
302369
302579
 
@@ -302414,10 +302624,14 @@ Here's an example of how your output should be structured:
302414
302624
  9. Optional Next Step:
302415
302625
  [Optional Next step to take]
302416
302626
 
302627
+ 10. Uncertain or Incomplete Context:
302628
+ - [Item with unclear details] [NEEDS_TRANSCRIPT_LOOKUP]
302629
+ - [...]
302630
+
302417
302631
  </summary>
302418
302632
  </example>
302419
302633
 
302420
- Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.
302634
+ Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.
302421
302635
 
302422
302636
  There may be additional summarization instructions provided in the included context. If so, remember to follow these instructions when creating the above summary. Examples of instructions include:
302423
302637
  <example>
@@ -302445,6 +302659,7 @@ Your summary should include the following sections:
302445
302659
  7. Pending Tasks: Outline any pending tasks from the recent messages.
302446
302660
  8. Current Work: Describe precisely what was being worked on immediately before this summary request.
302447
302661
  9. Optional Next Step: List the next step related to the most recent work. Include direct quotes from the most recent conversation.
302662
+ 10. Uncertain or Incomplete Context: List any items where details are unclear or potentially missing from the recent messages. Mark each with [NEEDS_TRANSCRIPT_LOOKUP].
302448
302663
 
302449
302664
  Here's an example of how your output should be structured:
302450
302665
 
@@ -302485,6 +302700,9 @@ Here's an example of how your output should be structured:
302485
302700
  9. Optional Next Step:
302486
302701
  [Optional Next step to take]
302487
302702
 
302703
+ 10. Uncertain or Incomplete Context:
302704
+ - [Item with unclear details] [NEEDS_TRANSCRIPT_LOOKUP]
302705
+
302488
302706
  </summary>
302489
302707
  </example>
302490
302708
 
@@ -302505,6 +302723,7 @@ Your summary should include the following sections:
302505
302723
  7. Pending Tasks: Outline any pending tasks.
302506
302724
  8. Work Completed: Describe what was accomplished by the end of this portion.
302507
302725
  9. Context for Continuing Work: Summarize any context, decisions, or state that would be needed to understand and continue the work in subsequent messages.
302726
+ 10. Uncertain or Incomplete Context: List any items where details are unclear or potentially incomplete. Mark each with [NEEDS_TRANSCRIPT_LOOKUP] so the continuing session knows to look them up in the transcript before acting.
302508
302727
 
302509
302728
  Here's an example of how your output should be structured:
302510
302729
 
@@ -302545,6 +302764,9 @@ Here's an example of how your output should be structured:
302545
302764
  9. Context for Continuing Work:
302546
302765
  [Key context, decisions, or state needed to continue the work]
302547
302766
 
302767
+ 10. Uncertain or Incomplete Context:
302768
+ - [Item with unclear details] [NEEDS_TRANSCRIPT_LOOKUP]
302769
+
302548
302770
  </summary>
302549
302771
  </example>
302550
302772
 
@@ -303199,7 +303421,10 @@ async function streamCompactSummary({
303199
303421
  toolChoice: undefined,
303200
303422
  isNonInteractiveSession: context4.options.isNonInteractiveSession,
303201
303423
  hasAppendSystemPrompt: !!context4.options.appendSystemPrompt,
303202
- maxOutputTokensOverride: Math.min(COMPACT_MAX_OUTPUT_TOKENS, getMaxOutputTokensForModel(context4.options.mainLoopModel)),
303424
+ maxOutputTokensOverride: Math.min(COMPACT_MAX_OUTPUT_TOKENS, getMaxOutputTokensForModel(context4.options.mainLoopModel, {
303425
+ upperLimitOverride: context4.options.maxOutputTokensLimit
303426
+ })),
303427
+ maxOutputTokensLimitOverride: context4.options.maxOutputTokensLimit,
303203
303428
  querySource: "compact",
303204
303429
  agents: context4.options.agentDefinitions.activeAgents,
303205
303430
  mcpTools: [],
@@ -304096,7 +304321,10 @@ var init_sessionMemoryCompact = __esm(() => {
304096
304321
 
304097
304322
  // src/controller/compact/autoCompact.ts
304098
304323
  function getEffectiveContextWindowSize(model, opts) {
304099
- const reservedTokensForSummary = Math.min(getMaxOutputTokensForModel(model, { override: opts?.maxOutputTokens }), MAX_OUTPUT_TOKENS_FOR_SUMMARY);
304324
+ const reservedTokensForSummary = Math.min(getMaxOutputTokensForModel(model, {
304325
+ override: opts?.maxOutputTokens,
304326
+ upperLimitOverride: opts?.maxOutputTokensLimit
304327
+ }), MAX_OUTPUT_TOKENS_FOR_SUMMARY);
304100
304328
  let contextWindow = getContextWindowForModel(model, getSdkBetas(), {
304101
304329
  override: opts?.contextWindow
304102
304330
  });
@@ -304182,7 +304410,8 @@ async function autoCompactIfNeeded(messages, toolUseContext, cacheSafeParams, qu
304182
304410
  const model = toolUseContext.options.mainLoopModel;
304183
304411
  const opts = {
304184
304412
  contextWindow: toolUseContext.options.contextWindow,
304185
- maxOutputTokens: toolUseContext.options.maxOutputTokens
304413
+ maxOutputTokens: toolUseContext.options.maxOutputTokens,
304414
+ maxOutputTokensLimit: toolUseContext.options.maxOutputTokensLimit
304186
304415
  };
304187
304416
  const shouldCompact = await shouldAutoCompact(messages, model, querySource, snipTokensFreed, opts);
304188
304417
  if (!shouldCompact) {
@@ -305287,6 +305516,11 @@ var init_toolSearch = __esm(() => {
305287
305516
  });
305288
305517
 
305289
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
+ }
305290
305524
  function hasThinkingBlocks(messages) {
305291
305525
  for (const message of messages) {
305292
305526
  if (message.role === "assistant" && Array.isArray(message.content)) {
@@ -305361,17 +305595,18 @@ async function countMessagesTokensWithAPI(messages, tools) {
305361
305595
  model,
305362
305596
  source: "count_tokens"
305363
305597
  });
305364
- const response = await anthropic.beta.messages.countTokens({
305598
+ const response = await anthropic.messages.countTokens({
305365
305599
  model: normalizeModelStringForAPI(model),
305366
305600
  messages: messages.length > 0 ? messages : [{ role: "user", content: "foo" }],
305367
305601
  tools,
305368
- ...betas.length > 0 && { betas },
305369
305602
  ...containsThinking && {
305370
305603
  thinking: {
305371
305604
  type: "enabled",
305372
305605
  budget_tokens: TOKEN_COUNT_THINKING_BUDGET
305373
305606
  }
305374
305607
  }
305608
+ }, {
305609
+ ...betas.length > 0 ? { headers: headersForBetas2(betas) } : {}
305375
305610
  });
305376
305611
  if (typeof response.input_tokens !== "number") {
305377
305612
  return null;
@@ -305410,12 +305645,11 @@ async function countTokensViaHaikuFallback(messages, tools) {
305410
305645
  const normalizedMessages = stripToolSearchFieldsFromMessages(messages);
305411
305646
  const messagesToSend = normalizedMessages.length > 0 ? normalizedMessages : [{ role: "user", content: "count" }];
305412
305647
  const betas = getModelBetas(model);
305413
- const response = await anthropic.beta.messages.create({
305648
+ const response = await anthropic.messages.create({
305414
305649
  model: normalizeModelStringForAPI(model),
305415
305650
  max_tokens: containsThinking ? TOKEN_COUNT_MAX_TOKENS : 1,
305416
305651
  messages: messagesToSend,
305417
305652
  tools: tools.length > 0 ? tools : undefined,
305418
- ...betas.length > 0 && { betas },
305419
305653
  metadata: getAPIMetadata(),
305420
305654
  ...getExtraBodyParams(),
305421
305655
  ...containsThinking && {
@@ -305424,6 +305658,8 @@ async function countTokensViaHaikuFallback(messages, tools) {
305424
305658
  budget_tokens: TOKEN_COUNT_THINKING_BUDGET
305425
305659
  }
305426
305660
  }
305661
+ }, {
305662
+ ...betas.length > 0 ? { headers: headersForBetas2(betas) } : {}
305427
305663
  });
305428
305664
  const usage = response.usage;
305429
305665
  const inputTokens = usage.input_tokens;
@@ -307224,6 +307460,11 @@ var init_apiMicrocompact = __esm(() => {
307224
307460
 
307225
307461
  // src/controller/loop.ts
307226
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
+ }
307227
307468
  function adjustParamsForNonStreaming(params, maxTokensCap) {
307228
307469
  const cappedMaxTokens = Math.min(params.max_tokens, maxTokensCap);
307229
307470
  const adjustedParams = { ...params };
@@ -307301,13 +307542,16 @@ async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFr
307301
307542
  captureRequest(retryParams);
307302
307543
  onAttempt(attempt, start, retryParams.max_tokens);
307303
307544
  const adjustedParams = adjustParamsForNonStreaming(retryParams, MAX_NON_STREAMING_TOKENS);
307545
+ const { betas: requestBetas, ...standardParams } = adjustedParams;
307546
+ const headers = headersForBetas3(requestBetas);
307304
307547
  try {
307305
- return await anthropic.beta.messages.create({
307306
- ...adjustedParams,
307307
- model: normalizeModelStringForAPI(adjustedParams.model)
307548
+ return await anthropic.messages.create({
307549
+ ...standardParams,
307550
+ model: normalizeModelStringForAPI(standardParams.model)
307308
307551
  }, {
307309
307552
  signal: retryOptions.signal,
307310
- timeout: fallbackTimeoutMs
307553
+ timeout: fallbackTimeoutMs,
307554
+ ...headers ? { headers } : {}
307311
307555
  });
307312
307556
  } catch (err2) {
307313
307557
  if (err2 instanceof APIUserAbortError)
@@ -307630,7 +307874,10 @@ ${deferredToolList}
307630
307874
  betasParams.push(STRUCTURED_OUTPUTS_BETA_HEADER);
307631
307875
  }
307632
307876
  }
307633
- const maxOutputTokens2 = retryContext?.maxTokensOverride || options2.maxOutputTokensOverride || getMaxOutputTokensForModel(options2.model);
307877
+ const maxOutputTokens2 = retryContext?.maxTokensOverride || getMaxOutputTokensForModel(options2.model, {
307878
+ override: options2.maxOutputTokensOverride,
307879
+ upperLimitOverride: options2.maxOutputTokensLimitOverride
307880
+ });
307634
307881
  const hasThinking = thinkingConfig.type !== "disabled" && !isEnvTruthy(resolveEnvVar("DISABLE_THINKING"));
307635
307882
  let thinking = undefined;
307636
307883
  if (hasThinking && modelSupportsThinking(options2.model)) {
@@ -307786,11 +308033,19 @@ ${deferredToolList}
307786
308033
  headlessProfilerCheckpoint("api_request_sent");
307787
308034
  }
307788
308035
  clientRequestId = shouldSendClientRequestId() ? randomUUID17() : undefined;
307789
- const result = await anthropic.beta.messages.create({ ...params, stream: true }, {
307790
- signal,
308036
+ const { betas: requestBetas, ...standardParams } = params;
308037
+ const headers = {
308038
+ ...headersForBetas3(requestBetas) ?? {},
307791
308039
  ...clientRequestId && {
307792
- headers: { [CLIENT_REQUEST_ID_HEADER]: clientRequestId }
308040
+ [CLIENT_REQUEST_ID_HEADER]: clientRequestId
307793
308041
  }
308042
+ };
308043
+ const result = await anthropic.messages.create({
308044
+ ...standardParams,
308045
+ stream: true
308046
+ }, {
308047
+ signal,
308048
+ ...Object.keys(headers).length > 0 ? { headers } : {}
307794
308049
  }).withResponse();
307795
308050
  queryCheckpoint("query_response_headers_received");
307796
308051
  streamRequestId = result.request_id;
@@ -312103,6 +312358,11 @@ function stripToolReferenceBlocksFromUserMessage(message) {
312103
312358
  }
312104
312359
  };
312105
312360
  }
312361
+ function omitToolSearchCaller(block2) {
312362
+ const blockWithoutCaller = { ...block2 };
312363
+ delete blockWithoutCaller.caller;
312364
+ return blockWithoutCaller;
312365
+ }
312106
312366
  function stripCallerFieldFromAssistantMessage(message) {
312107
312367
  const hasCallerField = message.message.content.some((block2) => block2.type === "tool_use" && ("caller" in block2) && block2.caller !== null);
312108
312368
  if (!hasCallerField) {
@@ -312116,12 +312376,7 @@ function stripCallerFieldFromAssistantMessage(message) {
312116
312376
  if (block2.type !== "tool_use") {
312117
312377
  return block2;
312118
312378
  }
312119
- return {
312120
- type: "tool_use",
312121
- id: block2.id,
312122
- name: block2.name,
312123
- input: block2.input
312124
- };
312379
+ return omitToolSearchCaller(block2);
312125
312380
  })
312126
312381
  }
312127
312382
  };
@@ -312398,9 +312653,9 @@ function normalizeMessagesForAPI(messages, tools = []) {
312398
312653
  input: normalizedInput
312399
312654
  };
312400
312655
  }
312656
+ const blockWithoutCaller = omitToolSearchCaller(block2);
312401
312657
  return {
312402
- type: "tool_use",
312403
- id: block2.id,
312658
+ ...blockWithoutCaller,
312404
312659
  name: canonicalName,
312405
312660
  input: normalizedInput
312406
312661
  };
@@ -312597,6 +312852,15 @@ function mergeUserContentBlocks(a2, b) {
312597
312852
  }
312598
312853
  return [...a2.slice(0, -1), smooshed, ...toolResults];
312599
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
+ }
312600
312864
  function normalizeContentFromAPI(contentBlocks, tools, agentId) {
312601
312865
  if (!contentBlocks) {
312602
312866
  return [];
@@ -312635,6 +312899,7 @@ function normalizeContentFromAPI(contentBlocks, tools, agentId) {
312635
312899
  }
312636
312900
  return {
312637
312901
  ...contentBlock,
312902
+ id: normalizeToolUseIdFromAPI(contentBlock),
312638
312903
  input: normalizedInput
312639
312904
  };
312640
312905
  }
@@ -458141,6 +458406,11 @@ var init_useDeferredHookMessages = __esm(() => {
458141
458406
  });
458142
458407
 
458143
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
+ }
458144
458414
  async function verifyApiKey(apiKey, isNonInteractiveSession) {
458145
458415
  if (isNonInteractiveSession) {
458146
458416
  return true;
@@ -458155,14 +458425,15 @@ async function verifyApiKey(apiKey, isNonInteractiveSession) {
458155
458425
  source: "verify_api_key"
458156
458426
  }), async (anthropic) => {
458157
458427
  const messages = [{ role: "user", content: "test" }];
458158
- await anthropic.beta.messages.create({
458428
+ await anthropic.messages.create({
458159
458429
  model,
458160
458430
  max_tokens: 1,
458161
458431
  messages,
458162
458432
  temperature: 1,
458163
- ...betas.length > 0 && { betas },
458164
458433
  metadata: getAPIMetadata(),
458165
458434
  ...getExtraBodyParams()
458435
+ }, {
458436
+ ...betas.length > 0 ? { headers: headersForBetas4(betas) } : {}
458166
458437
  });
458167
458438
  return true;
458168
458439
  }, { maxRetries: 2, model, thinkingConfig: { type: "disabled" } }));
@@ -460063,8 +460334,10 @@ async function processUserInputBase(input, mode, setToolJSX, context6, pastedCon
460063
460334
  }
460064
460335
  }
460065
460336
  }
460337
+ const processSlashCommand = getProcessSlashCommand();
460066
460338
  if (false) {}
460067
- const shouldExtractAttachments = !skipAttachments && inputString !== null && (mode !== "prompt" || effectiveSkipSlash || !inputString.startsWith("/"));
460339
+ const shouldFallbackSlashToPrompt = inputString !== null && mode === "prompt" && !effectiveSkipSlash && inputString.startsWith("/") && !processSlashCommand;
460340
+ const shouldExtractAttachments = !skipAttachments && inputString !== null && (mode !== "prompt" || effectiveSkipSlash || !inputString.startsWith("/") || shouldFallbackSlashToPrompt);
460068
460341
  queryCheckpoint("query_attachment_loading_start");
460069
460342
  const attachmentMessages = shouldExtractAttachments ? await toArray2(getAttachmentMessages(inputString, context6, ideSelection ?? null, [], messages, querySource)) : [];
460070
460343
  queryCheckpoint("query_attachment_loading_end");
@@ -460075,11 +460348,10 @@ async function processUserInputBase(input, mode, setToolJSX, context6, pastedCon
460075
460348
  return addImageMetadataMessage(await processBashCommand(inputString, precedingInputBlocks, attachmentMessages, context6, setToolJSX), imageMetadataTexts);
460076
460349
  }
460077
460350
  if (inputString !== null && !effectiveSkipSlash && inputString.startsWith("/")) {
460078
- const processSlashCommand = getProcessSlashCommand();
460079
- if (!processSlashCommand)
460080
- throw new SlashCommandHandlerNotRegisteredError("slash");
460081
- const slashResult = await processSlashCommand(inputString, precedingInputBlocks, imageContentBlocks, attachmentMessages, context6, setToolJSX, uuid3, isAlreadyProcessing, canUseTool);
460082
- return addImageMetadataMessage(slashResult, imageMetadataTexts);
460351
+ if (processSlashCommand) {
460352
+ const slashResult = await processSlashCommand(inputString, precedingInputBlocks, imageContentBlocks, attachmentMessages, context6, setToolJSX, uuid3, isAlreadyProcessing, canUseTool);
460353
+ return addImageMetadataMessage(slashResult, imageMetadataTexts);
460354
+ }
460083
460355
  }
460084
460356
  if (inputString !== null && mode === "prompt") {
460085
460357
  const trimmedInput = inputString.trim();
@@ -468371,21 +468643,21 @@ function extractLspInfoFromManifest(lspServers) {
468371
468643
  }
468372
468644
  return extractFromServerConfigRecord(lspServers);
468373
468645
  }
468374
- function isRecord2(value) {
468646
+ function isRecord3(value) {
468375
468647
  return typeof value === "object" && value !== null;
468376
468648
  }
468377
468649
  function extractFromServerConfigRecord(serverConfigs) {
468378
468650
  const extensions = new Set;
468379
468651
  let command = null;
468380
468652
  for (const [_serverName, config2] of Object.entries(serverConfigs)) {
468381
- if (!isRecord2(config2)) {
468653
+ if (!isRecord3(config2)) {
468382
468654
  continue;
468383
468655
  }
468384
468656
  if (!command && typeof config2.command === "string") {
468385
468657
  command = config2.command;
468386
468658
  }
468387
468659
  const extMapping = config2.extensionToLanguage;
468388
- if (isRecord2(extMapping)) {
468660
+ if (isRecord3(extMapping)) {
468389
468661
  for (const ext of Object.keys(extMapping)) {
468390
468662
  extensions.add(ext.toLowerCase());
468391
468663
  }
@@ -479782,7 +480054,7 @@ function buildPrimarySection() {
479782
480054
  }, undefined, false, undefined, this);
479783
480055
  return [{
479784
480056
  label: "Version",
479785
- value: "0.4.12"
480057
+ value: "0.4.14"
479786
480058
  }, {
479787
480059
  label: "Session name",
479788
480060
  value: nameValue
@@ -483063,7 +483335,7 @@ var init_OverageCreditUpsell = __esm(() => {
483063
483335
  });
483064
483336
 
483065
483337
  // src/providers/codex/usage.ts
483066
- function isRecord3(value) {
483338
+ function isRecord4(value) {
483067
483339
  return typeof value === "object" && value !== null;
483068
483340
  }
483069
483341
  function asString(value) {
@@ -483082,7 +483354,7 @@ function toIsoFromUnixSeconds(value) {
483082
483354
  return new Date(seconds * 1000).toISOString();
483083
483355
  }
483084
483356
  function normalizeWindow(value) {
483085
- if (!isRecord3(value))
483357
+ if (!isRecord4(value))
483086
483358
  return;
483087
483359
  const usedPercent = asNumber(value.used_percent) ?? asNumber(value.usedPercent);
483088
483360
  if (usedPercent === undefined)
@@ -483099,7 +483371,7 @@ function normalizeWindow(value) {
483099
483371
  };
483100
483372
  }
483101
483373
  function normalizeCredits(value) {
483102
- if (!isRecord3(value))
483374
+ if (!isRecord4(value))
483103
483375
  return;
483104
483376
  const hasCredits = asBoolean(value.has_credits) ?? asBoolean(value.hasCredits) ?? false;
483105
483377
  const unlimited = asBoolean(value.unlimited) ?? false;
@@ -483114,7 +483386,7 @@ function normalizeCredits(value) {
483114
483386
  };
483115
483387
  }
483116
483388
  function normalizeSnapshot(value, fallbackLimitName) {
483117
- if (!isRecord3(value))
483389
+ if (!isRecord4(value))
483118
483390
  return;
483119
483391
  const limitName = asString(value.limit_name) ?? asString(value.limitName) ?? asString(value.limit_id) ?? asString(value.limitId) ?? fallbackLimitName;
483120
483392
  const primary = normalizeWindow(value.primary) ?? normalizeWindow(value.primary_window);
@@ -483134,7 +483406,7 @@ function normalizeSnapshotsFromCollection(value, defaultLimitName = "codex") {
483134
483406
  if (Array.isArray(value)) {
483135
483407
  return value.map((item, index) => normalizeSnapshot(item, index === 0 ? defaultLimitName : `${defaultLimitName}-${index + 1}`)).filter((item) => item !== undefined);
483136
483408
  }
483137
- if (!isRecord3(value))
483409
+ if (!isRecord4(value))
483138
483410
  return [];
483139
483411
  return Object.entries(value).map(([key, entry]) => normalizeSnapshot(entry, key)).filter((item) => item !== undefined);
483140
483412
  }
@@ -483168,7 +483440,7 @@ function normalizeCodexUsagePayload(payload) {
483168
483440
  snapshots: normalizeSnapshotsFromCollection(payload)
483169
483441
  };
483170
483442
  }
483171
- if (!isRecord3(payload)) {
483443
+ if (!isRecord4(payload)) {
483172
483444
  return { snapshots: [] };
483173
483445
  }
483174
483446
  if ("rate_limit" in payload || "code_review_rate_limit" in payload || "additional_rate_limits" in payload || "credits" in payload) {
@@ -533101,8 +533373,8 @@ var AGENT_CREATION_SYSTEM_PROMPT, AGENT_MEMORY_INSTRUCTIONS = `
533101
533373
  - [domain-specific item 3]"
533102
533374
 
533103
533375
  Examples of domain-specific memory instructions:
533104
- - For a code-reviewer: "Update your agent memory as you discover code patterns, style conventions, common issues, and architectural decisions in this codebase."
533105
- - 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."
533106
533378
  - For an architect: "Update your agent memory as you discover codepaths, library locations, key architectural decisions, and component relationships."
533107
533379
  - For a documentation writer: "Update your agent memory as you discover documentation patterns, API structures, and terminology conventions."
533108
533380
 
@@ -533151,29 +533423,30 @@ When a user describes what they want an agent to do, you will:
533151
533423
  - in the 'whenToUse' field of the JSON object, you should include examples of when this agent should be used.
533152
533424
  - examples should be of the form:
533153
533425
  - <example>
533154
- 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.
533155
533427
  user: "Please write a function that checks if a number is prime"
533156
533428
  assistant: "Here is the relevant function: "
533157
533429
  <function call omitted for brevity only for this example>
533158
533430
  <commentary>
533159
- 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.
533160
533432
  </commentary>
533161
- 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."
533162
533434
  </example>
533163
533435
  - <example>
533164
- Context: User is creating an agent to respond to the word "hello" with a friendly jok.
533165
- user: "Hello"
533166
- 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."
533167
533439
  <commentary>
533168
- 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.
533169
533441
  </commentary>
533170
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.
533171
533444
  - If the user mentioned or implied that the agent should be used proactively, you should include examples of this.
533172
533445
  - NOTE: Ensure that in the examples, you are making the assistant use the Agent tool and not simply respond directly to the task.
533173
533446
 
533174
533447
  Your output must be a valid JSON object with exactly these fields:
533175
533448
  {
533176
- "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.",
533177
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.",
533178
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"
533179
533452
  }
@@ -536104,7 +536377,7 @@ var init_bridge_kick = __esm(() => {
536104
536377
  var call58 = async () => {
536105
536378
  return {
536106
536379
  type: "text",
536107
- value: `${"99.0.0"} (built ${"2026-06-24T10:02:32.669Z"})`
536380
+ value: `${"99.0.0"} (built ${"2026-07-07T07:10:57.155Z"})`
536108
536381
  };
536109
536382
  }, version2, version_default;
536110
536383
  var init_version = __esm(() => {
@@ -558214,7 +558487,7 @@ function WelcomeV2() {
558214
558487
  dimColor: true,
558215
558488
  children: [
558216
558489
  "v",
558217
- "0.4.12",
558490
+ "0.4.14",
558218
558491
  " "
558219
558492
  ]
558220
558493
  }, undefined, true, undefined, this)
@@ -558414,7 +558687,7 @@ function WelcomeV2() {
558414
558687
  dimColor: true,
558415
558688
  children: [
558416
558689
  "v",
558417
- "0.4.12",
558690
+ "0.4.14",
558418
558691
  " "
558419
558692
  ]
558420
558693
  }, undefined, true, undefined, this)
@@ -558640,7 +558913,7 @@ function AppleTerminalWelcomeV2(t0) {
558640
558913
  dimColor: true,
558641
558914
  children: [
558642
558915
  "v",
558643
- "0.4.12",
558916
+ "0.4.14",
558644
558917
  " "
558645
558918
  ]
558646
558919
  }, undefined, true, undefined, this);
@@ -558894,7 +559167,7 @@ function AppleTerminalWelcomeV2(t0) {
558894
559167
  dimColor: true,
558895
559168
  children: [
558896
559169
  "v",
558897
- "0.4.12",
559170
+ "0.4.14",
558898
559171
  " "
558899
559172
  ]
558900
559173
  }, undefined, true, undefined, this);
@@ -569513,6 +569786,7 @@ class QueryEngine {
569513
569786
  maxTurns,
569514
569787
  maxBudgetUsd,
569515
569788
  maxOutputTokens,
569789
+ maxOutputTokensLimit,
569516
569790
  contextWindow,
569517
569791
  compact: compact2,
569518
569792
  taskBudget,
@@ -569602,6 +569876,7 @@ class QueryEngine {
569602
569876
  theme: resolveThemeSetting(getGlobalConfig().theme),
569603
569877
  maxBudgetUsd,
569604
569878
  maxOutputTokens,
569879
+ maxOutputTokensLimit,
569605
569880
  contextWindow,
569606
569881
  modelProviders: this.config.modelProviders,
569607
569882
  subagentDisallowedTools: this.config.subagentDisallowedTools
@@ -569707,6 +569982,7 @@ class QueryEngine {
569707
569982
  agentDefinitions: { activeAgents: agents2, allAgents: [] },
569708
569983
  maxBudgetUsd,
569709
569984
  maxOutputTokens,
569985
+ maxOutputTokensLimit,
569710
569986
  contextWindow,
569711
569987
  modelProviders: this.config.modelProviders,
569712
569988
  subagentDisallowedTools: this.config.subagentDisallowedTools
@@ -569827,6 +570103,7 @@ class QueryEngine {
569827
570103
  querySource: "sdk",
569828
570104
  maxTurns,
569829
570105
  maxOutputTokensOverride: maxOutputTokens,
570106
+ maxOutputTokensLimitOverride: maxOutputTokensLimit,
569830
570107
  compactRequest: compact2,
569831
570108
  taskBudget
569832
570109
  })) {
@@ -570197,6 +570474,7 @@ async function* ask({
570197
570474
  maxTurns,
570198
570475
  maxBudgetUsd,
570199
570476
  maxOutputTokens,
570477
+ maxOutputTokensLimit,
570200
570478
  contextWindow,
570201
570479
  compact: compact2,
570202
570480
  taskBudget,
@@ -570242,6 +570520,7 @@ async function* ask({
570242
570520
  maxTurns,
570243
570521
  maxBudgetUsd,
570244
570522
  maxOutputTokens,
570523
+ maxOutputTokensLimit,
570245
570524
  contextWindow,
570246
570525
  compact: compact2,
570247
570526
  taskBudget,
@@ -579756,7 +580035,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
579756
580035
  pendingHookMessages
579757
580036
  }, renderAndRun);
579758
580037
  }
579759
- }).version("0.4.12 (OpenCow)", "-v, --version", "Output the version number");
580038
+ }).version("0.4.14 (OpenCow)", "-v, --version", "Output the version number");
579760
580039
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
579761
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.");
579762
580041
  if (canUserConfigureAdvisor()) {
@@ -580402,7 +580681,7 @@ if (false) {}
580402
580681
  async function main2() {
580403
580682
  const args = process.argv.slice(2);
580404
580683
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
580405
- console.log(`${"0.4.12"} (OpenCow)`);
580684
+ console.log(`${"0.4.14"} (OpenCow)`);
580406
580685
  return;
580407
580686
  }
580408
580687
  if (args.includes("--provider")) {
@@ -580520,4 +580799,4 @@ async function main2() {
580520
580799
  }
580521
580800
  main2();
580522
580801
 
580523
- //# debugId=61239C1856C7488B64756E2164756E21
580802
+ //# debugId=C329783BF76928B664756E2164756E21