nolo-cli 0.105.0 → 0.106.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 (115) hide show
  1. package/{_executeModel-JXG5TLPE.js → _executeModel-EP6HAX3W.js} +38 -37
  2. package/{addContentAction-J3DLDV64.js → addContentAction-NZZNAVCB.js} +4 -4
  3. package/{addDialogAgentAction-PHIXJCF2.js → addDialogAgentAction-5HVGEIXI.js} +4 -4
  4. package/{agentDeleteCommand-2AWJGHXG.js → agentDeleteCommand-M25A6UGB.js} +45 -45
  5. package/{agentEmailCommands-VV5OSILE.js → agentEmailCommands-RUL4NL64.js} +46 -46
  6. package/{agentListCommands-OQMRBDWP.js → agentListCommands-KSPFKHFO.js} +23 -24
  7. package/{agentMachineCommands-3VLLR6RL.js → agentMachineCommands-IHBB6PHD.js} +20 -21
  8. package/{agentProviderCommands-XPJYZSCE.js → agentProviderCommands-ND4S2Q6Q.js} +1 -1
  9. package/{agentRecordCommands-GPIARVOW.js → agentRecordCommands-7OKIBN6H.js} +45 -45
  10. package/{agentRunCommand-LRJTZ7IM.js → agentRunCommand-GBKJTQQU.js} +45 -45
  11. package/{agentRuntimeLocal-PV6AZOEU.js → agentRuntimeLocal-E5HXZNXZ.js} +18 -19
  12. package/{agentSlice-6R3JKS6I.js → agentSlice-7T3ZLYET.js} +4 -4
  13. package/{appDeleteCommands-WEX73P5R.js → appDeleteCommands-TTJUYTQN.js} +21 -22
  14. package/{appDeployCommands-7BAXWA4M.js → appDeployCommands-65WYK2TQ.js} +21 -22
  15. package/{appDeployStatusCommands-EJ6A2U4X.js → appDeployStatusCommands-U4XESYYG.js} +21 -22
  16. package/{appGetCommands-SB355OEX.js → appGetCommands-VNHZZC4D.js} +21 -22
  17. package/{appListCommands-TSZDPIKJ.js → appListCommands-O667ZEU6.js} +21 -22
  18. package/{authCommand-5PB3YRVV.js → authCommand-SUHHTVHA.js} +8 -8
  19. package/{builtinSkillRegistry-SBBWTANC.js → builtinSkillRegistry-PUGT65WS.js} +5 -5
  20. package/{chunk-Z5NGE5DH.js → chunk-2NGKYC3L.js} +3 -3
  21. package/{chunk-S2NSK7AZ.js → chunk-3SXZ6SUC.js} +4 -4
  22. package/{chunk-NSBID7PR.js → chunk-3VKDWQMJ.js} +2 -2
  23. package/{chunk-QKTESDWK.js → chunk-4VDS344D.js} +3 -3
  24. package/{chunk-7KVZ5LDQ.js → chunk-5F7UKMLN.js} +8 -4
  25. package/{chunk-BB7LVBTS.js → chunk-6AIURTE7.js} +3 -3
  26. package/{chunk-HP57OUJO.js → chunk-7I25CBT5.js} +31 -5
  27. package/{chunk-NSAFG343.js → chunk-AM4G3LDJ.js} +59 -47
  28. package/{chunk-NTR4SD3P.js → chunk-AZB6HR4I.js} +13 -48
  29. package/{chunk-AFH5QC6R.js → chunk-BIH7KCDJ.js} +3 -3
  30. package/{chunk-UA324D4O.js → chunk-BPLIXNC6.js} +1 -1
  31. package/{chunk-YK5MHOWM.js → chunk-CEQ75WPL.js} +1 -1
  32. package/{chunk-K6U4NKFJ.js → chunk-DBKRC5O2.js} +1 -1
  33. package/{chunk-UWXDA7L5.js → chunk-DJ3JABG5.js} +22 -37
  34. package/{chunk-HYXABXCZ.js → chunk-DSXRVBTA.js} +98 -21
  35. package/{chunk-3Q7NEHAR.js → chunk-EBS4FKW4.js} +1 -1
  36. package/{chunk-ZBHR642M.js → chunk-EHGIEGLI.js} +161 -43
  37. package/{chunk-YVU4XVJD.js → chunk-FJKZSR5P.js} +1 -1
  38. package/{chunk-54VPQTOA.js → chunk-GMP3NBAA.js} +5 -7
  39. package/{chunk-3BXNTXYI.js → chunk-GU7DC2TD.js} +2 -1
  40. package/{chunk-FGSJ3YMD.js → chunk-HNA5KV37.js} +5 -5
  41. package/{chunk-CYSYR67N.js → chunk-I5YMDACN.js} +1 -1
  42. package/{chunk-WJ3B6FX6.js → chunk-IXH3HKY2.js} +0 -8
  43. package/{chunk-Y3PMXGLH.js → chunk-IYIXAIEB.js} +197 -92
  44. package/{chunk-RWX7AY7J.js → chunk-JWNBEIME.js} +1 -1
  45. package/{chunk-VVJ2ENLY.js → chunk-LGWABBTZ.js} +4 -4
  46. package/{chunk-QYUBY3OZ.js → chunk-LOPP5VT6.js} +1 -1
  47. package/{chunk-GSKPJIHY.js → chunk-LUBFABMJ.js} +2 -6
  48. package/{chunk-BNGW5ASC.js → chunk-LYLO5U3H.js} +15 -2
  49. package/{chunk-L5WOICCV.js → chunk-MJ3CRU77.js} +22 -6
  50. package/{chunk-AWVP7PPG.js → chunk-NTNKA5VL.js} +1 -1
  51. package/{chunk-EP7BWZ4B.js → chunk-OAXBDMT7.js} +1 -1
  52. package/{chunk-4DPP773Q.js → chunk-ODTBO4W6.js} +9 -6
  53. package/{chunk-B7APRSPS.js → chunk-OQ5IVGCV.js} +3 -3
  54. package/{chunk-EKPKW6RM.js → chunk-OYTWDOQV.js} +3 -3
  55. package/{chunk-P5GCTVGV.js → chunk-OZ2IIIRP.js} +2 -2
  56. package/{chunk-D2GQE6AF.js → chunk-PFLF4R4E.js} +1 -1
  57. package/{chunk-RILRSUGC.js → chunk-QDH32WF5.js} +1 -1
  58. package/{chunk-VCAQFMVN.js → chunk-QVAWUJAJ.js} +1 -1
  59. package/{chunk-27ONFIEY.js → chunk-SJ7CUF65.js} +2 -2
  60. package/{chunk-CNA27EMD.js → chunk-SYEBIZOF.js} +1 -1
  61. package/{chunk-ZSUDOTPL.js → chunk-TLKXNTQJ.js} +3 -3
  62. package/{chunk-A4SQRTZ6.js → chunk-TLYSGGPG.js} +1 -1
  63. package/chunk-UM7TA3K4.js +1008 -0
  64. package/{chunk-BZ7NPA6G.js → chunk-VBG7GWWR.js} +218 -6
  65. package/{chunk-DZ7R5V3Y.js → chunk-VBQGO5NX.js} +1 -1
  66. package/{chunk-44CU7CKA.js → chunk-VYKXIHRP.js} +181 -34
  67. package/chunk-VZLO4XJD.js +17 -0
  68. package/{chunk-IEJ5YDA4.js → chunk-WMWYWYK2.js} +2 -2
  69. package/{chunk-LWXE6IFU.js → chunk-XDQ7PHU3.js} +31 -196
  70. package/{chunk-AFSY3ZMB.js → chunk-XGOHDYM2.js} +1 -1
  71. package/{chunk-2WJ57RJA.js → chunk-XLWMNFBZ.js} +1 -1
  72. package/{chunk-3F424ASC.js → chunk-YFU5EELM.js} +1 -1
  73. package/{chunk-QMXJ5KDJ.js → chunk-YQFLBS6A.js} +13 -13
  74. package/{chunk-CFHWVEUJ.js → chunk-ZVGXD7UJ.js} +2 -2
  75. package/{chunk-4WMMIL66.js → chunk-ZYM73IHG.js} +3 -2
  76. package/{commandRegistry-QU62WJQX.js → commandRegistry-6QIAUQDS.js} +49 -49
  77. package/{contentThunks-VGV3JJVB.js → contentThunks-5DDMUQ7B.js} +17 -16
  78. package/{createAgentAutomationAction-ZNVLI4WV.js → createAgentAutomationAction-NQ6AZM42.js} +17 -16
  79. package/{createDialogAction-TTUA46DT.js → createDialogAction-QZ6X4A7O.js} +20 -19
  80. package/{createPageAction-KUFSC5XW.js → createPageAction-NCGEJBVK.js} +17 -16
  81. package/{dbSlice-MYEETO73.js → dbSlice-RCZ7NRAF.js} +3 -3
  82. package/{dialogCommands-DRDPEOTL.js → dialogCommands-OGQLEF63.js} +21 -22
  83. package/{dialogSlice-V2SVSTIV.js → dialogSlice-GIKNUHNW.js} +30 -17
  84. package/{docCreateCommands-M26CFDDQ.js → docCreateCommands-RW6LNYT6.js} +20 -21
  85. package/{docDeleteCommands-LRZHCKVX.js → docDeleteCommands-Z742TRNY.js} +21 -22
  86. package/{docReadCommands-6QJSISHK.js → docReadCommands-5DIGA42Y.js} +20 -21
  87. package/{docStore-4RWAFNDM.js → docStore-6GUOZH52.js} +4 -4
  88. package/{docUpdateCommands-W4KU4U5T.js → docUpdateCommands-ZFZ2QEVK.js} +20 -21
  89. package/{getPricing-NMMFT3YI.js → getPricing-QVSNUFZ6.js} +3 -3
  90. package/{handleSendMessageAction-VEWLGB5Z.js → handleSendMessageAction-B2VXOLMM.js} +16 -15
  91. package/index.js +3 -3
  92. package/{machineCommands-AEHHCJEW.js → machineCommands-AI3N7JHQ.js} +44 -44
  93. package/{machineWsRunDispatch-MY2KHS36.js → machineWsRunDispatch-RPF2D6VV.js} +44 -44
  94. package/{memberThunks-EE6TI3TV.js → memberThunks-YICJI4IS.js} +4 -4
  95. package/{models-ZPU5EDF4.js → models-FTNFVO3D.js} +2 -2
  96. package/package.json +1 -1
  97. package/{providerPresetApply-TEBH7FDX.js → providerPresetApply-OJJXQ7NM.js} +6 -6
  98. package/{providerRegistry-CBJLNCET.js → providerRegistry-DXFBDCGQ.js} +6 -6
  99. package/{read-PJIT2YEJ.js → read-XMBM52Y4.js} +2 -2
  100. package/{readDocTool-DRSXHGNL.js → readDocTool-LAQHKCVT.js} +1 -1
  101. package/{readlineWorkspace-7Q6MITLV.js → readlineWorkspace-EPUCVZ73.js} +48 -48
  102. package/{removeDialogAgentAction-IN4WUKJJ.js → removeDialogAgentAction-HDUI2MU3.js} +5 -5
  103. package/{runAgentClientLoop-H2JALUVD.js → runAgentClientLoop-OXQMDGAN.js} +36 -35
  104. package/{setDialogExtraReferencesAction-VDRF7LPK.js → setDialogExtraReferencesAction-ADBVOP4O.js} +5 -5
  105. package/{setPrimaryDialogAgentAction-RO6LIWJ4.js → setPrimaryDialogAgentAction-PXVXQJ62.js} +5 -5
  106. package/{settingThunks-3OPOLOIA.js → settingThunks-G2MJRKUE.js} +6 -6
  107. package/{spaceCommands-UBLL5EF2.js → spaceCommands-Z662QYY6.js} +20 -21
  108. package/{streamAgentChatTurn-FFJWW3FD.js → streamAgentChatTurn-YJYEJHP7.js} +40 -46
  109. package/{switchDialogAgentAction-MVF2JNE7.js → switchDialogAgentAction-Z3RZACGF.js} +4 -4
  110. package/{toolApiClient-EJT6TMFG.js → toolApiClient-AD7CXTA4.js} +3 -2
  111. package/{tools-AZRYLYNK.js → tools-GHI3WBEI.js} +32 -31
  112. package/{tuiSummaryLlmCaller-7S5HJ3MT.js → tuiSummaryLlmCaller-WTC6GCQC.js} +11 -12
  113. package/{updateDialogTitleAction-5WXTRUJM.js → updateDialogTitleAction-GJCNWTPY.js} +17 -16
  114. package/chunk-M7VLQGQP.js +0 -405
  115. package/chunk-NKWIS6G2.js +0 -442
package/chunk-NKWIS6G2.js DELETED
@@ -1,442 +0,0 @@
1
- // packages/agent-runtime/declaredToolNames.ts
2
- function extractDeclaredToolNames(tools) {
3
- if (!Array.isArray(tools)) return void 0;
4
- const names = /* @__PURE__ */ new Set();
5
- for (const t of tools) {
6
- const fn = t?.function;
7
- if (fn && typeof fn.name === "string" && fn.name) names.add(fn.name);
8
- }
9
- return names;
10
- }
11
-
12
- // packages/agent-runtime/outboundHistorySanitize.ts
13
- function sanitizeForOutbound(messages, tools) {
14
- return sanitizeOutboundHistory(messages, {
15
- declaredToolNames: extractDeclaredToolNames(tools)
16
- });
17
- }
18
- function stableToolCallId(assistantIndex, callIndex) {
19
- return `call_sanitize_${assistantIndex}_${callIndex}`;
20
- }
21
- function isString(v) {
22
- return typeof v === "string";
23
- }
24
- function isNonEmptyString(v) {
25
- return typeof v === "string" && v.length > 0;
26
- }
27
- function joinLines(...parts) {
28
- return parts.filter(isNonEmptyString).join("\n");
29
- }
30
- function jsonStringifyArguments(args) {
31
- if (typeof args === "string") return args;
32
- try {
33
- return JSON.stringify(args ?? "");
34
- } catch {
35
- return "";
36
- }
37
- }
38
- function renderToolCallAsText(call) {
39
- const c = call && typeof call === "object" ? call : {};
40
- const name = isString(c.function?.name) && c.function.name.length > 0 ? c.function.name : "unknown";
41
- const rawArgs = c.function?.arguments;
42
- const args = jsonStringifyArguments(rawArgs);
43
- return `[tool_call: ${name}(${args})]`;
44
- }
45
- function renderToolResultAsText(message) {
46
- const name = isNonEmptyString(message.toolName) ? message.toolName : "tool";
47
- const body = typeof message.content === "string" ? message.content : "";
48
- return `[tool_result: ${name}: ${body}]`;
49
- }
50
- function normalizeToolCall(call, assistantIndex, callIndex) {
51
- if (!call || typeof call !== "object") return null;
52
- const c = call;
53
- const fn = c.function;
54
- if (!fn || typeof fn !== "object" || !isString(fn.name) || fn.name.length === 0) return null;
55
- const id = isNonEmptyString(c.id) ? c.id : stableToolCallId(assistantIndex, callIndex);
56
- return {
57
- id,
58
- type: isString(c.type) && c.type ? c.type : "function",
59
- function: { name: fn.name, arguments: jsonStringifyArguments(fn.arguments) },
60
- ...typeof c.thought_signature === "string" ? { thought_signature: c.thought_signature } : {}
61
- };
62
- }
63
- function classifyAssistantCalls(toolCalls, assistantIndex) {
64
- const callIds = [];
65
- const idCounts = /* @__PURE__ */ new Map();
66
- const unparsableIndices = /* @__PURE__ */ new Set();
67
- const unparsableIds = /* @__PURE__ */ new Set();
68
- toolCalls.forEach((rawCall, callIndex) => {
69
- const c = rawCall && typeof rawCall === "object" ? rawCall : {};
70
- const id = isNonEmptyString(c.id) ? c.id : stableToolCallId(assistantIndex, callIndex);
71
- callIds.push(id);
72
- idCounts.set(id, (idCounts.get(id) ?? 0) + 1);
73
- if (!hasParsableObjectArguments(c.function?.arguments)) {
74
- unparsableIndices.add(callIndex);
75
- unparsableIds.add(id);
76
- }
77
- });
78
- const duplicateIds = /* @__PURE__ */ new Set();
79
- for (const [id, count] of idCounts) {
80
- if (count > 1) duplicateIds.add(id);
81
- }
82
- return { callIds, duplicateIds, unparsableIndices, unparsableIds };
83
- }
84
- function sanitizeOutboundHistory(messages, options) {
85
- if (!Array.isArray(messages) || messages.length === 0) return messages;
86
- const declared = options?.declaredToolNames;
87
- const keptCallIndicesPerAssistant = /* @__PURE__ */ new Map();
88
- const keptToolIndices = /* @__PURE__ */ new Set();
89
- let i = 0;
90
- while (i < messages.length) {
91
- const m = messages[i];
92
- if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
93
- const asstIdx = i;
94
- const { callIds, duplicateIds, unparsableIndices } = classifyAssistantCalls(m.tool_calls, asstIdx);
95
- const candidateCallMap = /* @__PURE__ */ new Map();
96
- m.tool_calls.forEach((call, callIndex) => {
97
- const id = callIds[callIndex];
98
- if (duplicateIds.has(id)) return;
99
- if (unparsableIndices.has(callIndex)) return;
100
- const name = call?.function?.name;
101
- if (!isString(name) || name.length === 0) return;
102
- const declaredAllows = !declared || declared.has(name);
103
- if (!declaredAllows) return;
104
- candidateCallMap.set(id, callIndex);
105
- });
106
- let j = i + 1;
107
- const matchedCallIndices = /* @__PURE__ */ new Set();
108
- const matchedToolIds = /* @__PURE__ */ new Set();
109
- while (j < messages.length && messages[j].role === "tool") {
110
- const toolMsg = messages[j];
111
- const toolCallId = isNonEmptyString(toolMsg.tool_call_id) ? toolMsg.tool_call_id : "";
112
- if (toolCallId && candidateCallMap.has(toolCallId) && !matchedToolIds.has(toolCallId)) {
113
- matchedToolIds.add(toolCallId);
114
- matchedCallIndices.add(candidateCallMap.get(toolCallId));
115
- keptToolIndices.add(j);
116
- }
117
- j++;
118
- }
119
- keptCallIndicesPerAssistant.set(asstIdx, matchedCallIndices);
120
- i = j;
121
- } else {
122
- i++;
123
- }
124
- }
125
- const out = [];
126
- let k = 0;
127
- while (k < messages.length) {
128
- const m = messages[k];
129
- if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
130
- const asstIdx = k;
131
- const keptIndices = keptCallIndicesPerAssistant.get(asstIdx) ?? /* @__PURE__ */ new Set();
132
- const keptToolCalls = [];
133
- const downgradedCallLines = [];
134
- m.tool_calls.forEach((call, callIndex) => {
135
- const name = call?.function?.name;
136
- const declaredAllows = !declared || isString(name) && declared.has(name);
137
- const keep = keptIndices.has(callIndex) && declaredAllows && hasParsableObjectArguments(call?.function?.arguments);
138
- if (keep) {
139
- const normalized = normalizeToolCall(call, asstIdx, callIndex);
140
- if (normalized) {
141
- keptToolCalls.push(normalized);
142
- } else {
143
- downgradedCallLines.push(renderToolCallAsText(call));
144
- }
145
- } else {
146
- downgradedCallLines.push(renderToolCallAsText(call));
147
- }
148
- });
149
- if (keptToolCalls.length === 0) {
150
- const downgradedText = joinLines(...downgradedCallLines);
151
- const contentWithDowngrade = downgradedText.length > 0 ? combineContentWithText(m.content, downgradedText) : m.content;
152
- const sanitizedAssistant2 = {
153
- ...m,
154
- content: contentWithDowngrade
155
- };
156
- delete sanitizedAssistant2.tool_calls;
157
- out.push(sanitizedAssistant2);
158
- let nextIdx2 = k + 1;
159
- while (nextIdx2 < messages.length && messages[nextIdx2].role === "tool") {
160
- out.push({
161
- role: "assistant",
162
- content: renderToolResultAsText(messages[nextIdx2])
163
- });
164
- nextIdx2++;
165
- }
166
- k = nextIdx2;
167
- continue;
168
- }
169
- const sanitizedAssistant = {
170
- ...m,
171
- tool_calls: keptToolCalls
172
- };
173
- out.push(sanitizedAssistant);
174
- let nextIdx = k + 1;
175
- const deferredResultLines = [];
176
- while (nextIdx < messages.length && messages[nextIdx].role === "tool") {
177
- if (keptToolIndices.has(nextIdx)) {
178
- const toolMsg = messages[nextIdx];
179
- out.push({
180
- ...toolMsg,
181
- content: toolMsg.content ?? "",
182
- tool_call_id: toolMsg.tool_call_id
183
- });
184
- } else {
185
- deferredResultLines.push(renderToolResultAsText(messages[nextIdx]));
186
- }
187
- nextIdx++;
188
- }
189
- const deferredLines = [...downgradedCallLines, ...deferredResultLines];
190
- if (deferredLines.length > 0) {
191
- out.push({
192
- role: "assistant",
193
- content: joinLines(...deferredLines)
194
- });
195
- }
196
- k = nextIdx;
197
- continue;
198
- }
199
- if (m.role === "tool") {
200
- out.push({
201
- role: "assistant",
202
- content: renderToolResultAsText(m)
203
- });
204
- k++;
205
- continue;
206
- }
207
- out.push({ ...m });
208
- k++;
209
- }
210
- return out;
211
- }
212
- function combineContentWithText(base, extra) {
213
- if (typeof base === "string") {
214
- return base ? `${base}
215
- ${extra}` : extra;
216
- }
217
- if (Array.isArray(base)) {
218
- return [...base, { type: "text", text: extra }];
219
- }
220
- return extra;
221
- }
222
- function hasParsableObjectArguments(raw) {
223
- if (raw === void 0) return true;
224
- if (raw === null || typeof raw === "number" || typeof raw === "boolean") {
225
- return false;
226
- }
227
- if (typeof raw !== "string") return true;
228
- if (raw.trim() === "") return true;
229
- try {
230
- const parsed = JSON.parse(raw);
231
- return parsed !== null && typeof parsed === "object";
232
- } catch {
233
- return false;
234
- }
235
- }
236
- var STRICT_JSON_STRING_TOKEN = /^"(?:[^"\\\u0000-\u001F]|\\["\\/bfnrt]|\\u[0-9A-Fa-f]{4})*"$/;
237
- function isStrictJsonStringToken(value) {
238
- if (!STRICT_JSON_STRING_TOKEN.test(value)) return false;
239
- try {
240
- return typeof JSON.parse(value) === "string";
241
- } catch {
242
- return false;
243
- }
244
- }
245
- function closersOf(openStack) {
246
- return openStack.slice().reverse().map((ch) => ch === "{" ? "}" : "]").join("");
247
- }
248
- function scanJsonForTailRepair(input) {
249
- const stack = [];
250
- let inString = false;
251
- let escaped = false;
252
- let lastCommaOutsideString = null;
253
- for (let i = 0; i < input.length; i += 1) {
254
- const ch = input[i];
255
- if (inString) {
256
- if (escaped) escaped = false;
257
- else if (ch === "\\") escaped = true;
258
- else if (ch === '"') inString = false;
259
- continue;
260
- }
261
- if (ch === '"') {
262
- inString = true;
263
- continue;
264
- }
265
- if (ch === "{" || ch === "[") {
266
- stack.push(ch);
267
- continue;
268
- }
269
- if (ch === "}" || ch === "]") {
270
- const open = stack.pop();
271
- if (open !== (ch === "}" ? "{" : "[")) return null;
272
- continue;
273
- }
274
- if (ch === ",") {
275
- lastCommaOutsideString = { index: i, closers: closersOf(stack) };
276
- continue;
277
- }
278
- }
279
- return { inString, closers: closersOf(stack), lastCommaOutsideString };
280
- }
281
- function repairTruncatedToolArguments(raw) {
282
- if (typeof raw !== "string") return null;
283
- const withoutTrailingSpace = raw.replace(/\s+$/, "");
284
- const endsWithComma = withoutTrailingSpace.endsWith(",");
285
- const trimmed = endsWithComma ? withoutTrailingSpace.slice(0, -1).replace(/\s+$/, "") : withoutTrailingSpace;
286
- if (trimmed === "" || trimmed.endsWith(",")) return null;
287
- const scan = scanJsonForTailRepair(trimmed);
288
- if (!scan || scan.inString) return null;
289
- const lastChar = trimmed[trimmed.length - 1];
290
- const tailIsCompleteToken = endsWithComma || lastChar === '"' || lastChar === "}" || lastChar === "]";
291
- if (!tailIsCompleteToken) return null;
292
- const candidates = [trimmed + scan.closers];
293
- const lastComma = scan.lastCommaOutsideString;
294
- if (lastComma && lastComma.index > 0) {
295
- const tailAfterComma = trimmed.slice(lastComma.index + 1).trim();
296
- if (isStrictJsonStringToken(tailAfterComma)) {
297
- const head = trimmed.slice(0, lastComma.index);
298
- candidates.push(head + lastComma.closers);
299
- }
300
- }
301
- for (const candidate of candidates) {
302
- try {
303
- const parsed = JSON.parse(candidate);
304
- if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) && Object.keys(parsed).length > 0) {
305
- return candidate;
306
- }
307
- } catch {
308
- }
309
- }
310
- return null;
311
- }
312
- function downgradeUnparsableToolCalls(messages) {
313
- if (!Array.isArray(messages) || messages.length === 0) {
314
- return { messages, downgraded: 0 };
315
- }
316
- let hasAnyPoison = false;
317
- for (const m of messages) {
318
- if (m.role === "assistant" && Array.isArray(m.tool_calls)) {
319
- for (const call of m.tool_calls) {
320
- if (!hasParsableObjectArguments(call?.function?.arguments)) {
321
- hasAnyPoison = true;
322
- break;
323
- }
324
- }
325
- }
326
- if (hasAnyPoison) break;
327
- }
328
- if (!hasAnyPoison) return { messages, downgraded: 0 };
329
- const poisonedCallsPerAssistant = /* @__PURE__ */ new Map();
330
- const poisonedToolIndices = /* @__PURE__ */ new Set();
331
- let i = 0;
332
- while (i < messages.length) {
333
- const m = messages[i];
334
- if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
335
- const asstIdx = i;
336
- const { unparsableIds } = classifyAssistantCalls(m.tool_calls, asstIdx);
337
- let j = i + 1;
338
- while (j < messages.length && messages[j].role === "tool") {
339
- const toolMsg = messages[j];
340
- const toolCallId = isNonEmptyString(toolMsg.tool_call_id) ? toolMsg.tool_call_id : "";
341
- if (toolCallId && unparsableIds.has(toolCallId)) {
342
- poisonedToolIndices.add(j);
343
- }
344
- j++;
345
- }
346
- if (unparsableIds.size > 0) {
347
- poisonedCallsPerAssistant.set(asstIdx, unparsableIds);
348
- }
349
- i = j;
350
- } else {
351
- i++;
352
- }
353
- }
354
- let downgraded = 0;
355
- const out = [];
356
- let k = 0;
357
- while (k < messages.length) {
358
- const m = messages[k];
359
- if (m.role === "assistant" && Array.isArray(m.tool_calls) && m.tool_calls.length > 0) {
360
- const badIds = poisonedCallsPerAssistant.get(k);
361
- if (!badIds || badIds.size === 0) {
362
- out.push(m);
363
- k++;
364
- continue;
365
- }
366
- const kept = [];
367
- const lines = [];
368
- const { callIds } = classifyAssistantCalls(m.tool_calls, k);
369
- m.tool_calls.forEach((call, callIndex) => {
370
- const id = callIds[callIndex];
371
- if (badIds.has(id)) {
372
- lines.push(renderToolCallAsText(call));
373
- downgraded++;
374
- } else {
375
- kept.push(call);
376
- }
377
- });
378
- if (kept.length === 0) {
379
- const sanitized2 = {
380
- ...m,
381
- content: combineContentWithText(m.content, joinLines(...lines))
382
- };
383
- delete sanitized2.tool_calls;
384
- out.push(sanitized2);
385
- let nextIdx2 = k + 1;
386
- while (nextIdx2 < messages.length && messages[nextIdx2].role === "tool") {
387
- if (poisonedToolIndices.has(nextIdx2)) {
388
- out.push({ role: "assistant", content: renderToolResultAsText(messages[nextIdx2]) });
389
- } else {
390
- out.push(messages[nextIdx2]);
391
- }
392
- nextIdx2++;
393
- }
394
- k = nextIdx2;
395
- continue;
396
- }
397
- const sanitized = {
398
- ...m,
399
- content: lines.length > 0 ? combineContentWithText(m.content, joinLines(...lines)) : m.content,
400
- tool_calls: kept
401
- };
402
- out.push(sanitized);
403
- let nextIdx = k + 1;
404
- const deferredResultLines = [];
405
- while (nextIdx < messages.length && messages[nextIdx].role === "tool") {
406
- if (poisonedToolIndices.has(nextIdx)) {
407
- deferredResultLines.push(renderToolResultAsText(messages[nextIdx]));
408
- } else {
409
- out.push(messages[nextIdx]);
410
- }
411
- nextIdx++;
412
- }
413
- if (deferredResultLines.length > 0) {
414
- out.push({
415
- role: "assistant",
416
- content: joinLines(...deferredResultLines)
417
- });
418
- }
419
- k = nextIdx;
420
- continue;
421
- }
422
- if (m.role === "tool") {
423
- if (poisonedToolIndices.has(k)) {
424
- out.push({ role: "assistant", content: renderToolResultAsText(m) });
425
- } else {
426
- out.push(m);
427
- }
428
- k++;
429
- continue;
430
- }
431
- out.push(m);
432
- k++;
433
- }
434
- return { messages: out, downgraded };
435
- }
436
-
437
- export {
438
- sanitizeForOutbound,
439
- hasParsableObjectArguments,
440
- repairTruncatedToolArguments,
441
- downgradeUnparsableToolCalls
442
- };