nolo-cli 0.77.0 → 0.78.0

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/README.md +2 -2
  2. package/{_executeModel-G6BRN2BO.js → _executeModel-W26HVI75.js} +31 -31
  3. package/{action-7GHFPDSQ.js → action-6DXQGJMX.js} +7 -7
  4. package/{addContentAction-ZNVB2NOV.js → addContentAction-I7VX5SAC.js} +5 -5
  5. package/{addDialogAgentAction-CIDFWATM.js → addDialogAgentAction-OJSFV7DZ.js} +4 -4
  6. package/{agentDeleteCommand-C5JTDBIX.js → agentDeleteCommand-XNFWCKBH.js} +16 -16
  7. package/{agentEmailCommands-AYSYNUSH.js → agentEmailCommands-XYOZGQ6F.js} +38 -38
  8. package/{agentGrantCommands-R3VQEZJR.js → agentGrantCommands-YW6PQAQ2.js} +2 -2
  9. package/{agentListCommands-CVFL3P3D.js → agentListCommands-DFWFU6XO.js} +24 -18
  10. package/{agentMachineCommands-2EPX7IYC.js → agentMachineCommands-2EANXBQS.js} +16 -16
  11. package/{agentProviderCommands-EHR3PV2V.js → agentProviderCommands-ZBYHGTGY.js} +1 -1
  12. package/{agentPullCommand-U73W5IBM.js → agentPullCommand-GLOOXJ2E.js} +2 -2
  13. package/{agentRecordCommands-DPZVHOOA.js → agentRecordCommands-DRY5LE4F.js} +37 -37
  14. package/{agentRunCommand-BE53VNNN.js → agentRunCommand-YONMYI4X.js} +38 -38
  15. package/{agentRuntimeLocal-BPN5IOFT.js → agentRuntimeLocal-2JFG4HDU.js} +12 -12
  16. package/{agentSlice-PYJFXGZL.js → agentSlice-ZNLGFUB5.js} +5 -5
  17. package/{appDeleteCommands-TREMNXCA.js → appDeleteCommands-2UN4N2NR.js} +17 -17
  18. package/{appDeployCommands-7FYCMERT.js → appDeployCommands-37D74KRR.js} +17 -17
  19. package/{appDeployStatusCommands-7LAYH7IX.js → appDeployStatusCommands-QBLWL2IA.js} +17 -17
  20. package/{appGetCommands-BONTQ2XH.js → appGetCommands-6KXIDF2T.js} +17 -17
  21. package/{appListCommands-BYIELWUL.js → appListCommands-G2WFGEWQ.js} +17 -17
  22. package/{authCommand-J5C7GS33.js → authCommand-V2DJ7DB7.js} +75 -10
  23. package/{authCommands-VOTT6XWX.js → authCommands-RGOGCPP6.js} +2 -2
  24. package/{builtinSkillRegistry-YITVDLWG.js → builtinSkillRegistry-WBGYKIAZ.js} +5 -5
  25. package/{chatQueueReduxAdapter-PIOXZBGH.js → chatQueueReduxAdapter-XCJHIY3R.js} +12 -12
  26. package/{chunk-JT7FRJP5.js → chunk-2ADBVBEM.js} +2 -2
  27. package/{chunk-6LWO3QQS.js → chunk-2AYMFHUG.js} +2 -2
  28. package/{chunk-RHB6OCZS.js → chunk-36ZJDN6A.js} +5 -5
  29. package/{chunk-GXWEF4IZ.js → chunk-3CR2LC6X.js} +1 -1
  30. package/{chunk-UQ45IHLM.js → chunk-3R5PH4IP.js} +1 -1
  31. package/{chunk-UQYEVBMM.js → chunk-4BYPU626.js} +210 -193
  32. package/{chunk-PHDKTASK.js → chunk-4DRWWIOL.js} +1 -1
  33. package/{chunk-5DAMTON3.js → chunk-576IMUGH.js} +1 -1
  34. package/{chunk-XIYOAH3S.js → chunk-5DFFKASO.js} +3 -3
  35. package/{chunk-5XTOKQLW.js → chunk-5UTFL4QJ.js} +6 -2
  36. package/{chunk-JRFQPOPS.js → chunk-5V4NJHRM.js} +5 -5
  37. package/{chunk-US463UAD.js → chunk-6BEA566T.js} +2 -2
  38. package/{chunk-UINEAQ2R.js → chunk-6D6VBVEW.js} +1 -1
  39. package/{chunk-FSISQCCB.js → chunk-74UCTXK3.js} +78 -31
  40. package/{chunk-7TEU3WX2.js → chunk-7MYYE7WX.js} +8 -8
  41. package/{chunk-3DZIWHJ6.js → chunk-A2C4AKKM.js} +1 -1
  42. package/{chunk-2KDR4CWE.js → chunk-BYMV6QZG.js} +24 -1
  43. package/{chunk-XCSSFPTB.js → chunk-CLI4LFSM.js} +1 -1
  44. package/{chunk-2XEVK4BT.js → chunk-DPQ2WVBY.js} +1 -1
  45. package/{chunk-PGO7O65Q.js → chunk-EXTJ4GXV.js} +4 -4
  46. package/{chunk-VEJ4BOQV.js → chunk-F2CGG72C.js} +2 -2
  47. package/{chunk-UDK3ZSMN.js → chunk-FQYMLZ6C.js} +5 -5
  48. package/{chunk-BJIRLHJR.js → chunk-GII32WZW.js} +1 -0
  49. package/{chunk-LGSXBNWH.js → chunk-GRYGRGPS.js} +3 -3
  50. package/{chunk-ACFF7U3F.js → chunk-HMEMJ7GH.js} +100 -20
  51. package/{chunk-OZX2IPKM.js → chunk-HQCSU3DI.js} +1 -1
  52. package/{chunk-FWGPT6VI.js → chunk-HYZHJ5GW.js} +2 -2
  53. package/{chunk-OAJRZ35U.js → chunk-IIKPWSPX.js} +1 -1
  54. package/{chunk-MRT4KARW.js → chunk-JBBZ5KUM.js} +9 -9
  55. package/{chunk-KC5FAHVS.js → chunk-JEDZAO7L.js} +1 -1
  56. package/{chunk-LSV2BOJL.js → chunk-JTK3TJYV.js} +1 -1
  57. package/{chunk-OHUU52T3.js → chunk-L2ICPOAL.js} +1 -1
  58. package/{chunk-UUVQJZ75.js → chunk-N3OAPEZE.js} +3 -3
  59. package/{chunk-JITSBA52.js → chunk-PH5J5VUY.js} +2 -2
  60. package/{chunk-JYYZCK2Z.js → chunk-QFMFJZLO.js} +1 -1
  61. package/{chunk-6HCLDVEI.js → chunk-QHETQ3KI.js} +1 -1
  62. package/{chunk-IZAWJCG7.js → chunk-RZANZZL2.js} +1 -1
  63. package/{chunk-SPAQ4PVV.js → chunk-SAFZABH7.js} +1 -1
  64. package/{chunk-TIJK4PBP.js → chunk-SMZSWB44.js} +1 -1
  65. package/{chunk-HJKGQPYF.js → chunk-TL6L5XUT.js} +1 -1
  66. package/{chunk-D4TJCP3V.js → chunk-TVNI5FLG.js} +4 -4
  67. package/{chunk-5EJZGJS2.js → chunk-UA5S3LQQ.js} +3 -3
  68. package/{chunk-IEILL33V.js → chunk-UMGHLCDZ.js} +20 -16
  69. package/{chunk-HLRYI5XO.js → chunk-UTCCPWB2.js} +3 -3
  70. package/{chunk-KT6LENVP.js → chunk-VHJLQHPQ.js} +2 -2
  71. package/{chunk-DQD4PYQY.js → chunk-WXPVOQD7.js} +32 -30
  72. package/{chunk-AGX5TE5W.js → chunk-XKQJJK4F.js} +1 -1
  73. package/{chunk-GIG262ZG.js → chunk-XMGHGEN6.js} +1 -1
  74. package/{chunk-4PAFEM6V.js → chunk-XTUY5EL4.js} +16 -12
  75. package/{chunk-OKCTLCKS.js → chunk-YOXYA2GU.js} +1 -1
  76. package/{chunk-RJ3TDODF.js → chunk-ZAB3A45K.js} +12 -0
  77. package/{chunk-YZHP76TR.js → chunk-ZBT3WNBK.js} +1 -1
  78. package/{contentThunks-RYZTYVUV.js → contentThunks-VURN3DFW.js} +13 -13
  79. package/{createAgentAutomationAction-GUBB2LWY.js → createAgentAutomationAction-QZAAY77R.js} +13 -13
  80. package/{createDialogAction-577E6FB2.js → createDialogAction-CHGXVTAC.js} +15 -15
  81. package/{createPageAction-4CNYIRJ5.js → createPageAction-IOGAFIN7.js} +13 -13
  82. package/{dbSlice-4CUQE35F.js → dbSlice-YXQ6RYIH.js} +4 -4
  83. package/{dialogCommands-U4RQIRKK.js → dialogCommands-XREAP6WQ.js} +18 -18
  84. package/{dialogSlice-YXMORK5T.js → dialogSlice-DOPGWGS4.js} +12 -12
  85. package/{docCreateCommands-AXXATGCL.js → docCreateCommands-3PYZGSCL.js} +16 -16
  86. package/{docDeleteCommands-CRPIFYFA.js → docDeleteCommands-3Y6MU44Q.js} +17 -17
  87. package/{docReadCommands-4IMZXFDR.js → docReadCommands-UBANMAFR.js} +16 -16
  88. package/{docStore-3U5FBN2O.js → docStore-SYYFBENY.js} +5 -5
  89. package/{docUpdateCommands-RRPRZXCE.js → docUpdateCommands-4GK2X6BN.js} +16 -16
  90. package/{handleSendMessageAction-BQIRKHC6.js → handleSendMessageAction-NPVTY2GE.js} +12 -12
  91. package/index.js +76 -76
  92. package/{machineCommands-RNBADNTE.js → machineCommands-LES3MCTZ.js} +36 -36
  93. package/{machineWsRunDispatch-7J6WNF57.js → machineWsRunDispatch-FZLFAUUP.js} +36 -36
  94. package/{memberThunks-N35XAOC6.js → memberThunks-5T4J6KXQ.js} +5 -5
  95. package/{offlineMarxistsAgentCommand-GEH6SNNA.js → offlineMarxistsAgentCommand-JEWCIAWM.js} +1 -1
  96. package/package.json +1 -1
  97. package/{providerPresetApply-SAJAK7C3.js → providerPresetApply-OCWWKBSD.js} +1 -1
  98. package/{providerRegistry-COD57OVY.js → providerRegistry-ZJQU7AJ7.js} +1 -1
  99. package/{read-2PV4PN2E.js → read-M2Q6WEKB.js} +3 -3
  100. package/{readDocTool-FGK5XGAW.js → readDocTool-T37P3YPB.js} +1 -1
  101. package/{readlineWorkspace-ZO2W3N4U.js → readlineWorkspace-OZBKHD4T.js} +112 -81
  102. package/{removeDialogAgentAction-O2POGBOE.js → removeDialogAgentAction-HB3JBVAI.js} +7 -7
  103. package/{runAgentClientLoop-KJZ7DK6D.js → runAgentClientLoop-3NDADLVE.js} +29 -29
  104. package/{setDialogExtraReferencesAction-KPSVVY3C.js → setDialogExtraReferencesAction-4XLHRV37.js} +5 -5
  105. package/{setPrimaryDialogAgentAction-RMJETONI.js → setPrimaryDialogAgentAction-C3JOFC4W.js} +7 -7
  106. package/{settingSlice-I6MTTNDX.js → settingSlice-CZRURSTH.js} +6 -6
  107. package/{spaceCommands-VZRYKVWZ.js → spaceCommands-ENYCUUZH.js} +16 -16
  108. package/{streamAgentChatTurn-L3SO4N2R.js → streamAgentChatTurn-634OFUSR.js} +32 -32
  109. package/{switchDialogAgentAction-OQSGWVQQ.js → switchDialogAgentAction-C6KVUKJP.js} +4 -4
  110. package/{tableCommands-SUNTHAYX.js → tableCommands-O6NWHFKV.js} +1 -1
  111. package/{toolApiClient-VGYUB4P5.js → toolApiClient-7PSIFQPJ.js} +2 -2
  112. package/{tools-GRV74JPO.js → tools-ILBLCF7D.js} +26 -26
  113. package/{tuiSummaryLlmCaller-ATDKMGI5.js → tuiSummaryLlmCaller-LFUBZKXK.js} +7 -7
  114. package/{updateCommands-Y363MC3L.js → updateCommands-2M74UL7P.js} +2 -2
  115. package/{updateDialogTitleAction-KRUWX66L.js → updateDialogTitleAction-RKFET73N.js} +13 -13
@@ -8,7 +8,7 @@ import {
8
8
  readSseFrames,
9
9
  streamSseDataValues,
10
10
  throwIfChatCompletionStreamFailed
11
- } from "./chunk-TIJK4PBP.js";
11
+ } from "./chunk-SMZSWB44.js";
12
12
  import {
13
13
  DEVIN_CONNECT_URL
14
14
  } from "./chunk-Q5FJJ6XI.js";
@@ -20,7 +20,7 @@ import {
20
20
  resolveHistoricalToolContentCap,
21
21
  resolveToolOutputProfile,
22
22
  stripImagePartsFromMessages
23
- } from "./chunk-6HCLDVEI.js";
23
+ } from "./chunk-QHETQ3KI.js";
24
24
  import {
25
25
  downgradeUnparsableToolCalls,
26
26
  hasParsableObjectArguments,
@@ -44,7 +44,7 @@ import {
44
44
  requiresBareImageUrl,
45
45
  resolveToolGuidedSections,
46
46
  toBareImageUrlMessages
47
- } from "./chunk-UUVQJZ75.js";
47
+ } from "./chunk-N3OAPEZE.js";
48
48
  import {
49
49
  convertMessagesToResponsesInput,
50
50
  extractReasoningFromResponseOutput,
@@ -68,7 +68,7 @@ import {
68
68
  parseNoloWorkspaceToolArguments,
69
69
  readTextStreamUpToChars,
70
70
  resolveNoloDialogInput
71
- } from "./chunk-OKCTLCKS.js";
71
+ } from "./chunk-YOXYA2GU.js";
72
72
  import {
73
73
  getAntigravityUserAgent,
74
74
  readAntigravityProjectId,
@@ -91,7 +91,7 @@ import {
91
91
  resolveEmptyAssistantFallbackMessage,
92
92
  resolveEmptyAssistantOutcome,
93
93
  resolveTruncatedReasoningTailLog
94
- } from "./chunk-VEJ4BOQV.js";
94
+ } from "./chunk-F2CGG72C.js";
95
95
  import {
96
96
  COMPACTION_SUMMARY_SCHEMA_VERSION,
97
97
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
@@ -110,7 +110,7 @@ import {
110
110
  resolveCompressionTriggerRatio,
111
111
  truncateToolOutputForContext,
112
112
  withProviderCallTimingFields
113
- } from "./chunk-KT6LENVP.js";
113
+ } from "./chunk-VHJLQHPQ.js";
114
114
  import {
115
115
  estimateTokenCount
116
116
  } from "./chunk-PSCNXBYA.js";
@@ -12202,6 +12202,206 @@ function summarizeToolArguments(toolName, rawArgs) {
12202
12202
  );
12203
12203
  }
12204
12204
 
12205
+ // packages/agent-runtime/progressGuard.ts
12206
+ var DEFAULT_MAX_CONSECUTIVE_IDENTICAL_ROUNDS = 5;
12207
+ var DEFAULT_MAX_CONSECUTIVE_STAGNANT_TOOL_ROUNDS = 8;
12208
+ function sortJsonKeys(obj) {
12209
+ if (obj === null || typeof obj !== "object") return obj;
12210
+ if (Array.isArray(obj)) return obj.map(sortJsonKeys);
12211
+ const sorted = {};
12212
+ for (const key of Object.keys(obj).sort()) {
12213
+ sorted[key] = sortJsonKeys(obj[key]);
12214
+ }
12215
+ return sorted;
12216
+ }
12217
+ function normalizeToolArguments(rawArgs) {
12218
+ if (typeof rawArgs !== "string") {
12219
+ try {
12220
+ return JSON.stringify(sortJsonKeys(rawArgs ?? ""));
12221
+ } catch {
12222
+ return String(rawArgs ?? "");
12223
+ }
12224
+ }
12225
+ const trimmed = rawArgs.trim();
12226
+ if (!trimmed) return "";
12227
+ try {
12228
+ const parsed = JSON.parse(trimmed);
12229
+ return JSON.stringify(sortJsonKeys(parsed));
12230
+ } catch {
12231
+ return trimmed;
12232
+ }
12233
+ }
12234
+ function extractNormalizedContentText(content) {
12235
+ if (typeof content === "string") return content.trim();
12236
+ if (!Array.isArray(content)) return "";
12237
+ return content.map((part) => {
12238
+ if (part?.type === "text") return String(part.text ?? "").trim();
12239
+ if (part?.type === "image_url") return `[img:${part.image_url?.url ?? ""}]`;
12240
+ return "";
12241
+ }).filter(Boolean).join("\n");
12242
+ }
12243
+ function buildToolCallsSignature(toolCalls) {
12244
+ if (!toolCalls || toolCalls.length === 0) return "";
12245
+ return toolCalls.map(
12246
+ (tc) => `${tc.function?.name ?? ""}:${normalizeToolArguments(tc.function?.arguments)}`
12247
+ ).join(";;");
12248
+ }
12249
+ function buildAssistantActionFingerprint(result4) {
12250
+ const content = extractNormalizedContentText(result4.content);
12251
+ const reasoning = typeof result4.reasoning_content === "string" ? result4.reasoning_content.trim() : "";
12252
+ let toolCallsSig = buildToolCallsSignature(result4.tool_calls);
12253
+ let hasToolCalls = Array.isArray(result4.tool_calls) && result4.tool_calls.length > 0;
12254
+ if (!toolCallsSig && Array.isArray(result4.output) && result4.output.length > 0) {
12255
+ const blocksToolCalls = result4.output.filter(
12256
+ (b) => b.type === "toolCall"
12257
+ ).map((b) => b.toolCall);
12258
+ if (blocksToolCalls.length > 0) {
12259
+ toolCallsSig = buildToolCallsSignature(blocksToolCalls);
12260
+ hasToolCalls = true;
12261
+ }
12262
+ }
12263
+ const hasNonEmptyText = content.length > 0 || reasoning.length > 0;
12264
+ const fingerprint = `${content}##${reasoning}##${toolCallsSig}`;
12265
+ return {
12266
+ fingerprint,
12267
+ hasNonEmptyText,
12268
+ hasToolCalls,
12269
+ toolCallsSignature: toolCallsSig
12270
+ };
12271
+ }
12272
+ function buildToolResultsSignature(toolExecutions) {
12273
+ if (toolExecutions.length === 0) return "";
12274
+ return toolExecutions.map((exec) => {
12275
+ const contentStr = typeof exec.content === "string" ? exec.content.trim() : "";
12276
+ const metaStr = exec.metadata ? JSON.stringify(sortJsonKeys(exec.metadata)) : "";
12277
+ return `${exec.toolName}:${contentStr}:${metaStr}`;
12278
+ }).join(";;");
12279
+ }
12280
+ function resolveProgressGuardConfig(options, env = typeof process !== "undefined" ? process.env : {}) {
12281
+ const envDisabled = env.NOLO_LOOP_PROGRESS_GUARD_DISABLED === "true" || env.NOLO_LOOP_PROGRESS_GUARD_DISABLED === "1";
12282
+ const disabled = options?.disabled ?? envDisabled ?? false;
12283
+ const parsePositiveInt = (val, fallback) => {
12284
+ if (typeof val === "number" && Number.isFinite(val) && val >= 1) {
12285
+ return Math.floor(val);
12286
+ }
12287
+ if (typeof val === "string") {
12288
+ const parsed = parseInt(val, 10);
12289
+ if (Number.isFinite(parsed) && parsed >= 1) {
12290
+ return parsed;
12291
+ }
12292
+ }
12293
+ return fallback;
12294
+ };
12295
+ const maxConsecutiveIdenticalRounds = parsePositiveInt(
12296
+ options?.maxConsecutiveIdenticalRounds ?? env.NOLO_LOOP_MAX_IDENTICAL_ROUNDS,
12297
+ DEFAULT_MAX_CONSECUTIVE_IDENTICAL_ROUNDS
12298
+ );
12299
+ const maxConsecutiveStagnantToolRounds = parsePositiveInt(
12300
+ options?.maxConsecutiveStagnantToolRounds ?? env.NOLO_LOOP_MAX_STAGNANT_TOOL_ROUNDS,
12301
+ DEFAULT_MAX_CONSECUTIVE_STAGNANT_TOOL_ROUNDS
12302
+ );
12303
+ return {
12304
+ disabled,
12305
+ maxConsecutiveIdenticalRounds,
12306
+ maxConsecutiveStagnantToolRounds
12307
+ };
12308
+ }
12309
+ var LocalLoopProgressGuard = class {
12310
+ config;
12311
+ lastAssistantFingerprint = null;
12312
+ lastAssistantHasNonEmptyText = false;
12313
+ consecutiveIdenticalCount = 0;
12314
+ lastToolCallsSignature = null;
12315
+ lastToolResultsSignature = null;
12316
+ consecutiveStagnantToolCount = 0;
12317
+ constructor(config, env) {
12318
+ this.config = resolveProgressGuardConfig(config, env);
12319
+ }
12320
+ /**
12321
+ * 在 LLM 返回 assistant 响应后调用。
12322
+ * 仅在纯文本/无工具调用且实质文本相同达到阈值时直接熔断;
12323
+ * 若存在工具调用,则不在此处熔断,留待工具执行后结合工具结果综合判定。
12324
+ */
12325
+ observeAssistantResponse(result4) {
12326
+ if (this.config.disabled) return { action: "continue" };
12327
+ const { fingerprint, hasNonEmptyText, hasToolCalls } = buildAssistantActionFingerprint(result4);
12328
+ if (this.lastAssistantFingerprint !== null && this.lastAssistantFingerprint === fingerprint) {
12329
+ this.consecutiveIdenticalCount += 1;
12330
+ if (!hasToolCalls && hasNonEmptyText && this.consecutiveIdenticalCount >= this.config.maxConsecutiveIdenticalRounds) {
12331
+ return {
12332
+ action: "stall",
12333
+ reason: "repetition_loop",
12334
+ detail: `Consecutive identical text-only assistant response for ${this.consecutiveIdenticalCount} rounds.`,
12335
+ consecutiveRounds: this.consecutiveIdenticalCount
12336
+ };
12337
+ }
12338
+ } else {
12339
+ this.lastAssistantFingerprint = fingerprint;
12340
+ this.lastAssistantHasNonEmptyText = hasNonEmptyText;
12341
+ this.consecutiveIdenticalCount = 1;
12342
+ }
12343
+ return { action: "continue" };
12344
+ }
12345
+ /**
12346
+ * 在本轮所有工具执行完毕后调用,检查是否陷入停滞死循环。
12347
+ * 只有当工具返回内容与元数据完全无变化时才计入无进展 streak;
12348
+ * 一旦工具结果发生变化(如合法轮询状态推进),立即重置 identical streak,确保绝不误杀正常长任务。
12349
+ */
12350
+ observeToolExecution(toolCalls, toolResults) {
12351
+ if (this.config.disabled) return { action: "continue" };
12352
+ if (!toolCalls || toolCalls.length === 0) return { action: "continue" };
12353
+ const toolCallsSig = buildToolCallsSignature(toolCalls);
12354
+ const toolResultsSig = buildToolResultsSignature(toolResults);
12355
+ const toolCallsUnchanged = this.lastToolCallsSignature !== null && this.lastToolCallsSignature === toolCallsSig;
12356
+ const toolResultsUnchanged = this.lastToolResultsSignature !== null && this.lastToolResultsSignature === toolResultsSig;
12357
+ if (toolCallsUnchanged && toolResultsUnchanged) {
12358
+ this.consecutiveStagnantToolCount += 1;
12359
+ if (this.consecutiveIdenticalCount >= this.config.maxConsecutiveIdenticalRounds) {
12360
+ return {
12361
+ action: "stall",
12362
+ reason: "repetition_loop",
12363
+ detail: `Consecutive identical assistant response with unchanged tool results for ${this.consecutiveIdenticalCount} rounds.`,
12364
+ consecutiveRounds: this.consecutiveIdenticalCount
12365
+ };
12366
+ }
12367
+ if (this.consecutiveStagnantToolCount >= this.config.maxConsecutiveStagnantToolRounds) {
12368
+ return {
12369
+ action: "stall",
12370
+ reason: "stagnant_tool_calls",
12371
+ detail: `Consecutive stagnant tool calls with unchanged results for ${this.consecutiveStagnantToolCount} rounds.`,
12372
+ consecutiveRounds: this.consecutiveStagnantToolCount
12373
+ };
12374
+ }
12375
+ } else {
12376
+ this.lastToolCallsSignature = toolCallsSig;
12377
+ this.lastToolResultsSignature = toolResultsSig;
12378
+ this.consecutiveStagnantToolCount = 1;
12379
+ if (!toolResultsUnchanged) {
12380
+ this.consecutiveIdenticalCount = 1;
12381
+ }
12382
+ }
12383
+ return { action: "continue" };
12384
+ }
12385
+ };
12386
+ function createLocalLoopProgressGuard(config, env) {
12387
+ return new LocalLoopProgressGuard(config, env);
12388
+ }
12389
+
12390
+ // packages/agent-runtime/toolArgumentsFingerprint.ts
12391
+ var hashFingerprintInput = (value) => {
12392
+ let hash2 = 2166136261;
12393
+ for (let index = 0; index < value.length; index += 1) {
12394
+ hash2 ^= value.charCodeAt(index);
12395
+ hash2 = Math.imul(hash2, 16777619);
12396
+ }
12397
+ return (hash2 >>> 0).toString(16).padStart(8, "0");
12398
+ };
12399
+ function buildToolArgumentsFingerprint(rawArguments) {
12400
+ if (rawArguments === void 0 || rawArguments === null) return void 0;
12401
+ const normalized = normalizeToolArguments(rawArguments);
12402
+ return hashFingerprintInput(normalized);
12403
+ }
12404
+
12205
12405
  // packages/agent-runtime/leafFinalHandoff.ts
12206
12406
  var LEAF_FINAL_HANDOFF_INSTRUCTIONS = `Leaf subtask final: return only the result, blockers/findings, and minimal evidence the parent needs. Do not narrate your process or restate the task. Keep success minimal (a one-line result is enough); on failure include the blocker, severity when relevant, and an evidence reference (file:line, test command, commit, artifact, or run/dialog). If the task explicitly requires a long-form deliverable (document, translation, dataset, code, or other artifact), provide that deliverable in full and keep only the handoff around it concise. During execution, follow the brief as given: only when new evidence would materially change the goal, risk, irreversibility, or DoD should you surface it as a blocker/finding in the handoff \u2014 do not silently expand scope or re-litigate the settled direction.`;
12207
12407
 
@@ -12558,191 +12758,6 @@ async function maybeAutoCompactLocalHistory(args2) {
12558
12758
  }
12559
12759
  }
12560
12760
 
12561
- // packages/agent-runtime/progressGuard.ts
12562
- var DEFAULT_MAX_CONSECUTIVE_IDENTICAL_ROUNDS = 5;
12563
- var DEFAULT_MAX_CONSECUTIVE_STAGNANT_TOOL_ROUNDS = 8;
12564
- function sortJsonKeys(obj) {
12565
- if (obj === null || typeof obj !== "object") return obj;
12566
- if (Array.isArray(obj)) return obj.map(sortJsonKeys);
12567
- const sorted = {};
12568
- for (const key of Object.keys(obj).sort()) {
12569
- sorted[key] = sortJsonKeys(obj[key]);
12570
- }
12571
- return sorted;
12572
- }
12573
- function normalizeToolArguments(rawArgs) {
12574
- if (typeof rawArgs !== "string") {
12575
- try {
12576
- return JSON.stringify(sortJsonKeys(rawArgs ?? ""));
12577
- } catch {
12578
- return String(rawArgs ?? "");
12579
- }
12580
- }
12581
- const trimmed = rawArgs.trim();
12582
- if (!trimmed) return "";
12583
- try {
12584
- const parsed = JSON.parse(trimmed);
12585
- return JSON.stringify(sortJsonKeys(parsed));
12586
- } catch {
12587
- return trimmed;
12588
- }
12589
- }
12590
- function extractNormalizedContentText(content) {
12591
- if (typeof content === "string") return content.trim();
12592
- if (!Array.isArray(content)) return "";
12593
- return content.map((part) => {
12594
- if (part?.type === "text") return String(part.text ?? "").trim();
12595
- if (part?.type === "image_url") return `[img:${part.image_url?.url ?? ""}]`;
12596
- return "";
12597
- }).filter(Boolean).join("\n");
12598
- }
12599
- function buildToolCallsSignature(toolCalls) {
12600
- if (!toolCalls || toolCalls.length === 0) return "";
12601
- return toolCalls.map(
12602
- (tc) => `${tc.function?.name ?? ""}:${normalizeToolArguments(tc.function?.arguments)}`
12603
- ).join(";;");
12604
- }
12605
- function buildAssistantActionFingerprint(result4) {
12606
- const content = extractNormalizedContentText(result4.content);
12607
- const reasoning = typeof result4.reasoning_content === "string" ? result4.reasoning_content.trim() : "";
12608
- let toolCallsSig = buildToolCallsSignature(result4.tool_calls);
12609
- let hasToolCalls = Array.isArray(result4.tool_calls) && result4.tool_calls.length > 0;
12610
- if (!toolCallsSig && Array.isArray(result4.output) && result4.output.length > 0) {
12611
- const blocksToolCalls = result4.output.filter(
12612
- (b) => b.type === "toolCall"
12613
- ).map((b) => b.toolCall);
12614
- if (blocksToolCalls.length > 0) {
12615
- toolCallsSig = buildToolCallsSignature(blocksToolCalls);
12616
- hasToolCalls = true;
12617
- }
12618
- }
12619
- const hasNonEmptyText = content.length > 0 || reasoning.length > 0;
12620
- const fingerprint = `${content}##${reasoning}##${toolCallsSig}`;
12621
- return {
12622
- fingerprint,
12623
- hasNonEmptyText,
12624
- hasToolCalls,
12625
- toolCallsSignature: toolCallsSig
12626
- };
12627
- }
12628
- function buildToolResultsSignature(toolExecutions) {
12629
- if (toolExecutions.length === 0) return "";
12630
- return toolExecutions.map((exec) => {
12631
- const contentStr = typeof exec.content === "string" ? exec.content.trim() : "";
12632
- const metaStr = exec.metadata ? JSON.stringify(sortJsonKeys(exec.metadata)) : "";
12633
- return `${exec.toolName}:${contentStr}:${metaStr}`;
12634
- }).join(";;");
12635
- }
12636
- function resolveProgressGuardConfig(options, env = typeof process !== "undefined" ? process.env : {}) {
12637
- const envDisabled = env.NOLO_LOOP_PROGRESS_GUARD_DISABLED === "true" || env.NOLO_LOOP_PROGRESS_GUARD_DISABLED === "1";
12638
- const disabled = options?.disabled ?? envDisabled ?? false;
12639
- const parsePositiveInt = (val, fallback) => {
12640
- if (typeof val === "number" && Number.isFinite(val) && val >= 1) {
12641
- return Math.floor(val);
12642
- }
12643
- if (typeof val === "string") {
12644
- const parsed = parseInt(val, 10);
12645
- if (Number.isFinite(parsed) && parsed >= 1) {
12646
- return parsed;
12647
- }
12648
- }
12649
- return fallback;
12650
- };
12651
- const maxConsecutiveIdenticalRounds = parsePositiveInt(
12652
- options?.maxConsecutiveIdenticalRounds ?? env.NOLO_LOOP_MAX_IDENTICAL_ROUNDS,
12653
- DEFAULT_MAX_CONSECUTIVE_IDENTICAL_ROUNDS
12654
- );
12655
- const maxConsecutiveStagnantToolRounds = parsePositiveInt(
12656
- options?.maxConsecutiveStagnantToolRounds ?? env.NOLO_LOOP_MAX_STAGNANT_TOOL_ROUNDS,
12657
- DEFAULT_MAX_CONSECUTIVE_STAGNANT_TOOL_ROUNDS
12658
- );
12659
- return {
12660
- disabled,
12661
- maxConsecutiveIdenticalRounds,
12662
- maxConsecutiveStagnantToolRounds
12663
- };
12664
- }
12665
- var LocalLoopProgressGuard = class {
12666
- config;
12667
- lastAssistantFingerprint = null;
12668
- lastAssistantHasNonEmptyText = false;
12669
- consecutiveIdenticalCount = 0;
12670
- lastToolCallsSignature = null;
12671
- lastToolResultsSignature = null;
12672
- consecutiveStagnantToolCount = 0;
12673
- constructor(config, env) {
12674
- this.config = resolveProgressGuardConfig(config, env);
12675
- }
12676
- /**
12677
- * 在 LLM 返回 assistant 响应后调用。
12678
- * 仅在纯文本/无工具调用且实质文本相同达到阈值时直接熔断;
12679
- * 若存在工具调用,则不在此处熔断,留待工具执行后结合工具结果综合判定。
12680
- */
12681
- observeAssistantResponse(result4) {
12682
- if (this.config.disabled) return { action: "continue" };
12683
- const { fingerprint, hasNonEmptyText, hasToolCalls } = buildAssistantActionFingerprint(result4);
12684
- if (this.lastAssistantFingerprint !== null && this.lastAssistantFingerprint === fingerprint) {
12685
- this.consecutiveIdenticalCount += 1;
12686
- if (!hasToolCalls && hasNonEmptyText && this.consecutiveIdenticalCount >= this.config.maxConsecutiveIdenticalRounds) {
12687
- return {
12688
- action: "stall",
12689
- reason: "repetition_loop",
12690
- detail: `Consecutive identical text-only assistant response for ${this.consecutiveIdenticalCount} rounds.`,
12691
- consecutiveRounds: this.consecutiveIdenticalCount
12692
- };
12693
- }
12694
- } else {
12695
- this.lastAssistantFingerprint = fingerprint;
12696
- this.lastAssistantHasNonEmptyText = hasNonEmptyText;
12697
- this.consecutiveIdenticalCount = 1;
12698
- }
12699
- return { action: "continue" };
12700
- }
12701
- /**
12702
- * 在本轮所有工具执行完毕后调用,检查是否陷入停滞死循环。
12703
- * 只有当工具返回内容与元数据完全无变化时才计入无进展 streak;
12704
- * 一旦工具结果发生变化(如合法轮询状态推进),立即重置 identical streak,确保绝不误杀正常长任务。
12705
- */
12706
- observeToolExecution(toolCalls, toolResults) {
12707
- if (this.config.disabled) return { action: "continue" };
12708
- if (!toolCalls || toolCalls.length === 0) return { action: "continue" };
12709
- const toolCallsSig = buildToolCallsSignature(toolCalls);
12710
- const toolResultsSig = buildToolResultsSignature(toolResults);
12711
- const toolCallsUnchanged = this.lastToolCallsSignature !== null && this.lastToolCallsSignature === toolCallsSig;
12712
- const toolResultsUnchanged = this.lastToolResultsSignature !== null && this.lastToolResultsSignature === toolResultsSig;
12713
- if (toolCallsUnchanged && toolResultsUnchanged) {
12714
- this.consecutiveStagnantToolCount += 1;
12715
- if (this.consecutiveIdenticalCount >= this.config.maxConsecutiveIdenticalRounds) {
12716
- return {
12717
- action: "stall",
12718
- reason: "repetition_loop",
12719
- detail: `Consecutive identical assistant response with unchanged tool results for ${this.consecutiveIdenticalCount} rounds.`,
12720
- consecutiveRounds: this.consecutiveIdenticalCount
12721
- };
12722
- }
12723
- if (this.consecutiveStagnantToolCount >= this.config.maxConsecutiveStagnantToolRounds) {
12724
- return {
12725
- action: "stall",
12726
- reason: "stagnant_tool_calls",
12727
- detail: `Consecutive stagnant tool calls with unchanged results for ${this.consecutiveStagnantToolCount} rounds.`,
12728
- consecutiveRounds: this.consecutiveStagnantToolCount
12729
- };
12730
- }
12731
- } else {
12732
- this.lastToolCallsSignature = toolCallsSig;
12733
- this.lastToolResultsSignature = toolResultsSig;
12734
- this.consecutiveStagnantToolCount = 1;
12735
- if (!toolResultsUnchanged) {
12736
- this.consecutiveIdenticalCount = 1;
12737
- }
12738
- }
12739
- return { action: "continue" };
12740
- }
12741
- };
12742
- function createLocalLoopProgressGuard(config, env) {
12743
- return new LocalLoopProgressGuard(config, env);
12744
- }
12745
-
12746
12761
  // packages/agent-runtime/localLoop.ts
12747
12762
  var LOOP_TIMING_ENABLED = typeof process !== "undefined" && process.env?.NOLO_LOOP_TIMING === "1";
12748
12763
  var LOOP_TIMING_FILE = typeof process !== "undefined" ? process.env?.NOLO_LOOP_TIMING_FILE : void 0;
@@ -13950,6 +13965,7 @@ ${reasoningTailLog}
13950
13965
  const startedAt = Date.now();
13951
13966
  loopTimingMark("toolCallStart", round);
13952
13967
  const argumentsPreview = summarizeToolArguments(toolName, toolCall.function.arguments);
13968
+ const argumentsFingerprint = buildToolArgumentsFingerprint(toolCall.function.arguments);
13953
13969
  emitLoopEvent(
13954
13970
  observationBoundary,
13955
13971
  {
@@ -13958,7 +13974,8 @@ ${reasoningTailLog}
13958
13974
  toolCallId: toolCall.id,
13959
13975
  toolName,
13960
13976
  atMs: startedAt,
13961
- ...argumentsPreview ? { argumentsPreview } : {}
13977
+ ...argumentsPreview ? { argumentsPreview } : {},
13978
+ ...argumentsFingerprint ? { argumentsFingerprint } : {}
13962
13979
  },
13963
13980
  {
13964
13981
  type: "tool-call",
@@ -19356,7 +19373,7 @@ function buildLoadSkillExecutor(args2) {
19356
19373
  const { resolveSkillByName } = await import("./skillDiscovery-CYUCJMAG.js");
19357
19374
  const resolved = resolveSkillByName(args2.cwd, name);
19358
19375
  if (!resolved) {
19359
- const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-YITVDLWG.js");
19376
+ const { resolveBuiltinSkillByName } = await import("./builtinSkillRegistry-WBGYKIAZ.js");
19360
19377
  const builtin = resolveBuiltinSkillByName(name);
19361
19378
  if (builtin) {
19362
19379
  return {
@@ -4,7 +4,7 @@ import {
4
4
  import {
5
5
  patch,
6
6
  read
7
- } from "./chunk-5EJZGJS2.js";
7
+ } from "./chunk-UA5S3LQQ.js";
8
8
  import {
9
9
  DEVICE_LOCAL_OWNER_ID,
10
10
  isDeviceLocalSpaceBody
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  fetchReferenceContents,
3
3
  resolveReferenceAssets
4
- } from "./chunk-7TEU3WX2.js";
4
+ } from "./chunk-7MYYE7WX.js";
5
5
 
6
6
  // packages/ai/agent/fetchAgentContexts.ts
7
7
  async function fetchAgentContexts(references, dispatch) {
@@ -10,7 +10,7 @@ import {
10
10
  import {
11
11
  patch,
12
12
  readAndWait
13
- } from "./chunk-5EJZGJS2.js";
13
+ } from "./chunk-UA5S3LQQ.js";
14
14
  import {
15
15
  asOptionalTrimmedString
16
16
  } from "./chunk-G3SUCT4W.js";
@@ -326,7 +326,7 @@ async function saveDocState(arg, { dispatch, getState }) {
326
326
  ).unwrap();
327
327
  if (dbSpaceId) {
328
328
  try {
329
- const { updateContentTitle } = await import("./contentThunks-RYZTYVUV.js");
329
+ const { updateContentTitle } = await import("./contentThunks-VURN3DFW.js");
330
330
  await dispatch(
331
331
  updateContentTitle({
332
332
  spaceId: dbSpaceId,
@@ -365,7 +365,7 @@ async function saveDocState(arg, { dispatch, getState }) {
365
365
  }
366
366
  }
367
367
  async function createDocState(args, thunkApi) {
368
- const { createPageAction } = await import("./createPageAction-4CNYIRJ5.js");
368
+ const { createPageAction } = await import("./createPageAction-IOGAFIN7.js");
369
369
  return createPageAction(args, thunkApi);
370
370
  }
371
371
  function subscribe(listener) {
@@ -18,9 +18,13 @@ var CORE_DRAINING_MAX_ATTEMPTS = 30;
18
18
  var RETRYABLE_HTTP_STATUSES = /* @__PURE__ */ new Set([429, 503]);
19
19
  function isTransientFetchError(error) {
20
20
  const message = toErrorMessage(error);
21
- return /certificate|handshake|network|socket|timed out|timeout|ECONNRESET/i.test(
21
+ return /certificate|handshake|network|socket|timed out|timeout|ECONNRESET|UND_ERR_SOCKET|other side closed/i.test(
22
22
  message
23
- );
23
+ ) || // undici(Node fetch)连接中途被断开时抛 `TypeError: terminated`,message
24
+ // 就是裸的 "terminated"(真实 cause 是 UND_ERR_SOCKET)。只认「整条就是
25
+ // terminated」或「前缀: terminated」这种形态,避免把 access_terminated_error
26
+ // (配额封禁)或 "process was terminated by signal" 误判成可重试的网络抖动。
27
+ /(?:^|:\s*)terminated$/i.test(message.trim());
24
28
  }
25
29
  async function defaultSleep(ms) {
26
30
  await new Promise((resolve) => setTimeout(resolve, ms));
@@ -1,17 +1,17 @@
1
1
  import {
2
2
  addContentToSpace
3
- } from "./chunk-UDK3ZSMN.js";
3
+ } from "./chunk-FQYMLZ6C.js";
4
4
  import {
5
5
  prepareAndPersistMessage,
6
6
  uiAskChoiceFunc,
7
7
  uiAskChoiceFunctionSchema
8
- } from "./chunk-ACFF7U3F.js";
8
+ } from "./chunk-HMEMJ7GH.js";
9
9
  import {
10
10
  require_date_fns
11
11
  } from "./chunk-M76ECQRD.js";
12
12
  import {
13
13
  buildBuiltinObjectSkillReference
14
- } from "./chunk-XCSSFPTB.js";
14
+ } from "./chunk-CLI4LFSM.js";
15
15
  import {
16
16
  PLATFORM_HOSTED_DEEPSEEK_FLASH_MODEL,
17
17
  PLATFORM_HOSTED_KIMI_PROVIDER
@@ -22,7 +22,7 @@ import {
22
22
  removeCachedEntity,
23
23
  upsertSSREntity,
24
24
  write
25
- } from "./chunk-5EJZGJS2.js";
25
+ } from "./chunk-UA5S3LQQ.js";
26
26
  import {
27
27
  createAgentKey,
28
28
  createDialogKey,
@@ -33,7 +33,7 @@ import {
33
33
  } from "./chunk-VMFTFOWF.js";
34
34
  import {
35
35
  extractCustomId
36
- } from "./chunk-BJIRLHJR.js";
36
+ } from "./chunk-GII32WZW.js";
37
37
  import {
38
38
  isDevelopment
39
39
  } from "./chunk-QOKAKDPE.js";
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  selectCurrentServer
3
- } from "./chunk-JITSBA52.js";
3
+ } from "./chunk-PH5J5VUY.js";
4
4
  import {
5
5
  patch
6
- } from "./chunk-5EJZGJS2.js";
6
+ } from "./chunk-UA5S3LQQ.js";
7
7
  import {
8
8
  getIsDesktopApp
9
9
  } from "./chunk-QOKAKDPE.js";
@@ -12,7 +12,7 @@ import {
12
12
  getProfileTokens,
13
13
  loadProfileConfig,
14
14
  saveDefaultProfile
15
- } from "./chunk-2KDR4CWE.js";
15
+ } from "./chunk-BYMV6QZG.js";
16
16
  import {
17
17
  resolveAuthTokenFromEnv
18
18
  } from "./chunk-A7GB5UGH.js";