nolo-cli 0.170.1 → 0.172.0-alpha.1

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.
Files changed (101) hide show
  1. package/{_executeModel-7J6IIHWQ.js → _executeModel-PVY4AXG4.js} +29 -29
  2. package/{agentDeleteCommand-F66NIWCF.js → agentDeleteCommand-QYNICESQ.js} +38 -37
  3. package/{agentEmailCommands-M4SHODDA.js → agentEmailCommands-QEJHRESH.js} +42 -41
  4. package/{agentListCommands-4BBFWXHX.js → agentListCommands-MGMBNFAS.js} +24 -23
  5. package/{agentMachineCommands-R55P5SZY.js → agentMachineCommands-SKOAHGVC.js} +22 -21
  6. package/{agentProviderCommands-4USYTCL3.js → agentProviderCommands-TWVILNAN.js} +2 -2
  7. package/{agentRecordCommands-PDWACZFR.js → agentRecordCommands-2NVWBDQN.js} +38 -37
  8. package/{agentRunCommand-U2F74LTS.js → agentRunCommand-2LHV37FZ.js} +39 -38
  9. package/{agentRunControl-EI3BGJFM.js → agentRunControl-SBHIICUQ.js} +5 -5
  10. package/{agentRuntimeLocal-7EZYBR6X.js → agentRuntimeLocal-K3777H5R.js} +20 -19
  11. package/{agentSlice-UN7ZHCAM.js → agentSlice-QMOFHPJR.js} +3 -3
  12. package/{appDeleteCommands-WS3UFMCB.js → appDeleteCommands-3HZNWZ2V.js} +23 -22
  13. package/{appDeployCommands-W5B7I73P.js → appDeployCommands-Q5BIBQE2.js} +23 -22
  14. package/{appDeployStatusCommands-UEHNV2GU.js → appDeployStatusCommands-ZZFFVM3W.js} +23 -22
  15. package/{appGetCommands-XJOBVREN.js → appGetCommands-7AAOXZQK.js} +23 -22
  16. package/{appListCommands-BISQV6BQ.js → appListCommands-H76IX2X5.js} +23 -22
  17. package/{authCommand-H35CPF25.js → authCommand-BSOLJFPV.js} +12 -12
  18. package/{builtinSkillRegistry-LJV7FHNI.js → builtinSkillRegistry-V76JTNCJ.js} +2 -2
  19. package/{chunk-DHNQA4VI.js → chunk-2FAQDT6E.js} +1 -1
  20. package/chunk-2WZXXAQD.js +57 -0
  21. package/{chunk-SH3XD4E2.js → chunk-3LNVSFTH.js} +2 -1
  22. package/{chunk-WC7UXON2.js → chunk-3XUE7WJA.js} +95 -38
  23. package/{chunk-XLBQQ5SB.js → chunk-54YLFF7P.js} +4 -4
  24. package/{chunk-O2AY3CVI.js → chunk-7OQ7IDU3.js} +19 -17
  25. package/{chunk-HEC32F3G.js → chunk-7TBARDLF.js} +1 -46
  26. package/{chunk-G3VYRPTV.js → chunk-AJ52EA72.js} +4 -4
  27. package/{chunk-JPPQ3GUO.js → chunk-APB44JID.js} +3 -3
  28. package/{chunk-XITIONPS.js → chunk-BE42X662.js} +4 -4
  29. package/{chunk-ASSNAASW.js → chunk-BKCR2JHG.js} +48 -3
  30. package/{chunk-IMMA7QFE.js → chunk-CAAH5LNN.js} +2 -2
  31. package/{chunk-45IOFLGH.js → chunk-CFLYUFMA.js} +11 -11
  32. package/{chunk-URW5UM6Y.js → chunk-CI5DVWU7.js} +1 -1
  33. package/{chunk-CMRP4XHV.js → chunk-DNQ55DHN.js} +13 -13
  34. package/{chunk-CEQFVBI2.js → chunk-EK3LIELB.js} +3 -3
  35. package/{chunk-IOFLVIKF.js → chunk-EWLPIR2S.js} +1 -1
  36. package/{chunk-6EQD4AQL.js → chunk-GC64WGMD.js} +1 -1
  37. package/{chunk-CEXJ6Y3C.js → chunk-HBUKJB3W.js} +9 -1
  38. package/{chunk-FYYSDHVQ.js → chunk-HLAL63BZ.js} +1 -1
  39. package/{chunk-PIG2IUVZ.js → chunk-I2QHI2XM.js} +2 -2
  40. package/{chunk-BSKTDOGA.js → chunk-I33CJERI.js} +3 -58
  41. package/{chunk-7VWWGKEQ.js → chunk-ISMHFI2Y.js} +3 -3
  42. package/{chunk-3ELX6JK5.js → chunk-JCILHZJZ.js} +10 -10
  43. package/{chunk-FQU23S3P.js → chunk-JIGBVOHH.js} +11 -11
  44. package/{chunk-I7S63QUU.js → chunk-KNDA4K34.js} +1 -1
  45. package/{chunk-Z6HR75HX.js → chunk-KUA3PPFK.js} +3 -3
  46. package/{chunk-2DXGW4UO.js → chunk-ME7N4YHG.js} +142 -30
  47. package/{chunk-WLPUUBFR.js → chunk-MOOQN57G.js} +3 -3
  48. package/{chunk-URO44BCD.js → chunk-MTAWQNSU.js} +1 -1
  49. package/{chunk-KJETBEEN.js → chunk-OPNHKULV.js} +1 -1
  50. package/{chunk-EWO77ZGF.js → chunk-OQ3DOBYB.js} +3 -3
  51. package/{chunk-2AZSL4GL.js → chunk-PPR6G2U2.js} +3 -3
  52. package/{chunk-TOUKACDK.js → chunk-RATR6VCP.js} +1 -1
  53. package/{chunk-DI7ZFGDQ.js → chunk-SHPY7A3P.js} +102 -3
  54. package/{chunk-LEZLJTQ4.js → chunk-SUBKVXFM.js} +1 -1
  55. package/{chunk-ZPKUJROL.js → chunk-TDNAAXUQ.js} +2 -2
  56. package/{chunk-3USFOET4.js → chunk-TI7ZIWYR.js} +3 -3
  57. package/{chunk-SQX235S2.js → chunk-TSCI6X6C.js} +1 -1
  58. package/{chunk-V7PCFWX3.js → chunk-TVGX5QIN.js} +2 -2
  59. package/{chunk-XLQFVHNX.js → chunk-TYQZRSL6.js} +1 -1
  60. package/{chunk-QW6SSF7V.js → chunk-UMVEB5QT.js} +15 -15
  61. package/{chunk-WVREKHHJ.js → chunk-UU4TLYRZ.js} +3 -3
  62. package/{chunk-HZMWJUSD.js → chunk-VAQ3EGPC.js} +2 -2
  63. package/{chunk-MFVOJ6KF.js → chunk-W6E5IXIP.js} +3 -3
  64. package/{chunk-YCRROBDY.js → chunk-WXOKJP3W.js} +2 -1
  65. package/{chunk-SAZSXMTR.js → chunk-XBJIESNS.js} +4 -4
  66. package/{chunk-46OQD3AP.js → chunk-XUZQCRSA.js} +4 -4
  67. package/{chunk-KMDDG73K.js → chunk-XWX5ZGWR.js} +1 -1
  68. package/{chunk-7NKZA46B.js → chunk-YEOFTC2H.js} +10 -4
  69. package/{commandRegistry-3XBG7JHS.js → commandRegistry-D3V6AB3G.js} +56 -56
  70. package/{contentThunks-OO3MJAED.js → contentThunks-P2GNXUKN.js} +11 -11
  71. package/{createAgentAutomationAction-F3O6FJ5W.js → createAgentAutomationAction-PQA43W2W.js} +11 -11
  72. package/{createDialogAction-UBQKDUK5.js → createDialogAction-ITOZ5TAM.js} +13 -13
  73. package/{createPageAction-RDEDO4GF.js → createPageAction-IKB3LOMU.js} +11 -11
  74. package/{dialogCommands-P5HSDZ7T.js → dialogCommands-IZAQB6GY.js} +24 -23
  75. package/{dialogSlice-WZCWWYR3.js → dialogSlice-Y6WIZWTC.js} +10 -10
  76. package/{docCreateCommands-B2M3MGX7.js → docCreateCommands-U25MRSOL.js} +22 -21
  77. package/{docDeleteCommands-NHCUX4XL.js → docDeleteCommands-F46A6FJZ.js} +23 -22
  78. package/{docReadCommands-FOLST4JD.js → docReadCommands-DITPVWA3.js} +22 -21
  79. package/{docStore-PTSCGC6T.js → docStore-HRNZKKVS.js} +1 -1
  80. package/{docUpdateCommands-YZT2PQP2.js → docUpdateCommands-O447KO7Z.js} +22 -21
  81. package/{getPricing-XQ3N3RBP.js → getPricing-2UPNNW3Y.js} +3 -3
  82. package/{handleSendMessageAction-3YMQS6XO.js → handleSendMessageAction-4OVVUVJ4.js} +24 -23
  83. package/index.js +4 -4
  84. package/{localRuntimeAdapter-ZIAOTUBE.js → localRuntimeAdapter-CL3QW3OJ.js} +36 -35
  85. package/{machineCommands-3LSEP24P.js → machineCommands-T3VQCFHT.js} +37 -36
  86. package/{machineWsRunDispatch-7A3TSH4Q.js → machineWsRunDispatch-IGX4UK4C.js} +37 -36
  87. package/{models-PZQC7VV4.js → models-UUNO6DOL.js} +2 -2
  88. package/package.json +1 -1
  89. package/{providerPresetApply-PKUOHQJT.js → providerPresetApply-5K4PBX4J.js} +6 -6
  90. package/{providerRegistry-HNQLIFN2.js → providerRegistry-K5MSZ3Y5.js} +6 -6
  91. package/{readlineWorkspace-OFBP6OA7.js → readlineWorkspace-3IZBF57U.js} +45 -44
  92. package/{runAgentClientLoop-F6EQK26A.js → runAgentClientLoop-RUBF4JIP.js} +27 -27
  93. package/{runtimeDoctorCommands-LYMJEM4F.js → runtimeDoctorCommands-DXJH5HIB.js} +6 -6
  94. package/{secretCommands-DNY56NSU.js → secretCommands-7S6REMJV.js} +2 -2
  95. package/{spaceCommands-XESXH5CW.js → spaceCommands-FSATGIKW.js} +22 -21
  96. package/{streamAgentChatTurn-KXELVHFR.js → streamAgentChatTurn-N7UJ6FFK.js} +36 -35
  97. package/{tools-FMNDEVTZ.js → tools-Z7EJ6KIM.js} +21 -21
  98. package/{tuiSummaryLlmCaller-FQOEF4IE.js → tuiSummaryLlmCaller-ZETARZOH.js} +14 -8
  99. package/{updateDialogTitleAction-65R3Y22L.js → updateDialogTitleAction-CEFNJE4T.js} +11 -11
  100. package/{chunk-CGFNDIKK.js → chunk-5KTQVMCX.js} +0 -0
  101. package/{chunk-UHTDNB5Y.js → chunk-76YUTLOT.js} +3 -3
@@ -2,7 +2,7 @@ import {
2
2
  DEVIN_CONNECT_URL,
3
3
  parseSseDataLineJson,
4
4
  parseSseDataLineObject
5
- } from "./chunk-KMDDG73K.js";
5
+ } from "./chunk-XWX5ZGWR.js";
6
6
  import {
7
7
  applyChatCompletionDelta,
8
8
  applyResponsesToolEvent,
@@ -11,7 +11,7 @@ import {
11
11
  flushChatCompletionStream,
12
12
  providerHttpFailure,
13
13
  throwIfChatCompletionStreamFailed
14
- } from "./chunk-7NKZA46B.js";
14
+ } from "./chunk-YEOFTC2H.js";
15
15
  import {
16
16
  readSseFrames
17
17
  } from "./chunk-HNUWUO75.js";
@@ -25,13 +25,15 @@ import {
25
25
  import {
26
26
  hasImageInRuntimeMessages,
27
27
  stripImagePartsFromMessages
28
- } from "./chunk-CEXJ6Y3C.js";
28
+ } from "./chunk-HBUKJB3W.js";
29
29
  import {
30
30
  clipToolText,
31
- resolveAgentImageInputSupport,
32
31
  resolveHistoricalToolContentCap,
33
32
  resolveToolOutputProfile
34
- } from "./chunk-BSKTDOGA.js";
33
+ } from "./chunk-2WZXXAQD.js";
34
+ import {
35
+ resolveAgentImageInputSupport
36
+ } from "./chunk-I33CJERI.js";
35
37
  import {
36
38
  applyShapingCounts,
37
39
  attachProjectionFacts,
@@ -66,16 +68,20 @@ import {
66
68
  hashStablePrefixContent,
67
69
  resolveResponseGuidelines,
68
70
  resolveToolGuidedSections
69
- } from "./chunk-TOUKACDK.js";
71
+ } from "./chunk-RATR6VCP.js";
70
72
  import {
73
+ TOOL_HAD_IMAGES,
74
+ TOOL_IMAGES,
71
75
  classifyUnparsableToolArgs,
72
76
  collectStablePromptPrefix,
73
77
  convertMessagesToResponsesInput,
78
+ createToolImageLedger,
74
79
  downgradeUnparsableToolCalls,
75
80
  extractReasoningFromResponseOutput,
76
81
  extractTextFromResponseOutput,
77
82
  extractToolCallsFromResponseOutput,
78
83
  getUsageRequestOptions,
84
+ hadToolImages,
79
85
  hasParsableObjectArguments,
80
86
  markDowngradedToolTurnOrigin,
81
87
  normalizeChatCompletionsBodyForProvider,
@@ -86,11 +92,14 @@ import {
86
92
  scanTruncation,
87
93
  shouldStripReasoningContentForOutbound,
88
94
  stablePromptCacheKey,
95
+ stripToolImages,
89
96
  toBareImageUrlMessages,
90
97
  toOpenAiCompatibleMessages,
91
98
  toResponsesTools,
92
- transferDowngradedToolTurnOrigin
93
- } from "./chunk-DI7ZFGDQ.js";
99
+ toolImages,
100
+ transferDowngradedToolTurnOrigin,
101
+ withoutToolImages
102
+ } from "./chunk-SHPY7A3P.js";
94
103
  import {
95
104
  BRIDGE_STREAM_MAX_CHARS,
96
105
  CLI_NOLO_WORKSPACE_TOOL_NAMES,
@@ -125,7 +134,7 @@ import {
125
134
  resolveEmptyAssistantFallbackMessage,
126
135
  resolveEmptyAssistantOutcome,
127
136
  resolveTruncatedReasoningTailLog
128
- } from "./chunk-HEC32F3G.js";
137
+ } from "./chunk-7TBARDLF.js";
129
138
  import {
130
139
  COMPACTION_SUMMARY_SCHEMA_VERSION,
131
140
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
@@ -148,7 +157,7 @@ import {
148
157
  sha256Hex,
149
158
  truncateToolOutputForContext,
150
159
  withProviderCallTimingFields
151
- } from "./chunk-ASSNAASW.js";
160
+ } from "./chunk-BKCR2JHG.js";
152
161
  import {
153
162
  clipCompactText
154
163
  } from "./chunk-5MMAK75Q.js";
@@ -158,6 +167,9 @@ import {
158
167
  import {
159
168
  isAbortError
160
169
  } from "./chunk-7DPNBQSV.js";
170
+ import {
171
+ resolveNoloStateDir
172
+ } from "./chunk-ZWQUWF6W.js";
161
173
  import {
162
174
  buildDialogSummaryLayer
163
175
  } from "./chunk-VEA7H5FG.js";
@@ -187,7 +199,7 @@ import {
187
199
  import {
188
200
  buildProviderAuthHeaders,
189
201
  buildProviderExecutionPlan
190
- } from "./chunk-PIG2IUVZ.js";
202
+ } from "./chunk-I2QHI2XM.js";
191
203
  import {
192
204
  isRecord
193
205
  } from "./chunk-KUG52IAP.js";
@@ -206,9 +218,6 @@ import {
206
218
  import {
207
219
  asTrimmedLowercaseString
208
220
  } from "./chunk-QSJ3HFEF.js";
209
- import {
210
- resolveNoloStateDir
211
- } from "./chunk-ZWQUWF6W.js";
212
221
  import {
213
222
  __export
214
223
  } from "./chunk-4VNS5WPM.js";
@@ -12845,7 +12854,8 @@ function scrubObjectSecrets(val) {
12845
12854
  // packages/agent-runtime/providerMessageProjection.ts
12846
12855
  var TOOL_DURATION_METADATA_KEY = "toolExecMs";
12847
12856
  var OBSERVATION_ONLY_METADATA_KEYS = /* @__PURE__ */ new Set([
12848
- TOOL_DURATION_METADATA_KEY
12857
+ TOOL_DURATION_METADATA_KEY,
12858
+ TOOL_HAD_IMAGES
12849
12859
  ]);
12850
12860
  function formatToolMessageContent(args2) {
12851
12861
  const scrubbedContent = scrubSecrets(args2.content).cleaned;
@@ -13170,7 +13180,7 @@ function prepareHistoryForNextTurn(history, contextReferenceResolver) {
13170
13180
  function filterImagePartsFromMessages(messages, supportsImages) {
13171
13181
  if (supportsImages) return messages;
13172
13182
  return stripImagePartsFromMessages(messages).map(
13173
- (stripped, index) => transferDowngradedToolTurnOrigin(messages[index], stripped)
13183
+ (stripped, index) => stripToolImages(transferDowngradedToolTurnOrigin(messages[index], stripped))
13174
13184
  );
13175
13185
  }
13176
13186
  var MODEL_PROJECTED_USER_PART_TYPES = /* @__PURE__ */ new Set(["attachment", "media_job"]);
@@ -15706,7 +15716,74 @@ async function invokeCapability(capabilityOrName, input, ctx = {}) {
15706
15716
  // packages/agent-runtime/localWorkspaceTools.ts
15707
15717
  import { existsSync as existsSync4 } from "node:fs";
15708
15718
  import { createHash as createHash4 } from "node:crypto";
15709
- import { lstat, mkdir, readdir as readdir2, readFile as readFile3, realpath, stat as stat3, writeFile } from "node:fs/promises";
15719
+
15720
+ // packages/agent-runtime/readImage.ts
15721
+ import { readFile } from "node:fs/promises";
15722
+ import { extname } from "node:path";
15723
+ var MAX_IMAGE_BASE64_BYTES = 2 * 1024 * 1024;
15724
+ var MAX_IMAGE_EDGE = 1568;
15725
+ var MIME_BY_EXTENSION = {
15726
+ ".png": "image/png",
15727
+ ".jpg": "image/jpeg",
15728
+ ".jpeg": "image/jpeg",
15729
+ ".webp": "image/webp",
15730
+ ".gif": "image/gif"
15731
+ };
15732
+ function detectMime(bytes) {
15733
+ if (bytes.subarray(0, 8).equals(Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]))) return "image/png";
15734
+ if (bytes[0] === 255 && bytes[1] === 216 && bytes[2] === 255) return "image/jpeg";
15735
+ if (["GIF87a", "GIF89a"].includes(bytes.toString("ascii", 0, 6))) return "image/gif";
15736
+ if (bytes.toString("ascii", 0, 4) === "RIFF" && bytes.toString("ascii", 8, 12) === "WEBP") return "image/webp";
15737
+ }
15738
+ async function readLocalImage(path, options) {
15739
+ const limit = options?.maxBase64Bytes ?? MAX_IMAGE_BASE64_BYTES;
15740
+ const expected = MIME_BY_EXTENSION[extname(path).toLowerCase()];
15741
+ if (!expected) throw new Error("read_image: unsupported image extension (PNG/JPEG/WebP/GIF only)");
15742
+ const bytes = await readFile(path);
15743
+ if (detectMime(bytes) !== expected) throw new Error("read_image: image extension and magic bytes do not match");
15744
+ const { default: sharp } = await import("./dist-Q2JSMAKA.js");
15745
+ const image = sharp(bytes, { limitInputPixels: 4e7, animated: false });
15746
+ const meta = await image.metadata();
15747
+ if (!meta.width || !meta.height) throw new Error("read_image: invalid image dimensions");
15748
+ const encoded = (length) => 4 * Math.ceil(length / 3);
15749
+ let output = bytes;
15750
+ let mimeType = expected;
15751
+ let width = meta.width;
15752
+ let height = meta.height;
15753
+ if (Math.max(width, height) > MAX_IMAGE_EDGE || encoded(output.length) > limit) {
15754
+ const resized = await image.rotate().resize({ width: MAX_IMAGE_EDGE, height: MAX_IMAGE_EDGE, fit: "inside", withoutEnlargement: true }).jpeg({ quality: 80 }).toBuffer({ resolveWithObject: true });
15755
+ output = resized.data;
15756
+ width = resized.info.width;
15757
+ height = resized.info.height;
15758
+ mimeType = "image/jpeg";
15759
+ }
15760
+ while (encoded(output.length) > limit) {
15761
+ const current = encoded(output.length);
15762
+ if (width === 1 && height === 1) {
15763
+ throw new Error(
15764
+ `read_image: compressed image ${width}x${height}, ${output.length} bytes (${current} base64 bytes) still exceeds ${limit} base64 bytes`
15765
+ );
15766
+ }
15767
+ const scale = Math.min(0.9, Math.sqrt(limit / current) * 0.95);
15768
+ const resized = await image.clone().rotate().resize({
15769
+ width: Math.max(1, Math.floor(width * scale)),
15770
+ height: Math.max(1, Math.floor(height * scale)),
15771
+ fit: "inside",
15772
+ withoutEnlargement: true
15773
+ }).jpeg({ quality: 80 }).toBuffer({ resolveWithObject: true });
15774
+ output = resized.data;
15775
+ width = resized.info.width;
15776
+ height = resized.info.height;
15777
+ mimeType = "image/jpeg";
15778
+ }
15779
+ return {
15780
+ content: `[image ${width}x${height} ${output.length} bytes \u2192 ${path}]`,
15781
+ images: [{ mimeType, dataBase64: output.toString("base64") }]
15782
+ };
15783
+ }
15784
+
15785
+ // packages/agent-runtime/localWorkspaceTools.ts
15786
+ import { lstat, mkdir, readdir as readdir2, readFile as readFile4, realpath, stat as stat3, writeFile } from "node:fs/promises";
15710
15787
  import { homedir } from "node:os";
15711
15788
  import { dirname as dirname2, isAbsolute as isAbsolute2, relative as relative3, resolve as resolve4, sep } from "node:path";
15712
15789
  import { spawn as spawnChildProcess3 } from "node:child_process";
@@ -15744,15 +15821,15 @@ function isLineRangeCovered(request3, covered) {
15744
15821
  }
15745
15822
 
15746
15823
  // packages/agent-runtime/fileTextSearch.ts
15747
- import { readdir, readFile as readFile2, stat as stat2 } from "node:fs/promises";
15824
+ import { readdir, readFile as readFile3, stat as stat2 } from "node:fs/promises";
15748
15825
  import { basename, relative as relative2, resolve as resolve3 } from "node:path";
15749
15826
  import { spawn as spawnChildProcess2 } from "node:child_process";
15750
15827
 
15751
15828
  // packages/agent-runtime/gitignore.ts
15752
- import { readFile, stat } from "node:fs/promises";
15829
+ import { readFile as readFile2, stat } from "node:fs/promises";
15753
15830
  import { resolve as resolve2 } from "node:path";
15754
15831
  async function readRootGitignorePatterns(workspaceRoot) {
15755
- const content = await readFile(resolve2(workspaceRoot, ".gitignore"), "utf8").catch(() => null);
15832
+ const content = await readFile2(resolve2(workspaceRoot, ".gitignore"), "utf8").catch(() => null);
15756
15833
  if (content === null) return [];
15757
15834
  return content.split(/\r?\n/).map((line) => line.trim()).filter((line) => line && !line.startsWith("#") && !line.startsWith("!")).flatMap((line) => {
15758
15835
  const unanchored = line.replace(/^\//, "");
@@ -15832,7 +15909,7 @@ async function decorate(root, raw, context3, absolute = false) {
15832
15909
  let lines = cache.get(x.file);
15833
15910
  if (!lines) {
15834
15911
  try {
15835
- lines = (await readFile2(x.file, "utf8")).split(/\r\n|\r|\n/);
15912
+ lines = (await readFile3(x.file, "utf8")).split(/\r\n|\r|\n/);
15836
15913
  } catch {
15837
15914
  continue;
15838
15915
  }
@@ -15861,7 +15938,7 @@ function globMatch(pattern, value) {
15861
15938
  const r = new RegExp(`^${source}$`);
15862
15939
  return r.test(value) || r.test(basename(value));
15863
15940
  }
15864
- var defaultReadTextFile = (filePath) => readFile2(filePath, "utf8").catch(() => "");
15941
+ var defaultReadTextFile = (filePath) => readFile3(filePath, "utf8").catch(() => "");
15865
15942
  async function jsSearch(o, targetPath) {
15866
15943
  const max4 = o.maxResults ?? Number.MAX_SAFE_INTEGER;
15867
15944
  const excludes = o.exclude ?? [];
@@ -16221,6 +16298,7 @@ function runTasks(args2) {
16221
16298
  // packages/agent-runtime/localWorkspaceToolDefs.ts
16222
16299
  var WORKSPACE_TOOL_NAMES = [
16223
16300
  "readFile",
16301
+ "read_image",
16224
16302
  "writeFile",
16225
16303
  "editFile",
16226
16304
  "globFiles",
@@ -16526,6 +16604,16 @@ function buildTaskStopTool() {
16526
16604
  };
16527
16605
  }
16528
16606
  function buildWorkspaceToolDefinition(toolName) {
16607
+ if (toolName === "read_image") {
16608
+ return {
16609
+ type: "function",
16610
+ function: {
16611
+ name: "read_image",
16612
+ description: "Read one local PNG/JPEG/WebP/GIF image. Long edges above 1568px are resized to JPEG q80. Maximum encoded base64 size is 2MiB.",
16613
+ parameters: { type: "object", properties: { path: buildWorkspacePathProperty() }, required: ["path"], additionalProperties: false }
16614
+ }
16615
+ };
16616
+ }
16529
16617
  if (toolName === "readFile") {
16530
16618
  return buildReadWorkspaceFileTool();
16531
16619
  }
@@ -16922,7 +17010,7 @@ function readVisualStateCaptureArgs(args2) {
16922
17010
  }
16923
17011
  async function readWorkspacePackageScripts(workspaceRoot) {
16924
17012
  try {
16925
- const raw = await readFile3(resolve4(workspaceRoot, "package.json"), "utf8");
17013
+ const raw = await readFile4(resolve4(workspaceRoot, "package.json"), "utf8");
16926
17014
  const parsed = JSON.parse(raw);
16927
17015
  const scripts = parsed && typeof parsed === "object" && parsed.scripts && typeof parsed.scripts === "object" ? Object.keys(parsed.scripts).sort() : [];
16928
17016
  return { scripts };
@@ -17107,7 +17195,7 @@ async function readFileTool(args2) {
17107
17195
  allowRuntimeOwnedSpill: true,
17108
17196
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17109
17197
  });
17110
- const content = await readFile3(absolutePath, "utf8");
17198
+ const content = await readFile4(absolutePath, "utf8");
17111
17199
  const activity = extractActivity(parsed);
17112
17200
  const sliced = sliceReadFileContent({
17113
17201
  content,
@@ -17300,7 +17388,7 @@ async function editFileTool(args2) {
17300
17388
  requestedPath,
17301
17389
  ...args2.confirmExternalFileAccess ? { confirmExternalFileAccess: args2.confirmExternalFileAccess } : {}
17302
17390
  });
17303
- const content = await readFile3(absolutePath, "utf8");
17391
+ const content = await readFile4(absolutePath, "utf8");
17304
17392
  const { count: replacementCount, result: nextContent } = countAndReplaceEolTolerant({
17305
17393
  content,
17306
17394
  oldText,
@@ -17993,6 +18081,16 @@ function createLocalWorkspaceToolExecutors(args2) {
17993
18081
  ...fileAccess,
17994
18082
  ...args2.resolveRipgrepBinary ? { resolveRipgrepBinary: args2.resolveRipgrepBinary } : {}
17995
18083
  }),
18084
+ read_image: async (call) => {
18085
+ const parsed = parseWorkspaceToolArguments(call.arguments);
18086
+ if (Object.keys(parsed).some((key) => key !== "path")) throw new Error("read_image accepts exactly one path");
18087
+ const absolutePath = await resolveLocalWorkspaceToolPath({
18088
+ workspaceRoot: args2.workspaceRoot,
18089
+ requestedPath: requireWorkspaceToolPath(parsed),
18090
+ ...fileAccess
18091
+ });
18092
+ return readLocalImage(absolutePath);
18093
+ },
17996
18094
  readFile: (call) => readFileTool({
17997
18095
  call,
17998
18096
  workspaceRoot: args2.workspaceRoot,
@@ -18203,6 +18301,7 @@ var NEVER_LOCAL_TOOLS = /* @__PURE__ */ new Set([
18203
18301
  ]);
18204
18302
  var DEFAULT_LOCAL_TOOLS = /* @__PURE__ */ new Set([
18205
18303
  "readFile",
18304
+ "read_image",
18206
18305
  "writeFile",
18207
18306
  "editFile",
18208
18307
  "globFiles",
@@ -18763,13 +18862,13 @@ function createTurnTranscript(args2) {
18763
18862
  pushTool: (msg) => {
18764
18863
  const capped = cap(msg);
18765
18864
  working.push(capped);
18766
- raw.push(capped);
18865
+ raw.push(withoutToolImages(capped));
18767
18866
  },
18768
18867
  popLast: () => {
18769
18868
  raw.pop();
18770
18869
  return working.pop();
18771
18870
  },
18772
- persisted: (persistedInput, persistedInputReference) => applyPersistedTurnInput(raw, persistedInput, persistedInputReference)
18871
+ persisted: (persistedInput, persistedInputReference) => applyPersistedTurnInput(raw.map(withoutToolImages), persistedInput, persistedInputReference)
18773
18872
  };
18774
18873
  }
18775
18874
 
@@ -19568,6 +19667,7 @@ function buildRoundBudgetWarningPrompt(threshold) {
19568
19667
  }
19569
19668
  var CONCURRENT_READONLY_TOOLS = /* @__PURE__ */ new Set([
19570
19669
  "readFile",
19670
+ "read_image",
19571
19671
  "read_file",
19572
19672
  "readWorkspaceFile",
19573
19673
  "globFiles",
@@ -20049,6 +20149,7 @@ async function runLocalAgentTurn(input) {
20049
20149
  ...msg,
20050
20150
  content: truncateToolOutputForContext(msg.content, contextWindow)
20051
20151
  } : msg;
20152
+ const acceptToolImages = createToolImageLedger();
20052
20153
  const transcript = createTurnTranscript({
20053
20154
  initialWorking: messages,
20054
20155
  prefixCount,
@@ -20229,6 +20330,8 @@ async function runLocalAgentTurn(input) {
20229
20330
  providerName: agentConfig.provider,
20230
20331
  model: provider.model
20231
20332
  });
20333
+ acceptToolImages.commit(requestMessages.flatMap(toolImages));
20334
+ transcript.replaceWorkingHistory(transcript.working().map((message) => stripToolImages(message)));
20232
20335
  loopTiming.mark("llmCall", round);
20233
20336
  usageLedger.recordProviderCall({
20234
20337
  usage: result4.usage,
@@ -20413,7 +20516,11 @@ ${reasoningTailLog}
20413
20516
  }),
20414
20517
  tool_call_id: toolCall.id,
20415
20518
  toolName,
20416
- ...observedMetadata ? { tool_result_metadata: observedMetadata } : {}
20519
+ [TOOL_IMAGES]: acceptToolImages(toolResult.images),
20520
+ ...observedMetadata || toolResult.images?.length ? { tool_result_metadata: {
20521
+ ...observedMetadata,
20522
+ ...toolResult.images?.length ? { [TOOL_HAD_IMAGES]: true } : {}
20523
+ } } : {}
20417
20524
  });
20418
20525
  };
20419
20526
  const skippedToolCalls = [];
@@ -20921,6 +21028,7 @@ function buildOpenAiCompatibleChatCompletionRequest(args2) {
20921
21028
  );
20922
21029
  const sanitizedMessages = sanitizeForOutbound(args2.messages, args2.tools);
20923
21030
  const messages = toOpenAiCompatibleMessages(sanitizedMessages, {
21031
+ supportsToolImages: !isResponses && resolveAgentImageInputSupport({ provider: args2.providerConfig.usageProvider ?? args2.providerConfig.provider, model: args2.providerConfig.model, customProviderUrl: args2.providerConfig.endpoint, hasVision: args2.providerConfig.hasVision ?? false }),
20924
21032
  stripReasoningContent: shouldStripReasoning,
20925
21033
  ...args2.shapingCounts ? { shapingCounts: args2.shapingCounts } : {},
20926
21034
  ...resolveReasoningReplayOptions(
@@ -21253,6 +21361,7 @@ async function resolveOpenAiCompatibleProviderConfig(args2) {
21253
21361
  throw new Error("OpenAI-compatible provider config requires a direct provider execution plan.");
21254
21362
  }
21255
21363
  return {
21364
+ hasVision: args2.agentConfig.hasVision,
21256
21365
  model: plan.model,
21257
21366
  endpoint: plan.endpoint,
21258
21367
  apiKey: plan.apiKey,
@@ -21550,7 +21659,10 @@ function buildDialogMessageWriteOps(args2) {
21550
21659
  ...message.tool_call_id ? { toolCallId: message.tool_call_id } : {},
21551
21660
  ...toolName ? { toolName } : {},
21552
21661
  ...Array.isArray(message.tool_calls) ? { tool_calls: message.tool_calls } : {},
21553
- ...message.tool_result_metadata ? { metadata: message.tool_result_metadata } : {},
21662
+ ...message.tool_result_metadata || hadToolImages(message) ? { metadata: {
21663
+ ...message.tool_result_metadata,
21664
+ ...hadToolImages(message) ? { [TOOL_HAD_IMAGES]: true } : {}
21665
+ } } : {},
21554
21666
  createdAt: args2.nowIso
21555
21667
  }
21556
21668
  };
@@ -21945,7 +22057,7 @@ function buildLoadSkillExecutor(args2) {
21945
22057
  const { resolveSkillByName } = await import("./skillDiscovery-QC35EQY4.js");
21946
22058
  const resolved = resolveSkillByName(args2.cwd, name);
21947
22059
  if (!resolved) {
21948
- const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-LJV7FHNI.js");
22060
+ const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-V76JTNCJ.js");
21949
22061
  const builtin = resolveBuiltinSkillByName(name);
21950
22062
  if (builtin) {
21951
22063
  return {
@@ -8,7 +8,7 @@ import {
8
8
  } from "./chunk-VYNMQ6HW.js";
9
9
  import {
10
10
  fetchAndCacheTableRows
11
- } from "./chunk-URO44BCD.js";
11
+ } from "./chunk-MTAWQNSU.js";
12
12
  import {
13
13
  require_react
14
14
  } from "./chunk-YDH3FDFQ.js";
@@ -22,7 +22,7 @@ import {
22
22
  import {
23
23
  resolveBuiltinCapability,
24
24
  resolveBuiltinSkillEntry
25
- } from "./chunk-SH3XD4E2.js";
25
+ } from "./chunk-3LNVSFTH.js";
26
26
  import {
27
27
  DEFAULT_SYSTEM_AGENT_CAPABILITIES
28
28
  } from "./chunk-EUGTFFO6.js";
@@ -521,7 +521,7 @@ var executeToolRun = createAsyncThunk(
521
521
  if (!executionInput) {
522
522
  throw new Error(`ToolRun ${id} has no input to execute with.`);
523
523
  }
524
- const { findToolExecutor } = await import("./tools-FMNDEVTZ.js");
524
+ const { findToolExecutor } = await import("./tools-Z7EJ6KIM.js");
525
525
  const { executor } = findToolExecutor(run.toolName);
526
526
  toolRunStarted({
527
527
  id: run.id,
@@ -2,7 +2,7 @@ import {
2
2
  deleteDialog,
3
3
  runtime_default,
4
4
  toast
5
- } from "./chunk-CMRP4XHV.js";
5
+ } from "./chunk-DNQ55DHN.js";
6
6
  import {
7
7
  getCurrentSpaceId,
8
8
  getCurrentSpaceIdRaw,
@@ -556,7 +556,7 @@ async function buildCreatedAgentRecord(args) {
556
556
  const resolvedAgentInput = resolveCliAgentKeyInput(args.parsed.agentInput);
557
557
  const agentKey = resolvedAgentInput.startsWith("agent-") ? resolvedAgentInput : createAgentKey.private(userId || "local", resolvedAgentInput);
558
558
  if (args.parsed.presetId) {
559
- const { resolveProviderPresetFields } = await import("./providerPresetApply-PKUOHQJT.js");
559
+ const { resolveProviderPresetFields } = await import("./providerPresetApply-5K4PBX4J.js");
560
560
  const fields = resolveProviderPresetFields(args.parsed.presetId);
561
561
  if (fields.kind === "manual") {
562
562
  throw new Error(
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  ANTIGRAVITY_CLOUD_CODE_BASE_URL
3
- } from "./chunk-SQX235S2.js";
3
+ } from "./chunk-TSCI6X6C.js";
4
4
  import {
5
5
  commandCodeModels,
6
6
  kimiCodeModels,
@@ -11,13 +11,13 @@ import {
11
11
  qwenTokenPlanModels,
12
12
  stepfunModels,
13
13
  stepfunStepPlanModels
14
- } from "./chunk-6EQD4AQL.js";
14
+ } from "./chunk-GC64WGMD.js";
15
15
  import {
16
16
  PLATFORM_HOSTED_DEEPSEEK_FLASH_OFF_PEAK_PRICE,
17
17
  PLATFORM_HOSTED_DEEPSEEK_FLASH_PEAK_PRICE,
18
18
  PLATFORM_HOSTED_DEEPSEEK_PRO_OFF_PEAK_PRICE,
19
19
  PLATFORM_HOSTED_DEEPSEEK_PRO_PEAK_PRICE
20
- } from "./chunk-CGFNDIKK.js";
20
+ } from "./chunk-5KTQVMCX.js";
21
21
  import {
22
22
  asTrimmedLowercaseString
23
23
  } from "./chunk-QSJ3HFEF.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  toolRegistry
3
- } from "./chunk-QW6SSF7V.js";
3
+ } from "./chunk-UMVEB5QT.js";
4
4
  import {
5
5
  runtime_default
6
- } from "./chunk-CMRP4XHV.js";
6
+ } from "./chunk-DNQ55DHN.js";
7
7
  import {
8
8
  canonicalizeToolNames
9
9
  } from "./chunk-5EBLANFT.js";
@@ -12,7 +12,7 @@ import {
12
12
  } from "./chunk-KUG52IAP.js";
13
13
  import {
14
14
  isNoloHostedProvider
15
- } from "./chunk-CGFNDIKK.js";
15
+ } from "./chunk-5KTQVMCX.js";
16
16
  import {
17
17
  asTrimmedLowercaseString
18
18
  } from "./chunk-QSJ3HFEF.js";
@@ -15,7 +15,7 @@ import {
15
15
  } from "./chunk-PSCNXBYA.js";
16
16
  import {
17
17
  getModelConfig
18
- } from "./chunk-6EQD4AQL.js";
18
+ } from "./chunk-GC64WGMD.js";
19
19
  import {
20
20
  asTrimmedString
21
21
  } from "./chunk-3EUW3WEO.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getModelContextWindow
3
- } from "./chunk-ASSNAASW.js";
3
+ } from "./chunk-BKCR2JHG.js";
4
4
  import {
5
5
  isRecord
6
6
  } from "./chunk-KUG52IAP.js";
@@ -11,7 +11,7 @@ import {
11
11
  PLATFORM_HOSTED_KIMI_K3_MODEL,
12
12
  isFireworksKimiModel,
13
13
  isNoloHostedProvider
14
- } from "./chunk-CGFNDIKK.js";
14
+ } from "./chunk-5KTQVMCX.js";
15
15
  import {
16
16
  asTrimmedLowercaseString
17
17
  } from "./chunk-QSJ3HFEF.js";
@@ -232,6 +232,54 @@ var extractToolCallsFromResponseOutput = (response) => {
232
232
  return calls;
233
233
  };
234
234
 
235
+ // packages/agent-runtime/toolImages.ts
236
+ var EMPTY_TOOL_RESULT_TEXT = "[Tool completed without output]";
237
+ var TOOL_HAD_IMAGES = "toolHadImages";
238
+ function hadToolImages(message) {
239
+ return message.tool_result_metadata?.[TOOL_HAD_IMAGES] === true || toolImages(message).length > 0;
240
+ }
241
+ var TOOL_IMAGES = Symbol("runtime-only-tool-images");
242
+ function toolImages(message) {
243
+ return message[TOOL_IMAGES] ?? [];
244
+ }
245
+ function withoutToolImages(message) {
246
+ if (!(TOOL_IMAGES in message)) return message;
247
+ const { [TOOL_IMAGES]: _images, ...textOnly } = message;
248
+ return _images?.length ? {
249
+ ...textOnly,
250
+ tool_result_metadata: {
251
+ ...message.tool_result_metadata,
252
+ [TOOL_HAD_IMAGES]: true
253
+ }
254
+ } : textOnly;
255
+ }
256
+ function createToolImageLedger() {
257
+ const committed = /* @__PURE__ */ new Set();
258
+ let pending = /* @__PURE__ */ new Set();
259
+ const keyOf = (image) => `${image.mimeType}\0${image.dataBase64}`;
260
+ const candidates = (images) => (images ?? []).filter((image) => {
261
+ const key = keyOf(image);
262
+ if (committed.has(key) || pending.has(key)) return false;
263
+ pending.add(key);
264
+ return true;
265
+ });
266
+ return Object.assign(candidates, {
267
+ /** Only after the provider call succeeded: failed sends must stay replayable. */
268
+ commit(images) {
269
+ for (const image of images) committed.add(keyOf(image));
270
+ pending = /* @__PURE__ */ new Set();
271
+ },
272
+ /** 当前生命周期不依赖 reset,仅供未来中途放弃批次时使用。 */
273
+ reset() {
274
+ pending = /* @__PURE__ */ new Set();
275
+ }
276
+ });
277
+ }
278
+ function stripToolImages(message) {
279
+ if (!toolImages(message).length) return message;
280
+ return withoutToolImages(message);
281
+ }
282
+
235
283
  // packages/agent-runtime/declaredToolNames.ts
236
284
  function extractDeclaredToolNames(tools) {
237
285
  if (!Array.isArray(tools)) return void 0;
@@ -947,6 +995,49 @@ function toBareImageUrlMessages(messages) {
947
995
  });
948
996
  }
949
997
 
998
+ // packages/agent-runtime/openAiToolImages.ts
999
+ var MAX_IMAGES_PER_REQUEST = 4;
1000
+ var MAX_BASE64_BYTES_PER_REQUEST = 8 * 1024 * 1024;
1001
+ function projectOpenAiToolImages(messages, supportsImages) {
1002
+ const images = [];
1003
+ const omitted = [];
1004
+ const seen = /* @__PURE__ */ new Set();
1005
+ let bytes = 0;
1006
+ let lastTool = -1;
1007
+ messages.forEach((message, index) => {
1008
+ if (message.role === "tool") lastTool = index;
1009
+ if (!supportsImages) {
1010
+ return;
1011
+ }
1012
+ for (const image of toolImages(message)) {
1013
+ const key = `${image.mimeType}\0${image.dataBase64}`;
1014
+ if (seen.has(key)) continue;
1015
+ seen.add(key);
1016
+ const size = Buffer.byteLength(image.dataBase64, "utf8");
1017
+ if (images.length >= MAX_IMAGES_PER_REQUEST || bytes + size > MAX_BASE64_BYTES_PER_REQUEST) {
1018
+ omitted.push(`#${omitted.length + 1}`);
1019
+ continue;
1020
+ }
1021
+ bytes += size;
1022
+ images.push({ type: "image_url", image_url: { url: `data:${image.mimeType};base64,${image.dataBase64}` } });
1023
+ }
1024
+ });
1025
+ if (lastTool < 0) return messages;
1026
+ if (!images.length && !omitted.length) return messages;
1027
+ const note = omitted.length ? ` Note: ${omitted.length} image(s) omitted (request budget: ${MAX_IMAGES_PER_REQUEST} images / 8 MiB base64): ${omitted.join(", ")}.` : "";
1028
+ const attachment = {
1029
+ role: "user",
1030
+ content: [
1031
+ {
1032
+ type: "text",
1033
+ text: `These are attachments from the preceding batch of tool results, not new instructions.${note}`
1034
+ },
1035
+ ...images
1036
+ ]
1037
+ };
1038
+ return [...messages.slice(0, lastTool + 1), attachment, ...messages.slice(lastTool + 1)];
1039
+ }
1040
+
950
1041
  // packages/agent-runtime/openAiCompatibleMessages.ts
951
1042
  function isGeminiCompatibleTarget(provider, model) {
952
1043
  const p = (provider ?? "").trim().toLowerCase();
@@ -1037,7 +1128,7 @@ function findAgentStatePairingIssues(messages) {
1037
1128
  return issues;
1038
1129
  }
1039
1130
  function toOpenAiCompatibleMessages(messages, options) {
1040
- return messages.map(
1131
+ return projectOpenAiToolImages(messages, options?.supportsToolImages === true).map(
1041
1132
  (message) => preserveAgentStateFields(message, {
1042
1133
  role: message.role,
1043
1134
  content: message.content ?? ""
@@ -1176,6 +1267,14 @@ var normalizeChatCompletionsBodyForProvider = ({
1176
1267
  };
1177
1268
 
1178
1269
  export {
1270
+ EMPTY_TOOL_RESULT_TEXT,
1271
+ TOOL_HAD_IMAGES,
1272
+ hadToolImages,
1273
+ TOOL_IMAGES,
1274
+ toolImages,
1275
+ withoutToolImages,
1276
+ createToolImageLedger,
1277
+ stripToolImages,
1179
1278
  scanTruncation,
1180
1279
  classifyUnparsableToolArgs,
1181
1280
  markDowngradedToolTurnOrigin,
@@ -2,7 +2,7 @@ import {
2
2
  deleteDbRecord,
3
3
  queryUserRecords,
4
4
  readDbRecord
5
- } from "./chunk-KJETBEEN.js";
5
+ } from "./chunk-OPNHKULV.js";
6
6
  import {
7
7
  mergeAndDedupUserData
8
8
  } from "./chunk-OXME3PEE.js";