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

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
@@ -5484,6 +5484,27 @@ var init_types = __esm(() => {
5484
5484
  CanonicalUserAbortError = APIUserAbortError;
5485
5485
  });
5486
5486
 
5487
+ // src/session/canonical/imageSource.ts
5488
+ function normalizeCanonicalImageSource(source) {
5489
+ if (!source || typeof source !== "object")
5490
+ return null;
5491
+ const s = source;
5492
+ if (s.type === "base64" && typeof s.data === "string") {
5493
+ return {
5494
+ kind: "base64",
5495
+ mediaType: typeof s.media_type === "string" ? s.media_type : "image/png",
5496
+ data: s.data
5497
+ };
5498
+ }
5499
+ if (s.type === "url" && typeof s.url === "string") {
5500
+ return { kind: "url", url: s.url };
5501
+ }
5502
+ return null;
5503
+ }
5504
+ function imageSourceToDataUri(img) {
5505
+ return img.kind === "base64" ? `data:${img.mediaType};base64,${img.data}` : img.url;
5506
+ }
5507
+
5487
5508
  // src/session/canonical/index.ts
5488
5509
  var init_canonical = __esm(() => {
5489
5510
  init_types();
@@ -84658,19 +84679,9 @@ function splitToolResultMedia(content) {
84658
84679
  continue;
84659
84680
  }
84660
84681
  if (block?.type === "image") {
84661
- const src = block.source;
84662
- if (src?.type === "base64" && typeof src.data === "string") {
84663
- images.push({
84664
- kind: "base64",
84665
- mediaType: src.media_type ?? "image/png",
84666
- data: src.data
84667
- });
84668
- continue;
84669
- }
84670
- if (src?.type === "url" && typeof src.url === "string") {
84671
- images.push({ kind: "url", url: src.url });
84672
- continue;
84673
- }
84682
+ const img = normalizeCanonicalImageSource(block.source);
84683
+ if (img)
84684
+ images.push(img);
84674
84685
  continue;
84675
84686
  }
84676
84687
  if (typeof block?.text === "string") {
@@ -84681,8 +84692,7 @@ function splitToolResultMedia(content) {
84681
84692
  `), images };
84682
84693
  }
84683
84694
  function toResponsesInputImagePart(img) {
84684
- const url3 = img.kind === "base64" ? `data:${img.mediaType};base64,${img.data}` : img.url;
84685
- return { type: "input_image", image_url: url3 };
84695
+ return { type: "input_image", image_url: imageSourceToDataUri(img) };
84686
84696
  }
84687
84697
  function convertContentBlocksToResponsesParts(content, role) {
84688
84698
  const textType = role === "assistant" ? "output_text" : "input_text";
@@ -84701,18 +84711,9 @@ function convertContentBlocksToResponsesParts(content, role) {
84701
84711
  case "image": {
84702
84712
  if (role === "assistant")
84703
84713
  break;
84704
- const source = block.source;
84705
- if (source?.type === "base64") {
84706
- parts.push({
84707
- type: "input_image",
84708
- image_url: `data:${source.media_type};base64,${source.data}`
84709
- });
84710
- } else if (source?.type === "url" && source.url) {
84711
- parts.push({
84712
- type: "input_image",
84713
- image_url: source.url
84714
- });
84715
- }
84714
+ const img = normalizeCanonicalImageSource(block.source);
84715
+ if (img)
84716
+ parts.push(toResponsesInputImagePart(img));
84716
84717
  break;
84717
84718
  }
84718
84719
  case "thinking":
@@ -85300,6 +85301,7 @@ var init_shim = __esm(() => {
85300
85301
  init_sdk();
85301
85302
  init_schema();
85302
85303
  init_capabilities2();
85304
+ init_canonical();
85303
85305
  });
85304
85306
 
85305
85307
  // src/providers/openai/shim.ts
@@ -85367,19 +85369,9 @@ function splitToolResultMedia2(content) {
85367
85369
  continue;
85368
85370
  }
85369
85371
  if (block?.type === "image") {
85370
- const source = block.source;
85371
- if (source?.type === "base64" && typeof source.data === "string") {
85372
- images.push({
85373
- kind: "base64",
85374
- mediaType: source.media_type ?? "image/png",
85375
- data: source.data
85376
- });
85377
- continue;
85378
- }
85379
- if (source?.type === "url" && typeof source.url === "string") {
85380
- images.push({ kind: "url", url: source.url });
85381
- continue;
85382
- }
85372
+ const img = normalizeCanonicalImageSource(block.source);
85373
+ if (img)
85374
+ images.push(img);
85383
85375
  continue;
85384
85376
  }
85385
85377
  if (block?.type === "tool_reference" && typeof block.tool_name === "string") {
@@ -85394,8 +85386,7 @@ function splitToolResultMedia2(content) {
85394
85386
  `), images };
85395
85387
  }
85396
85388
  function toOpenAIImageUrl(img) {
85397
- const url3 = img.kind === "base64" ? `data:${img.mediaType};base64,${img.data}` : img.url;
85398
- return { type: "image_url", image_url: { url: url3 } };
85389
+ return { type: "image_url", image_url: { url: imageSourceToDataUri(img) } };
85399
85390
  }
85400
85391
  function convertContentBlocks(content) {
85401
85392
  if (typeof content === "string")
@@ -85409,17 +85400,9 @@ function convertContentBlocks(content) {
85409
85400
  parts.push({ type: "text", text: block.text ?? "" });
85410
85401
  break;
85411
85402
  case "image": {
85412
- const src = block.source;
85413
- if (src?.type === "base64") {
85414
- parts.push({
85415
- type: "image_url",
85416
- image_url: {
85417
- url: `data:${src.media_type};base64,${src.data}`
85418
- }
85419
- });
85420
- } else if (src?.type === "url") {
85421
- parts.push({ type: "image_url", image_url: { url: src.url } });
85422
- }
85403
+ const img = normalizeCanonicalImageSource(block.source);
85404
+ if (img)
85405
+ parts.push(toOpenAIImageUrl(img));
85423
85406
  break;
85424
85407
  }
85425
85408
  case "tool_use":
@@ -85578,7 +85561,7 @@ function convertChunkUsage(usage) {
85578
85561
  return openaiUsageToAnthropicUsage(usage);
85579
85562
  }
85580
85563
  function toOpenAIChatReasoningEffort(effort) {
85581
- return effort === "xhigh" ? "high" : effort;
85564
+ return effort;
85582
85565
  }
85583
85566
  function getOpenAIChatProviderCapabilities(model) {
85584
85567
  return {
@@ -86023,7 +86006,14 @@ class OpenAIShimMessages {
86023
86006
  let httpResponse;
86024
86007
  const promise2 = (async () => {
86025
86008
  const overrideTransport = self2.providerOverride?.transport === "anthropic" ? undefined : self2.providerOverride?.transport;
86026
- const request = resolveProviderRequest({ model: self2.providerOverride?.model ?? params.model, baseUrl: self2.providerOverride?.baseURL, reasoningEffortOverride: self2.reasoningEffort, transportOverride: overrideTransport });
86009
+ const hasProviderReasoningEffortOverride = !!self2.providerOverride && Object.prototype.hasOwnProperty.call(self2.providerOverride, "reasoningEffort");
86010
+ const reasoningEffortOverride = hasProviderReasoningEffortOverride ? self2.providerOverride?.reasoningEffort ?? null : self2.reasoningEffort;
86011
+ const request = resolveProviderRequest({
86012
+ model: self2.providerOverride?.model ?? params.model,
86013
+ baseUrl: self2.providerOverride?.baseURL,
86014
+ ...reasoningEffortOverride !== undefined ? { reasoningEffortOverride } : {},
86015
+ transportOverride: overrideTransport
86016
+ });
86027
86017
  const response = await self2._doRequest(request, params, options);
86028
86018
  httpResponse = response;
86029
86019
  if (params.stream) {
@@ -86296,6 +86286,7 @@ var init_shim2 = __esm(() => {
86296
86286
  init_schemaSanitizer();
86297
86287
  init_providerProfile();
86298
86288
  init_capabilities2();
86289
+ init_canonical();
86299
86290
  OpenAIShimStream = class OpenAIShimStream {
86300
86291
  generator;
86301
86292
  controller = new AbortController;
@@ -92644,7 +92635,7 @@ function parseReasoningEffort(value) {
92644
92635
  if (!value)
92645
92636
  return;
92646
92637
  const normalized = value.trim().toLowerCase();
92647
- if (normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "xhigh") {
92638
+ if (normalized === "none" || normalized === "minimal" || normalized === "low" || normalized === "medium" || normalized === "high" || normalized === "xhigh") {
92648
92639
  return normalized;
92649
92640
  }
92650
92641
  return;
@@ -92765,7 +92756,10 @@ function resolveProviderRequest(options) {
92765
92756
  transportOverride: options?.transportOverride
92766
92757
  });
92767
92758
  const resolvedModel = transport === "chat_completions" && isEnvTruthy(getQueryEnvVar("CLAUDE_CODE_USE_GITHUB")) ? normalizeGithubModelsApiModel(requestedModel) : descriptor.baseModel;
92768
- const reasoning = options?.reasoningEffortOverride ? { effort: options.reasoningEffortOverride } : descriptor.reasoning;
92759
+ const hasReasoningEffortOverride = !!options && Object.prototype.hasOwnProperty.call(options, "reasoningEffortOverride");
92760
+ const rawEnvReasoningEffortOverride = getQueryEnvVar(QUERY_ENV_KEY_REASONING_EFFORT_OVERRIDE);
92761
+ const envReasoningEffortOverride = parseReasoningEffort(rawEnvReasoningEffortOverride);
92762
+ const reasoning = hasReasoningEffortOverride ? options?.reasoningEffortOverride ? { effort: options.reasoningEffortOverride } : undefined : rawEnvReasoningEffortOverride === QUERY_ENV_VALUE_REASONING_EFFORT_CLEAR ? undefined : envReasoningEffortOverride ? { effort: envReasoningEffortOverride } : descriptor.reasoning;
92769
92763
  return {
92770
92764
  transport,
92771
92765
  requestedModel,
@@ -92876,7 +92870,7 @@ function getReasoningEffortForModel(model) {
92876
92870
  const aliasConfig = CODEX_ALIAS_MODELS[alias];
92877
92871
  return aliasConfig?.reasoningEffort;
92878
92872
  }
92879
- 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;
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;
92880
92874
  var init_config3 = __esm(() => {
92881
92875
  init_envUtils();
92882
92876
  init_state2();
@@ -94540,7 +94534,7 @@ function printStartupScreen() {
94540
94534
  const sLen = ` ● ${sL} Ready — type /help to begin`.length;
94541
94535
  out.push(boxRow(sRow, W2, sLen));
94542
94536
  out.push(`${rgb(...BORDER)}╚${"═".repeat(W2 - 2)}╝${RESET}`);
94543
- out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.11"}${RESET}`);
94537
+ out.push(` ${DIM}${rgb(...DIMCOL)}opencow ${RESET}${rgb(...ACCENT)}v${"0.4.13"}${RESET}`);
94544
94538
  out.push("");
94545
94539
  process.stdout.write(out.join(`
94546
94540
  `) + `
@@ -113085,15 +113079,16 @@ function isMaxTokensCapEnabled() {
113085
113079
  }
113086
113080
  function getMaxOutputTokensForModel(model, opts) {
113087
113081
  const maxOutputTokens = getModelMaxOutputTokens(model);
113088
- const defaultTokens = isMaxTokensCapEnabled() ? Math.min(maxOutputTokens.default, CAPPED_DEFAULT_MAX_TOKENS) : maxOutputTokens.default;
113082
+ const upperLimit = opts?.upperLimitOverride !== undefined && Number.isFinite(opts.upperLimitOverride) && opts.upperLimitOverride >= 1 ? Math.floor(opts.upperLimitOverride) : maxOutputTokens.upperLimit;
113083
+ const defaultTokens = isMaxTokensCapEnabled() ? Math.min(maxOutputTokens.default, CAPPED_DEFAULT_MAX_TOKENS, upperLimit) : Math.min(maxOutputTokens.default, upperLimit);
113089
113084
  if (opts?.override !== undefined) {
113090
- if (!Number.isFinite(opts.override) || opts.override < 1 || opts.override > maxOutputTokens.upperLimit) {
113091
- console.warn(`[opencow] Options.maxOutputTokens=${opts.override} out of range ` + `[1, ${maxOutputTokens.upperLimit}] for model ${model}; clamping.`);
113085
+ if (!Number.isFinite(opts.override) || opts.override < 1 || opts.override > upperLimit) {
113086
+ console.warn(`[opencow] Options.maxOutputTokens=${opts.override} out of range ` + `[1, ${upperLimit}] for model ${model}; clamping.`);
113092
113087
  }
113093
- const clamped = Math.min(Math.max(1, Math.floor(opts.override)), maxOutputTokens.upperLimit);
113088
+ const clamped = Math.min(Math.max(1, Math.floor(opts.override)), upperLimit);
113094
113089
  return clamped;
113095
113090
  }
113096
- const result = validateBoundedIntEnvVar("CLAUDE_CODE_MAX_OUTPUT_TOKENS", resolveEnvVar("MAX_OUTPUT_TOKENS"), defaultTokens, maxOutputTokens.upperLimit);
113091
+ const result = validateBoundedIntEnvVar("CLAUDE_CODE_MAX_OUTPUT_TOKENS", resolveEnvVar("MAX_OUTPUT_TOKENS"), defaultTokens, upperLimit);
113097
113092
  return result.effective;
113098
113093
  }
113099
113094
  var init_maxTokens = __esm(() => {
@@ -118606,6 +118601,13 @@ function getDisableExtglobCommand(shellPath) {
118606
118601
  }
118607
118602
  return null;
118608
118603
  }
118604
+ function getHostProvidedPathCommand() {
118605
+ const path11 = getHostProvidedEnvVar("PATH");
118606
+ if (!path11) {
118607
+ return null;
118608
+ }
118609
+ return `export PATH=${quote([path11])}`;
118610
+ }
118609
118611
  async function createBashShellProvider(shellPath, options2) {
118610
118612
  let currentSandboxTmpDir;
118611
118613
  const snapshotPromise = options2?.skipSnapshot ? Promise.resolve(undefined) : createAndSaveSnapshot(shellPath).catch((error41) => {
@@ -118646,6 +118648,10 @@ async function createBashShellProvider(shellPath, options2) {
118646
118648
  const finalPath = getPlatform() === "windows" ? windowsPathToPosixPath(snapshotFilePath) : snapshotFilePath;
118647
118649
  commandParts.push(`source ${quote([finalPath])} 2>/dev/null || true`);
118648
118650
  }
118651
+ const hostPathCommand = getHostProvidedPathCommand();
118652
+ if (hostPathCommand) {
118653
+ commandParts.push(hostPathCommand);
118654
+ }
118649
118655
  const sessionEnvScript2 = await getSessionEnvironmentScript();
118650
118656
  if (sessionEnvScript2) {
118651
118657
  commandParts.push(sessionEnvScript2);
@@ -120483,6 +120489,16 @@ async function validateContentTokens(content, ext, maxTokens) {
120483
120489
  throw new MaxFileReadTokenExceededError(effectiveCount, effectiveMaxTokens);
120484
120490
  }
120485
120491
  }
120492
+ async function maybeUploadBytes(uploadMedia, bytes, mediaType) {
120493
+ if (!uploadMedia)
120494
+ return null;
120495
+ try {
120496
+ return await uploadMedia({ bytes, mediaType });
120497
+ } catch (e) {
120498
+ logError(e);
120499
+ return null;
120500
+ }
120501
+ }
120486
120502
  function createImageResponse(buffer, mediaType, originalSize, dimensions) {
120487
120503
  return {
120488
120504
  type: "image",
@@ -120530,6 +120546,10 @@ async function callInner(file_path, fullFilePath, resolvedFilePath, ext, offset,
120530
120546
  if (IMAGE_EXTENSIONS.has(ext)) {
120531
120547
  const data2 = await readImageWithTokenBudget(resolvedFilePath, maxTokens);
120532
120548
  context3.nestedMemoryAttachmentTriggers?.add(fullFilePath);
120549
+ const uploadedUrl = await maybeUploadBytes(context3.uploadMedia, Buffer.from(data2.file.base64, "base64"), data2.file.type);
120550
+ if (uploadedUrl) {
120551
+ data2.file.url = uploadedUrl;
120552
+ }
120533
120553
  logFileOperation({
120534
120554
  operation: "read",
120535
120555
  tool: "FileReadTool",
@@ -120571,14 +120591,14 @@ async function callInner(file_path, fullFilePath, resolvedFilePath, ext, offset,
120571
120591
  const imgPath = path11.join(extractResult.data.file.outputDir, f);
120572
120592
  const imgBuffer = await getFsImplementation().readFile(imgPath);
120573
120593
  const resized = await maybeResizeAndDownsampleImageBuffer(imgBuffer, imgBuffer.length, "jpeg");
120574
- return {
120575
- type: "image",
120576
- source: {
120577
- type: "base64",
120578
- media_type: `image/${resized.mediaType}`,
120579
- data: resized.buffer.toString("base64")
120580
- }
120594
+ const mediaType = `image/${resized.mediaType}`;
120595
+ const uploadedUrl2 = await maybeUploadBytes(context3.uploadMedia, resized.buffer, mediaType);
120596
+ const source = uploadedUrl2 ? { type: "url", url: uploadedUrl2 } : {
120597
+ type: "base64",
120598
+ media_type: mediaType,
120599
+ data: resized.buffer.toString("base64")
120581
120600
  };
120601
+ return { type: "image", source };
120582
120602
  }));
120583
120603
  return {
120584
120604
  data: extractResult.data,
@@ -120626,20 +120646,17 @@ async function callInner(file_path, fullFilePath, resolvedFilePath, ext, offset,
120626
120646
  filePath: fullFilePath,
120627
120647
  content: pdfData.file.base64
120628
120648
  });
120649
+ const uploadedUrl = await maybeUploadBytes(context3.uploadMedia, Buffer.from(pdfData.file.base64, "base64"), "application/pdf");
120650
+ const documentSource = uploadedUrl ? { type: "url", url: uploadedUrl } : {
120651
+ type: "base64",
120652
+ media_type: "application/pdf",
120653
+ data: pdfData.file.base64
120654
+ };
120629
120655
  return {
120630
120656
  data: pdfData,
120631
120657
  newMessages: [
120632
120658
  createUserMessage({
120633
- content: [
120634
- {
120635
- type: "document",
120636
- source: {
120637
- type: "base64",
120638
- media_type: "application/pdf",
120639
- data: pdfData.file.base64
120640
- }
120641
- }
120642
- ],
120659
+ content: [{ type: "document", source: documentSource }],
120643
120660
  isMeta: true
120644
120661
  })
120645
120662
  ]
@@ -120846,6 +120863,7 @@ var init_FileReadTool = __esm(() => {
120846
120863
  base64: exports_external.string().describe("Base64-encoded image data"),
120847
120864
  type: imageMediaTypes.describe("The MIME type of the image"),
120848
120865
  originalSize: exports_external.number().describe("Original file size in bytes"),
120866
+ url: exports_external.string().optional().describe("Fetchable URL for the (compressed) image when a host uploader is configured; takes precedence over base64 for rendering"),
120849
120867
  dimensions: exports_external.object({
120850
120868
  originalWidth: exports_external.number().optional().describe("Original image width in pixels"),
120851
120869
  originalHeight: exports_external.number().optional().describe("Original image height in pixels"),
@@ -121074,17 +121092,18 @@ var init_FileReadTool = __esm(() => {
121074
121092
  mapToolResultToToolResultBlockParam(data, toolUseID) {
121075
121093
  switch (data.type) {
121076
121094
  case "image": {
121095
+ const source = data.file.url ? { type: "url", url: data.file.url } : {
121096
+ type: "base64",
121097
+ data: data.file.base64,
121098
+ media_type: data.file.type
121099
+ };
121077
121100
  return {
121078
121101
  tool_use_id: toolUseID,
121079
121102
  type: "tool_result",
121080
121103
  content: [
121081
121104
  {
121082
121105
  type: "image",
121083
- source: {
121084
- type: "base64",
121085
- data: data.file.base64,
121086
- media_type: data.file.type
121087
- }
121106
+ source
121088
121107
  }
121089
121108
  ]
121090
121109
  };
@@ -243658,7 +243677,11 @@ async function* queryLoop(params, consumedCommandUuids) {
243658
243677
  if (false) {}
243659
243678
  const mediaRecoveryEnabled = reactiveCompact?.isReactiveCompactEnabled() ?? false;
243660
243679
  if (!compactionResult && querySource !== "compact" && querySource !== "session_memory" && !(reactiveCompact?.isReactiveCompactEnabled() && isAutoCompactEnabled()) && !collapseOwnsIt) {
243661
- const { isAtBlockingLimit } = calculateTokenWarningState(tokenCountWithEstimation(messagesForQuery) - snipTokensFreed, toolUseContext.options.mainLoopModel);
243680
+ const { isAtBlockingLimit } = calculateTokenWarningState(tokenCountWithEstimation(messagesForQuery) - snipTokensFreed, toolUseContext.options.mainLoopModel, {
243681
+ contextWindow: toolUseContext.options.contextWindow,
243682
+ maxOutputTokens: toolUseContext.options.maxOutputTokens,
243683
+ maxOutputTokensLimit: toolUseContext.options.maxOutputTokensLimit
243684
+ });
243662
243685
  if (isAtBlockingLimit) {
243663
243686
  yield createAssistantAPIErrorMessage({
243664
243687
  content: PROMPT_TOO_LONG_ERROR_MESSAGE,
@@ -243701,6 +243724,7 @@ async function* queryLoop(params, consumedCommandUuids) {
243701
243724
  allowedAgentTypes: toolUseContext.options.agentDefinitions.allowedAgentTypes,
243702
243725
  hasAppendSystemPrompt: !!toolUseContext.options.appendSystemPrompt,
243703
243726
  maxOutputTokensOverride,
243727
+ maxOutputTokensLimitOverride: params.maxOutputTokensLimitOverride,
243704
243728
  fetchOverride: dumpPromptsFetch,
243705
243729
  mcpTools: appState.mcp.tools,
243706
243730
  hasPendingMcpServers: appState.mcp.clients.some((c6) => c6.type === "pending"),
@@ -244410,7 +244434,7 @@ function getAnthropicEnvMetadata() {
244410
244434
  function getBuildAgeMinutes() {
244411
244435
  if (false)
244412
244436
  ;
244413
- const buildTime = new Date("2026-06-24T03:20:56.844Z").getTime();
244437
+ const buildTime = new Date("2026-06-25T12:29:02.938Z").getTime();
244414
244438
  if (isNaN(buildTime))
244415
244439
  return;
244416
244440
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -245011,6 +245035,7 @@ async function runForkedAgent({
245011
245035
  toolUseContext: isolatedToolUseContext,
245012
245036
  querySource,
245013
245037
  maxOutputTokensOverride: maxOutputTokens,
245038
+ maxOutputTokensLimitOverride: isolatedToolUseContext.options.maxOutputTokensLimit,
245014
245039
  maxTurns,
245015
245040
  skipCacheWrite
245016
245041
  })) {
@@ -293033,9 +293058,21 @@ var init_mcpWebSocketTransport = __esm(() => {
293033
293058
  });
293034
293059
 
293035
293060
  // src/capabilities/adapters/callToolResultAdapter.ts
293061
+ async function buildImageBlock(bytes, mediaType, uploadMedia) {
293062
+ let url3 = null;
293063
+ if (uploadMedia) {
293064
+ try {
293065
+ url3 = await uploadMedia({ bytes, mediaType });
293066
+ } catch (e) {
293067
+ logError(e);
293068
+ }
293069
+ }
293070
+ const source = url3 ? { type: "url", url: url3 } : { type: "base64", media_type: mediaType, data: bytes.toString("base64") };
293071
+ return { type: "image", source };
293072
+ }
293036
293073
  async function translateMcpContentItem(input) {
293037
293074
  const { item, options: options2 } = input;
293038
- const { sourceName } = options2;
293075
+ const { sourceName, uploadMedia } = options2;
293039
293076
  switch (item.type) {
293040
293077
  case "text":
293041
293078
  return [{ type: "text", text: item.text }];
@@ -293053,14 +293090,7 @@ async function translateMcpContentItem(input) {
293053
293090
  const ext = item.mimeType?.split("/")[1] || "png";
293054
293091
  const resized = await maybeResizeAndDownsampleImageBuffer(imageBuffer, imageBuffer.length, ext);
293055
293092
  return [
293056
- {
293057
- type: "image",
293058
- source: {
293059
- data: resized.buffer.toString("base64"),
293060
- media_type: `image/${resized.mediaType}`,
293061
- type: "base64"
293062
- }
293063
- }
293093
+ await buildImageBlock(resized.buffer, `image/${resized.mediaType}`, uploadMedia)
293064
293094
  ];
293065
293095
  }
293066
293096
  case "resource": {
@@ -293077,14 +293107,7 @@ async function translateMcpContentItem(input) {
293077
293107
  const resized = await maybeResizeAndDownsampleImageBuffer(imageBuffer, imageBuffer.length, ext);
293078
293108
  return [
293079
293109
  { type: "text", text: prefix },
293080
- {
293081
- type: "image",
293082
- source: {
293083
- data: resized.buffer.toString("base64"),
293084
- media_type: `image/${resized.mediaType}`,
293085
- type: "base64"
293086
- }
293087
- }
293110
+ await buildImageBlock(resized.buffer, `image/${resized.mediaType}`, uploadMedia)
293088
293111
  ];
293089
293112
  }
293090
293113
  return await persistBlobToTextBlock({
@@ -293130,6 +293153,7 @@ var IMAGE_MIME_TYPES;
293130
293153
  var init_callToolResultAdapter = __esm(() => {
293131
293154
  init_imageResizer();
293132
293155
  init_mcpOutputStorage();
293156
+ init_log2();
293133
293157
  IMAGE_MIME_TYPES = new Set([
293134
293158
  "image/jpeg",
293135
293159
  "image/png",
@@ -302301,7 +302325,17 @@ ${formattedSummary}`;
302301
302325
  if (transcriptPath) {
302302
302326
  baseSummary += `
302303
302327
 
302304
- If you need specific details from before compaction (like exact code snippets, error messages, or content you generated), read the full transcript at: ${transcriptPath}`;
302328
+ IMPORTANT Transcript recovery protocol:
302329
+ The full pre-compaction conversation is preserved at: ${transcriptPath}
302330
+ When you encounter ANY of these situations, you MUST use the Read tool to search the transcript for the missing context BEFORE responding:
302331
+ - You are unsure about a specific detail (file path, function name, error message, code snippet, user preference)
302332
+ - The user references something you cannot find in the summary above
302333
+ - You need exact code that was previously read or written
302334
+ - You are about to make a decision but feel uncertain whether the user already gave guidance on it
302335
+ - A tool name, skill name, or configuration was discussed but is not in the summary
302336
+
302337
+ 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.
302338
+ Do NOT guess or hallucinate details that might have been discussed — read the transcript instead.`;
302305
302339
  }
302306
302340
  if (recentMessagesPreserved) {
302307
302341
  baseSummary += `
@@ -302368,6 +302402,7 @@ Your summary should include the following sections:
302368
302402
  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.
302369
302403
  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.
302370
302404
  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.
302405
+ 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.
302371
302406
 
302372
302407
  Here's an example of how your output should be structured:
302373
302408
 
@@ -302418,10 +302453,14 @@ Here's an example of how your output should be structured:
302418
302453
  9. Optional Next Step:
302419
302454
  [Optional Next step to take]
302420
302455
 
302456
+ 10. Uncertain or Incomplete Context:
302457
+ - [Item with unclear details] [NEEDS_TRANSCRIPT_LOOKUP]
302458
+ - [...]
302459
+
302421
302460
  </summary>
302422
302461
  </example>
302423
302462
 
302424
- Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.
302463
+ Please provide your summary based on the conversation so far, following this structure and ensuring precision and thoroughness in your response.
302425
302464
 
302426
302465
  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:
302427
302466
  <example>
@@ -302449,6 +302488,7 @@ Your summary should include the following sections:
302449
302488
  7. Pending Tasks: Outline any pending tasks from the recent messages.
302450
302489
  8. Current Work: Describe precisely what was being worked on immediately before this summary request.
302451
302490
  9. Optional Next Step: List the next step related to the most recent work. Include direct quotes from the most recent conversation.
302491
+ 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].
302452
302492
 
302453
302493
  Here's an example of how your output should be structured:
302454
302494
 
@@ -302489,6 +302529,9 @@ Here's an example of how your output should be structured:
302489
302529
  9. Optional Next Step:
302490
302530
  [Optional Next step to take]
302491
302531
 
302532
+ 10. Uncertain or Incomplete Context:
302533
+ - [Item with unclear details] [NEEDS_TRANSCRIPT_LOOKUP]
302534
+
302492
302535
  </summary>
302493
302536
  </example>
302494
302537
 
@@ -302509,6 +302552,7 @@ Your summary should include the following sections:
302509
302552
  7. Pending Tasks: Outline any pending tasks.
302510
302553
  8. Work Completed: Describe what was accomplished by the end of this portion.
302511
302554
  9. Context for Continuing Work: Summarize any context, decisions, or state that would be needed to understand and continue the work in subsequent messages.
302555
+ 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.
302512
302556
 
302513
302557
  Here's an example of how your output should be structured:
302514
302558
 
@@ -302549,6 +302593,9 @@ Here's an example of how your output should be structured:
302549
302593
  9. Context for Continuing Work:
302550
302594
  [Key context, decisions, or state needed to continue the work]
302551
302595
 
302596
+ 10. Uncertain or Incomplete Context:
302597
+ - [Item with unclear details] [NEEDS_TRANSCRIPT_LOOKUP]
302598
+
302552
302599
  </summary>
302553
302600
  </example>
302554
302601
 
@@ -303203,7 +303250,10 @@ async function streamCompactSummary({
303203
303250
  toolChoice: undefined,
303204
303251
  isNonInteractiveSession: context4.options.isNonInteractiveSession,
303205
303252
  hasAppendSystemPrompt: !!context4.options.appendSystemPrompt,
303206
- maxOutputTokensOverride: Math.min(COMPACT_MAX_OUTPUT_TOKENS, getMaxOutputTokensForModel(context4.options.mainLoopModel)),
303253
+ maxOutputTokensOverride: Math.min(COMPACT_MAX_OUTPUT_TOKENS, getMaxOutputTokensForModel(context4.options.mainLoopModel, {
303254
+ upperLimitOverride: context4.options.maxOutputTokensLimit
303255
+ })),
303256
+ maxOutputTokensLimitOverride: context4.options.maxOutputTokensLimit,
303207
303257
  querySource: "compact",
303208
303258
  agents: context4.options.agentDefinitions.activeAgents,
303209
303259
  mcpTools: [],
@@ -304100,7 +304150,10 @@ var init_sessionMemoryCompact = __esm(() => {
304100
304150
 
304101
304151
  // src/controller/compact/autoCompact.ts
304102
304152
  function getEffectiveContextWindowSize(model, opts) {
304103
- const reservedTokensForSummary = Math.min(getMaxOutputTokensForModel(model, { override: opts?.maxOutputTokens }), MAX_OUTPUT_TOKENS_FOR_SUMMARY);
304153
+ const reservedTokensForSummary = Math.min(getMaxOutputTokensForModel(model, {
304154
+ override: opts?.maxOutputTokens,
304155
+ upperLimitOverride: opts?.maxOutputTokensLimit
304156
+ }), MAX_OUTPUT_TOKENS_FOR_SUMMARY);
304104
304157
  let contextWindow = getContextWindowForModel(model, getSdkBetas(), {
304105
304158
  override: opts?.contextWindow
304106
304159
  });
@@ -304186,7 +304239,8 @@ async function autoCompactIfNeeded(messages, toolUseContext, cacheSafeParams, qu
304186
304239
  const model = toolUseContext.options.mainLoopModel;
304187
304240
  const opts = {
304188
304241
  contextWindow: toolUseContext.options.contextWindow,
304189
- maxOutputTokens: toolUseContext.options.maxOutputTokens
304242
+ maxOutputTokens: toolUseContext.options.maxOutputTokens,
304243
+ maxOutputTokensLimit: toolUseContext.options.maxOutputTokensLimit
304190
304244
  };
304191
304245
  const shouldCompact = await shouldAutoCompact(messages, model, querySource, snipTokensFreed, opts);
304192
304246
  if (!shouldCompact) {
@@ -307634,7 +307688,10 @@ ${deferredToolList}
307634
307688
  betasParams.push(STRUCTURED_OUTPUTS_BETA_HEADER);
307635
307689
  }
307636
307690
  }
307637
- const maxOutputTokens2 = retryContext?.maxTokensOverride || options2.maxOutputTokensOverride || getMaxOutputTokensForModel(options2.model);
307691
+ const maxOutputTokens2 = retryContext?.maxTokensOverride || getMaxOutputTokensForModel(options2.model, {
307692
+ override: options2.maxOutputTokensOverride,
307693
+ upperLimitOverride: options2.maxOutputTokensLimitOverride
307694
+ });
307638
307695
  const hasThinking = thinkingConfig.type !== "disabled" && !isEnvTruthy(resolveEnvVar("DISABLE_THINKING"));
307639
307696
  let thinking = undefined;
307640
307697
  if (hasThinking && modelSupportsThinking(options2.model)) {
@@ -460067,8 +460124,10 @@ async function processUserInputBase(input, mode, setToolJSX, context6, pastedCon
460067
460124
  }
460068
460125
  }
460069
460126
  }
460127
+ const processSlashCommand = getProcessSlashCommand();
460070
460128
  if (false) {}
460071
- const shouldExtractAttachments = !skipAttachments && inputString !== null && (mode !== "prompt" || effectiveSkipSlash || !inputString.startsWith("/"));
460129
+ const shouldFallbackSlashToPrompt = inputString !== null && mode === "prompt" && !effectiveSkipSlash && inputString.startsWith("/") && !processSlashCommand;
460130
+ const shouldExtractAttachments = !skipAttachments && inputString !== null && (mode !== "prompt" || effectiveSkipSlash || !inputString.startsWith("/") || shouldFallbackSlashToPrompt);
460072
460131
  queryCheckpoint("query_attachment_loading_start");
460073
460132
  const attachmentMessages = shouldExtractAttachments ? await toArray2(getAttachmentMessages(inputString, context6, ideSelection ?? null, [], messages, querySource)) : [];
460074
460133
  queryCheckpoint("query_attachment_loading_end");
@@ -460079,11 +460138,10 @@ async function processUserInputBase(input, mode, setToolJSX, context6, pastedCon
460079
460138
  return addImageMetadataMessage(await processBashCommand(inputString, precedingInputBlocks, attachmentMessages, context6, setToolJSX), imageMetadataTexts);
460080
460139
  }
460081
460140
  if (inputString !== null && !effectiveSkipSlash && inputString.startsWith("/")) {
460082
- const processSlashCommand = getProcessSlashCommand();
460083
- if (!processSlashCommand)
460084
- throw new SlashCommandHandlerNotRegisteredError("slash");
460085
- const slashResult = await processSlashCommand(inputString, precedingInputBlocks, imageContentBlocks, attachmentMessages, context6, setToolJSX, uuid3, isAlreadyProcessing, canUseTool);
460086
- return addImageMetadataMessage(slashResult, imageMetadataTexts);
460141
+ if (processSlashCommand) {
460142
+ const slashResult = await processSlashCommand(inputString, precedingInputBlocks, imageContentBlocks, attachmentMessages, context6, setToolJSX, uuid3, isAlreadyProcessing, canUseTool);
460143
+ return addImageMetadataMessage(slashResult, imageMetadataTexts);
460144
+ }
460087
460145
  }
460088
460146
  if (inputString !== null && mode === "prompt") {
460089
460147
  const trimmedInput = inputString.trim();
@@ -479786,7 +479844,7 @@ function buildPrimarySection() {
479786
479844
  }, undefined, false, undefined, this);
479787
479845
  return [{
479788
479846
  label: "Version",
479789
- value: "0.4.11"
479847
+ value: "0.4.13"
479790
479848
  }, {
479791
479849
  label: "Session name",
479792
479850
  value: nameValue
@@ -536108,7 +536166,7 @@ var init_bridge_kick = __esm(() => {
536108
536166
  var call58 = async () => {
536109
536167
  return {
536110
536168
  type: "text",
536111
- value: `${"99.0.0"} (built ${"2026-06-24T03:20:56.844Z"})`
536169
+ value: `${"99.0.0"} (built ${"2026-06-25T12:29:02.938Z"})`
536112
536170
  };
536113
536171
  }, version2, version_default;
536114
536172
  var init_version = __esm(() => {
@@ -558218,7 +558276,7 @@ function WelcomeV2() {
558218
558276
  dimColor: true,
558219
558277
  children: [
558220
558278
  "v",
558221
- "0.4.11",
558279
+ "0.4.13",
558222
558280
  " "
558223
558281
  ]
558224
558282
  }, undefined, true, undefined, this)
@@ -558418,7 +558476,7 @@ function WelcomeV2() {
558418
558476
  dimColor: true,
558419
558477
  children: [
558420
558478
  "v",
558421
- "0.4.11",
558479
+ "0.4.13",
558422
558480
  " "
558423
558481
  ]
558424
558482
  }, undefined, true, undefined, this)
@@ -558644,7 +558702,7 @@ function AppleTerminalWelcomeV2(t0) {
558644
558702
  dimColor: true,
558645
558703
  children: [
558646
558704
  "v",
558647
- "0.4.11",
558705
+ "0.4.13",
558648
558706
  " "
558649
558707
  ]
558650
558708
  }, undefined, true, undefined, this);
@@ -558898,7 +558956,7 @@ function AppleTerminalWelcomeV2(t0) {
558898
558956
  dimColor: true,
558899
558957
  children: [
558900
558958
  "v",
558901
- "0.4.11",
558959
+ "0.4.13",
558902
558960
  " "
558903
558961
  ]
558904
558962
  }, undefined, true, undefined, this);
@@ -569517,6 +569575,7 @@ class QueryEngine {
569517
569575
  maxTurns,
569518
569576
  maxBudgetUsd,
569519
569577
  maxOutputTokens,
569578
+ maxOutputTokensLimit,
569520
569579
  contextWindow,
569521
569580
  compact: compact2,
569522
569581
  taskBudget,
@@ -569533,6 +569592,7 @@ class QueryEngine {
569533
569592
  agents: agents2 = [],
569534
569593
  setSDKStatus,
569535
569594
  onToolInvoke,
569595
+ uploadMedia,
569536
569596
  orphanedPermission
569537
569597
  } = this.config;
569538
569598
  this.discoveredSkillNames.clear();
@@ -569605,6 +569665,7 @@ class QueryEngine {
569605
569665
  theme: resolveThemeSetting(getGlobalConfig().theme),
569606
569666
  maxBudgetUsd,
569607
569667
  maxOutputTokens,
569668
+ maxOutputTokensLimit,
569608
569669
  contextWindow,
569609
569670
  modelProviders: this.config.modelProviders,
569610
569671
  subagentDisallowedTools: this.config.subagentDisallowedTools
@@ -569636,7 +569697,8 @@ class QueryEngine {
569636
569697
  });
569637
569698
  },
569638
569699
  setSDKStatus,
569639
- onToolInvoke
569700
+ onToolInvoke,
569701
+ uploadMedia
569640
569702
  };
569641
569703
  if (orphanedPermission && !this.hasHandledOrphanedPermission) {
569642
569704
  this.hasHandledOrphanedPermission = true;
@@ -569709,6 +569771,7 @@ class QueryEngine {
569709
569771
  agentDefinitions: { activeAgents: agents2, allAgents: [] },
569710
569772
  maxBudgetUsd,
569711
569773
  maxOutputTokens,
569774
+ maxOutputTokensLimit,
569712
569775
  contextWindow,
569713
569776
  modelProviders: this.config.modelProviders,
569714
569777
  subagentDisallowedTools: this.config.subagentDisallowedTools
@@ -569725,7 +569788,8 @@ class QueryEngine {
569725
569788
  setResponseLength: () => {},
569726
569789
  updateFileHistoryState: processUserInputContext.updateFileHistoryState,
569727
569790
  updateAttributionState: processUserInputContext.updateAttributionState,
569728
- setSDKStatus
569791
+ setSDKStatus,
569792
+ uploadMedia
569729
569793
  };
569730
569794
  headlessProfilerCheckpoint("before_skills_plugins");
569731
569795
  const [skills2, { enabled: enabledPlugins }] = await Promise.all([
@@ -569828,6 +569892,7 @@ class QueryEngine {
569828
569892
  querySource: "sdk",
569829
569893
  maxTurns,
569830
569894
  maxOutputTokensOverride: maxOutputTokens,
569895
+ maxOutputTokensLimitOverride: maxOutputTokensLimit,
569831
569896
  compactRequest: compact2,
569832
569897
  taskBudget
569833
569898
  })) {
@@ -570198,6 +570263,7 @@ async function* ask({
570198
570263
  maxTurns,
570199
570264
  maxBudgetUsd,
570200
570265
  maxOutputTokens,
570266
+ maxOutputTokensLimit,
570201
570267
  contextWindow,
570202
570268
  compact: compact2,
570203
570269
  taskBudget,
@@ -570220,6 +570286,7 @@ async function* ask({
570220
570286
  agents: agents2 = [],
570221
570287
  setSDKStatus,
570222
570288
  onToolInvoke,
570289
+ uploadMedia,
570223
570290
  orphanedPermission
570224
570291
  }) {
570225
570292
  const engine = new QueryEngine({
@@ -570242,6 +570309,7 @@ async function* ask({
570242
570309
  maxTurns,
570243
570310
  maxBudgetUsd,
570244
570311
  maxOutputTokens,
570312
+ maxOutputTokensLimit,
570245
570313
  contextWindow,
570246
570314
  compact: compact2,
570247
570315
  taskBudget,
@@ -570252,6 +570320,7 @@ async function* ask({
570252
570320
  includePartialMessages,
570253
570321
  setSDKStatus,
570254
570322
  onToolInvoke,
570323
+ uploadMedia,
570255
570324
  abortController,
570256
570325
  orphanedPermission,
570257
570326
  ...{}
@@ -579755,7 +579824,7 @@ Usage: claude --remote "your task description"`, () => gracefulShutdown(1));
579755
579824
  pendingHookMessages
579756
579825
  }, renderAndRun);
579757
579826
  }
579758
- }).version("0.4.11 (OpenCow)", "-v, --version", "Output the version number");
579827
+ }).version("0.4.13 (OpenCow)", "-v, --version", "Output the version number");
579759
579828
  program2.option("-w, --worktree [name]", "Create a new git worktree for this session (optionally specify a name)");
579760
579829
  program2.option("--tmux", "Create a tmux session for the worktree (requires --worktree). Uses iTerm2 native panes when available; use --tmux=classic for traditional tmux.");
579761
579830
  if (canUserConfigureAdvisor()) {
@@ -580401,7 +580470,7 @@ if (false) {}
580401
580470
  async function main2() {
580402
580471
  const args = process.argv.slice(2);
580403
580472
  if (args.length === 1 && (args[0] === "--version" || args[0] === "-v" || args[0] === "-V")) {
580404
- console.log(`${"0.4.11"} (OpenCow)`);
580473
+ console.log(`${"0.4.13"} (OpenCow)`);
580405
580474
  return;
580406
580475
  }
580407
580476
  if (args.includes("--provider")) {
@@ -580519,4 +580588,4 @@ async function main2() {
580519
580588
  }
580520
580589
  main2();
580521
580590
 
580522
- //# debugId=A3FE6F2E9266C7E764756E2164756E21
580591
+ //# debugId=D1D0071A1FA049F864756E2164756E21