nolo-cli 0.49.1 → 0.50.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 (131) hide show
  1. package/{_executeModel-KE4PQSZ3.js → _executeModel-JKEH7ACW.js} +48 -42
  2. package/{action-IU6ON7ZB.js → action-VSG2IYP3.js} +8 -8
  3. package/{addContentAction-5V5CCI3I.js → addContentAction-2HJJITDI.js} +8 -7
  4. package/{addDialogAgentAction-KF3KZZNZ.js → addDialogAgentAction-7BSQVVL5.js} +10 -9
  5. package/{agentDeleteCommand-Z67TJG3W.js → agentDeleteCommand-SVXKS5SC.js} +30 -28
  6. package/{agentEmailCommands-7LPIK7JE.js → agentEmailCommands-WN7QBTP3.js} +57 -52
  7. package/{agentListCommands-5J2IM3IT.js → agentListCommands-2BEBOQIG.js} +42 -33
  8. package/{agentMachineCommands-YXH6FXUQ.js → agentMachineCommands-WALP3ONU.js} +30 -28
  9. package/{agentRecordCommands-GZLCDVUS.js → agentRecordCommands-E652SW57.js} +55 -50
  10. package/{agentRunCommand-WYH5Q54Q.js → agentRunCommand-6VXWXKCS.js} +60 -53
  11. package/{agentRunControl-4GHHSXFZ.js → agentRunControl-LJVFDJGU.js} +3 -1
  12. package/{agentRuntimeLocal-A6EF3RUY.js → agentRuntimeLocal-SBG7BDFQ.js} +30 -26
  13. package/{agentSlice-ARTDF6VD.js → agentSlice-3WYXIGEO.js} +8 -8
  14. package/{agentSuperviseCommands-VB6BUS5H.js → agentSuperviseCommands-F3RFAL7K.js} +2 -2
  15. package/{appDeleteCommands-V2B7ZCLC.js → appDeleteCommands-NTUNMEXY.js} +31 -29
  16. package/{appDeployCommands-AXQU44RD.js → appDeployCommands-DISWXRTL.js} +31 -29
  17. package/{appDeployStatusCommands-FWGSC2UM.js → appDeployStatusCommands-IKRA6B6F.js} +31 -29
  18. package/{appGetCommands-67R3RFZK.js → appGetCommands-UMOP2DFV.js} +31 -29
  19. package/{appListCommands-TTASJPGV.js → appListCommands-ZKFD2AKS.js} +31 -29
  20. package/{authCommand-QOPOEYEK.js → authCommand-BS3CQC6I.js} +11 -11
  21. package/{chatQueueReduxAdapter-6CAHUQ4O.js → chatQueueReduxAdapter-A3YH4MT4.js} +24 -21
  22. package/{chunk-76UA7376.js → chunk-273FJUYI.js} +6 -6
  23. package/{chunk-7CH6U3FL.js → chunk-2GRGFCF6.js} +2 -4
  24. package/{chunk-T27IEBNQ.js → chunk-2QDDKFG5.js} +74 -1
  25. package/{chunk-IRJVFYOH.js → chunk-2TLYVDTN.js} +321 -1100
  26. package/{chunk-6BYAXNH5.js → chunk-3QOCS5IF.js} +11 -2
  27. package/chunk-6IGD47IC.js +19 -0
  28. package/{chunk-GFD7TIZU.js → chunk-6TUT5ZJD.js} +4 -6
  29. package/chunk-6YTOJY35.js +352 -0
  30. package/{chunk-B54WOZ77.js → chunk-7H7GQL6V.js} +2 -2
  31. package/{chunk-OYNDYVSE.js → chunk-B45YNDAE.js} +1 -1
  32. package/{chunk-UQWFIWHX.js → chunk-BKIDF5LV.js} +1 -1
  33. package/{chunk-5XCW6RQG.js → chunk-BUBPRCIU.js} +1 -1
  34. package/chunk-BYXBJQAS.js +0 -0
  35. package/{chunk-X7S7OFUX.js → chunk-CEVCRRHU.js} +4 -4
  36. package/{chunk-SP3DPVBH.js → chunk-DEIGUGP6.js} +2 -2
  37. package/{chunk-V2IPBG5U.js → chunk-DGEPT6FH.js} +1 -1
  38. package/{chunk-3AOLVADY.js → chunk-DVINR3PL.js} +1 -1
  39. package/{chunk-NN3AMBY3.js → chunk-DXOELY7S.js} +64 -69
  40. package/{chunk-OFZPJ3NT.js → chunk-E4MARS3Q.js} +1 -1
  41. package/{chunk-QUCSAM43.js → chunk-EAYBPWHX.js} +87 -66
  42. package/{chunk-DQLYEGP7.js → chunk-EGVY3GMT.js} +1 -1
  43. package/{chunk-2JYSSXLY.js → chunk-EJFW7TRP.js} +5 -26
  44. package/{chunk-HPZL4IBN.js → chunk-FGRCSLPV.js} +34 -45
  45. package/{chunk-WL3UOGYO.js → chunk-G4WSLTQF.js} +31 -97
  46. package/{chunk-HR5XDXYM.js → chunk-G5SQVIFZ.js} +3 -3
  47. package/{chunk-J3UALFHL.js → chunk-GHE5XMVR.js} +1 -1
  48. package/{chunk-6SMMK7MD.js → chunk-GKB4AZKV.js} +440 -2981
  49. package/{chunk-IKSFDJXB.js → chunk-GKNGRBE6.js} +150 -27
  50. package/{chunk-Q24S4NDF.js → chunk-HQTK2SFT.js} +1 -1
  51. package/{chunk-GDGIEGHV.js → chunk-IPTZ5TVU.js} +7 -6
  52. package/{chunk-4RXXP6WD.js → chunk-J7KDNHUO.js} +5 -64
  53. package/{chunk-QDHZCAH3.js → chunk-KNQ5LYVZ.js} +57 -2
  54. package/{chunk-VRJUIUIY.js → chunk-KVVNC5V3.js} +2 -2
  55. package/{chunk-CVT7L2WZ.js → chunk-LVCAWHI5.js} +4 -4
  56. package/{chunk-WX5E6HZS.js → chunk-N6SLQMSA.js} +6 -6
  57. package/{chunk-SQTVMYMU.js → chunk-NTZO3KX2.js} +3 -3
  58. package/{chunk-LGUQHYAL.js → chunk-O5FLGN2L.js} +3 -2
  59. package/{chunk-WKOEOQCI.js → chunk-OSUZKICS.js} +1600 -190
  60. package/{chunk-EXDR5D6X.js → chunk-Q2QN2RHG.js} +7 -7
  61. package/{chunk-L3JWI7WX.js → chunk-QOKAKDPE.js} +15 -11
  62. package/{chunk-757BGY6Y.js → chunk-RFYXK6KI.js} +1 -1
  63. package/chunk-RQSN75DW.js +1766 -0
  64. package/{chunk-HCMFFI2G.js → chunk-S3JNURSO.js} +2 -2
  65. package/{chunk-YZ2WE6CW.js → chunk-SAJSBPI2.js} +2 -2
  66. package/{chunk-WHVQA7PJ.js → chunk-SCBBGS2N.js} +23 -5
  67. package/chunk-SGSJBBKP.js +297 -0
  68. package/{chunk-GFUOVFQA.js → chunk-TUBNQ3OF.js} +2 -2
  69. package/{chunk-BANYWEYY.js → chunk-TY3ADTX5.js} +1 -1
  70. package/chunk-UAD2WT54.js +64 -0
  71. package/{chunk-SW7RCUGA.js → chunk-UEV5WVQV.js} +3 -3
  72. package/{chunk-EURF2SV6.js → chunk-UMCMW5R3.js} +51 -34
  73. package/{chunk-K524MUQC.js → chunk-VFDRZHPM.js} +16 -16
  74. package/{chunk-5WADL4O7.js → chunk-W22UTILW.js} +3 -3
  75. package/{chunk-IKTHA3JH.js → chunk-WERPP2S7.js} +2 -2
  76. package/{chunk-GBADO3SM.js → chunk-WSUHBABG.js} +1 -1
  77. package/{chunk-U5Z7LFZF.js → chunk-X3OGKR5Q.js} +4 -4
  78. package/{chunk-AVKUDHJO.js → chunk-X5LRMXTS.js} +10 -10
  79. package/{chunk-DIQCV4FR.js → chunk-X665UCNM.js} +1 -1
  80. package/{chunk-HCBQVVFZ.js → chunk-X7P6EJUY.js} +4 -4
  81. package/{chunk-HHBXCRJS.js → chunk-XOJRZUPF.js} +4 -4
  82. package/{chunk-MRWGHF56.js → chunk-YDH3FDFQ.js} +12 -356
  83. package/{chunk-TNPCQNGQ.js → chunk-YEFRCO5N.js} +4 -9
  84. package/{chunk-RO2IUWZE.js → chunk-YUKTCDVN.js} +1 -1
  85. package/{chunk-56W233KG.js → chunk-YWY25N4V.js} +1 -1
  86. package/{chunk-RU5D3B22.js → chunk-ZDS63Y4O.js} +2 -2
  87. package/chunk-ZJ7UHBJS.js +89 -0
  88. package/{chunk-SG65C33A.js → chunk-ZLMG6NRV.js} +4 -4
  89. package/{codingSkills-BYQI6EPT.js → codingSkills-FQPCEIWL.js} +2 -2
  90. package/contentThunks-J33BZB3E.js +71 -0
  91. package/{createAgentAutomationAction-7BBF5YXN.js → createAgentAutomationAction-HTMTGX6Q.js} +25 -21
  92. package/{createDialogAction-B5URPHP4.js → createDialogAction-WYQBSN6A.js} +27 -23
  93. package/{createPageAction-ISJKM5Q3.js → createPageAction-ICRRK3SA.js} +27 -22
  94. package/{dbSlice-FWF5F4L7.js → dbSlice-YORO4VL4.js} +6 -6
  95. package/{deleteFile-NPZ64DFN.js → deleteFile-JYKRT7C3.js} +4 -4
  96. package/{dialogCommands-XHH4MVA4.js → dialogCommands-FRSIAPKY.js} +31 -29
  97. package/{dialogSlice-NRAN5X7F.js → dialogSlice-5KPVIAWH.js} +24 -21
  98. package/{docCreateCommands-FUN2Z7HQ.js → docCreateCommands-DBRJMPDX.js} +30 -28
  99. package/{docDeleteCommands-OZDPFXPF.js → docDeleteCommands-BCYPLWXN.js} +31 -29
  100. package/{docReadCommands-FIPK7LE3.js → docReadCommands-L5JX4Q7G.js} +30 -28
  101. package/{docStore-LUS7SWC3.js → docStore-34NXLCEO.js} +8 -33
  102. package/{docUpdateCommands-BZ5GKAN4.js → docUpdateCommands-RELG7XJD.js} +30 -28
  103. package/fetchMessages-KZQVBXKY.js +1 -1
  104. package/{getPricing-HAU62AFM.js → getPricing-FM7TJZFV.js} +4 -4
  105. package/{handleSendMessageAction-RA4OD2ZH.js → handleSendMessageAction-MEYK7RPD.js} +25 -22
  106. package/index.js +64 -64
  107. package/{machineCommands-WDAYEFBE.js → machineCommands-YSXTOWHQ.js} +59 -54
  108. package/{machineWsRunDispatch-TPQ2FQVS.js → machineWsRunDispatch-DNAYOPQT.js} +54 -49
  109. package/memberThunks-KVPBG4V7.js +638 -0
  110. package/{models-4QF4BJVY.js → models-CW5EL6Z7.js} +2 -2
  111. package/package.json +2 -3
  112. package/{read-J7RVVCHH.js → read-NIOV5F7W.js} +4 -4
  113. package/{readDocTool-G2WBM4IH.js → readDocTool-ULKJ5BEM.js} +1 -1
  114. package/{readlineWorkspace-HN44KGIF.js → readlineWorkspace-KZ3LPQG2.js} +829 -393
  115. package/{removeDialogAgentAction-RMPISD42.js → removeDialogAgentAction-JGSCPML3.js} +12 -11
  116. package/{runAgentClientLoop-ZYUI22EA.js → runAgentClientLoop-O2AUHIJT.js} +46 -40
  117. package/{setDialogExtraReferencesAction-7BUTHDAL.js → setDialogExtraReferencesAction-CORU64NM.js} +9 -8
  118. package/{setPrimaryDialogAgentAction-WCYIBGZ4.js → setPrimaryDialogAgentAction-5VS2VKLZ.js} +12 -11
  119. package/{settingSlice-7NN2MI6Y.js → settingSlice-3GNGTC2T.js} +7 -7
  120. package/{skillDiscovery-COX56OBO.js → skillDiscovery-CYUCJMAG.js} +3 -3
  121. package/{spaceCommands-OJ2567D4.js → spaceCommands-OI7RIB2T.js} +30 -28
  122. package/{streamAgentChatTurn-FNFMMGNN.js → streamAgentChatTurn-TA3PGS6C.js} +61 -54
  123. package/{switchDialogAgentAction-WGMMQHDI.js → switchDialogAgentAction-LP433X4D.js} +10 -9
  124. package/{tableCommands-P2TXJ3CF.js → tableCommands-R6WFRDYF.js} +1 -1
  125. package/{toolApiClient-B2MFXMEG.js → toolApiClient-53U4UDFF.js} +3 -2
  126. package/{tools-QCDR3UMD.js → tools-6ZPQ75XA.js} +37 -32
  127. package/{tuiSummaryLlmCaller-LCGT62QC.js → tuiSummaryLlmCaller-YKYQB4ZL.js} +17 -15
  128. package/{updateDialogTitleAction-Y3OGJWDB.js → updateDialogTitleAction-LRJ7NSOS.js} +26 -22
  129. package/chunk-EUG45QJR.js +0 -6104
  130. package/spaceSlice-F7JCOZEF.js +0 -127
  131. package/{chunk-NQ4N4IGO.js → chunk-CS6TCJ7E.js} +3 -3
@@ -7,7 +7,7 @@ import {
7
7
  providerHttpFailure,
8
8
  readSseFrames,
9
9
  throwIfChatCompletionStreamFailed
10
- } from "./chunk-GDGIEGHV.js";
10
+ } from "./chunk-IPTZ5TVU.js";
11
11
  import {
12
12
  FRESH_TOOL_OUTPUT_MAX_CHARS,
13
13
  MAX_HISTORICAL_TOOL_CONTENT_CHARS,
@@ -17,10 +17,12 @@ import {
17
17
  resolveHistoricalToolContentCap,
18
18
  resolveToolOutputProfile,
19
19
  stripImagePartsFromMessages
20
- } from "./chunk-CVT7L2WZ.js";
20
+ } from "./chunk-LVCAWHI5.js";
21
21
  import {
22
+ downgradeUnparsableToolCalls,
23
+ hasParsableObjectArguments,
22
24
  sanitizeForOutbound
23
- } from "./chunk-T27IEBNQ.js";
25
+ } from "./chunk-2QDDKFG5.js";
24
26
  import {
25
27
  createThinkParserState,
26
28
  createToolCallAccumulator,
@@ -29,6 +31,7 @@ import {
29
31
  finalizeAccumulatedToolCalls
30
32
  } from "./chunk-N7J63Q6C.js";
31
33
  import {
34
+ TOOL_GUIDED_SECTION_ORDER,
32
35
  buildCurrentTimeBlock,
33
36
  buildIdentityBlock,
34
37
  buildRuntimeGuidanceBlocks,
@@ -36,7 +39,7 @@ import {
36
39
  requiresBareImageUrl,
37
40
  resolveToolGuidedSections,
38
41
  toBareImageUrlMessages
39
- } from "./chunk-NN3AMBY3.js";
42
+ } from "./chunk-DXOELY7S.js";
40
43
  import {
41
44
  convertMessagesToResponsesInput,
42
45
  extractReasoningFromResponseOutput,
@@ -46,11 +49,11 @@ import {
46
49
  shouldStripReasoningContentForOutbound,
47
50
  toOpenAiCompatibleMessages,
48
51
  toResponsesTools
49
- } from "./chunk-6BYAXNH5.js";
52
+ } from "./chunk-3QOCS5IF.js";
50
53
  import {
51
54
  buildProviderAuthHeaders,
52
55
  buildProviderExecutionPlan
53
- } from "./chunk-SP3DPVBH.js";
56
+ } from "./chunk-DEIGUGP6.js";
54
57
  import {
55
58
  NOLO_WORKSPACE_TOOL_NAMES,
56
59
  buildNoloWorkspaceCommandArgs,
@@ -58,7 +61,7 @@ import {
58
61
  noloStringArg,
59
62
  parseNoloWorkspaceToolArguments,
60
63
  resolveNoloDialogInput
61
- } from "./chunk-TNPCQNGQ.js";
64
+ } from "./chunk-YEFRCO5N.js";
62
65
  import {
63
66
  buildDialogFallbackTitleFromUserInput
64
67
  } from "./chunk-2MBTWINN.js";
@@ -69,7 +72,7 @@ import {
69
72
  resolveEmptyAssistantFallbackMessage,
70
73
  resolveEmptyAssistantOutcome,
71
74
  resolveTruncatedReasoningTailLog
72
- } from "./chunk-SW7RCUGA.js";
75
+ } from "./chunk-UEV5WVQV.js";
73
76
  import {
74
77
  COMPACTION_SUMMARY_SCHEMA_VERSION,
75
78
  COMPACTION_SUMMARY_SYSTEM_PROMPT,
@@ -83,7 +86,7 @@ import {
83
86
  formatMessagesForSummaryWithTruncation,
84
87
  planCompression,
85
88
  planContextUsage
86
- } from "./chunk-HR5XDXYM.js";
89
+ } from "./chunk-G5SQVIFZ.js";
87
90
  import {
88
91
  resolveNoloStateDir
89
92
  } from "./chunk-FD36SCCD.js";
@@ -92,10 +95,10 @@ import {
92
95
  } from "./chunk-HNMXYYJR.js";
93
96
  import {
94
97
  buildDialogSummaryLayer
95
- } from "./chunk-3AOLVADY.js";
98
+ } from "./chunk-DVINR3PL.js";
96
99
  import {
97
100
  buildUserResponseLanguageContext
98
- } from "./chunk-7CH6U3FL.js";
101
+ } from "./chunk-2GRGFCF6.js";
99
102
  import {
100
103
  canonicalizeToolName,
101
104
  canonicalizeToolNames
@@ -116,15 +119,15 @@ import {
116
119
  import {
117
120
  asTrimmedLowercaseString
118
121
  } from "./chunk-QSJ3HFEF.js";
119
- import {
120
- isRecord
121
- } from "./chunk-KUG52IAP.js";
122
122
  import {
123
123
  asTrimmedString
124
124
  } from "./chunk-3EUW3WEO.js";
125
125
  import {
126
126
  asOptionalPositiveFiniteNumber
127
127
  } from "./chunk-U6VC4MU4.js";
128
+ import {
129
+ isRecord
130
+ } from "./chunk-KUG52IAP.js";
128
131
  import {
129
132
  normalizeServerOrigin
130
133
  } from "./chunk-CF7PE763.js";
@@ -359,6 +362,9 @@ import { existsSync, mkdirSync, readdirSync, renameSync, statSync, unlinkSync, u
359
362
  import { isAbsolute, join, relative } from "node:path";
360
363
  var DEFAULT_MAX_SPILL_DIR_BYTES = 50 * 1024 * 1024;
361
364
  var DEFAULT_SPILL_TTL_MS = 24 * 60 * 60 * 1e3;
365
+ var SPILL_CLEANUP_THROTTLE_MS = 60 * 1e3;
366
+ var SPILL_THROTTLE_MAX_DIRS = 64;
367
+ var lastSpillCleanupAtMsByDir = /* @__PURE__ */ new Map();
362
368
  function resolveSpillDirectory(options) {
363
369
  if (options?.baseDir) {
364
370
  return options.baseDir;
@@ -380,6 +386,16 @@ function countLines(text) {
380
386
  }
381
387
  function cleanupExpiredSpills(spillDir, options) {
382
388
  if (!existsSync(spillDir)) return;
389
+ const throttleMs = options?.throttleMs ?? 0;
390
+ if (throttleMs > 0) {
391
+ const now2 = Date.now();
392
+ const last = lastSpillCleanupAtMsByDir.get(spillDir);
393
+ if (last !== void 0 && now2 - last < throttleMs) return;
394
+ if (lastSpillCleanupAtMsByDir.size >= SPILL_THROTTLE_MAX_DIRS) {
395
+ lastSpillCleanupAtMsByDir.clear();
396
+ }
397
+ lastSpillCleanupAtMsByDir.set(spillDir, now2);
398
+ }
383
399
  const maxAge = options?.maxAgeMs ?? DEFAULT_SPILL_TTL_MS;
384
400
  const maxBytes = options?.maxTotalBytes ?? DEFAULT_MAX_SPILL_DIR_BYTES;
385
401
  const now = Date.now();
@@ -430,7 +446,8 @@ function spillToolOutput(options) {
430
446
  }
431
447
  cleanupExpiredSpills(spillDir, {
432
448
  maxAgeMs: options.ttlMs,
433
- maxTotalBytes: options.maxRetentionBytes
449
+ maxTotalBytes: options.maxRetentionBytes,
450
+ throttleMs: SPILL_CLEANUP_THROTTLE_MS
434
451
  });
435
452
  const hash = createHash("sha256").update(content).digest("hex").slice(0, 12);
436
453
  const safeToolName = (options.toolName || "tool").replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 24);
@@ -936,6 +953,34 @@ function createLocalLoopProgressGuard(config, env) {
936
953
  }
937
954
 
938
955
  // packages/agent-runtime/localLoop.ts
956
+ var LOOP_TIMING_ENABLED = typeof process !== "undefined" && process.env?.NOLO_LOOP_TIMING === "1";
957
+ var LOOP_TIMING_FILE = typeof process !== "undefined" ? process.env?.NOLO_LOOP_TIMING_FILE : void 0;
958
+ var loopTimingRows = [];
959
+ var loopTimingLastMark;
960
+ function loopTimingMark(phase, round) {
961
+ if (!LOOP_TIMING_ENABLED) return;
962
+ const now = performance.now();
963
+ if (loopTimingLastMark !== void 0) {
964
+ loopTimingRows.push({ phase, round, durationMs: now - loopTimingLastMark });
965
+ }
966
+ loopTimingLastMark = now;
967
+ }
968
+ async function loopTimingFlush() {
969
+ if (!LOOP_TIMING_ENABLED) return;
970
+ const lines = loopTimingRows.map((row) => JSON.stringify(row)).join("\n");
971
+ loopTimingRows = [];
972
+ loopTimingLastMark = void 0;
973
+ if (!lines) return;
974
+ if (LOOP_TIMING_FILE) {
975
+ try {
976
+ const { appendFileSync } = await import("node:fs");
977
+ appendFileSync(LOOP_TIMING_FILE, lines + "\n");
978
+ } catch {
979
+ }
980
+ } else {
981
+ process.stderr.write(lines + "\n");
982
+ }
983
+ }
939
984
  var LOCAL_AGENT_CONFIG_MISSING_CODE = "LOCAL_AGENT_CONFIG_MISSING";
940
985
  function formatToolExecutionError(args) {
941
986
  const message = toErrorMessage(args.error);
@@ -1437,18 +1482,21 @@ function buildMessages(args) {
1437
1482
  const dynamicParts = blocks2.filter((b) => b.cacheScope === "turn").map((b) => b.content).map((block) => block.trim()).filter(Boolean);
1438
1483
  const stableContent = stableParts.join("\n\n");
1439
1484
  const dynamicContent = dynamicParts.join("\n\n");
1440
- const systemContent2 = dynamicContent ? `${stableContent}
1485
+ const userContent = dynamicContent ? typeof args.input === "string" ? `${dynamicContent}
1441
1486
 
1442
- ${dynamicContent}` : stableContent;
1487
+ ${args.input}` : [
1488
+ { type: "text", text: dynamicContent },
1489
+ ...Array.isArray(args.input) ? args.input : args.input ? [args.input] : []
1490
+ ] : args.input;
1443
1491
  return {
1444
1492
  messages: [
1445
- ...systemContent2 ? [{
1493
+ ...stableContent ? [{
1446
1494
  role: "system",
1447
- content: systemContent2,
1495
+ content: stableContent,
1448
1496
  ...stableContent ? { stable_prefix_chars: stableContent.length } : {}
1449
1497
  }] : [],
1450
1498
  ...prepareHistoryForNextTurn(args.history, args.contextReferenceResolver),
1451
- { role: "user", content: args.input }
1499
+ { role: "user", content: userContent }
1452
1500
  ],
1453
1501
  stableContextChars: stableContent.length,
1454
1502
  dynamicContextChars: dynamicContent.length
@@ -1596,6 +1644,7 @@ function isCompletedActionGateResult(value) {
1596
1644
  );
1597
1645
  }
1598
1646
  async function runLocalAgentTurn(input) {
1647
+ loopTimingMark("turnStart", 0);
1599
1648
  const agentConfig = await input.adapter.loadAgentConfig(input.agentRef);
1600
1649
  if (!agentConfig) {
1601
1650
  const error = new Error(
@@ -1632,6 +1681,7 @@ async function runLocalAgentTurn(input) {
1632
1681
  attachDialogIdToError(error, dialogId);
1633
1682
  throw error;
1634
1683
  }
1684
+ loopTimingMark("loadDialogHistory", 0);
1635
1685
  const identityBlock = buildIdentityBlock({
1636
1686
  agentName: agentConfig.name,
1637
1687
  agentId: agentConfig.key,
@@ -1647,7 +1697,9 @@ async function runLocalAgentTurn(input) {
1647
1697
  guidanceBlocks.startupProtocol,
1648
1698
  guidanceBlocks.contextLayerContract,
1649
1699
  guidanceBlocks.emailRegistrationWorkflow,
1650
- ...Object.values(toolGuidedSections)
1700
+ // 注入顺序遵循 TOOL_GUIDED_SECTION_ORDER(与 buildSystemPrompt 的显式
1701
+ // layer 列表同源),禁止用 Object.values 自行定序。
1702
+ ...TOOL_GUIDED_SECTION_ORDER.map((id) => toolGuidedSections[id] ?? "")
1651
1703
  ].map((content) => content.trim()).filter((content) => content.length > 0).map((content) => ({ content, cacheScope: "session" }));
1652
1704
  const currentTimeScope = [
1653
1705
  { content: buildCurrentTimeBlock(/* @__PURE__ */ new Date(), void 0), cacheScope: "turn" }
@@ -1662,6 +1714,7 @@ async function runLocalAgentTurn(input) {
1662
1714
  ...currentTimeScope,
1663
1715
  ...callerScopes
1664
1716
  ];
1717
+ loopTimingMark("buildContextBlocks", 0);
1665
1718
  let resolvedProvider;
1666
1719
  const resolveProviderOnce = async () => {
1667
1720
  if (!resolvedProvider) {
@@ -1696,10 +1749,12 @@ async function runLocalAgentTurn(input) {
1696
1749
  } catch (error) {
1697
1750
  console.warn("[localLoop] auto-compaction unexpected error:", error);
1698
1751
  }
1752
+ loopTimingMark("maybeAutoCompactLocalHistory", 0);
1699
1753
  const trimmedHistory = trimHistoryToContextBudget(history, agentConfig.model);
1700
1754
  if (trimmedHistory.droppedCount > 0) {
1701
1755
  history = trimmedHistory.history;
1702
1756
  }
1757
+ loopTimingMark("trimHistoryToContextBudget", 0);
1703
1758
  const hasContextBlocks = callerScopes.some((block) => block.content.trim()) || mergedContextBlockScopes.some((block) => block.content.trim());
1704
1759
  const promptMessageCount = agentConfig.prompt?.trim() || hasContextBlocks ? 1 : 0;
1705
1760
  const turnStartIndex = promptMessageCount + history.length;
@@ -1711,6 +1766,14 @@ async function runLocalAgentTurn(input) {
1711
1766
  contextReferenceResolver: input.adapter.host === "cli" ? input.contextReferenceResolver : void 0
1712
1767
  });
1713
1768
  let messages = builtMessages.messages;
1769
+ loopTimingMark("buildMessages", 0);
1770
+ const poisonDowngrade = downgradeUnparsableToolCalls(messages);
1771
+ if (poisonDowngrade.downgraded > 0) {
1772
+ messages = poisonDowngrade.messages;
1773
+ console.warn(
1774
+ `[nolo] downgraded ${poisonDowngrade.downgraded} tool_call(s) with unparsable JSON arguments from outbound history (suspected upstream stream truncation); persisted history untouched`
1775
+ );
1776
+ }
1714
1777
  const supportsImages = resolveAgentImageInputSupport({
1715
1778
  apiSource: agentConfig.apiSource,
1716
1779
  provider: agentConfig.provider,
@@ -1741,9 +1804,28 @@ async function runLocalAgentTurn(input) {
1741
1804
  const progressGuard = createLocalLoopProgressGuard(input.progressGuardConfig);
1742
1805
  try {
1743
1806
  const provider = await resolveProviderOnce();
1807
+ const applyPendingInjections = () => {
1808
+ if (!input.drainInjections) return false;
1809
+ let pending = [];
1810
+ try {
1811
+ pending = input.drainInjections() ?? [];
1812
+ } catch (error) {
1813
+ console.warn("[localLoop] drainInjections failed:", error);
1814
+ return false;
1815
+ }
1816
+ let injected = false;
1817
+ for (const text of pending) {
1818
+ if (typeof text !== "string" || !text.trim()) continue;
1819
+ messages.push({ role: "user", content: text });
1820
+ injected = true;
1821
+ }
1822
+ return injected;
1823
+ };
1744
1824
  while (true) {
1745
1825
  partialContent = "";
1746
1826
  throwIfAborted(input);
1827
+ loopTimingMark("roundStart", round);
1828
+ applyPendingInjections();
1747
1829
  const preparedMessages = prepareMessagesForProviderCall(messages);
1748
1830
  const baseRequestMessages = filterImagePartsFromMessages(
1749
1831
  preparedMessages.messages,
@@ -1761,6 +1843,7 @@ async function runLocalAgentTurn(input) {
1761
1843
  dynamicContextChars: builtMessages.dynamicContextChars
1762
1844
  };
1763
1845
  emptyAssistantRepairPending = false;
1846
+ loopTimingMark("prepareMessagesForProviderCall", round);
1764
1847
  result = await runCompleteWithTimeout({
1765
1848
  provider,
1766
1849
  messages: requestMessages,
@@ -1788,6 +1871,7 @@ async function runLocalAgentTurn(input) {
1788
1871
  providerName: agentConfig.provider,
1789
1872
  model: provider.model
1790
1873
  });
1874
+ loopTimingMark("llmCall", round);
1791
1875
  turnUsage = mergeTurnUsage(turnUsage, result.usage);
1792
1876
  contextUsage = result.usage;
1793
1877
  if (result.usage && Object.keys(result.usage).length > 0) {
@@ -1817,6 +1901,7 @@ async function runLocalAgentTurn(input) {
1817
1901
  }
1818
1902
  const toolCalls = result.tool_calls ?? [];
1819
1903
  const rawToolCallsCount = (result.tool_calls?.length ?? 0) || (Array.isArray(result.raw_tool_calls) ? result.raw_tool_calls.length : 0);
1904
+ loopTimingMark("postLlmProcessing", round);
1820
1905
  if (toolCalls.length === 0 && rawToolCallsCount === 0) {
1821
1906
  const outcome = resolveEmptyAssistantOutcome({
1822
1907
  hasToolCalls: rawToolCallsCount > 0,
@@ -1862,6 +1947,20 @@ ${reasoningTailLog}
1862
1947
  };
1863
1948
  break;
1864
1949
  }
1950
+ if (input.drainInjections) {
1951
+ const assistantMessage = {
1952
+ role: "assistant",
1953
+ content: result.content,
1954
+ ...result.reasoning_content ? { reasoning_content: result.reasoning_content } : {}
1955
+ };
1956
+ messages.push(assistantMessage);
1957
+ if (applyPendingInjections()) {
1958
+ loopTimingMark("roundEnd", round);
1959
+ round += 1;
1960
+ continue;
1961
+ }
1962
+ messages.pop();
1963
+ }
1865
1964
  break;
1866
1965
  }
1867
1966
  const outputBlocks = result.output ?? [];
@@ -1895,11 +1994,13 @@ ${reasoningTailLog}
1895
1994
  tool_calls: toolCalls
1896
1995
  });
1897
1996
  const executedToolResults = [];
1997
+ loopTimingMark("toolLoopStart", round);
1898
1998
  for (const toolCall of toolCalls) {
1899
1999
  throwIfAborted(input);
1900
2000
  const toolName = toolCall.function.name;
1901
2001
  let toolResult;
1902
2002
  const startedAt = Date.now();
2003
+ loopTimingMark("toolCallStart", round);
1903
2004
  const argumentsPreview = summarizeToolArguments(toolName, toolCall.function.arguments);
1904
2005
  emitLoopEvent(
1905
2006
  input,
@@ -1920,8 +2021,14 @@ ${reasoningTailLog}
1920
2021
  }
1921
2022
  );
1922
2023
  try {
2024
+ const rawPoisonArguments = toolCall.function?.arguments;
2025
+ if (typeof rawPoisonArguments === "string" && rawPoisonArguments.trim() !== "" && !hasParsableObjectArguments(rawPoisonArguments)) {
2026
+ throw new Error(
2027
+ `\u6A21\u578B\u751F\u6210\u7684 tool_call arguments \u4E0D\u662F\u5408\u6CD5 JSON\uFF08\u7591\u4F3C\u4E0A\u6E38\u6D41\u5F0F\u622A\u65AD\uFF0C\u539F\u59CB\u957F\u5EA6 ${rawPoisonArguments.length}\uFF09\u3002\u8BF7\u91CD\u65B0\u5B8C\u6574\u8C03\u7528 ${toolName}\uFF0C\u786E\u4FDD arguments \u662F\u95ED\u5408\u7684 JSON \u5BF9\u8C61\u3002`
2028
+ );
2029
+ }
1923
2030
  const writeTool = toolName === "writeFile" || toolName === "editFile";
1924
- if (writeTool && input.onActionGate) {
2031
+ if (writeTool && input.onActionGate && input.fileWriteGateEnabled !== false) {
1925
2032
  const writeSession = getFileWriteSessionApproval(input);
1926
2033
  const policy = evaluateFileWritePolicy({
1927
2034
  tool: toolName,
@@ -1983,6 +2090,7 @@ ${reasoningTailLog}
1983
2090
  const finishedAt = Date.now();
1984
2091
  const summary = summarizeToolResult(toolResult.content, toolResult.metadata);
1985
2092
  const safeMetadata = projectSafeToolObservationMetadata(toolResult.metadata);
2093
+ loopTimingMark("toolExecute", round);
1986
2094
  emitLoopEvent(
1987
2095
  input,
1988
2096
  {
@@ -2049,6 +2157,7 @@ ${reasoningTailLog}
2049
2157
  content: toolResult.content,
2050
2158
  metadata: toolResult.metadata
2051
2159
  });
2160
+ loopTimingMark("toolResultFormat", round);
2052
2161
  messages.push({
2053
2162
  role: "tool",
2054
2163
  content: formatToolMessageContent({
@@ -2081,6 +2190,7 @@ ${reasoningTailLog}
2081
2190
  };
2082
2191
  break;
2083
2192
  }
2193
+ loopTimingMark("roundEnd", round);
2084
2194
  round += 1;
2085
2195
  }
2086
2196
  } catch (error) {
@@ -2115,6 +2225,7 @@ ${reasoningTailLog}
2115
2225
  input
2116
2226
  });
2117
2227
  attachDialogIdToError(loopError, dialogId);
2228
+ await loopTimingFlush();
2118
2229
  throw loopError;
2119
2230
  }
2120
2231
  result = result;
@@ -2146,6 +2257,7 @@ ${reasoningTailLog}
2146
2257
  });
2147
2258
  }
2148
2259
  const accountingUsage = addOutOfBandUsage(turnUsage, compactionUsage);
2260
+ loopTimingMark("saveTurnStart", round);
2149
2261
  const saved = await input.adapter.saveTurn({
2150
2262
  agentKey: agentConfig.key,
2151
2263
  messages: turnMessages,
@@ -2164,6 +2276,8 @@ ${reasoningTailLog}
2164
2276
  ...input.inheritedFromDialogKey ? { inheritedFromDialogKey: input.inheritedFromDialogKey } : {},
2165
2277
  ...input.parentDialogId ? { parentDialogId: input.parentDialogId } : {}
2166
2278
  });
2279
+ loopTimingMark("saveTurn", round);
2280
+ await loopTimingFlush();
2167
2281
  return {
2168
2282
  ...result,
2169
2283
  ...usageRecords.length > 0 ? { usageRecords } : {},
@@ -2396,7 +2510,10 @@ function buildOpenAiCompatibleChatCompletionRequest(args) {
2396
2510
  stream: args.stream ?? false,
2397
2511
  ...args.providerConfig.requestOptions,
2398
2512
  ...args.tools && args.tools.length > 0 ? { tools: args.tools } : {},
2399
- ...!isResponses && args.stream ? getUsageRequestOptions(args.providerConfig.usageProvider ?? args.providerConfig.provider, { api: "chat-completions" }) : {}
2513
+ ...!isResponses && args.stream ? getUsageRequestOptions(args.providerConfig.usageProvider ?? args.providerConfig.provider, {
2514
+ api: "chat-completions",
2515
+ endpoint: args.providerConfig.endpoint
2516
+ }) : {}
2400
2517
  };
2401
2518
  const body = isResponses ? buildResponsesRequestBody(rawBody, args.providerConfig.model) : normalizeChatCompletionsBodyForProvider({
2402
2519
  body: rawBody,
@@ -3100,19 +3217,24 @@ function parseSyncServersEnv(env) {
3100
3217
  if (!raw) return [];
3101
3218
  return raw.split(",").map((value) => value.trim()).filter((value) => value.length > 0);
3102
3219
  }
3220
+ var DEFAULT_HYBRID_READ_TIMEOUT_MS = 250;
3103
3221
  function createHybridRecordStore(deps) {
3104
3222
  const fetchImpl = deps.fetchImpl ?? fetch;
3223
+ const requestTimeoutMs = deps.requestTimeoutMs ?? DEFAULT_HYBRID_READ_TIMEOUT_MS;
3105
3224
  return {
3106
3225
  read: async (dbKey, options) => {
3107
3226
  const localRecord = await readHybridLocalRecord(deps.db, dbKey);
3108
3227
  const normalizedLocalRecord = normalizeHybridRecord(dbKey, localRecord);
3109
3228
  if (normalizedLocalRecord && options?.remote !== true) return normalizedLocalRecord;
3110
3229
  if (options?.remote === false) return null;
3230
+ const fallbackDeadlineMs = requestTimeoutMs > 0 ? Date.now() + requestTimeoutMs : null;
3111
3231
  for (const server of resolveHybridServers(
3112
3232
  deps.defaultServer,
3113
3233
  options?.preferredServerOrigin,
3114
3234
  deps.fallbackServers
3115
3235
  )) {
3236
+ const remainingMs = fallbackDeadlineMs === null ? null : fallbackDeadlineMs - Date.now();
3237
+ if (remainingMs !== null && remainingMs <= 0) break;
3116
3238
  let remoteRecord = null;
3117
3239
  try {
3118
3240
  remoteRecord = await fetchHybridRemoteRecord({
@@ -3120,7 +3242,7 @@ function createHybridRecordStore(deps) {
3120
3242
  server,
3121
3243
  authToken: deps.authToken,
3122
3244
  fetchImpl,
3123
- ...deps.requestTimeoutMs ? { signal: AbortSignal.timeout(deps.requestTimeoutMs) } : {}
3245
+ ...remainingMs !== null ? { signal: AbortSignal.timeout(remainingMs) } : {}
3124
3246
  });
3125
3247
  } catch {
3126
3248
  continue;
@@ -6986,10 +7108,10 @@ function buildLoadSkillExecutor(args) {
6986
7108
  metadata: { loadSkill: true, resolved: false }
6987
7109
  };
6988
7110
  }
6989
- const { resolveSkillByName } = await import("./skillDiscovery-COX56OBO.js");
7111
+ const { resolveSkillByName } = await import("./skillDiscovery-CYUCJMAG.js");
6990
7112
  const resolved = resolveSkillByName(args.cwd, name);
6991
7113
  if (!resolved) {
6992
- const { resolveCodingBuiltinSlug, buildCodingSkillContentBySlug } = await import("./codingSkills-BYQI6EPT.js");
7114
+ const { resolveCodingBuiltinSlug, buildCodingSkillContentBySlug } = await import("./codingSkills-FQPCEIWL.js");
6993
7115
  const builtinSlug = resolveCodingBuiltinSlug(name);
6994
7116
  if (builtinSlug) {
6995
7117
  const body = buildCodingSkillContentBySlug(builtinSlug);
@@ -7024,7 +7146,7 @@ ${body}`,
7024
7146
  };
7025
7147
  }
7026
7148
  async function formatUnknownSkillMessage(cwd, requestedName) {
7027
- const { discoverSkills } = await import("./skillDiscovery-COX56OBO.js");
7149
+ const { discoverSkills } = await import("./skillDiscovery-CYUCJMAG.js");
7028
7150
  let available = [];
7029
7151
  try {
7030
7152
  available = discoverSkills(cwd).map((s) => s.name);
@@ -7060,6 +7182,7 @@ export {
7060
7182
  buildAgentRuntimeDialogWritePlan,
7061
7183
  shouldCacheHybridRemoteRecord,
7062
7184
  parseSyncServersEnv,
7185
+ DEFAULT_HYBRID_READ_TIMEOUT_MS,
7063
7186
  createHybridRecordStore,
7064
7187
  isDestructiveShellCommand,
7065
7188
  evaluateShellCommandPolicy,
@@ -2,7 +2,7 @@ import {
2
2
  deleteDbRecord,
3
3
  queryUserRecords,
4
4
  readDbRecord
5
- } from "./chunk-DQLYEGP7.js";
5
+ } from "./chunk-EGVY3GMT.js";
6
6
  import {
7
7
  mergeAndDedupUserData
8
8
  } from "./chunk-KQHGZWSV.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  sanitizeForOutbound
3
- } from "./chunk-T27IEBNQ.js";
3
+ } from "./chunk-2QDDKFG5.js";
4
4
  import {
5
5
  accumulateToolCallDelta,
6
6
  createThinkParserState,
@@ -23,7 +23,7 @@ import {
23
23
  shouldStripReasoningContentForOutbound,
24
24
  toOpenAiCompatibleMessages,
25
25
  toResponsesTools
26
- } from "./chunk-6BYAXNH5.js";
26
+ } from "./chunk-3QOCS5IF.js";
27
27
  import {
28
28
  buildProviderExecutionPlan,
29
29
  canUsePlatformChatProvider,
@@ -33,13 +33,13 @@ import {
33
33
  resolvePlatformAuthToken,
34
34
  resolvePlatformServerUrl,
35
35
  resolveProviderTransportDecision
36
- } from "./chunk-SP3DPVBH.js";
36
+ } from "./chunk-DEIGUGP6.js";
37
37
  import {
38
38
  clipCompactText
39
- } from "./chunk-HR5XDXYM.js";
39
+ } from "./chunk-G5SQVIFZ.js";
40
40
  import {
41
41
  NOLO_CLIENT_VERSION_HEADER
42
- } from "./chunk-WL3UOGYO.js";
42
+ } from "./chunk-G4WSLTQF.js";
43
43
  import {
44
44
  isRecord
45
45
  } from "./chunk-KUG52IAP.js";
@@ -477,7 +477,8 @@ function buildPlatformChatCompletionRequest(args) {
477
477
  },
478
478
  stream: args.stream ?? false,
479
479
  ...args.stream ? getUsageRequestOptions(args.providerConfig.usageProvider ?? args.providerConfig.provider, {
480
- api: usesResponsesApi ? "responses" : "chat-completions"
480
+ api: usesResponsesApi ? "responses" : "chat-completions",
481
+ endpoint: usesResponsesApi ? null : args.providerConfig.endpoint
481
482
  }) : {},
482
483
  ...requestOptions,
483
484
  ...args.tools && args.tools.length > 0 ? {
@@ -1,72 +1,15 @@
1
+ import {
2
+ createSpaceKey
3
+ } from "./chunk-UAD2WT54.js";
1
4
  import {
2
5
  patch,
3
6
  read
4
- } from "./chunk-76UA7376.js";
7
+ } from "./chunk-273FJUYI.js";
5
8
  import {
6
9
  DEVICE_LOCAL_OWNER_ID,
7
10
  isDeviceLocalSpaceBody,
8
11
  selectIdentityUserId
9
- } from "./chunk-HHBXCRJS.js";
10
-
11
- // packages/create/space/spaceKeys.ts
12
- var SEPARATOR = "-";
13
- var SPACE_PREFIX = "space";
14
- var SPACE_PREFIX_WITH_SEPARATOR = `${SPACE_PREFIX}${SEPARATOR}`;
15
- var normalizeSpaceId = (spaceId) => {
16
- if (!spaceId) return spaceId;
17
- return spaceId.startsWith(SPACE_PREFIX_WITH_SEPARATOR) ? spaceId.slice(SPACE_PREFIX_WITH_SEPARATOR.length) : spaceId;
18
- };
19
- var createSpaceKey = {
20
- // 空间基础信息的key
21
- space: (spaceId) => {
22
- return [SPACE_PREFIX, normalizeSpaceId(spaceId)].join(SEPARATOR);
23
- },
24
- // 空间成员的key
25
- member: (userId, spaceId) => {
26
- return [SPACE_PREFIX, "member", userId, normalizeSpaceId(spaceId)].join(
27
- SEPARATOR
28
- );
29
- },
30
- // 查询用户所在的所有空间的范围
31
- memberRange: (userId) => {
32
- return {
33
- start: [SPACE_PREFIX, "member", userId, ""].join(SEPARATOR),
34
- end: [SPACE_PREFIX, "member", userId, "\uFFFF"].join(SEPARATOR)
35
- };
36
- },
37
- /**
38
- * 预留:未来若出现“按用户、按空间、且必须跨设备同步”的空间级偏好,
39
- * 统一使用这个 key family。当前产品主链不要依赖它。
40
- */
41
- setting: (userId, spaceId) => {
42
- return [SPACE_PREFIX, "setting", userId, normalizeSpaceId(spaceId)].join(
43
- SEPARATOR
44
- );
45
- },
46
- /**
47
- * 预留:未来如确实需要批量读取空间级远端偏好,再使用这个范围。
48
- */
49
- settingRange: (userId) => {
50
- return {
51
- start: [SPACE_PREFIX, "setting", userId, ""].join(SEPARATOR),
52
- end: [SPACE_PREFIX, "setting", userId, "\uFFFF"].join(SEPARATOR)
53
- };
54
- },
55
- // 从成员key中提取空间key
56
- // 成员 key 格式: space-member-{userId}-{spaceId}
57
- // userId 是单段(无连字符),spaceId 是 ULID(无连字符)
58
- spaceFromMember: (memberKey) => {
59
- const parts = memberKey.split(SEPARATOR);
60
- if (parts.length < 4) return "";
61
- const spaceId = parts[parts.length - 1];
62
- return [SPACE_PREFIX, spaceId].join(SEPARATOR);
63
- },
64
- // 从成员key中提取空间ID
65
- spaceIdFromMember: (memberKey) => {
66
- const parts = memberKey.split(SEPARATOR);
67
- return parts.length >= 4 ? parts[parts.length - 1] : "";
68
- }
69
- };
12
+ } from "./chunk-XOJRZUPF.js";
70
13
 
71
14
  // packages/create/space/utils/permissions.ts
72
15
  var checkSpaceMembership = (spaceData, userId) => {
@@ -163,8 +106,6 @@ var addContentAction = async (input, thunkAPI) => {
163
106
  };
164
107
 
165
108
  export {
166
- normalizeSpaceId,
167
- createSpaceKey,
168
109
  checkSpaceMembership,
169
110
  localSpaceAuthorityPatchStamp,
170
111
  UNCATEGORIZED_ID,