nolo-cli 0.107.0-alpha.4 → 0.107.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 (211) hide show
  1. package/README.md +1 -1
  2. package/{_executeModel-UDCSOTD2.js → _executeModel-M573MKVE.js} +78 -70
  3. package/action-GVA5ARSJ.js +20 -0
  4. package/{addContentAction-MB2HHMDZ.js → addContentAction-M2WOWZCL.js} +13 -12
  5. package/{addDialogAgentAction-MCEABSBA.js → addDialogAgentAction-QMAQ5Z6N.js} +19 -20
  6. package/{agentDeleteCommand-OWYHN6D6.js → agentDeleteCommand-ZFHYRHBS.js} +118 -43
  7. package/{agentEmailCommands-AU5I4M4W.js → agentEmailCommands-X6AVPIVQ.js} +100 -90
  8. package/agentListCommands-PAD2CI2I.js +741 -0
  9. package/{agentMachineCommands-YMNME2L6.js → agentMachineCommands-UPH6RJCC.js} +50 -46
  10. package/{agentProviderCommands-GNPTL5XR.js → agentProviderCommands-CMVTBY5X.js} +97 -2
  11. package/{agentPullCommand-O5MPVJ5E.js → agentPullCommand-B4T2DJ5H.js} +1 -1
  12. package/agentRecordCommands-UMACPRAF.js +138 -0
  13. package/agentRunCommand-H6KKHHMU.js +167 -0
  14. package/{agentRunControl-AVJR4JW4.js → agentRunControl-3HWA2LLQ.js} +2 -2
  15. package/{agentRuntimeLocal-KCMC2TBD.js → agentRuntimeLocal-N4YGKL7M.js} +44 -40
  16. package/{agentSlice-R7PR6KYM.js → agentSlice-2LPP43XH.js} +15 -14
  17. package/{appDeleteCommands-JEPA3EWE.js → appDeleteCommands-7DAF33AM.js} +46 -42
  18. package/{appDeployCommands-UTB76XFM.js → appDeployCommands-ZPZSMFGZ.js} +46 -42
  19. package/{appDeployStatusCommands-LGHF2SBD.js → appDeployStatusCommands-FWBDSSS5.js} +46 -42
  20. package/{appGetCommands-PX2BFHOB.js → appGetCommands-SZZOHGEP.js} +46 -42
  21. package/{appListCommands-BSMPTWKC.js → appListCommands-FPMUBDPM.js} +46 -42
  22. package/{authCommand-YW42YZA4.js → authCommand-VL3G26NQ.js} +119 -25
  23. package/{authCommands-RGOGCPP6.js → authCommands-5RTUDYZW.js} +7 -5
  24. package/{builtinSkillRegistry-FUAVTRVZ.js → builtinSkillRegistry-ZK4K67Y5.js} +11 -9
  25. package/{chromeCommands-FZYAU75D.js → chromeCommands-AU5ZJXBG.js} +289 -37
  26. package/{chromeOpsCommands-62P2Q2YB.js → chromeOpsCommands-ZYTCMNHG.js} +156 -22
  27. package/{chunk-JEDZAO7L.js → chunk-2SYTUTLI.js} +257 -37
  28. package/{chunk-HVURBGF3.js → chunk-2U3NHADM.js} +6 -6
  29. package/{chunk-QTGQ2LTL.js → chunk-3DQY5IFB.js} +6 -10
  30. package/{chunk-XT35TTFG.js → chunk-3IXAHOJS.js} +19 -21
  31. package/{chunk-UVA7OYO3.js → chunk-3W67RV75.js} +29 -9
  32. package/chunk-4LCOCOR5.js +50 -0
  33. package/{chunk-JPGCXHNM.js → chunk-4LKMZ3RR.js} +1 -1
  34. package/{chunk-2GRGFCF6.js → chunk-4VJAC32I.js} +2 -1
  35. package/{chunk-6D6VBVEW.js → chunk-4W24JM32.js} +80 -14
  36. package/{chunk-MC4XLIJ7.js → chunk-523DITKR.js} +1 -1
  37. package/{chunk-E4MARS3Q.js → chunk-5GVBDNTO.js} +1 -1
  38. package/{chunk-C3M4465B.js → chunk-5HYJ3DSZ.js} +404 -659
  39. package/chunk-5MMAK75Q.js +15 -0
  40. package/{chunk-7S4YWN7P.js → chunk-5UUIGN6I.js} +4 -4
  41. package/{chunk-42V6BK2E.js → chunk-62IL3KQV.js} +4 -34
  42. package/{chunk-4MK3I7Y4.js → chunk-6MAW4XOF.js} +5 -5
  43. package/{chunk-3UZPUAES.js → chunk-74PPKIY2.js} +1 -1
  44. package/chunk-76HO2DP6.js +15 -0
  45. package/{chunk-ASIFZ2WY.js → chunk-7BBP7ZX3.js} +66 -54
  46. package/{chunk-VLTIYV3X.js → chunk-7I25CBT5.js} +34 -8
  47. package/{chunk-IBOZNTG2.js → chunk-7X5XZ34C.js} +23 -28
  48. package/chunk-AGIM7IMJ.js +147 -0
  49. package/{chunk-5UTFL4QJ.js → chunk-APO5TOXO.js} +1 -1
  50. package/{chunk-EEGDMATE.js → chunk-AZOVPTL6.js} +91 -81
  51. package/{chunk-6OZ36FXI.js → chunk-BIPGGSJS.js} +22 -4
  52. package/{chunk-EYAQT56M.js → chunk-BNQMNUKZ.js} +9 -6
  53. package/{chunk-62CATUYY.js → chunk-CBUMFIFE.js} +834 -962
  54. package/{chunk-OIVSQH2O.js → chunk-CDEEFJXN.js} +308 -11
  55. package/chunk-CHOZJMJS.js +78 -0
  56. package/{chunk-ETI2NYVF.js → chunk-CIP3AAMT.js} +4 -4
  57. package/{chunk-GBRG75BQ.js → chunk-D2MDMY2M.js} +1 -0
  58. package/{chunk-W7HLWAQ7.js → chunk-DE45KZNH.js} +118 -90
  59. package/{chunk-Q554LLSI.js → chunk-DMXLXZKL.js} +1 -1
  60. package/{chunk-3VNWWVKB.js → chunk-E3YWHWCR.js} +50 -18
  61. package/{chunk-HKNXJGEC.js → chunk-ECFHBYUW.js} +85 -50
  62. package/{chunk-ACTMNVHM.js → chunk-EHSYSKXV.js} +1 -1
  63. package/{chunk-WV42OMV7.js → chunk-ELUDRSRD.js} +8 -8
  64. package/{chunk-ABQYVJBJ.js → chunk-EV235ILT.js} +5 -5
  65. package/{chunk-TRV2MIDW.js → chunk-EXAJ6DCR.js} +1 -0
  66. package/{chunk-BFDFRLLQ.js → chunk-EZ4VZHAG.js} +5 -5
  67. package/{chunk-GO3Z72MT.js → chunk-FHLMQIU7.js} +65 -95
  68. package/{chunk-2F7RJC6L.js → chunk-FOXQ7BAB.js} +1 -1
  69. package/{chunk-SH43IESU.js → chunk-GGC55Q32.js} +199 -29
  70. package/chunk-GMZLP5DV.js +82 -0
  71. package/{chunk-FDTR4QJ6.js → chunk-H6A6X4EK.js} +32 -1
  72. package/{chunk-DVINR3PL.js → chunk-HDLLCBRF.js} +1 -1
  73. package/{chunk-QOKAKDPE.js → chunk-HIM3FCLF.js} +0 -1
  74. package/{chunk-ONXOABJR.js → chunk-HNGRBWYF.js} +3 -0
  75. package/{chunk-BNGW5ASC.js → chunk-I2RGRVQ7.js} +22 -2
  76. package/{chunk-O6OSWFZQ.js → chunk-IHPDK6UD.js} +6 -0
  77. package/{chunk-QDSINZM3.js → chunk-IXH3HKY2.js} +1 -22
  78. package/{chunk-GQBOR3G6.js → chunk-JBKHQOYK.js} +8 -4
  79. package/{chunk-XD2MJFUG.js → chunk-JEFXP73H.js} +1 -1
  80. package/{chunk-PBA4UJBK.js → chunk-JIXGJTBU.js} +4 -4
  81. package/{chunk-AEOE4Z6Q.js → chunk-K6L5PNXK.js} +39 -15
  82. package/{chunk-Z77CRGTW.js → chunk-KA5O5KQL.js} +1 -1
  83. package/{chunk-GPCZ7UXG.js → chunk-KD6D6BLA.js} +1 -1
  84. package/{chunk-4CR5I7BD.js → chunk-KFWDYYSS.js} +47 -67
  85. package/{chunk-UZGQNTVW.js → chunk-KHKTDMYG.js} +8 -6
  86. package/{chunk-JDPFV2JV.js → chunk-KWUKOQM2.js} +20 -11
  87. package/{chunk-MRIHM22T.js → chunk-LBFL6RZG.js} +58 -9
  88. package/{chunk-LS2ZANRJ.js → chunk-LOCNXNOU.js} +1 -1
  89. package/{chunk-DHDMC6FO.js → chunk-LUBFABMJ.js} +15 -14
  90. package/{chunk-NA35QHCF.js → chunk-LVBFKW65.js} +1 -1
  91. package/chunk-LWLNLZC5.js +265 -0
  92. package/chunk-N4NGJDT6.js +929 -0
  93. package/{chunk-BFU6C242.js → chunk-NMFV26UG.js} +1 -1
  94. package/{chunk-FZGV4FGK.js → chunk-NUHHBEJC.js} +378 -187
  95. package/chunk-NWENLDMM.js +42 -0
  96. package/chunk-O7SVKKLY.js +875 -0
  97. package/chunk-OCZKATRC.js +129 -0
  98. package/{chunk-6Z7MY3V7.js → chunk-OEJLGVBL.js} +5 -5
  99. package/{chunk-VMFTFOWF.js → chunk-OKGVNZTL.js} +35 -8
  100. package/{chunk-GEPUP7OO.js → chunk-OR2UWD6X.js} +3 -3
  101. package/{chunk-KQHGZWSV.js → chunk-OXME3PEE.js} +1 -1
  102. package/{chunk-J4MOO56S.js → chunk-PNXHPLRU.js} +10 -2
  103. package/{chunk-3BMYXEUW.js → chunk-R5AJODNI.js} +1 -1
  104. package/{chunk-P5EVSOPA.js → chunk-R6EBQEQE.js} +22 -29
  105. package/chunk-RQ6CTX2E.js +164 -0
  106. package/{chunk-MS7TSPZR.js → chunk-RU36ZYSG.js} +19 -17
  107. package/{chunk-ALXHV7NK.js → chunk-RWXLPUKI.js} +40 -4
  108. package/{chunk-KQ4ONNQD.js → chunk-RXA3HAVW.js} +190 -8
  109. package/{chunk-IIVGDG4I.js → chunk-SJKULPGX.js} +13 -7
  110. package/{chunk-Q67DOFOO.js → chunk-SZC4REES.js} +212 -105
  111. package/{chunk-JRQFUXY7.js → chunk-TBAXFWOS.js} +99 -22
  112. package/{chunk-PQFHGD77.js → chunk-TBM2RS3U.js} +161 -14
  113. package/{chunk-NOF3HDSN.js → chunk-TFOIJFCM.js} +11 -9
  114. package/{chunk-BYMV6QZG.js → chunk-TNIX77YM.js} +4 -0
  115. package/chunk-TY3TIUJK.js +89 -0
  116. package/{chunk-I3TQJXQ7.js → chunk-U3C3IA32.js} +9 -2
  117. package/{chunk-YYLHWIW6.js → chunk-UKZX3NHN.js} +1 -1
  118. package/chunk-UM7TA3K4.js +1008 -0
  119. package/{chunk-6YTOJY35.js → chunk-VBG7GWWR.js} +253 -8
  120. package/{chunk-GL3EHUR4.js → chunk-VHGYUYQ3.js} +69 -47
  121. package/chunk-VIWDGTDA.js +8 -0
  122. package/chunk-VJVNU77E.js +83 -0
  123. package/chunk-VM6IE2GN.js +8004 -0
  124. package/{chunk-UKWGR5SS.js → chunk-VY6VFGKR.js} +194 -1144
  125. package/chunk-VZLO4XJD.js +17 -0
  126. package/chunk-W32HPLTL.js +13692 -0
  127. package/{chunk-AHAHBQMU.js → chunk-WDLSZMTA.js} +2 -2
  128. package/{chunk-53HEEOTT.js → chunk-WF5X57VW.js} +83 -16
  129. package/{chunk-VRTTFDBM.js → chunk-WPHY3VPF.js} +35 -22
  130. package/{chunk-3L2WKC3W.js → chunk-XPWGOTBQ.js} +8 -1
  131. package/chunk-YV25TM3R.js +780 -0
  132. package/chunk-ZRAU6T47.js +56 -0
  133. package/{chunk-IBOOZVVD.js → chunk-ZTKZZY2A.js} +851 -279
  134. package/commandRegistry-ASW6IVZ3.js +833 -0
  135. package/{contentThunks-IV2T3EJC.js → contentThunks-4XNVOIR7.js} +39 -36
  136. package/{cooldownCommands-REAWYVTY.js → cooldownCommands-ZLEPIB4A.js} +2 -2
  137. package/{createAgentAutomationAction-JCOIEYY4.js → createAgentAutomationAction-NHHTCJMC.js} +40 -37
  138. package/createDialogAction-XEBTHDB3.js +70 -0
  139. package/{createPageAction-D2VOOLP3.js → createPageAction-VR3WW2AQ.js} +47 -43
  140. package/{chunk-FG3HKPQP.js → cursorProvider-YGGNMVWX.js} +2751 -10185
  141. package/{dbSlice-A6C6H32X.js → dbSlice-TG4MZ5EB.js} +12 -11
  142. package/{deleteFile-YG6QMJLU.js → deleteFile-KESP65GC.js} +7 -6
  143. package/{dialogCommands-H7FPUYUQ.js → dialogCommands-FJWQG3MX.js} +50 -47
  144. package/{dialogSlice-6JZOOTDS.js → dialogSlice-GVRDGCRG.js} +57 -37
  145. package/{dist-VODFSGNG.js → dist-NJC2W7I4.js} +61 -54
  146. package/{docCreateCommands-WRG2JLGM.js → docCreateCommands-AZSK4NAG.js} +48 -44
  147. package/{docDeleteCommands-SHWJIBJS.js → docDeleteCommands-DDJMSMFZ.js} +49 -45
  148. package/{docReadCommands-WJN3WT6O.js → docReadCommands-5F5Q6EBZ.js} +47 -43
  149. package/{docStore-HUPQ2FSS.js → docStore-SUZUUWDI.js} +17 -13
  150. package/{docUpdateCommands-IE32IL6O.js → docUpdateCommands-XPNPVZOC.js} +48 -44
  151. package/{fetchMessages-EIU7UFFK.js → fetchMessages-3PXAHKCR.js} +5 -5
  152. package/{getPricing-LUSEABA6.js → getPricing-DOBBZLOK.js} +4 -4
  153. package/{handleSendMessageAction-DFPMQ7YM.js → handleSendMessageAction-VC6VTFKS.js} +109 -42
  154. package/index.js +87 -884
  155. package/{lib-FRRS27KN.js → lib-PU2G2MSO.js} +523 -191
  156. package/{localDialogRead-BTFJ4V2I.js → localDialogRead-UYCKO7YZ.js} +2 -2
  157. package/{localRuntimeAuthority-6IR6BBXE.js → localRuntimeAuthority-TU6OBC76.js} +9 -6
  158. package/{localRuntimeDb-SYQGUF4U.js → localRuntimeDb-VKWVOPPI.js} +1 -1
  159. package/{machineCommands-M2T2I5NF.js → machineCommands-M634V2L3.js} +98 -89
  160. package/machineWsRunDispatch-Z3HUSTFI.js +154 -0
  161. package/{memberThunks-P2ECUJ56.js → memberThunks-5S5D3N4U.js} +20 -18
  162. package/{models-T3SG6MJ5.js → models-PQU25T6Q.js} +2 -2
  163. package/oauthTokenStore-ITEB663N.js +23 -0
  164. package/package.json +1 -1
  165. package/processSpawn-SOAV3FEV.js +11 -0
  166. package/profileConfig-ZGOFORWV.js +43 -0
  167. package/{providerPresetApply-FG6NZ57W.js → providerPresetApply-HAQWVAQX.js} +7 -7
  168. package/{providerRegistry-757OWH3O.js → providerRegistry-5FGWB3X5.js} +11 -7
  169. package/{read-COE3ZYR6.js → read-LSYFLSIM.js} +8 -7
  170. package/{readDocTool-5USN4A6V.js → readDocTool-XWRXV3DR.js} +5 -3
  171. package/{readlineWorkspace-XQRDGWRZ.js → readlineWorkspace-J3YD3DNW.js} +2596 -2032
  172. package/{removeDialogAgentAction-J6X5QMTA.js → removeDialogAgentAction-4TEFC3VL.js} +22 -26
  173. package/{runAgentClientLoop-5ZA62FBA.js → runAgentClientLoop-APSMCLAF.js} +79 -72
  174. package/{runtimeDoctorCommands-X6WDBEQX.js → runtimeDoctorCommands-PIVSBZRZ.js} +4 -4
  175. package/runtimeModeArgs-2Y7BALTO.js +31 -0
  176. package/{setDialogExtraReferencesAction-WX5VTY6O.js → setDialogExtraReferencesAction-LSEN44OY.js} +16 -14
  177. package/{setPrimaryDialogAgentAction-FN22THHT.js → setPrimaryDialogAgentAction-SR366X5A.js} +23 -27
  178. package/{chunk-GP5LKBUZ.js → settingThunks-CTVPPGIN.js} +226 -940
  179. package/{skillDiscovery-CYUCJMAG.js → skillDiscovery-ZBU76COE.js} +3 -3
  180. package/{slateUtils-RIZES3PV.js → slateUtils-NGV2NMKM.js} +1 -1
  181. package/{spaceCommands-5GLCWZPO.js → spaceCommands-3UK63WPE.js} +51 -47
  182. package/{streamAgentChatTurn-6UZJMYRB.js → streamAgentChatTurn-DNY2PSRW.js} +215 -115
  183. package/{switchDialogAgentAction-LVTEV3FR.js → switchDialogAgentAction-M6NAFOOU.js} +19 -20
  184. package/{tableCommands-O6NWHFKV.js → tableCommands-6U4BMLRR.js} +10 -10
  185. package/{toolApiClient-QVJ6HDNN.js → toolApiClient-AD7CXTA4.js} +4 -3
  186. package/tools-X5UWATZK.js +117 -0
  187. package/{tuiSummaryLlmCaller-OHHFTHMG.js → tuiSummaryLlmCaller-DEH7ZEM6.js} +25 -23
  188. package/{updateCommands-2M74UL7P.js → updateCommands-4EHDLF5J.js} +3 -3
  189. package/{updateDialogTitleAction-QTKNIURB.js → updateDialogTitleAction-YSY5BF5A.js} +84 -45
  190. package/action-P4TNFGAD.js +0 -31
  191. package/agentListCommands-B2V4YAC4.js +0 -410
  192. package/agentRecordCommands-G4KK4R7H.js +0 -128
  193. package/agentRunCommand-UTZJA23G.js +0 -156
  194. package/browser-image-compression-MFDTD7K6.js +0 -1763
  195. package/chatQueueReduxAdapter-2P6NFX64.js +0 -186
  196. package/chunk-CQ3WA2NE.js +0 -299
  197. package/chunk-M76ECQRD.js +0 -13658
  198. package/chunk-MEYIRKDN.js +0 -8967
  199. package/chunk-PUOC4YRO.js +0 -394
  200. package/chunk-Q5FJJ6XI.js +0 -103
  201. package/chunk-S7Z2HMCN.js +0 -25
  202. package/chunk-T75QD6AB.js +0 -20923
  203. package/chunk-Y5GCAMGP.js +0 -9
  204. package/chunk-YPREESF4.js +0 -225
  205. package/createDialogAction-NGG7YVNU.js +0 -65
  206. package/machineWsRunDispatch-ISBKOOD7.js +0 -144
  207. package/settingSlice-P4ZW7K5X.js +0 -204
  208. package/syncMapping-N6RGXGBW.js +0 -437
  209. package/tools-KMGFWO43.js +0 -110
  210. package/{chunk-X7HHHIOZ.js → chunk-Y6ROFCZO.js} +0 -0
  211. package/{db-WK5MDZVN.js → db-VQSAOWAO.js} +1 -1
@@ -0,0 +1,1008 @@
1
+ import {
2
+ asTrimmedLowercaseString
3
+ } from "./chunk-QSJ3HFEF.js";
4
+ import {
5
+ isRecord
6
+ } from "./chunk-KUG52IAP.js";
7
+ import {
8
+ asOptionalTrimmedString
9
+ } from "./chunk-G3SUCT4W.js";
10
+
11
+ // packages/agent-runtime/declaredToolNames.ts
12
+ function extractDeclaredToolNames(tools) {
13
+ if (!Array.isArray(tools)) return void 0;
14
+ const names = /* @__PURE__ */ new Set();
15
+ for (const t of tools) {
16
+ const fn = t?.function;
17
+ if (fn && typeof fn.name === "string" && fn.name) names.add(fn.name);
18
+ }
19
+ return names;
20
+ }
21
+
22
+ // packages/agent-runtime/toolArgsShape.ts
23
+ function scanRawToolArgs(input) {
24
+ const stack = [];
25
+ const commaAtDepth = [];
26
+ let inString = false;
27
+ let escaped = false;
28
+ const closersOf2 = () => stack.slice().reverse().map((ch) => ch === "{" ? "}" : "]").join("");
29
+ for (let i = 0; i < input.length; i += 1) {
30
+ const ch = input[i];
31
+ if (inString) {
32
+ if (escaped) escaped = false;
33
+ else if (ch === "\\") escaped = true;
34
+ else if (ch === '"') inString = false;
35
+ continue;
36
+ }
37
+ if (ch === '"') {
38
+ inString = true;
39
+ } else if (ch === "{" || ch === "[") {
40
+ stack.push(ch);
41
+ commaAtDepth[stack.length] = void 0;
42
+ } else if (ch === "}" || ch === "]") {
43
+ const open = stack.pop();
44
+ if (open !== (ch === "}" ? "{" : "[")) {
45
+ return {
46
+ inString,
47
+ mismatched: true,
48
+ unclosed: false,
49
+ // 结构已坏:与迁移前一致,不再给出尾部数组逗号坐标。
50
+ tailArrayComma: null
51
+ };
52
+ }
53
+ commaAtDepth[stack.length + 1] = void 0;
54
+ } else if (ch === "," && stack[stack.length - 1] === "[") {
55
+ commaAtDepth[stack.length] = { index: i, closers: closersOf2() };
56
+ }
57
+ }
58
+ let tailArrayComma = null;
59
+ for (let d = stack.length; d >= 1; d -= 1) {
60
+ const c = commaAtDepth[d];
61
+ if (c && stack[d - 1] === "[") {
62
+ tailArrayComma = c;
63
+ break;
64
+ }
65
+ }
66
+ return {
67
+ inString,
68
+ mismatched: false,
69
+ unclosed: stack.length > 0,
70
+ tailArrayComma
71
+ };
72
+ }
73
+ function classifyUnparsableToolArgs(raw) {
74
+ if (typeof raw !== "string") return "malformed";
75
+ const scan = scanRawToolArgs(raw);
76
+ if (scan.inString) return "truncated";
77
+ return scan.mismatched || scan.unclosed ? "truncated" : "malformed";
78
+ }
79
+
80
+ // packages/agent-runtime/outboundHistorySanitize.ts
81
+ var DOWNGRADED_TOOL_TURN_ORIGIN = Symbol(
82
+ "nolo.downgradedToolTurnOrigin"
83
+ );
84
+ function markDowngradedToolTurnOrigin(message) {
85
+ Object.defineProperty(message, DOWNGRADED_TOOL_TURN_ORIGIN, {
86
+ value: true,
87
+ enumerable: false,
88
+ writable: false,
89
+ configurable: true
90
+ });
91
+ return message;
92
+ }
93
+ function transferDowngradedToolTurnOrigin(source, rebuilt) {
94
+ if (hasDowngradedToolTurnOrigin(source)) markDowngradedToolTurnOrigin(rebuilt);
95
+ return rebuilt;
96
+ }
97
+ function hasDowngradedToolTurnOrigin(message) {
98
+ return typeof message === "object" && message !== null && message[DOWNGRADED_TOOL_TURN_ORIGIN] === true;
99
+ }
100
+ function emptyToolArgsProjectionStats() {
101
+ return {
102
+ badArguments: { truncated: 0, malformed: 0 },
103
+ rewrittenToolCalls: 0,
104
+ rewrittenAssistantMessages: 0,
105
+ rewrittenToolMessages: 0
106
+ };
107
+ }
108
+ function sanitizeForOutbound(messages, tools) {
109
+ return sanitizeOutboundHistory(messages, {
110
+ declaredToolNames: extractDeclaredToolNames(tools)
111
+ });
112
+ }
113
+ function stableToolCallId(assistantIndex, callIndex) {
114
+ return `call_sanitize_${assistantIndex}_${callIndex}`;
115
+ }
116
+ function isString(v) {
117
+ return typeof v === "string";
118
+ }
119
+ function isNonEmptyString(v) {
120
+ return typeof v === "string" && v.length > 0;
121
+ }
122
+ function joinLines(...parts) {
123
+ return parts.filter(isNonEmptyString).join("\n");
124
+ }
125
+ function jsonStringifyArguments(args) {
126
+ if (typeof args === "string") return args;
127
+ try {
128
+ return JSON.stringify(args ?? "");
129
+ } catch {
130
+ return "";
131
+ }
132
+ }
133
+ function renderToolCallAsText(call) {
134
+ const c = call && typeof call === "object" ? call : {};
135
+ const name = isString(c.function?.name) && c.function.name.length > 0 ? c.function.name : "unknown";
136
+ const rawArgs = c.function?.arguments;
137
+ const args = jsonStringifyArguments(rawArgs);
138
+ return `[tool_call: ${name}(${args})]`;
139
+ }
140
+ function renderToolResultAsText(message) {
141
+ const name = isNonEmptyString(message.toolName) ? message.toolName : "tool";
142
+ const body = typeof message.content === "string" ? message.content : "";
143
+ return `[tool_result: ${name}: ${body}]`;
144
+ }
145
+ function normalizeToolCall(call, assistantIndex, callIndex) {
146
+ if (!call || typeof call !== "object") return null;
147
+ const c = call;
148
+ const fn = c.function;
149
+ if (!fn || typeof fn !== "object" || !isString(fn.name) || fn.name.length === 0) return null;
150
+ const id = isNonEmptyString(c.id) ? c.id : stableToolCallId(assistantIndex, callIndex);
151
+ return {
152
+ id,
153
+ type: isString(c.type) && c.type ? c.type : "function",
154
+ function: { name: fn.name, arguments: jsonStringifyArguments(fn.arguments) },
155
+ ...typeof c.extra_content?.google?.thought_signature === "string" ? { extra_content: { google: { thought_signature: c.extra_content.google.thought_signature } } } : {},
156
+ ...typeof c.thought_signature === "string" ? { thought_signature: c.thought_signature } : {}
157
+ };
158
+ }
159
+ function classifyAssistantCalls(toolCalls, assistantIndex) {
160
+ const callIds = [];
161
+ const idCounts = /* @__PURE__ */ new Map();
162
+ const unparsableIndices = /* @__PURE__ */ new Set();
163
+ const unparsableIds = /* @__PURE__ */ new Set();
164
+ toolCalls.forEach((rawCall, callIndex) => {
165
+ const c = rawCall && typeof rawCall === "object" ? rawCall : {};
166
+ const id = isNonEmptyString(c.id) ? c.id : stableToolCallId(assistantIndex, callIndex);
167
+ callIds.push(id);
168
+ idCounts.set(id, (idCounts.get(id) ?? 0) + 1);
169
+ if (!hasParsableObjectArguments(c.function?.arguments)) {
170
+ unparsableIndices.add(callIndex);
171
+ unparsableIds.add(id);
172
+ }
173
+ });
174
+ const duplicateIds = /* @__PURE__ */ new Set();
175
+ for (const [id, count] of idCounts) {
176
+ if (count > 1) duplicateIds.add(id);
177
+ }
178
+ return { callIds, duplicateIds, unparsableIndices, unparsableIds };
179
+ }
180
+ function sanitizeOutboundHistory(messages, options) {
181
+ if (!Array.isArray(messages) || messages.length === 0) return messages;
182
+ const declared = options?.declaredToolNames;
183
+ const keptCallIndicesPerAssistant = /* @__PURE__ */ new Map();
184
+ const keptToolIndices = /* @__PURE__ */ new Set();
185
+ let i = 0;
186
+ while (i < messages.length) {
187
+ const m = messages[i];
188
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
189
+ const asstIdx = i;
190
+ const { callIds, duplicateIds, unparsableIndices } = classifyAssistantCalls(m.tool_calls, asstIdx);
191
+ const candidateCallMap = /* @__PURE__ */ new Map();
192
+ m.tool_calls.forEach((call, callIndex) => {
193
+ const id = callIds[callIndex];
194
+ if (duplicateIds.has(id)) return;
195
+ if (unparsableIndices.has(callIndex)) return;
196
+ const name = call?.function?.name;
197
+ if (!isString(name) || name.length === 0) return;
198
+ const declaredAllows = !declared || declared.has(name);
199
+ if (!declaredAllows) return;
200
+ candidateCallMap.set(id, callIndex);
201
+ });
202
+ let j = i + 1;
203
+ const matchedCallIndices = /* @__PURE__ */ new Set();
204
+ const matchedToolIds = /* @__PURE__ */ new Set();
205
+ while (j < messages.length && messages[j].role === "tool") {
206
+ const toolMsg = messages[j];
207
+ const toolCallId = isNonEmptyString(toolMsg.tool_call_id) ? toolMsg.tool_call_id : "";
208
+ if (toolCallId && candidateCallMap.has(toolCallId) && !matchedToolIds.has(toolCallId)) {
209
+ matchedToolIds.add(toolCallId);
210
+ matchedCallIndices.add(candidateCallMap.get(toolCallId));
211
+ keptToolIndices.add(j);
212
+ }
213
+ j++;
214
+ }
215
+ keptCallIndicesPerAssistant.set(asstIdx, matchedCallIndices);
216
+ i = j;
217
+ } else {
218
+ i++;
219
+ }
220
+ }
221
+ const out = [];
222
+ let k = 0;
223
+ while (k < messages.length) {
224
+ const m = messages[k];
225
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
226
+ const asstIdx = k;
227
+ const keptIndices = keptCallIndicesPerAssistant.get(asstIdx) ?? /* @__PURE__ */ new Set();
228
+ const keptToolCalls = [];
229
+ const downgradedCallLines = [];
230
+ m.tool_calls.forEach((call, callIndex) => {
231
+ const name = call?.function?.name;
232
+ const declaredAllows = !declared || isString(name) && declared.has(name);
233
+ const keep = keptIndices.has(callIndex) && declaredAllows && hasParsableObjectArguments(call?.function?.arguments);
234
+ if (keep) {
235
+ const normalized = normalizeToolCall(call, asstIdx, callIndex);
236
+ if (normalized) {
237
+ keptToolCalls.push(normalized);
238
+ } else {
239
+ downgradedCallLines.push(renderToolCallAsText(call));
240
+ }
241
+ } else {
242
+ downgradedCallLines.push(renderToolCallAsText(call));
243
+ }
244
+ });
245
+ if (keptToolCalls.length === 0) {
246
+ const downgradedText = joinLines(...downgradedCallLines);
247
+ const contentWithDowngrade = downgradedText.length > 0 ? combineContentWithText(m.content, downgradedText) : m.content;
248
+ const sanitizedAssistant2 = transferDowngradedToolTurnOrigin(m, {
249
+ ...m,
250
+ content: contentWithDowngrade
251
+ });
252
+ delete sanitizedAssistant2.tool_calls;
253
+ markDowngradedToolTurnOrigin(sanitizedAssistant2);
254
+ out.push(sanitizedAssistant2);
255
+ let nextIdx2 = k + 1;
256
+ while (nextIdx2 < messages.length && messages[nextIdx2].role === "tool") {
257
+ const downgradedToolMsg = messages[nextIdx2];
258
+ out.push(
259
+ transferDowngradedToolTurnOrigin(downgradedToolMsg, {
260
+ role: "assistant",
261
+ content: renderToolResultAsText(downgradedToolMsg)
262
+ })
263
+ );
264
+ nextIdx2++;
265
+ }
266
+ k = nextIdx2;
267
+ continue;
268
+ }
269
+ const sanitizedAssistant = transferDowngradedToolTurnOrigin(m, {
270
+ ...m,
271
+ tool_calls: keptToolCalls
272
+ });
273
+ out.push(sanitizedAssistant);
274
+ let nextIdx = k + 1;
275
+ const deferredResultLines = [];
276
+ while (nextIdx < messages.length && messages[nextIdx].role === "tool") {
277
+ if (keptToolIndices.has(nextIdx)) {
278
+ const toolMsg = messages[nextIdx];
279
+ out.push({
280
+ ...toolMsg,
281
+ content: toolMsg.content ?? "",
282
+ tool_call_id: toolMsg.tool_call_id
283
+ });
284
+ } else {
285
+ deferredResultLines.push(renderToolResultAsText(messages[nextIdx]));
286
+ }
287
+ nextIdx++;
288
+ }
289
+ const deferredLines = [...downgradedCallLines, ...deferredResultLines];
290
+ if (deferredLines.length > 0) {
291
+ out.push({
292
+ role: "assistant",
293
+ content: joinLines(...deferredLines)
294
+ });
295
+ }
296
+ k = nextIdx;
297
+ continue;
298
+ }
299
+ if (m.role === "tool") {
300
+ out.push(
301
+ transferDowngradedToolTurnOrigin(m, {
302
+ role: "assistant",
303
+ content: renderToolResultAsText(m)
304
+ })
305
+ );
306
+ k++;
307
+ continue;
308
+ }
309
+ out.push(transferDowngradedToolTurnOrigin(m, { ...m }));
310
+ k++;
311
+ }
312
+ return out;
313
+ }
314
+ function combineContentWithText(base, extra) {
315
+ if (typeof base === "string") {
316
+ return base ? `${base}
317
+ ${extra}` : extra;
318
+ }
319
+ if (Array.isArray(base)) {
320
+ return [...base, { type: "text", text: extra }];
321
+ }
322
+ return extra;
323
+ }
324
+ function hasParsableObjectArguments(raw) {
325
+ if (raw === void 0) return true;
326
+ if (raw === null || typeof raw === "number" || typeof raw === "boolean") {
327
+ return false;
328
+ }
329
+ if (typeof raw !== "string") return true;
330
+ if (raw.trim() === "") return true;
331
+ try {
332
+ const parsed = JSON.parse(raw);
333
+ return parsed !== null && typeof parsed === "object";
334
+ } catch {
335
+ return false;
336
+ }
337
+ }
338
+ var STRICT_JSON_STRING_TOKEN = /^"(?:[^"\\\u0000-\u001F]|\\["\\/bfnrt]|\\u[0-9A-Fa-f]{4})*"$/;
339
+ function isStrictJsonStringToken(value) {
340
+ if (!STRICT_JSON_STRING_TOKEN.test(value)) return false;
341
+ try {
342
+ return typeof JSON.parse(value) === "string";
343
+ } catch {
344
+ return false;
345
+ }
346
+ }
347
+ function closersOf(openStack) {
348
+ return openStack.slice().reverse().map((ch) => ch === "{" ? "}" : "]").join("");
349
+ }
350
+ function scanJsonForTailRepair(input) {
351
+ const stack = [];
352
+ let inString = false;
353
+ let escaped = false;
354
+ let lastCommaOutsideString = null;
355
+ for (let i = 0; i < input.length; i += 1) {
356
+ const ch = input[i];
357
+ if (inString) {
358
+ if (escaped) escaped = false;
359
+ else if (ch === "\\") escaped = true;
360
+ else if (ch === '"') inString = false;
361
+ continue;
362
+ }
363
+ if (ch === '"') {
364
+ inString = true;
365
+ continue;
366
+ }
367
+ if (ch === "{" || ch === "[") {
368
+ stack.push(ch);
369
+ continue;
370
+ }
371
+ if (ch === "}" || ch === "]") {
372
+ const open = stack.pop();
373
+ if (open !== (ch === "}" ? "{" : "[")) return null;
374
+ continue;
375
+ }
376
+ if (ch === ",") {
377
+ lastCommaOutsideString = { index: i, closers: closersOf(stack) };
378
+ continue;
379
+ }
380
+ }
381
+ return { inString, closers: closersOf(stack), lastCommaOutsideString };
382
+ }
383
+ function repairTruncatedToolArguments(raw) {
384
+ if (typeof raw !== "string") return null;
385
+ const withoutTrailingSpace = raw.replace(/\s+$/, "");
386
+ const endsWithComma = withoutTrailingSpace.endsWith(",");
387
+ const trimmed = endsWithComma ? withoutTrailingSpace.slice(0, -1).replace(/\s+$/, "") : withoutTrailingSpace;
388
+ if (trimmed === "" || trimmed.endsWith(",")) return null;
389
+ const scan = scanJsonForTailRepair(trimmed);
390
+ if (!scan || scan.inString) return null;
391
+ const lastChar = trimmed[trimmed.length - 1];
392
+ const tailIsCompleteToken = endsWithComma || lastChar === '"' || lastChar === "}" || lastChar === "]";
393
+ if (!tailIsCompleteToken) return null;
394
+ const candidates = [trimmed + scan.closers];
395
+ const lastComma = scan.lastCommaOutsideString;
396
+ if (lastComma && lastComma.index > 0) {
397
+ const tailAfterComma = trimmed.slice(lastComma.index + 1).trim();
398
+ if (isStrictJsonStringToken(tailAfterComma)) {
399
+ const head = trimmed.slice(0, lastComma.index);
400
+ candidates.push(head + lastComma.closers);
401
+ }
402
+ }
403
+ for (const candidate of candidates) {
404
+ try {
405
+ const parsed = JSON.parse(candidate);
406
+ if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && Object.keys(parsed).length > 0) {
407
+ return candidate;
408
+ }
409
+ } catch {
410
+ }
411
+ }
412
+ return null;
413
+ }
414
+ function downgradeUnparsableToolCalls(messages) {
415
+ if (!Array.isArray(messages) || messages.length === 0) {
416
+ return { messages, downgraded: 0, stats: emptyToolArgsProjectionStats() };
417
+ }
418
+ let hasAnyPoison = false;
419
+ for (const m of messages) {
420
+ if (m.role === "assistant" && Array.isArray(m.tool_calls)) {
421
+ for (const call of m.tool_calls) {
422
+ if (!hasParsableObjectArguments(call?.function?.arguments)) {
423
+ hasAnyPoison = true;
424
+ break;
425
+ }
426
+ }
427
+ }
428
+ if (hasAnyPoison) break;
429
+ }
430
+ if (!hasAnyPoison) return { messages, downgraded: 0, stats: emptyToolArgsProjectionStats() };
431
+ const poisonedCallsPerAssistant = /* @__PURE__ */ new Map();
432
+ const poisonedToolIndices = /* @__PURE__ */ new Set();
433
+ const badArguments = {
434
+ truncated: 0,
435
+ malformed: 0
436
+ };
437
+ let i = 0;
438
+ while (i < messages.length) {
439
+ const m = messages[i];
440
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
441
+ const asstIdx = i;
442
+ const { unparsableIds, unparsableIndices } = classifyAssistantCalls(m.tool_calls, asstIdx);
443
+ for (const badIndex of unparsableIndices) {
444
+ const badCall = m.tool_calls[badIndex];
445
+ badArguments[classifyUnparsableToolArgs(badCall?.function?.arguments)] += 1;
446
+ }
447
+ let j = i + 1;
448
+ while (j < messages.length && messages[j].role === "tool") {
449
+ const toolMsg = messages[j];
450
+ const toolCallId = isNonEmptyString(toolMsg.tool_call_id) ? toolMsg.tool_call_id : "";
451
+ if (toolCallId && unparsableIds.has(toolCallId)) {
452
+ poisonedToolIndices.add(j);
453
+ }
454
+ j++;
455
+ }
456
+ if (unparsableIds.size > 0) {
457
+ poisonedCallsPerAssistant.set(asstIdx, unparsableIds);
458
+ }
459
+ i = j;
460
+ } else {
461
+ i++;
462
+ }
463
+ }
464
+ let downgraded = 0;
465
+ let rewrittenAssistantMessages = 0;
466
+ let rewrittenToolMessages = 0;
467
+ const out = [];
468
+ let k = 0;
469
+ while (k < messages.length) {
470
+ const m = messages[k];
471
+ if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
472
+ const badIds = poisonedCallsPerAssistant.get(k);
473
+ if (!badIds || badIds.size === 0) {
474
+ out.push(m);
475
+ k++;
476
+ continue;
477
+ }
478
+ const kept = [];
479
+ const lines = [];
480
+ const { callIds } = classifyAssistantCalls(m.tool_calls, k);
481
+ rewrittenAssistantMessages += 1;
482
+ m.tool_calls.forEach((call, callIndex) => {
483
+ const id = callIds[callIndex];
484
+ if (badIds.has(id)) {
485
+ lines.push(renderToolCallAsText(call));
486
+ downgraded++;
487
+ } else {
488
+ kept.push(call);
489
+ }
490
+ });
491
+ if (kept.length === 0) {
492
+ const sanitized2 = transferDowngradedToolTurnOrigin(m, {
493
+ ...m,
494
+ content: combineContentWithText(m.content, joinLines(...lines))
495
+ });
496
+ delete sanitized2.tool_calls;
497
+ markDowngradedToolTurnOrigin(sanitized2);
498
+ out.push(sanitized2);
499
+ let nextIdx2 = k + 1;
500
+ while (nextIdx2 < messages.length && messages[nextIdx2].role === "tool") {
501
+ if (poisonedToolIndices.has(nextIdx2)) {
502
+ const poisonedToolMsg = messages[nextIdx2];
503
+ out.push(
504
+ transferDowngradedToolTurnOrigin(poisonedToolMsg, {
505
+ role: "assistant",
506
+ content: renderToolResultAsText(poisonedToolMsg)
507
+ })
508
+ );
509
+ rewrittenToolMessages += 1;
510
+ } else {
511
+ out.push(messages[nextIdx2]);
512
+ }
513
+ nextIdx2++;
514
+ }
515
+ k = nextIdx2;
516
+ continue;
517
+ }
518
+ const sanitized = transferDowngradedToolTurnOrigin(m, {
519
+ ...m,
520
+ content: lines.length > 0 ? combineContentWithText(m.content, joinLines(...lines)) : m.content,
521
+ tool_calls: kept
522
+ });
523
+ out.push(sanitized);
524
+ let nextIdx = k + 1;
525
+ const deferredResultLines = [];
526
+ while (nextIdx < messages.length && messages[nextIdx].role === "tool") {
527
+ if (poisonedToolIndices.has(nextIdx)) {
528
+ deferredResultLines.push(renderToolResultAsText(messages[nextIdx]));
529
+ rewrittenToolMessages += 1;
530
+ } else {
531
+ out.push(messages[nextIdx]);
532
+ }
533
+ nextIdx++;
534
+ }
535
+ if (deferredResultLines.length > 0) {
536
+ out.push({
537
+ role: "assistant",
538
+ content: joinLines(...deferredResultLines)
539
+ });
540
+ }
541
+ k = nextIdx;
542
+ continue;
543
+ }
544
+ if (m.role === "tool") {
545
+ if (poisonedToolIndices.has(k)) {
546
+ out.push(
547
+ transferDowngradedToolTurnOrigin(m, {
548
+ role: "assistant",
549
+ content: renderToolResultAsText(m)
550
+ })
551
+ );
552
+ rewrittenToolMessages += 1;
553
+ } else {
554
+ out.push(m);
555
+ }
556
+ k++;
557
+ continue;
558
+ }
559
+ out.push(m);
560
+ k++;
561
+ }
562
+ return {
563
+ messages: out,
564
+ downgraded,
565
+ stats: {
566
+ badArguments,
567
+ // 投影改写数与坏参数数是两套口径:rewrittenToolCalls 含同 ID 连带降级的
568
+ // 调用,二者允许不相等(同 ID 一坏一好 → 坏参数 1、改写调用 2)。
569
+ rewrittenToolCalls: downgraded,
570
+ rewrittenAssistantMessages,
571
+ rewrittenToolMessages
572
+ }
573
+ };
574
+ }
575
+
576
+ // packages/core/ollamaEndpoint.ts
577
+ function isOllamaEndpoint(endpoint) {
578
+ if (!endpoint || typeof endpoint !== "string") return false;
579
+ try {
580
+ const url = new URL(endpoint.includes("://") ? endpoint : `http://${endpoint}`);
581
+ if (url.port === "11434") return true;
582
+ const host = url.hostname.toLowerCase();
583
+ return host === "ollama.com" || host.endsWith(".ollama.com") || host === "ollama.ai" || host.endsWith(".ollama.ai");
584
+ } catch {
585
+ return false;
586
+ }
587
+ }
588
+
589
+ // packages/ai/llm/usageRequestOptions.ts
590
+ var STREAM_USAGE_PROVIDERS = /* @__PURE__ */ new Set([
591
+ "google",
592
+ "openrouter",
593
+ "xai",
594
+ "openai",
595
+ "fireworks",
596
+ "mistral",
597
+ "cloudflare",
598
+ "gmi",
599
+ // OpenAI-compatible hosted providers expose the terminal usage chunk when
600
+ // requested, including DeepInfra and Vultr. Keep this capability decision
601
+ // in the shared seam so proxy and local runtimes cannot drift.
602
+ "deepinfra",
603
+ "vultr",
604
+ // Explicit local-runtime providers with OpenAI-compatible streaming: both
605
+ // DeepSeek official and Ollama honor stream_options.include_usage on their
606
+ // chat.completions endpoints. Without them, locally-configured agents lose
607
+ // token statistics / local billing (the whitelist replaced the previous
608
+ // always-on include_usage). ollama-cloud is the Ollama Cloud subscription
609
+ // endpoint (https://ollama.com/v1), an OpenAI-compatible API that likewise
610
+ // honors stream_options.include_usage.
611
+ "deepseek",
612
+ "ollama",
613
+ "ollama-cloud",
614
+ // RunInfra hosted fallback channel: OpenAI-compatible chat.completions
615
+ // endpoint, supports stream_options.include_usage (measured to return
616
+ // prompt_tokens_details.cached_tokens).
617
+ "runinfra",
618
+ "baseten",
619
+ // Kimi For Coding subscription (api.kimi.com/coding/v1): OpenAI-compatible
620
+ // chat.completions streaming that only emits the terminal usage frame when
621
+ // stream_options.include_usage is requested (measured; the official
622
+ // kimi-code CLI also sends include_usage). Custom agents pointing at the
623
+ // same endpoint are covered by the endpoint check below, not here.
624
+ "kimi-code"
625
+ ]);
626
+ var KIMI_CODE_ENDPOINT_MARKER = "api.kimi.com";
627
+ var isKimiCodeEndpoint = (endpoint) => typeof endpoint === "string" && endpoint.includes(KIMI_CODE_ENDPOINT_MARKER);
628
+ var EXTRA_USAGE_FIELD_PROVIDERS = /* @__PURE__ */ new Set(["openrouter"]);
629
+ var normalizeProviderName = (providerName) => asTrimmedLowercaseString(providerName);
630
+ var getUsageRequestOptions = (providerName, options) => {
631
+ const normalizedProvider = normalizeProviderName(providerName);
632
+ const api = options?.api ?? "chat-completions";
633
+ const shouldRequestStreamUsage = STREAM_USAGE_PROVIDERS.has(normalizedProvider) || normalizedProvider === "custom" && (isKimiCodeEndpoint(options?.endpoint) || isOllamaEndpoint(options?.endpoint));
634
+ if (api === "responses") {
635
+ return EXTRA_USAGE_FIELD_PROVIDERS.has(normalizedProvider) ? {
636
+ usage: {
637
+ include: true
638
+ }
639
+ } : {};
640
+ }
641
+ return {
642
+ ...shouldRequestStreamUsage ? {
643
+ stream_options: {
644
+ include_usage: true
645
+ }
646
+ } : {},
647
+ ...EXTRA_USAGE_FIELD_PROVIDERS.has(normalizedProvider) ? {
648
+ usage: {
649
+ include: true
650
+ }
651
+ } : {}
652
+ };
653
+ };
654
+
655
+ // packages/agent-runtime/openAiCompatibleMessages.ts
656
+ function isGeminiCompatibleTarget(provider, model) {
657
+ const p = (provider ?? "").trim().toLowerCase();
658
+ const m = (model ?? "").trim().toLowerCase();
659
+ return p === "google" || p === "google-antigravity" || p.startsWith("google-") || p.includes("gemini") || m.includes("gemini");
660
+ }
661
+ function preserveAgentStateFields(source, target, options) {
662
+ const mutableTarget = target;
663
+ if (source.role === "assistant") {
664
+ const shapingCounts = options?.shapingCounts;
665
+ if (!options?.stripReasoningContent && typeof source.reasoning_content === "string") {
666
+ mutableTarget.reasoning_content = source.reasoning_content;
667
+ }
668
+ if (Array.isArray(source.tool_calls)) {
669
+ if (shapingCounts && source.tool_calls.length > 0) {
670
+ shapingCounts.assistantToolTurns += 1;
671
+ const hadUsableReasoning = typeof source.reasoning_content === "string" && source.reasoning_content.length > 0;
672
+ if (options?.stripReasoningContent) {
673
+ if (hadUsableReasoning) shapingCounts.reasoningStrippedTurns += 1;
674
+ else shapingCounts.missingReasoningTurns += 1;
675
+ } else if (!hadUsableReasoning) {
676
+ shapingCounts.missingReasoningTurns += 1;
677
+ }
678
+ }
679
+ const isExplicitTarget = Boolean(options?.targetProvider || options?.targetModel);
680
+ const allowSignature = options?.allowThoughtSignature ?? (isExplicitTarget ? isGeminiCompatibleTarget(options?.targetProvider, options?.targetModel) : true);
681
+ mutableTarget.tool_calls = source.tool_calls.map((call) => {
682
+ if (!call || typeof call !== "object") return call;
683
+ const cleaned = {
684
+ id: call.id,
685
+ type: call.type ?? "function",
686
+ function: call.function
687
+ };
688
+ if (allowSignature) {
689
+ if (call.extra_content !== void 0) cleaned.extra_content = call.extra_content;
690
+ if (call.thought_signature !== void 0) cleaned.thought_signature = call.thought_signature;
691
+ }
692
+ return cleaned;
693
+ });
694
+ }
695
+ const hasReplayableToolCalls = Array.isArray(mutableTarget.tool_calls) && mutableTarget.tool_calls.length > 0;
696
+ const replayPlaceholder = options?.replayReasoningPlaceholder;
697
+ if (typeof replayPlaceholder === "string" && replayPlaceholder.length > 0 && // strip 优先:拒 string reasoning_content 的 provider 也会拒这个占位。
698
+ !options?.stripReasoningContent && (hasReplayableToolCalls || hasDowngradedToolTurnOrigin(source)) && !// 真实 reasoning_content 优先,永不被占位覆盖。
699
+ (typeof mutableTarget.reasoning_content === "string" && mutableTarget.reasoning_content.length > 0)) {
700
+ mutableTarget.reasoning_content = replayPlaceholder;
701
+ if (shapingCounts) shapingCounts.placeholderInjectedTurns += 1;
702
+ }
703
+ }
704
+ if (source.role === "tool") {
705
+ const toolCallId = typeof source.tool_call_id === "string" ? source.tool_call_id.trim() : typeof source.toolCallId === "string" ? source.toolCallId.trim() : "";
706
+ if (toolCallId) mutableTarget.tool_call_id = toolCallId;
707
+ }
708
+ return target;
709
+ }
710
+ function toOpenAiCompatibleMessages(messages, options) {
711
+ return messages.map(
712
+ (message) => preserveAgentStateFields(message, {
713
+ role: message.role,
714
+ content: message.content ?? ""
715
+ }, options)
716
+ );
717
+ }
718
+ function shouldStripReasoningContentForOutbound(provider, model) {
719
+ const p = provider?.trim().toLowerCase();
720
+ const m = model?.trim().toLowerCase();
721
+ if (!p || !m) return false;
722
+ if (p === "deepseek" || p === "nolo") {
723
+ return m === "deepseek-flash" || m === "deepseek-v4-flash" || m === "deepseek-v4-flash-vision-exp" || m === "deepseek-v4-pro";
724
+ }
725
+ return false;
726
+ }
727
+ function shouldReplayReasoningContentForOutbound(provider, model) {
728
+ const p = provider?.trim().toLowerCase();
729
+ const m = model?.trim().toLowerCase();
730
+ if (!p || !m) return false;
731
+ return (p === "opencode-go" || p === "opencode") && m.includes("deepseek");
732
+ }
733
+
734
+ // packages/integrations/openai/responsesHelpers.ts
735
+ var RESPONSES_TOP_LEVEL_SCHEMA_KEYS = ["anyOf", "oneOf", "allOf", "enum", "not"];
736
+ var sanitizeResponsesParameters = (parameters) => {
737
+ if (!isRecord(parameters)) {
738
+ return parameters;
739
+ }
740
+ const next = { ...parameters };
741
+ for (const key of RESPONSES_TOP_LEVEL_SCHEMA_KEYS) {
742
+ delete next[key];
743
+ }
744
+ return next;
745
+ };
746
+ var appendTextPart = (parts, text, role) => {
747
+ if (!text) return;
748
+ const last = parts.at(-1);
749
+ const textType = role === "assistant" ? "output_text" : "input_text";
750
+ if (last?.type === textType) {
751
+ last.text += text;
752
+ return;
753
+ }
754
+ parts.push({ type: textType, text });
755
+ };
756
+ var normalizeMessageParts = (content, role) => {
757
+ if (typeof content === "string") {
758
+ if (!content) return [];
759
+ return [
760
+ {
761
+ type: role === "assistant" ? "output_text" : "input_text",
762
+ text: content
763
+ }
764
+ ];
765
+ }
766
+ const parts = [];
767
+ for (const part of content ?? []) {
768
+ const typedPart = part;
769
+ if (typedPart?.type === "text" && typeof typedPart.text === "string") {
770
+ appendTextPart(parts, typedPart.text, role);
771
+ continue;
772
+ }
773
+ if (typedPart?.type === "image_url" && typeof typedPart.image_url?.url === "string" && typedPart.image_url.url) {
774
+ if (role === "assistant") continue;
775
+ parts.push({
776
+ type: "input_image",
777
+ image_url: typedPart.image_url.url,
778
+ detail: typedPart.image_url.detail
779
+ });
780
+ }
781
+ }
782
+ return parts;
783
+ };
784
+ var normalizeToolOutput = (content) => {
785
+ if (typeof content === "string") return content;
786
+ return JSON.stringify(content ?? "");
787
+ };
788
+ var toResponsesTools = (tools) => {
789
+ if (!Array.isArray(tools) || tools.length === 0) return void 0;
790
+ const normalized = tools.map((tool) => {
791
+ const fn = tool?.function;
792
+ const name = fn?.name ?? tool?.name;
793
+ if (!name) return null;
794
+ const parameters = fn?.parameters ?? tool?.parameters;
795
+ return {
796
+ type: "function",
797
+ name,
798
+ ...typeof (fn?.description ?? tool?.description) === "string" ? { description: fn?.description ?? tool?.description } : {},
799
+ parameters: sanitizeResponsesParameters(parameters),
800
+ ...fn?.strict !== void 0 || tool?.strict !== void 0 ? { strict: fn?.strict ?? tool?.strict } : {}
801
+ };
802
+ }).filter(Boolean);
803
+ return normalized.length > 0 ? normalized : void 0;
804
+ };
805
+ var convertMessagesToResponsesInput = (messages, options) => {
806
+ const input = [];
807
+ for (const message of messages) {
808
+ if (!message?.role) continue;
809
+ if (message.role === "tool") {
810
+ if (!message.tool_call_id) continue;
811
+ input.push({
812
+ type: "function_call_output",
813
+ call_id: message.tool_call_id,
814
+ output: normalizeToolOutput(message.content)
815
+ });
816
+ continue;
817
+ }
818
+ const role = message.role;
819
+ if (role === "assistant" && !options?.stripReasoningContent && typeof message.reasoning_content === "string" && message.reasoning_content) {
820
+ input.push({
821
+ type: "reasoning",
822
+ content: [
823
+ { type: "reasoning_text", text: message.reasoning_content }
824
+ ]
825
+ });
826
+ }
827
+ const contentParts = normalizeMessageParts(message.content, role);
828
+ if (contentParts.length > 0) {
829
+ input.push({
830
+ type: "message",
831
+ role,
832
+ content: contentParts
833
+ });
834
+ }
835
+ if (role === "assistant" && Array.isArray(message.content)) {
836
+ const replayImages = message.content.map((part) => part).filter(
837
+ (part) => part?.type === "image_url" && typeof part.image_url?.url === "string" && Boolean(part.image_url.url)
838
+ ).map((part) => ({
839
+ type: "input_image",
840
+ image_url: part.image_url.url,
841
+ detail: part.image_url.detail
842
+ }));
843
+ if (replayImages.length > 0) {
844
+ input.push({
845
+ type: "message",
846
+ role: "user",
847
+ content: replayImages
848
+ });
849
+ }
850
+ }
851
+ if (role === "assistant" && Array.isArray(message.tool_calls)) {
852
+ for (const toolCall of message.tool_calls) {
853
+ if (!toolCall?.id || !toolCall.function?.name) continue;
854
+ input.push({
855
+ type: "function_call",
856
+ call_id: toolCall.id,
857
+ name: toolCall.function.name,
858
+ arguments: typeof toolCall.function.arguments === "string" ? toolCall.function.arguments : JSON.stringify(toolCall.function.arguments ?? {})
859
+ });
860
+ }
861
+ }
862
+ }
863
+ return input;
864
+ };
865
+ var extractTextFromResponseOutput = (response) => {
866
+ const parts = [];
867
+ for (const item of response?.output ?? []) {
868
+ if (item?.type !== "message") continue;
869
+ for (const content of item.content ?? []) {
870
+ if (content?.type === "output_text" && typeof content.text === "string") {
871
+ parts.push(content.text);
872
+ }
873
+ }
874
+ }
875
+ return parts.join("");
876
+ };
877
+ var extractReasoningFromResponseOutput = (response) => {
878
+ const parts = [];
879
+ for (const item of response?.output ?? []) {
880
+ if (item?.type !== "reasoning") continue;
881
+ if (typeof item.content === "string") {
882
+ parts.push(item.content);
883
+ continue;
884
+ }
885
+ for (const content of item.content ?? []) {
886
+ if (typeof content === "string") parts.push(content);
887
+ else if (typeof content?.text === "string") parts.push(content.text);
888
+ }
889
+ }
890
+ return parts.join("");
891
+ };
892
+ var toDataUrl = (base64Data, mimeType) => {
893
+ const normalizedMimeType = asOptionalTrimmedString(mimeType) ?? "image/png";
894
+ return `data:${normalizedMimeType};base64,${base64Data}`;
895
+ };
896
+ var extractImagePartsFromResponseOutput = (response) => {
897
+ const images = [];
898
+ for (const item of response?.output ?? []) {
899
+ if (item?.type === "image_generation_call") {
900
+ const result = asOptionalTrimmedString(item.result);
901
+ if (result) {
902
+ const outputFormat = asOptionalTrimmedString(item.output_format);
903
+ images.push({
904
+ type: "image_url",
905
+ image_url: {
906
+ url: toDataUrl(
907
+ result,
908
+ outputFormat ? `image/${outputFormat}` : void 0
909
+ )
910
+ }
911
+ });
912
+ }
913
+ continue;
914
+ }
915
+ if (item?.type !== "message") continue;
916
+ for (const content of item.content ?? []) {
917
+ const result = asOptionalTrimmedString(content?.result);
918
+ if (content?.type === "output_image" && result) {
919
+ images.push({
920
+ type: "image_url",
921
+ image_url: {
922
+ url: toDataUrl(
923
+ result,
924
+ content.mime_type ?? content.mimeType ?? null
925
+ )
926
+ }
927
+ });
928
+ }
929
+ }
930
+ }
931
+ return images;
932
+ };
933
+ var extractToolCallsFromResponseOutput = (response) => {
934
+ const calls = [];
935
+ for (const item of response?.output ?? []) {
936
+ if (item?.type !== "function_call") continue;
937
+ if (!item.call_id || !item.name) continue;
938
+ calls.push({
939
+ id: item.call_id,
940
+ type: "function",
941
+ function: {
942
+ name: item.name,
943
+ arguments: typeof item.arguments === "string" ? item.arguments : JSON.stringify(item.arguments ?? {})
944
+ }
945
+ });
946
+ }
947
+ return calls;
948
+ };
949
+
950
+ // packages/agent-runtime/promptCacheKey.ts
951
+ function collectStablePromptPrefix(messages, fallbackPrompt) {
952
+ const systemTexts = [];
953
+ if (fallbackPrompt?.trim()) systemTexts.push(fallbackPrompt.trim());
954
+ for (const raw of messages) {
955
+ if (!raw || typeof raw !== "object") continue;
956
+ const message = raw;
957
+ const role = String(message.role ?? "");
958
+ if (role !== "system" && role !== "developer") continue;
959
+ if (typeof message.content === "string") {
960
+ const boundary = Number(message.stable_prefix_chars);
961
+ const text = Number.isFinite(boundary) && boundary > 0 ? message.content.slice(0, boundary) : message.content;
962
+ if (text.trim()) systemTexts.push(text.trim());
963
+ }
964
+ }
965
+ return systemTexts.join("\n\n");
966
+ }
967
+ function stablePromptCacheKey(parts, namespace) {
968
+ const value = JSON.stringify(parts);
969
+ let hash = 2166136261;
970
+ for (let index = 0; index < value.length; index += 1) {
971
+ hash ^= value.charCodeAt(index);
972
+ hash = Math.imul(hash, 16777619) >>> 0;
973
+ }
974
+ return `${namespace}-${hash.toString(16).padStart(8, "0")}`;
975
+ }
976
+
977
+ // packages/core/chat/imageParts.ts
978
+ function isImageUrlPart(part) {
979
+ return isRecord(part) && part.type === "image_url";
980
+ }
981
+ function hasImageParts(messages) {
982
+ return messages.some(
983
+ (message) => Array.isArray(message.content) && message.content.some(isImageUrlPart)
984
+ );
985
+ }
986
+
987
+ export {
988
+ sanitizeForOutbound,
989
+ hasParsableObjectArguments,
990
+ repairTruncatedToolArguments,
991
+ downgradeUnparsableToolCalls,
992
+ isOllamaEndpoint,
993
+ getUsageRequestOptions,
994
+ isImageUrlPart,
995
+ hasImageParts,
996
+ preserveAgentStateFields,
997
+ toOpenAiCompatibleMessages,
998
+ shouldStripReasoningContentForOutbound,
999
+ shouldReplayReasoningContentForOutbound,
1000
+ toResponsesTools,
1001
+ convertMessagesToResponsesInput,
1002
+ extractTextFromResponseOutput,
1003
+ extractReasoningFromResponseOutput,
1004
+ extractImagePartsFromResponseOutput,
1005
+ extractToolCallsFromResponseOutput,
1006
+ collectStablePromptPrefix,
1007
+ stablePromptCacheKey
1008
+ };