@opencow-ai/opencow-agent-sdk 0.4.10 → 0.4.12

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/client.js CHANGED
@@ -31267,6 +31267,27 @@ var init_types3 = __esm(() => {
31267
31267
  CanonicalUserAbortError = APIUserAbortError;
31268
31268
  });
31269
31269
 
31270
+ // src/session/canonical/imageSource.ts
31271
+ function normalizeCanonicalImageSource(source) {
31272
+ if (!source || typeof source !== "object")
31273
+ return null;
31274
+ const s = source;
31275
+ if (s.type === "base64" && typeof s.data === "string") {
31276
+ return {
31277
+ kind: "base64",
31278
+ mediaType: typeof s.media_type === "string" ? s.media_type : "image/png",
31279
+ data: s.data
31280
+ };
31281
+ }
31282
+ if (s.type === "url" && typeof s.url === "string") {
31283
+ return { kind: "url", url: s.url };
31284
+ }
31285
+ return null;
31286
+ }
31287
+ function imageSourceToDataUri(img) {
31288
+ return img.kind === "base64" ? `data:${img.mediaType};base64,${img.data}` : img.url;
31289
+ }
31290
+
31270
31291
  // src/session/canonical/index.ts
31271
31292
  var init_canonical = __esm(() => {
31272
31293
  init_types3();
@@ -94790,6 +94811,71 @@ var init_geminiAuth = __esm(() => {
94790
94811
  }, {}), GEMINI_ADC_CACHE_TTL_MS);
94791
94812
  });
94792
94813
 
94814
+ // src/providers/shared/dsmlSentinel.ts
94815
+ function normalizeDsmlSentinel(value) {
94816
+ return value.replace(/|/g, "|").replace(/\s+/g, "");
94817
+ }
94818
+ function isDsmlFunctionCallSentinelPrefix(value) {
94819
+ const normalized = normalizeDsmlSentinel(value);
94820
+ return normalized.length > 0 && DSML_FUNCTION_CALL_SENTINEL.startsWith(normalized);
94821
+ }
94822
+ function findDsmlFunctionCallSentinel(text) {
94823
+ const re = /<\s*[||]\s*DSML\s*[||]\s*function_calls\b/;
94824
+ const match = re.exec(text);
94825
+ if (!match || match.index === undefined)
94826
+ return null;
94827
+ return { start: match.index, end: match.index + match[0].length };
94828
+ }
94829
+ function findTrailingDsmlCandidateStart(text) {
94830
+ for (let i2 = 0;i2 < text.length; i2++) {
94831
+ if (isDsmlFunctionCallSentinelPrefix(text.slice(i2))) {
94832
+ return i2;
94833
+ }
94834
+ }
94835
+ return null;
94836
+ }
94837
+ function createDsmlFunctionCallTextFilter() {
94838
+ let pending = "";
94839
+ const drain = (final) => {
94840
+ let output = "";
94841
+ while (pending) {
94842
+ const sentinel = findDsmlFunctionCallSentinel(pending);
94843
+ if (sentinel) {
94844
+ output += pending.slice(0, sentinel.start).trimEnd();
94845
+ pending = pending.slice(sentinel.end);
94846
+ continue;
94847
+ }
94848
+ if (final) {
94849
+ output += pending;
94850
+ pending = "";
94851
+ break;
94852
+ }
94853
+ const candidateStart = findTrailingDsmlCandidateStart(pending);
94854
+ if (candidateStart === null) {
94855
+ output += pending;
94856
+ pending = "";
94857
+ break;
94858
+ }
94859
+ output += pending.slice(0, candidateStart).trimEnd();
94860
+ pending = pending.slice(candidateStart);
94861
+ break;
94862
+ }
94863
+ return output;
94864
+ };
94865
+ return {
94866
+ push(text) {
94867
+ if (!text)
94868
+ return "";
94869
+ pending += text;
94870
+ return drain(false);
94871
+ },
94872
+ flush() {
94873
+ return drain(true);
94874
+ }
94875
+ };
94876
+ }
94877
+ var DSML_FUNCTION_CALL_SENTINEL = "<|DSML|function_calls";
94878
+
94793
94879
  // src/providers/shared/geminiCredentials.ts
94794
94880
  function readGeminiAccessToken() {
94795
94881
  if (isBareMode())
@@ -95342,19 +95428,9 @@ function splitToolResultMedia(content) {
95342
95428
  continue;
95343
95429
  }
95344
95430
  if (block?.type === "image") {
95345
- const src = block.source;
95346
- if (src?.type === "base64" && typeof src.data === "string") {
95347
- images.push({
95348
- kind: "base64",
95349
- mediaType: src.media_type ?? "image/png",
95350
- data: src.data
95351
- });
95352
- continue;
95353
- }
95354
- if (src?.type === "url" && typeof src.url === "string") {
95355
- images.push({ kind: "url", url: src.url });
95356
- continue;
95357
- }
95431
+ const img = normalizeCanonicalImageSource(block.source);
95432
+ if (img)
95433
+ images.push(img);
95358
95434
  continue;
95359
95435
  }
95360
95436
  if (typeof block?.text === "string") {
@@ -95365,8 +95441,7 @@ function splitToolResultMedia(content) {
95365
95441
  `), images };
95366
95442
  }
95367
95443
  function toResponsesInputImagePart(img) {
95368
- const url3 = img.kind === "base64" ? `data:${img.mediaType};base64,${img.data}` : img.url;
95369
- return { type: "input_image", image_url: url3 };
95444
+ return { type: "input_image", image_url: imageSourceToDataUri(img) };
95370
95445
  }
95371
95446
  function convertContentBlocksToResponsesParts(content, role) {
95372
95447
  const textType = role === "assistant" ? "output_text" : "input_text";
@@ -95385,18 +95460,9 @@ function convertContentBlocksToResponsesParts(content, role) {
95385
95460
  case "image": {
95386
95461
  if (role === "assistant")
95387
95462
  break;
95388
- const source = block.source;
95389
- if (source?.type === "base64") {
95390
- parts.push({
95391
- type: "input_image",
95392
- image_url: `data:${source.media_type};base64,${source.data}`
95393
- });
95394
- } else if (source?.type === "url" && source.url) {
95395
- parts.push({
95396
- type: "input_image",
95397
- image_url: source.url
95398
- });
95399
- }
95463
+ const img = normalizeCanonicalImageSource(block.source);
95464
+ if (img)
95465
+ parts.push(toResponsesInputImagePart(img));
95400
95466
  break;
95401
95467
  }
95402
95468
  case "thinking":
@@ -95706,9 +95772,21 @@ async function* codexStreamToAnthropic(response, model) {
95706
95772
  let nextContentBlockIndex = 0;
95707
95773
  let sawToolUse = false;
95708
95774
  let finalResponse;
95775
+ const dsmlTextFilter = createDsmlFunctionCallTextFilter();
95709
95776
  const closeActiveTextBlock = async function* () {
95710
95777
  if (activeTextBlockIndex === null)
95711
95778
  return;
95779
+ const flushedText = dsmlTextFilter.flush();
95780
+ if (flushedText) {
95781
+ yield {
95782
+ type: "content_block_delta",
95783
+ index: activeTextBlockIndex,
95784
+ delta: {
95785
+ type: "text_delta",
95786
+ text: flushedText
95787
+ }
95788
+ };
95789
+ }
95712
95790
  yield {
95713
95791
  type: "content_block_stop",
95714
95792
  index: activeTextBlockIndex
@@ -95820,14 +95898,17 @@ async function* codexStreamToAnthropic(response, model) {
95820
95898
  if (event.event === "response.output_text.delta") {
95821
95899
  yield* startTextBlockIfNeeded();
95822
95900
  if (activeTextBlockIndex !== null) {
95823
- yield {
95824
- type: "content_block_delta",
95825
- index: activeTextBlockIndex,
95826
- delta: {
95827
- type: "text_delta",
95828
- text: payload.delta ?? ""
95829
- }
95830
- };
95901
+ const filteredText = dsmlTextFilter.push(payload.delta ?? "");
95902
+ if (filteredText) {
95903
+ yield {
95904
+ type: "content_block_delta",
95905
+ index: activeTextBlockIndex,
95906
+ delta: {
95907
+ type: "text_delta",
95908
+ text: filteredText
95909
+ }
95910
+ };
95911
+ }
95831
95912
  }
95832
95913
  continue;
95833
95914
  }
@@ -95969,6 +96050,7 @@ var init_shim = __esm(() => {
95969
96050
  init_sdk();
95970
96051
  init_schema();
95971
96052
  init_capabilities2();
96053
+ init_canonical();
95972
96054
  });
95973
96055
 
95974
96056
  // src/providers/shared/providerRecommendation.ts
@@ -96111,19 +96193,9 @@ function splitToolResultMedia2(content) {
96111
96193
  continue;
96112
96194
  }
96113
96195
  if (block?.type === "image") {
96114
- const source = block.source;
96115
- if (source?.type === "base64" && typeof source.data === "string") {
96116
- images.push({
96117
- kind: "base64",
96118
- mediaType: source.media_type ?? "image/png",
96119
- data: source.data
96120
- });
96121
- continue;
96122
- }
96123
- if (source?.type === "url" && typeof source.url === "string") {
96124
- images.push({ kind: "url", url: source.url });
96125
- continue;
96126
- }
96196
+ const img = normalizeCanonicalImageSource(block.source);
96197
+ if (img)
96198
+ images.push(img);
96127
96199
  continue;
96128
96200
  }
96129
96201
  if (block?.type === "tool_reference" && typeof block.tool_name === "string") {
@@ -96138,8 +96210,7 @@ function splitToolResultMedia2(content) {
96138
96210
  `), images };
96139
96211
  }
96140
96212
  function toOpenAIImageUrl(img) {
96141
- const url3 = img.kind === "base64" ? `data:${img.mediaType};base64,${img.data}` : img.url;
96142
- return { type: "image_url", image_url: { url: url3 } };
96213
+ return { type: "image_url", image_url: { url: imageSourceToDataUri(img) } };
96143
96214
  }
96144
96215
  function convertContentBlocks(content) {
96145
96216
  if (typeof content === "string")
@@ -96153,17 +96224,9 @@ function convertContentBlocks(content) {
96153
96224
  parts.push({ type: "text", text: block.text ?? "" });
96154
96225
  break;
96155
96226
  case "image": {
96156
- const src = block.source;
96157
- if (src?.type === "base64") {
96158
- parts.push({
96159
- type: "image_url",
96160
- image_url: {
96161
- url: `data:${src.media_type};base64,${src.data}`
96162
- }
96163
- });
96164
- } else if (src?.type === "url") {
96165
- parts.push({ type: "image_url", image_url: { url: src.url } });
96166
- }
96227
+ const img = normalizeCanonicalImageSource(block.source);
96228
+ if (img)
96229
+ parts.push(toOpenAIImageUrl(img));
96167
96230
  break;
96168
96231
  }
96169
96232
  case "tool_use":
@@ -96433,32 +96496,6 @@ function buildOpenAIRequestBody(params, ctx) {
96433
96496
  }
96434
96497
  return body;
96435
96498
  }
96436
- function normalizeDsmlSentinelPrefix(value) {
96437
- return value.replace(/|/g, "|").replace(/\s+/g, "");
96438
- }
96439
- function isDsmlFunctionCallSentinelPrefix(value) {
96440
- const normalized = normalizeDsmlSentinelPrefix(value);
96441
- return normalized.length > 0 && DSML_FUNCTION_CALL_SENTINEL.startsWith(normalized);
96442
- }
96443
- function findTrailingDsmlSentinelCandidateStart(text) {
96444
- const lt = text.lastIndexOf("<");
96445
- if (lt === -1)
96446
- return null;
96447
- return isDsmlFunctionCallSentinelPrefix(text.slice(lt)) ? lt : null;
96448
- }
96449
- function findBufferedTextFlushBoundary(text) {
96450
- const sentinelStart = findTrailingDsmlSentinelCandidateStart(text);
96451
- if (sentinelStart === null)
96452
- return text.length;
96453
- return text.slice(0, sentinelStart).trimEnd().length;
96454
- }
96455
- function findDsmlFunctionCallSentinel(text) {
96456
- const re = /<\s*[||]\s*DSML\s*[||]\s*function_calls\b/;
96457
- const match = re.exec(text);
96458
- if (!match || match.index === undefined)
96459
- return null;
96460
- return { start: match.index, end: match.index + match[0].length };
96461
- }
96462
96499
  async function* openaiStreamToAnthropic(response, model) {
96463
96500
  const messageId = makeMessageId2();
96464
96501
  let contentBlockIndex = 0;
@@ -96470,27 +96507,13 @@ async function* openaiStreamToAnthropic(response, model) {
96470
96507
  let hasEmittedFinalUsage = false;
96471
96508
  let hasProcessedFinishReason = false;
96472
96509
  let pendingTextBuffer = "";
96510
+ const dsmlTextFilter = createDsmlFunctionCallTextFilter();
96473
96511
  const emitBufferedText = (mode) => {
96474
96512
  const events = [];
96475
- if (!pendingTextBuffer)
96513
+ if (!pendingTextBuffer && mode !== "final")
96476
96514
  return events;
96477
- const sentinel = findDsmlFunctionCallSentinel(pendingTextBuffer);
96478
- if (sentinel) {
96479
- const visible2 = pendingTextBuffer.slice(0, sentinel.start).trimEnd();
96480
- pendingTextBuffer = pendingTextBuffer.slice(sentinel.end);
96481
- if (visible2) {
96482
- events.push(...emitTextDeltaEvents(visible2));
96483
- }
96484
- if (pendingTextBuffer) {
96485
- events.push(...emitBufferedText(mode));
96486
- }
96487
- return events;
96488
- }
96489
- const emitUntil = mode === "final" ? pendingTextBuffer.length : mode === "before_tool_call" ? findTrailingDsmlSentinelCandidateStart(pendingTextBuffer) ?? pendingTextBuffer.length : findBufferedTextFlushBoundary(pendingTextBuffer);
96490
- if (emitUntil <= 0)
96491
- return events;
96492
- const visible = pendingTextBuffer.slice(0, emitUntil);
96493
- pendingTextBuffer = pendingTextBuffer.slice(emitUntil);
96515
+ const visible = mode === "final" ? dsmlTextFilter.push(pendingTextBuffer) + dsmlTextFilter.flush() : dsmlTextFilter.push(pendingTextBuffer);
96516
+ pendingTextBuffer = "";
96494
96517
  if (visible) {
96495
96518
  events.push(...emitTextDeltaEvents(visible));
96496
96519
  }
@@ -97067,7 +97090,7 @@ function createOpenAIShimClient(options) {
97067
97090
  messages: beta.messages
97068
97091
  };
97069
97092
  }
97070
- var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, DSML_FUNCTION_CALL_SENTINEL = "<|DSML|function_calls", OpenAIShimStream;
97093
+ var GITHUB_MODELS_DEFAULT_BASE = "https://models.github.ai/inference", GITHUB_API_VERSION = "2022-11-28", GITHUB_429_MAX_RETRIES = 3, GITHUB_429_BASE_DELAY_SEC = 1, GITHUB_429_MAX_DELAY_SEC = 32, OpenAIShimStream;
97071
97094
  var init_shim2 = __esm(() => {
97072
97095
  init_sdk();
97073
97096
  init_envUtils();
@@ -97080,6 +97103,7 @@ var init_shim2 = __esm(() => {
97080
97103
  init_schemaSanitizer();
97081
97104
  init_providerProfile();
97082
97105
  init_capabilities2();
97106
+ init_canonical();
97083
97107
  OpenAIShimStream = class OpenAIShimStream {
97084
97108
  generator;
97085
97109
  controller = new AbortController;
@@ -273582,9 +273606,21 @@ var init_mcpWebSocketTransport = __esm(() => {
273582
273606
  });
273583
273607
 
273584
273608
  // src/capabilities/adapters/callToolResultAdapter.ts
273609
+ async function buildImageBlock(bytes, mediaType, uploadMedia) {
273610
+ let url3 = null;
273611
+ if (uploadMedia) {
273612
+ try {
273613
+ url3 = await uploadMedia({ bytes, mediaType });
273614
+ } catch (e) {
273615
+ logError(e);
273616
+ }
273617
+ }
273618
+ const source = url3 ? { type: "url", url: url3 } : { type: "base64", media_type: mediaType, data: bytes.toString("base64") };
273619
+ return { type: "image", source };
273620
+ }
273585
273621
  async function translateMcpContentItem(input) {
273586
273622
  const { item, options: options2 } = input;
273587
- const { sourceName } = options2;
273623
+ const { sourceName, uploadMedia } = options2;
273588
273624
  switch (item.type) {
273589
273625
  case "text":
273590
273626
  return [{ type: "text", text: item.text }];
@@ -273602,14 +273638,7 @@ async function translateMcpContentItem(input) {
273602
273638
  const ext = item.mimeType?.split("/")[1] || "png";
273603
273639
  const resized = await maybeResizeAndDownsampleImageBuffer(imageBuffer, imageBuffer.length, ext);
273604
273640
  return [
273605
- {
273606
- type: "image",
273607
- source: {
273608
- data: resized.buffer.toString("base64"),
273609
- media_type: `image/${resized.mediaType}`,
273610
- type: "base64"
273611
- }
273612
- }
273641
+ await buildImageBlock(resized.buffer, `image/${resized.mediaType}`, uploadMedia)
273613
273642
  ];
273614
273643
  }
273615
273644
  case "resource": {
@@ -273626,14 +273655,7 @@ async function translateMcpContentItem(input) {
273626
273655
  const resized = await maybeResizeAndDownsampleImageBuffer(imageBuffer, imageBuffer.length, ext);
273627
273656
  return [
273628
273657
  { type: "text", text: prefix },
273629
- {
273630
- type: "image",
273631
- source: {
273632
- data: resized.buffer.toString("base64"),
273633
- media_type: `image/${resized.mediaType}`,
273634
- type: "base64"
273635
- }
273636
- }
273658
+ await buildImageBlock(resized.buffer, `image/${resized.mediaType}`, uploadMedia)
273637
273659
  ];
273638
273660
  }
273639
273661
  return await persistBlobToTextBlock({
@@ -273687,6 +273709,7 @@ var IMAGE_MIME_TYPES;
273687
273709
  var init_callToolResultAdapter = __esm(() => {
273688
273710
  init_imageResizer();
273689
273711
  init_mcpOutputStorage();
273712
+ init_log2();
273690
273713
  IMAGE_MIME_TYPES = new Set([
273691
273714
  "image/jpeg",
273692
273715
  "image/png",
@@ -282652,7 +282675,7 @@ function getAnthropicEnvMetadata() {
282652
282675
  function getBuildAgeMinutes() {
282653
282676
  if (false)
282654
282677
  ;
282655
- const buildTime = new Date("2026-06-23T14:32:49.206Z").getTime();
282678
+ const buildTime = new Date("2026-06-24T10:02:32.669Z").getTime();
282656
282679
  if (isNaN(buildTime))
282657
282680
  return;
282658
282681
  return Math.floor((Date.now() - buildTime) / 60000);
@@ -285976,6 +285999,16 @@ async function validateContentTokens(content, ext, maxTokens) {
285976
285999
  throw new MaxFileReadTokenExceededError(effectiveCount, effectiveMaxTokens);
285977
286000
  }
285978
286001
  }
286002
+ async function maybeUploadBytes(uploadMedia, bytes, mediaType) {
286003
+ if (!uploadMedia)
286004
+ return null;
286005
+ try {
286006
+ return await uploadMedia({ bytes, mediaType });
286007
+ } catch (e) {
286008
+ logError(e);
286009
+ return null;
286010
+ }
286011
+ }
285979
286012
  function createImageResponse(buffer, mediaType, originalSize, dimensions) {
285980
286013
  return {
285981
286014
  type: "image",
@@ -286023,6 +286056,10 @@ async function callInner(file_path, fullFilePath, resolvedFilePath, ext, offset,
286023
286056
  if (IMAGE_EXTENSIONS.has(ext)) {
286024
286057
  const data2 = await readImageWithTokenBudget(resolvedFilePath, maxTokens);
286025
286058
  context4.nestedMemoryAttachmentTriggers?.add(fullFilePath);
286059
+ const uploadedUrl = await maybeUploadBytes(context4.uploadMedia, Buffer.from(data2.file.base64, "base64"), data2.file.type);
286060
+ if (uploadedUrl) {
286061
+ data2.file.url = uploadedUrl;
286062
+ }
286026
286063
  logFileOperation({
286027
286064
  operation: "read",
286028
286065
  tool: "FileReadTool",
@@ -286064,14 +286101,14 @@ async function callInner(file_path, fullFilePath, resolvedFilePath, ext, offset,
286064
286101
  const imgPath = path11.join(extractResult.data.file.outputDir, f);
286065
286102
  const imgBuffer = await getFsImplementation().readFile(imgPath);
286066
286103
  const resized = await maybeResizeAndDownsampleImageBuffer(imgBuffer, imgBuffer.length, "jpeg");
286067
- return {
286068
- type: "image",
286069
- source: {
286070
- type: "base64",
286071
- media_type: `image/${resized.mediaType}`,
286072
- data: resized.buffer.toString("base64")
286073
- }
286104
+ const mediaType = `image/${resized.mediaType}`;
286105
+ const uploadedUrl2 = await maybeUploadBytes(context4.uploadMedia, resized.buffer, mediaType);
286106
+ const source = uploadedUrl2 ? { type: "url", url: uploadedUrl2 } : {
286107
+ type: "base64",
286108
+ media_type: mediaType,
286109
+ data: resized.buffer.toString("base64")
286074
286110
  };
286111
+ return { type: "image", source };
286075
286112
  }));
286076
286113
  return {
286077
286114
  data: extractResult.data,
@@ -286119,20 +286156,17 @@ async function callInner(file_path, fullFilePath, resolvedFilePath, ext, offset,
286119
286156
  filePath: fullFilePath,
286120
286157
  content: pdfData.file.base64
286121
286158
  });
286159
+ const uploadedUrl = await maybeUploadBytes(context4.uploadMedia, Buffer.from(pdfData.file.base64, "base64"), "application/pdf");
286160
+ const documentSource = uploadedUrl ? { type: "url", url: uploadedUrl } : {
286161
+ type: "base64",
286162
+ media_type: "application/pdf",
286163
+ data: pdfData.file.base64
286164
+ };
286122
286165
  return {
286123
286166
  data: pdfData,
286124
286167
  newMessages: [
286125
286168
  createUserMessage({
286126
- content: [
286127
- {
286128
- type: "document",
286129
- source: {
286130
- type: "base64",
286131
- media_type: "application/pdf",
286132
- data: pdfData.file.base64
286133
- }
286134
- }
286135
- ],
286169
+ content: [{ type: "document", source: documentSource }],
286136
286170
  isMeta: true
286137
286171
  })
286138
286172
  ]
@@ -286339,6 +286373,7 @@ var init_FileReadTool = __esm(() => {
286339
286373
  base64: exports_external2.string().describe("Base64-encoded image data"),
286340
286374
  type: imageMediaTypes.describe("The MIME type of the image"),
286341
286375
  originalSize: exports_external2.number().describe("Original file size in bytes"),
286376
+ url: exports_external2.string().optional().describe("Fetchable URL for the (compressed) image when a host uploader is configured; takes precedence over base64 for rendering"),
286342
286377
  dimensions: exports_external2.object({
286343
286378
  originalWidth: exports_external2.number().optional().describe("Original image width in pixels"),
286344
286379
  originalHeight: exports_external2.number().optional().describe("Original image height in pixels"),
@@ -286567,17 +286602,18 @@ var init_FileReadTool = __esm(() => {
286567
286602
  mapToolResultToToolResultBlockParam(data, toolUseID) {
286568
286603
  switch (data.type) {
286569
286604
  case "image": {
286605
+ const source = data.file.url ? { type: "url", url: data.file.url } : {
286606
+ type: "base64",
286607
+ data: data.file.base64,
286608
+ media_type: data.file.type
286609
+ };
286570
286610
  return {
286571
286611
  tool_use_id: toolUseID,
286572
286612
  type: "tool_result",
286573
286613
  content: [
286574
286614
  {
286575
286615
  type: "image",
286576
- source: {
286577
- type: "base64",
286578
- data: data.file.base64,
286579
- media_type: data.file.type
286580
- }
286616
+ source
286581
286617
  }
286582
286618
  ]
286583
286619
  };
@@ -293936,6 +293972,7 @@ ${deferredToolList}
293936
293972
  const STALL_THRESHOLD_MS2 = 30000;
293937
293973
  let totalStallTime = 0;
293938
293974
  let stallCount = 0;
293975
+ const dsmlTextFilters = new Map;
293939
293976
  for await (const part of stream4) {
293940
293977
  resetStreamIdleTimer();
293941
293978
  const now = Date.now();
@@ -294002,6 +294039,7 @@ ${deferredToolList}
294002
294039
  ...part.content_block,
294003
294040
  text: ""
294004
294041
  };
294042
+ dsmlTextFilters.set(part.index, createDsmlFunctionCallTextFilter());
294005
294043
  break;
294006
294044
  case "thinking":
294007
294045
  contentBlocks[part.index] = {
@@ -294061,7 +294099,13 @@ ${deferredToolList}
294061
294099
  });
294062
294100
  throw new Error("Content block is not a text block");
294063
294101
  }
294064
- contentBlock.text += delta.text;
294102
+ {
294103
+ const filter2 = dsmlTextFilters.get(part.index) ?? createDsmlFunctionCallTextFilter();
294104
+ dsmlTextFilters.set(part.index, filter2);
294105
+ const visibleText = filter2.push(delta.text);
294106
+ delta.text = visibleText;
294107
+ contentBlock.text += visibleText;
294108
+ }
294065
294109
  break;
294066
294110
  case "signature_delta":
294067
294111
  if (false) {}
@@ -294110,6 +294154,11 @@ ${deferredToolList}
294110
294154
  });
294111
294155
  throw new Error("Message not found");
294112
294156
  }
294157
+ const filter2 = dsmlTextFilters.get(part.index);
294158
+ if (filter2 && contentBlock.type === "text") {
294159
+ contentBlock.text += filter2.flush();
294160
+ dsmlTextFilters.delete(part.index);
294161
+ }
294113
294162
  const m = {
294114
294163
  message: {
294115
294164
  ...partialMessage,
@@ -299960,6 +300009,7 @@ class QueryEngine {
299960
300009
  agents = [],
299961
300010
  setSDKStatus,
299962
300011
  onToolInvoke,
300012
+ uploadMedia,
299963
300013
  orphanedPermission
299964
300014
  } = this.config;
299965
300015
  this.discoveredSkillNames.clear();
@@ -300063,7 +300113,8 @@ class QueryEngine {
300063
300113
  });
300064
300114
  },
300065
300115
  setSDKStatus,
300066
- onToolInvoke
300116
+ onToolInvoke,
300117
+ uploadMedia
300067
300118
  };
300068
300119
  if (orphanedPermission && !this.hasHandledOrphanedPermission) {
300069
300120
  this.hasHandledOrphanedPermission = true;
@@ -300152,7 +300203,8 @@ class QueryEngine {
300152
300203
  setResponseLength: () => {},
300153
300204
  updateFileHistoryState: processUserInputContext.updateFileHistoryState,
300154
300205
  updateAttributionState: processUserInputContext.updateAttributionState,
300155
- setSDKStatus
300206
+ setSDKStatus,
300207
+ uploadMedia
300156
300208
  };
300157
300209
  headlessProfilerCheckpoint("before_skills_plugins");
300158
300210
  const [skills, { enabled: enabledPlugins }] = await Promise.all([
@@ -300647,6 +300699,7 @@ async function* ask({
300647
300699
  agents = [],
300648
300700
  setSDKStatus,
300649
300701
  onToolInvoke,
300702
+ uploadMedia,
300650
300703
  orphanedPermission
300651
300704
  }) {
300652
300705
  const engine = new QueryEngine({
@@ -300679,6 +300732,7 @@ async function* ask({
300679
300732
  includePartialMessages,
300680
300733
  setSDKStatus,
300681
300734
  onToolInvoke,
300735
+ uploadMedia,
300682
300736
  abortController,
300683
300737
  orphanedPermission,
300684
300738
  ...{}
@@ -329426,7 +329480,7 @@ function toInternalTool(sdkTool) {
329426
329480
  });
329427
329481
  const content = await translateCallToolResultContent({
329428
329482
  content: result.content,
329429
- options: { sourceName: sdkTool.name }
329483
+ options: { sourceName: sdkTool.name, uploadMedia: context4.uploadMedia }
329430
329484
  });
329431
329485
  return { data: content };
329432
329486
  }
@@ -329949,6 +330003,7 @@ function runSdkQueryRuntime(params) {
329949
330003
  includePartialMessages: Boolean(options2.includePartialMessages),
329950
330004
  agents: mergedAgents,
329951
330005
  onToolInvoke: typeof options2.onToolInvoke === "function" ? options2.onToolInvoke : undefined,
330006
+ uploadMedia: typeof options2.uploadMedia === "function" ? options2.uploadMedia : undefined,
329952
330007
  setSDKStatus: (status) => {
329953
330008
  turnStatusStream.enqueue({
329954
330009
  type: "system",
@@ -336002,4 +336057,4 @@ export {
336002
336057
  AbortError2 as AbortError
336003
336058
  };
336004
336059
 
336005
- //# debugId=F1D1A50370F2E48F64756E2164756E21
336060
+ //# debugId=C79EE43EDCAB4CD864756E2164756E21
@@ -1,5 +1,6 @@
1
1
  import type { ChildProcessWithoutNullStreams } from 'node:child_process';
2
2
  import type { ModelProviders } from '../../providers/shared/routing.js';
3
+ import type { UploadMediaFn } from '../../types/toolRuntime.js';
3
4
  export type { ModelProviders, ModelProviderConfig } from '../../providers/shared/routing.js';
4
5
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
6
  import type { CallToolResult, ToolAnnotations } from '@modelcontextprotocol/sdk/types.js';
@@ -278,6 +279,21 @@ export type Options = {
278
279
  toolInput: Record<string, unknown>;
279
280
  toolUseId: string;
280
281
  }) => void | Promise<void>;
282
+ /**
283
+ * Host-injected media uploader. When supplied, media-producing built-in
284
+ * tools (FileReadTool reading an image) upload the **compressed** bytes
285
+ * (post token-budget) and emit `{type:'image', source:{type:'url', url}}`
286
+ * in the tool_result instead of inline base64 — keeping the bytes out of
287
+ * every subsequent turn's request and letting the host materialize them.
288
+ * Media-neutral: the same port serves image / PDF / page-image tool output,
289
+ * driven by `mediaType`.
290
+ *
291
+ * Returns a fetchable URL, or `null` when upload is unavailable; the SDK
292
+ * also treats a thrown error as "unavailable". Either way it falls back to
293
+ * inline base64, so standalone SDK/CLI runs (no uploader) are byte-for-byte
294
+ * unchanged.
295
+ */
296
+ uploadMedia?: UploadMediaFn;
281
297
  jsonSchema?: Record<string, unknown>;
282
298
  betas?: string[];
283
299
  settingSources?: SettingSource[];
@@ -0,0 +1,5 @@
1
+ export interface DsmlFunctionCallTextFilter {
2
+ push(text: string): string;
3
+ flush(): string;
4
+ }
5
+ export declare function createDsmlFunctionCallTextFilter(): DsmlFunctionCallTextFilter;