nolo-cli 0.102.2 → 0.102.3

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 (58) hide show
  1. package/{_executeModel-B6SS2ISV.js → _executeModel-TOH473HN.js} +10 -10
  2. package/{agentDeleteCommand-MEKEAJS6.js → agentDeleteCommand-3EV2EOUI.js} +12 -12
  3. package/{agentEmailCommands-NCQSCDX7.js → agentEmailCommands-V2V54ZIH.js} +13 -13
  4. package/{agentListCommands-VLNQH2BR.js → agentListCommands-SRRN3TCW.js} +4 -4
  5. package/{agentMachineCommands-ZYKZGX65.js → agentMachineCommands-JYJMU27G.js} +5 -5
  6. package/{agentRecordCommands-2INKPT2O.js → agentRecordCommands-KQMZLZHW.js} +13 -13
  7. package/{agentRunCommand-2SZBC7BP.js → agentRunCommand-IWKQO47Q.js} +13 -13
  8. package/{agentRuntimeLocal-7VIX3R3R.js → agentRuntimeLocal-3QKZ76C7.js} +4 -4
  9. package/{agentSlice-4JIT2XG4.js → agentSlice-MR6JWMM5.js} +1 -1
  10. package/{appDeleteCommands-YLCAVP4I.js → appDeleteCommands-SZFKFV4S.js} +4 -4
  11. package/{appDeployCommands-7PQPIIEL.js → appDeployCommands-JWH5HMET.js} +4 -4
  12. package/{appDeployStatusCommands-Z3YBCYU3.js → appDeployStatusCommands-CLONFBVO.js} +4 -4
  13. package/{appGetCommands-MCY6JLD3.js → appGetCommands-4Z7V7UYA.js} +4 -4
  14. package/{appListCommands-O6QDXYKT.js → appListCommands-IIUS64VI.js} +4 -4
  15. package/{authCommand-I6LVUQKM.js → authCommand-NQPMGYHP.js} +1 -1
  16. package/{chunk-VPNDYFUB.js → chunk-3MSJ4XDQ.js} +2 -2
  17. package/{chunk-2K54PIZY.js → chunk-6XHM3LNF.js} +2 -2
  18. package/{chunk-S7HQBOEA.js → chunk-AFRHU2JO.js} +5 -6
  19. package/{chunk-ZQZZJIQI.js → chunk-BML3APFI.js} +28 -5
  20. package/{chunk-Z5X5MD6D.js → chunk-CMKQ7RCH.js} +1 -1
  21. package/{chunk-NMMU6M4Z.js → chunk-GLD6Q25H.js} +8 -8
  22. package/{chunk-NGO72MN2.js → chunk-HDYUKPEB.js} +3 -3
  23. package/{chunk-TAPMD4SO.js → chunk-JVP74JRH.js} +3 -3
  24. package/{chunk-V3R3UZ4F.js → chunk-MEZSLGQZ.js} +7 -7
  25. package/chunk-NKWIS6G2.js +442 -0
  26. package/{chunk-5UQRASYE.js → chunk-NR7N2RWA.js} +2 -2
  27. package/{chunk-XTM4WSXT.js → chunk-O2LBWZLR.js} +5 -5
  28. package/{chunk-GJ647AYV.js → chunk-REPRKRB2.js} +1 -1
  29. package/{chunk-DLXHN5XZ.js → chunk-S274RDSE.js} +3 -3
  30. package/{chunk-ERFIIS4C.js → chunk-USTPPV3J.js} +1 -1
  31. package/{chunk-K4URP6NQ.js → chunk-VL3H5ZU3.js} +47 -6
  32. package/{chunk-TTMNMJVI.js → chunk-YIEUDVD6.js} +8 -8
  33. package/{chunk-OW4APERY.js → chunk-YK5MHOWM.js} +54 -9
  34. package/{commandRegistry-X7FA6WJQ.js → commandRegistry-POKHERIN.js} +47 -47
  35. package/{contentThunks-CH5Z3XAD.js → contentThunks-HEEW3GBT.js} +3 -3
  36. package/{createAgentAutomationAction-4MV3MWVE.js → createAgentAutomationAction-C5UTM2ZI.js} +3 -3
  37. package/{createDialogAction-BYCJKWFY.js → createDialogAction-VODZCSHM.js} +4 -4
  38. package/{createPageAction-XWDTQHFL.js → createPageAction-XUFSVLBC.js} +3 -3
  39. package/{dialogCommands-NNSKMYZR.js → dialogCommands-4XNYPCE7.js} +4 -4
  40. package/{dialogSlice-LUUVLJKZ.js → dialogSlice-KXBFWRVK.js} +2 -2
  41. package/{docCreateCommands-BKCYZTJW.js → docCreateCommands-P4XCR2SW.js} +4 -4
  42. package/{docDeleteCommands-AJDU5BUV.js → docDeleteCommands-KZZ3L6LS.js} +4 -4
  43. package/{docReadCommands-PPI2UAIW.js → docReadCommands-JN6HL4BC.js} +4 -4
  44. package/{docStore-RRAGFCNQ.js → docStore-PLGBTV5U.js} +1 -1
  45. package/{docUpdateCommands-62WIRKAN.js → docUpdateCommands-EYE7BTXW.js} +4 -4
  46. package/{handleSendMessageAction-CW5HSH4E.js → handleSendMessageAction-BBB6A54Z.js} +2 -2
  47. package/index.js +3 -3
  48. package/{machineCommands-FG6HBFB7.js → machineCommands-4LP4XFEY.js} +13 -13
  49. package/{machineWsRunDispatch-7JCANNGT.js → machineWsRunDispatch-4PWOZYRA.js} +13 -13
  50. package/package.json +1 -1
  51. package/{readlineWorkspace-HISW3JNJ.js → readlineWorkspace-CFUUABFV.js} +41 -42
  52. package/{runAgentClientLoop-4XIIPXH3.js → runAgentClientLoop-CAPNBF7Q.js} +8 -8
  53. package/{spaceCommands-BBEY2U7J.js → spaceCommands-QCZUWUMS.js} +4 -4
  54. package/{streamAgentChatTurn-WRLQAWTW.js → streamAgentChatTurn-XX3N3P4J.js} +10 -10
  55. package/{tools-NPSZ3DTN.js → tools-U6BT6H56.js} +6 -6
  56. package/{tuiSummaryLlmCaller-O3DZKOHE.js → tuiSummaryLlmCaller-QCHCULPM.js} +2 -2
  57. package/{updateDialogTitleAction-DBW4OTMM.js → updateDialogTitleAction-NKHQ5LCX.js} +3 -3
  58. package/chunk-CQ3WA2NE.js +0 -299
@@ -2,7 +2,7 @@ import {
2
2
  DEVIN_CONNECT_URL,
3
3
  parseSseDataLineJson,
4
4
  parseSseDataLineObject
5
- } from "./chunk-OW4APERY.js";
5
+ } from "./chunk-YK5MHOWM.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-K4URP6NQ.js";
14
+ } from "./chunk-VL3H5ZU3.js";
15
15
  import {
16
16
  readSseFrames
17
17
  } from "./chunk-GMZLP5DV.js";
@@ -33,7 +33,7 @@ import {
33
33
  hasParsableObjectArguments,
34
34
  repairTruncatedToolArguments,
35
35
  sanitizeForOutbound
36
- } from "./chunk-CQ3WA2NE.js";
36
+ } from "./chunk-NKWIS6G2.js";
37
37
  import {
38
38
  createThinkParserState,
39
39
  createToolCallAccumulator,
@@ -14556,8 +14556,31 @@ function createResponsesStreamCollector(callbacks) {
14556
14556
  };
14557
14557
  const finalize2 = () => {
14558
14558
  let finalToolCalls = finalizeResponsesToolCalls(toolCallsAcc);
14559
- if (finalToolCalls.length === 0 && completedResponse) {
14560
- finalToolCalls = extractToolCallsFromResponseOutput(completedResponse);
14559
+ if (completedResponse) {
14560
+ const completedToolCalls = extractToolCallsFromResponseOutput(completedResponse);
14561
+ const completedById = new Map(completedToolCalls.map((call) => [call.id, call]));
14562
+ finalToolCalls = finalToolCalls.map((call) => {
14563
+ const completed = completedById.get(call.id);
14564
+ if (!completed) return call;
14565
+ let accumulatedParses = false;
14566
+ let completedParses = false;
14567
+ try {
14568
+ JSON.parse(call.function.arguments);
14569
+ accumulatedParses = true;
14570
+ } catch {
14571
+ }
14572
+ try {
14573
+ JSON.parse(completed.function.arguments);
14574
+ completedParses = true;
14575
+ } catch {
14576
+ return call;
14577
+ }
14578
+ if (completedParses && (!accumulatedParses || completed.function.arguments.startsWith(call.function.arguments))) {
14579
+ return { ...call, function: { ...call.function, arguments: completed.function.arguments } };
14580
+ }
14581
+ return call;
14582
+ });
14583
+ if (finalToolCalls.length === 0) finalToolCalls = completedToolCalls;
14561
14584
  }
14562
14585
  if (!content && completedResponse) {
14563
14586
  content = extractTextFromResponseOutput(completedResponse);
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  clearCliLocalRuntimePreparedAgentCache
3
- } from "./chunk-V3R3UZ4F.js";
3
+ } from "./chunk-MEZSLGQZ.js";
4
4
  import {
5
5
  getReadableCliDb
6
6
  } from "./chunk-LOCNXNOU.js";
@@ -14,7 +14,7 @@ import {
14
14
  } from "./chunk-AGGIDPCZ.js";
15
15
  import {
16
16
  runLlm
17
- } from "./chunk-TAPMD4SO.js";
17
+ } from "./chunk-JVP74JRH.js";
18
18
  import {
19
19
  cleanupCliSessionForDialog
20
20
  } from "./chunk-2K4TM6AW.js";
@@ -10528,7 +10528,7 @@ var messageSlice = createSliceWithThunks({
10528
10528
  runtimeOptions: args.runtimeOptions
10529
10529
  });
10530
10530
  if (agentKeyToUse) {
10531
- const { streamAgentChatTurn } = await import("./agentSlice-4JIT2XG4.js");
10531
+ const { streamAgentChatTurn } = await import("./agentSlice-MR6JWMM5.js");
10532
10532
  await dispatch(
10533
10533
  streamAgentChatTurn({
10534
10534
  agentKey: agentKeyToUse,
@@ -13273,7 +13273,7 @@ var deleteDialogThunk = async (payload, thunkApi) => {
13273
13273
  }
13274
13274
  if (isCurrentDialog) {
13275
13275
  await thunkApi.dispatch(resetMsgs());
13276
- const { clearPendingAttachments: clearPendingAttachments2 } = await import("./dialogSlice-LUUVLJKZ.js");
13276
+ const { clearPendingAttachments: clearPendingAttachments2 } = await import("./dialogSlice-KXBFWRVK.js");
13277
13277
  dispatch(clearPendingAttachments2());
13278
13278
  }
13279
13279
  return { dialogKey, isCurrentDialog, attachmentPlan };
@@ -13281,15 +13281,15 @@ var deleteDialogThunk = async (payload, thunkApi) => {
13281
13281
 
13282
13282
  // packages/chat/dialog/dialogSlice.ts
13283
13283
  var runCreateDialogAction = async (args, thunkApi) => {
13284
- const { createDialogAction } = await import("./createDialogAction-BYCJKWFY.js");
13284
+ const { createDialogAction } = await import("./createDialogAction-VODZCSHM.js");
13285
13285
  return createDialogAction(args, thunkApi);
13286
13286
  };
13287
13287
  var runCreateAgentAutomationAction = async (args, thunkApi) => {
13288
- const { createAgentAutomationAction } = await import("./createAgentAutomationAction-4MV3MWVE.js");
13288
+ const { createAgentAutomationAction } = await import("./createAgentAutomationAction-C5UTM2ZI.js");
13289
13289
  return createAgentAutomationAction(args, thunkApi);
13290
13290
  };
13291
13291
  var runUpdateDialogTitleAction = async (args, thunkApi) => {
13292
- const { updateDialogTitleAction } = await import("./updateDialogTitleAction-DBW4OTMM.js");
13292
+ const { updateDialogTitleAction } = await import("./updateDialogTitleAction-NKHQ5LCX.js");
13293
13293
  return updateDialogTitleAction(args, thunkApi);
13294
13294
  };
13295
13295
  var runAddDialogAgentAction = async (args, thunkApi) => {
@@ -13313,7 +13313,7 @@ var runSetDialogExtraReferencesAction = async (args, thunkApi) => {
13313
13313
  return setDialogExtraReferencesAction(args, thunkApi);
13314
13314
  };
13315
13315
  var runHandleSendMessageAction = async (args, thunkApi) => {
13316
- const { handleSendMessageAction } = await import("./handleSendMessageAction-CW5HSH4E.js");
13316
+ const { handleSendMessageAction } = await import("./handleSendMessageAction-BBB6A54Z.js");
13317
13317
  return handleSendMessageAction(args, thunkApi);
13318
13318
  };
13319
13319
  function clearDialogState() {
@@ -13326,7 +13326,7 @@ var createPageAndAddReference = createAsyncThunk(
13326
13326
  async (payload, { dispatch, getState, rejectWithValue }) => {
13327
13327
  const { slateData, jsonData, title, type, fileId, groupId, dialogKey } = payload;
13328
13328
  try {
13329
- const { createDocState } = await import("./docStore-RRAGFCNQ.js");
13329
+ const { createDocState } = await import("./docStore-PLGBTV5U.js");
13330
13330
  const pageKey = await createDocState(
13331
13331
  { slateData, title },
13332
13332
  { dispatch, getState }
@@ -1,13 +1,13 @@
1
1
  import {
2
2
  createCliLocalRuntimeAdapter,
3
3
  summarizeEndpoint
4
- } from "./chunk-V3R3UZ4F.js";
4
+ } from "./chunk-MEZSLGQZ.js";
5
5
  import {
6
6
  clipMultilineText
7
- } from "./chunk-TTMNMJVI.js";
7
+ } from "./chunk-YIEUDVD6.js";
8
8
  import {
9
9
  runLocalAgentTurn
10
- } from "./chunk-ZQZZJIQI.js";
10
+ } from "./chunk-BML3APFI.js";
11
11
  import {
12
12
  applyToolSurfaceConstraints
13
13
  } from "./chunk-7KWFIKKK.js";
@@ -306,7 +306,7 @@ var slice = createSliceWithThunks({
306
306
  const overrides = {};
307
307
  if (args.systemPromptOverride !== void 0) overrides.prompt = args.systemPromptOverride;
308
308
  if (args.toolsOverride !== void 0) overrides.tools = args.toolsOverride;
309
- const { _executeModel } = await import("./_executeModel-B6SS2ISV.js");
309
+ const { _executeModel } = await import("./_executeModel-TOH473HN.js");
310
310
  return _executeModel(
311
311
  {
312
312
  isStreaming: args.isStreaming ?? false,
@@ -327,7 +327,7 @@ var slice = createSliceWithThunks({
327
327
  * - 循环直到无工具调用或触发其他运行时停止条件
328
328
  */
329
329
  runAgent: create.asyncThunk(async (args, thunkApi) => {
330
- const { runAgentClientLoop } = await import("./runAgentClientLoop-4XIIPXH3.js");
330
+ const { runAgentClientLoop } = await import("./runAgentClientLoop-CAPNBF7Q.js");
331
331
  const { content: loopContent, toolCallCount } = await runAgentClientLoop(
332
332
  {
333
333
  agentKey: args.agentKey,
@@ -343,7 +343,7 @@ var slice = createSliceWithThunks({
343
343
  * 聊天轮次流式 Agent 调用
344
344
  */
345
345
  streamAgentChatTurn: create.asyncThunk(async (args, thunkApi) => {
346
- const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-WRLQAWTW.js");
346
+ const { streamAgentChatTurnHandler } = await import("./streamAgentChatTurn-XX3N3P4J.js");
347
347
  return streamAgentChatTurnHandler(args, thunkApi);
348
348
  }),
349
349
  /**
@@ -45,7 +45,7 @@ import {
45
45
  import {
46
46
  inlineImageUrlsForCustomProvider,
47
47
  prepareTools
48
- } from "./chunk-2K54PIZY.js";
48
+ } from "./chunk-6XHM3LNF.js";
49
49
  import {
50
50
  getServerProviderSecret
51
51
  } from "./chunk-HS7MLR74.js";
@@ -63,7 +63,7 @@ import {
63
63
  rememberMemoryFunctionSchema,
64
64
  resolveAgentRequiredPackIds,
65
65
  setTodoListFunc
66
- } from "./chunk-TTMNMJVI.js";
66
+ } from "./chunk-YIEUDVD6.js";
67
67
  import {
68
68
  deriveCredentialGroup,
69
69
  deriveCustomProviderCredentialGroup
@@ -115,14 +115,14 @@ import {
115
115
  prepareTokenUsageData,
116
116
  resolveBuiltinPlatformAgentConfig,
117
117
  runKeyed
118
- } from "./chunk-NMMU6M4Z.js";
118
+ } from "./chunk-GLD6Q25H.js";
119
119
  import {
120
120
  BUILTIN_DIALOG_LLM_CHAT_FALLBACK_MODEL,
121
121
  BUILTIN_TITLE_LLM_CONFIG
122
122
  } from "./chunk-523DITKR.js";
123
123
  import {
124
124
  fetchServerSyncedCredential
125
- } from "./chunk-TAPMD4SO.js";
125
+ } from "./chunk-JVP74JRH.js";
126
126
  import {
127
127
  FORCED_TOOLS,
128
128
  addDefaultLightWebToolsForConfiguredAgents,
@@ -163,7 +163,7 @@ import {
163
163
  readDevinUpstreamFailure,
164
164
  resolveOpenAiCompatibleProviderConfig,
165
165
  resolveSessionKey
166
- } from "./chunk-ZQZZJIQI.js";
166
+ } from "./chunk-BML3APFI.js";
167
167
  import {
168
168
  accumulateGeminiChunks,
169
169
  buildGeminiGenerateContentRequest,
@@ -174,7 +174,7 @@ import {
174
174
  parseUpstreamErrorBody,
175
175
  resolveAntigravityFinishReason,
176
176
  shouldUseGeminiNativeToolRoute
177
- } from "./chunk-OW4APERY.js";
177
+ } from "./chunk-YK5MHOWM.js";
178
178
  import {
179
179
  PlatformStreamInterruptedError,
180
180
  buildPlatformChatCompletionRequest,
@@ -185,7 +185,7 @@ import {
185
185
  readPlatformChatSseCompletion,
186
186
  resolvePlatformChatProviderConfig,
187
187
  shouldUsePlatformChatProvider
188
- } from "./chunk-K4URP6NQ.js";
188
+ } from "./chunk-VL3H5ZU3.js";
189
189
  import {
190
190
  readSseDataValues
191
191
  } from "./chunk-GMZLP5DV.js";
@@ -0,0 +1,442 @@
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
+ };
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  addContentToSpace
3
- } from "./chunk-GJ647AYV.js";
3
+ } from "./chunk-REPRKRB2.js";
4
4
  import {
5
5
  format,
6
6
  prepareAndPersistMessage,
7
7
  uiAskChoiceFunc,
8
8
  uiAskChoiceFunctionSchema
9
- } from "./chunk-NMMU6M4Z.js";
9
+ } from "./chunk-GLD6Q25H.js";
10
10
  import {
11
11
  formatISO
12
12
  } from "./chunk-ZRAU6T47.js";