nolo-cli 0.82.0-alpha.5 → 0.82.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 (161) hide show
  1. package/README.md +2 -2
  2. package/{_executeModel-225YRU52.js → _executeModel-FHVQOYWX.js} +48 -48
  3. package/{action-D22U6CTH.js → action-YVYQEAAV.js} +11 -11
  4. package/{addContentAction-XAPUTGL4.js → addContentAction-O7R66HEX.js} +9 -9
  5. package/{addDialogAgentAction-M7VLLBZM.js → addDialogAgentAction-74OA7KYP.js} +8 -8
  6. package/{agentDeleteCommand-ZJNQGVR2.js → agentDeleteCommand-4427YKQF.js} +31 -29
  7. package/{agentEmailCommands-VLVWFWX2.js → agentEmailCommands-LYDIAUOP.js} +67 -63
  8. package/{agentGrantCommands-R3VQEZJR.js → agentGrantCommands-M3XFO6EN.js} +2 -2
  9. package/{agentListCommands-GHQGLAUU.js → agentListCommands-O4AEMQVV.js} +40 -32
  10. package/{agentMachineCommands-QDXYENZJ.js → agentMachineCommands-F6IHXMPD.js} +31 -29
  11. package/{agentProviderCommands-65ZC2WB4.js → agentProviderCommands-GNPTL5XR.js} +87 -0
  12. package/{agentPullCommand-N7L2CT7L.js → agentPullCommand-O5MPVJ5E.js} +3 -3
  13. package/agentRecordCommands-BDLFOU7E.js +128 -0
  14. package/{agentRunCommand-YSCD65HH.js → agentRunCommand-HSSYFGMC.js} +65 -61
  15. package/{agentRunControl-T44MESII.js → agentRunControl-WCTKX5VL.js} +2 -2
  16. package/{agentRuntimeLocal-ZOHB7OOO.js → agentRuntimeLocal-IW3IM5P6.js} +27 -25
  17. package/{agentSlice-O2SBU5TK.js → agentSlice-G54NT6PX.js} +10 -10
  18. package/{appDeleteCommands-PRT6K5N2.js → appDeleteCommands-ZXLXNRHF.js} +31 -29
  19. package/{appDeployCommands-63ZONFAN.js → appDeployCommands-PWB4YERK.js} +31 -29
  20. package/{appDeployStatusCommands-AFAYCVR3.js → appDeployStatusCommands-2EZKZP7Y.js} +31 -29
  21. package/{appGetCommands-TNZDZE36.js → appGetCommands-JNUKOWHO.js} +31 -29
  22. package/{appListCommands-IA4SPG2X.js → appListCommands-6X3H67SS.js} +31 -29
  23. package/{authCommand-EVGFLAHO.js → authCommand-F4EFRRX6.js} +164 -24
  24. package/{authCommands-ILTBI6JV.js → authCommands-RGOGCPP6.js} +4 -5
  25. package/builtinSkillRegistry-FUAVTRVZ.js +33 -0
  26. package/{chatQueueReduxAdapter-4SM3DAWX.js → chatQueueReduxAdapter-VJXYSZ2D.js} +24 -24
  27. package/{chromeCommands-VOIRNJBL.js → chromeCommands-FZYAU75D.js} +1 -1
  28. package/{chromeOpsCommands-M7DPCX2T.js → chromeOpsCommands-62P2Q2YB.js} +31 -1
  29. package/{chunk-C3FZR5EC.js → chunk-2F7RJC6L.js} +1 -1
  30. package/{chunk-QC5LGHYP.js → chunk-2YMRWISD.js} +10 -5
  31. package/{chunk-HQUORJTM.js → chunk-3BMYXEUW.js} +1 -1
  32. package/{chunk-3QPYFHAH.js → chunk-3DII57IT.js} +1 -1
  33. package/{chunk-NTW5GWDM.js → chunk-3VNWWVKB.js} +2 -0
  34. package/{chunk-DWUCB2A3.js → chunk-42V6BK2E.js} +1 -1
  35. package/{chunk-KIS76A2P.js → chunk-4EZHSKTB.js} +38 -4
  36. package/{chunk-GBPZKFYK.js → chunk-53HEEOTT.js} +4 -4
  37. package/{chunk-5XTOKQLW.js → chunk-5UTFL4QJ.js} +6 -2
  38. package/chunk-5ZUL4CUO.js +10 -0
  39. package/{chunk-E6RGHPDR.js → chunk-6D6VBVEW.js} +4 -6
  40. package/{chunk-CMH2SYHX.js → chunk-6OZ36FXI.js} +2 -2
  41. package/{chunk-NRALD3CC.js → chunk-76WEAXJB.js} +49 -10
  42. package/{chunk-3W2JJOH3.js → chunk-7REEVK4I.js} +3 -3
  43. package/{chunk-BYEJ7K2Z.js → chunk-7S4YWN7P.js} +1 -1
  44. package/{chunk-SREASRV5.js → chunk-ABQYVJBJ.js} +1 -1
  45. package/chunk-ACTMNVHM.js +93 -0
  46. package/{chunk-XWNRAIUL.js → chunk-AFUORTY4.js} +6 -16
  47. package/{chunk-E36HZARC.js → chunk-ASQYTZTR.js} +46 -9
  48. package/{chunk-73IOJLK2.js → chunk-AVV3M6CX.js} +10 -10
  49. package/{chunk-WL2RKIBF.js → chunk-BLJWCTRL.js} +1 -1
  50. package/chunk-BNGW5ASC.js +344 -0
  51. package/{chunk-SZLVDREM.js → chunk-BP4XNZRM.js} +3 -3
  52. package/{chunk-2KDR4CWE.js → chunk-BYMV6QZG.js} +24 -1
  53. package/{chunk-MYU3MJCF.js → chunk-DHDMC6FO.js} +175 -7
  54. package/{chunk-FP27MNSX.js → chunk-DL2LVM5E.js} +3 -3
  55. package/{chunk-EXMHJN7C.js → chunk-EYAQT56M.js} +4 -3
  56. package/{chunk-5LSS6MFZ.js → chunk-F5OE5KSJ.js} +13 -15
  57. package/{chunk-CJCJF5XB.js → chunk-FDTR4QJ6.js} +4 -2
  58. package/{chunk-NJ6WLAPS.js → chunk-FEEHCOBD.js} +1 -1
  59. package/{chunk-YSKEOTPH.js → chunk-GGMVRZRO.js} +155 -795
  60. package/{chunk-PYXL2CJL.js → chunk-GPCZ7UXG.js} +1 -1
  61. package/{chunk-K7AG465Q.js → chunk-GQBOR3G6.js} +4 -2
  62. package/{chunk-YFADVSZE.js → chunk-H62HCIUP.js} +6 -6
  63. package/{chunk-PZM3EENV.js → chunk-HJUYAD4A.js} +1 -1
  64. package/{chunk-A3NNC2LA.js → chunk-HOBJGHLD.js} +1235 -59
  65. package/{chunk-3JQ2NRYU.js → chunk-HVURBGF3.js} +4 -4
  66. package/{chunk-6SD5OPQ4.js → chunk-IIBAPOTQ.js} +11 -173
  67. package/{chunk-ZVN6I33J.js → chunk-IIVGDG4I.js} +6 -5
  68. package/{chunk-UDQWGU7F.js → chunk-J4MOO56S.js} +1 -1
  69. package/{chunk-KC5FAHVS.js → chunk-JEDZAO7L.js} +1 -1
  70. package/{chunk-6XIE5ZGI.js → chunk-JPGCXHNM.js} +1 -1
  71. package/chunk-JRQFUXY7.js +1625 -0
  72. package/chunk-KQ4ONNQD.js +677 -0
  73. package/{chunk-CPSZJBLK.js → chunk-L7I247DF.js} +105 -26
  74. package/{chunk-RXX4GDIH.js → chunk-LS2ZANRJ.js} +1 -1
  75. package/{chunk-BJIRLHJR.js → chunk-M2EJHDJP.js} +4 -0
  76. package/{chunk-EVBFYPDC.js → chunk-MC4XLIJ7.js} +6 -2
  77. package/{chunk-DSRXPQWA.js → chunk-NEDZDG3M.js} +43 -43
  78. package/{chunk-UJ63UXGE.js → chunk-OIVSQH2O.js} +1006 -801
  79. package/{chunk-AETZ7AD6.js → chunk-Q554LLSI.js} +1 -1
  80. package/chunk-Q5FJJ6XI.js +103 -0
  81. package/{chunk-AJHEFRGJ.js → chunk-Q67DOFOO.js} +214 -5
  82. package/{chunk-UZ6XXCVR.js → chunk-QDSINZM3.js} +15 -2
  83. package/{chunk-D6XYLSOS.js → chunk-QIAVMDHY.js} +1 -1
  84. package/{chunk-YWG6EMH3.js → chunk-RG6JBBX5.js} +10 -6
  85. package/{chunk-YXLXHIT2.js → chunk-RTUYRRBM.js} +6 -6
  86. package/{chunk-HHLTFENG.js → chunk-SDTTBMBU.js} +907 -317
  87. package/{chunk-QCZX4FTW.js → chunk-SH43IESU.js} +173 -15
  88. package/{chunk-LSZXYE64.js → chunk-SL4QHSPQ.js} +756 -80
  89. package/{chunk-FNGAF7C4.js → chunk-SNPMM7H3.js} +137 -12
  90. package/{chunk-EM6MPSEI.js → chunk-SPUTJ4DW.js} +52 -30
  91. package/{chunk-SO7B7NW3.js → chunk-STHU4Y5X.js} +413 -62
  92. package/{chunk-SPAQ4PVV.js → chunk-SV5IJK6K.js} +1 -1
  93. package/{chunk-KVDUCO4Q.js → chunk-TDRTS7QW.js} +16 -12
  94. package/{chunk-BJCWNHVU.js → chunk-TOP2VXOR.js} +2 -2
  95. package/{chunk-4EJ5QYB5.js → chunk-UKZDAFYT.js} +1 -1
  96. package/{chunk-PGSKWZCB.js → chunk-UZGQNTVW.js} +1 -1
  97. package/{chunk-ZZCJUXUI.js → chunk-V4MJDUSR.js} +2 -2
  98. package/{chunk-JYYZCK2Z.js → chunk-V7E4PXQD.js} +1 -1
  99. package/{chunk-OZX2IPKM.js → chunk-VLTIYV3X.js} +1 -1
  100. package/{chunk-NHRQCXIQ.js → chunk-VMFTFOWF.js} +13 -3
  101. package/{chunk-4UW2LDVA.js → chunk-VQW3EKYS.js} +15 -15
  102. package/{chunk-HH65VA5U.js → chunk-WGR3J4Q6.js} +101 -4
  103. package/{chunk-5J7W2VWW.js → chunk-WV42OMV7.js} +6 -265
  104. package/{chunk-Q46HQOW3.js → chunk-XTAZCQUT.js} +7 -7
  105. package/{chunk-DUJWWUGV.js → chunk-YQTQQX2H.js} +1 -1
  106. package/{chunk-BOYUESO7.js → chunk-Z77CRGTW.js} +1 -1
  107. package/{contentThunks-ENAVF2YU.js → contentThunks-D6QQKIPF.js} +25 -25
  108. package/{cooldownCommands-BSCH2W7P.js → cooldownCommands-REAWYVTY.js} +2 -2
  109. package/{createAgentAutomationAction-CH6BYC7K.js → createAgentAutomationAction-UIPWW4DG.js} +25 -25
  110. package/{createDialogAction-23UDOXSO.js → createDialogAction-573VVP3X.js} +28 -28
  111. package/{createPageAction-J6AEMLHK.js → createPageAction-LRFSS6TD.js} +26 -26
  112. package/{dbSlice-GKGGFNOB.js → dbSlice-XVWBAGYN.js} +8 -8
  113. package/{deleteFile-LWSR674W.js → deleteFile-YG6QMJLU.js} +3 -3
  114. package/{dialogCommands-BJJGCCQR.js → dialogCommands-KFK2FF5B.js} +35 -31
  115. package/{dialogSlice-F7RD6PUY.js → dialogSlice-EXLC5XTD.js} +24 -24
  116. package/{docCreateCommands-53GB2FU3.js → docCreateCommands-V777WOZ7.js} +32 -30
  117. package/{docDeleteCommands-TAW5JEBU.js → docDeleteCommands-5KHT7Z5Q.js} +33 -31
  118. package/{docReadCommands-F5N7N5E3.js → docReadCommands-BLROGWP3.js} +32 -30
  119. package/{docStore-WX4YBGXC.js → docStore-DZNGJXX7.js} +9 -9
  120. package/{docUpdateCommands-YQ7TRT35.js → docUpdateCommands-QXOZHQ5H.js} +32 -30
  121. package/{fetchMessages-DRABNDPZ.js → fetchMessages-EIU7UFFK.js} +3 -4
  122. package/{getPricing-HRMSOF3E.js → getPricing-LUSEABA6.js} +4 -4
  123. package/{handleSendMessageAction-CW4LULIR.js → handleSendMessageAction-OROTZBPO.js} +24 -24
  124. package/index.js +102 -85
  125. package/{localDialogRead-PUQKFI73.js → localDialogRead-BTFJ4V2I.js} +2 -2
  126. package/{localRuntimeDb-P37ZTX55.js → localRuntimeDb-SYQGUF4U.js} +1 -1
  127. package/{machineCommands-FIYWY5EU.js → machineCommands-IJWERHRH.js} +64 -60
  128. package/{machineWsRunDispatch-KQ4OFFNR.js → machineWsRunDispatch-XQ36M4L7.js} +62 -58
  129. package/{memberThunks-KATHH3F4.js → memberThunks-QGFLFVCI.js} +9 -9
  130. package/{models-GS72DVJS.js → models-T3SG6MJ5.js} +2 -2
  131. package/{offlineMarxistsAgentCommand-GEH6SNNA.js → offlineMarxistsAgentCommand-HGXZV4XJ.js} +1 -1
  132. package/package.json +1 -1
  133. package/providerPresetApply-FG6NZ57W.js +214 -0
  134. package/providerRegistry-757OWH3O.js +31 -0
  135. package/{read-LC6HVYBN.js → read-COE3ZYR6.js} +5 -4
  136. package/{readDocTool-N3ERJHHF.js → readDocTool-5USN4A6V.js} +1 -1
  137. package/{readlineWorkspace-QYI6BRNA.js → readlineWorkspace-EB3362L3.js} +144 -108
  138. package/{removeDialogAgentAction-F5GPTALR.js → removeDialogAgentAction-IX3MN2ZO.js} +11 -11
  139. package/{runAgentClientLoop-GZ5VUGAW.js → runAgentClientLoop-3MR2NPWR.js} +47 -47
  140. package/{runtimeDoctorCommands-CROTMULY.js → runtimeDoctorCommands-X6WDBEQX.js} +2 -2
  141. package/{setDialogExtraReferencesAction-AY4ZCF3A.js → setDialogExtraReferencesAction-X4HCPNZL.js} +9 -9
  142. package/{setPrimaryDialogAgentAction-HPMG7V3R.js → setPrimaryDialogAgentAction-4GMIQLOD.js} +11 -11
  143. package/{settingSlice-OEJA4NQO.js → settingSlice-ZQZVUPKK.js} +10 -10
  144. package/{spaceCommands-IYMIXCMC.js → spaceCommands-TIDVUPDV.js} +30 -28
  145. package/{streamAgentChatTurn-EAXIUJTK.js → streamAgentChatTurn-CLP2JWCQ.js} +59 -58
  146. package/{switchDialogAgentAction-HMDZTZ4I.js → switchDialogAgentAction-N52LRPA3.js} +8 -8
  147. package/{tableCommands-SUNTHAYX.js → tableCommands-O6NWHFKV.js} +1 -1
  148. package/{toolApiClient-VGYUB4P5.js → toolApiClient-QVJ6HDNN.js} +2 -2
  149. package/{tools-QWQOW6J4.js → tools-OXEEBABR.js} +43 -43
  150. package/tuiSummaryLlmCaller-VJY3YD2Q.js +127 -0
  151. package/{updateCommands-Y363MC3L.js → updateCommands-2M74UL7P.js} +2 -2
  152. package/{updateDialogTitleAction-2HCE2M7S.js → updateDialogTitleAction-4YWKF2OE.js} +45 -28
  153. package/agentRecordCommands-AQFYM5HS.js +0 -124
  154. package/chunk-3IT2PFHL.js +0 -611
  155. package/chunk-I42VC5KR.js +0 -15
  156. package/chunk-NG4UT4K4.js +0 -79
  157. package/codingSkills-E6KSDNSJ.js +0 -48
  158. package/tuiSummaryLlmCaller-3Z24VUWM.js +0 -116
  159. package/{chunk-3RAG2NAD.js → chunk-UKWGR5SS.js} +3 -3
  160. package/{db-VQSAOWAO.js → db-WK5MDZVN.js} +1 -1
  161. package/{localRuntimeAuthority-R5UBODT3.js → localRuntimeAuthority-6IR6BBXE.js} +3 -3
@@ -9,7 +9,7 @@ import {
9
9
  resolveRawAgentInput,
10
10
  resolveServerUrl,
11
11
  writeUsage
12
- } from "./chunk-JYYZCK2Z.js";
12
+ } from "./chunk-V7E4PXQD.js";
13
13
  import {
14
14
  agentRunCardLabels,
15
15
  createCliLocalRuntimeAdapter,
@@ -27,7 +27,7 @@ import {
27
27
  resolveLocalUserId,
28
28
  t,
29
29
  toolLabel
30
- } from "./chunk-LSZXYE64.js";
30
+ } from "./chunk-SL4QHSPQ.js";
31
31
  import {
32
32
  createRunActivityTracker,
33
33
  popSingleQueueMessage,
@@ -35,22 +35,23 @@ import {
35
35
  resolveRunQueuePath,
36
36
  settleRunTerminalAuthoritatively,
37
37
  spawnLocalBackgroundRun
38
- } from "./chunk-HH65VA5U.js";
38
+ } from "./chunk-WGR3J4Q6.js";
39
39
  import {
40
+ clearCredentialAvailability,
40
41
  readCredentialEntry,
41
42
  recordCredentialProbe,
42
43
  resolveCredentialKeyWithFallback
43
- } from "./chunk-DWUCB2A3.js";
44
+ } from "./chunk-42V6BK2E.js";
44
45
  import {
45
46
  getReadableCliDb
46
- } from "./chunk-RXX4GDIH.js";
47
+ } from "./chunk-LS2ZANRJ.js";
47
48
  import {
48
49
  readDbRecord,
49
50
  resolveAgentRecordFromHybridStore
50
- } from "./chunk-NRALD3CC.js";
51
+ } from "./chunk-76WEAXJB.js";
51
52
  import {
52
53
  isLocalCliAgentKey
53
- } from "./chunk-SPAQ4PVV.js";
54
+ } from "./chunk-SV5IJK6K.js";
54
55
  import {
55
56
  CliProviderQuotaError
56
57
  } from "./chunk-MP64VFGD.js";
@@ -63,10 +64,10 @@ import {
63
64
  } from "./chunk-LTRXGFMS.js";
64
65
  import {
65
66
  formatAgentListCard
66
- } from "./chunk-YSKEOTPH.js";
67
+ } from "./chunk-GGMVRZRO.js";
67
68
  import {
68
69
  isTransientFetchError
69
- } from "./chunk-5XTOKQLW.js";
70
+ } from "./chunk-5UTFL4QJ.js";
70
71
  import {
71
72
  isGatewayHttpStatus
72
73
  } from "./chunk-NF64D32W.js";
@@ -78,17 +79,17 @@ import {
78
79
  formatStatusRunCard,
79
80
  formatStopRunCard,
80
81
  isAgentRunTerminalStatus
81
- } from "./chunk-NTW5GWDM.js";
82
+ } from "./chunk-3VNWWVKB.js";
82
83
  import {
83
84
  buildMemorySubjectsForAgent,
84
85
  chooseMemoryOwners,
85
86
  loadMemoryCandidatesFromDb,
86
87
  resolveAgentMemoryPolicy
87
- } from "./chunk-6SD5OPQ4.js";
88
+ } from "./chunk-IIBAPOTQ.js";
88
89
  import {
89
90
  API_REPORTED_COST_MULTIPLIER,
90
91
  parseUiAskChoiceContent
91
- } from "./chunk-SO7B7NW3.js";
92
+ } from "./chunk-STHU4Y5X.js";
92
93
  import {
93
94
  isOAuthApiKeyRef
94
95
  } from "./chunk-YYLHWIW6.js";
@@ -99,50 +100,51 @@ import {
99
100
  } from "./chunk-TRV2MIDW.js";
100
101
  import {
101
102
  getDefaultCliLocalRuntimeDb
102
- } from "./chunk-C3FZR5EC.js";
103
+ } from "./chunk-2F7RJC6L.js";
103
104
  import {
104
105
  buildSkillDiscoveryContextLayer
105
106
  } from "./chunk-E4MARS3Q.js";
106
107
  import {
107
108
  parseExternalSkillMarkdown,
108
109
  parseSkillDocProtocol
109
- } from "./chunk-AETZ7AD6.js";
110
+ } from "./chunk-Q554LLSI.js";
110
111
  import {
111
112
  LOCAL_AGENT_CONFIG_MISSING_CODE,
112
113
  LOCAL_TURN_ABORTED_CODE,
113
114
  readActionGate
114
- } from "./chunk-HHLTFENG.js";
115
+ } from "./chunk-SDTTBMBU.js";
115
116
  import {
116
117
  resolveAgentRuntimeConfigFromRecord
117
- } from "./chunk-KIS76A2P.js";
118
+ } from "./chunk-4EZHSKTB.js";
118
119
  import {
119
120
  createThinkParserState,
120
121
  flushThinkParser,
121
122
  processThinkChunk
122
123
  } from "./chunk-N7J63Q6C.js";
123
124
  import {
125
+ QUOTA_ERROR_PATTERNS,
124
126
  isQuotaExhaustedError,
125
127
  isQuotaLimited403Body,
126
128
  mergeAvailabilityDeadline,
127
129
  resolveCooldownGate
128
- } from "./chunk-CJCJF5XB.js";
130
+ } from "./chunk-FDTR4QJ6.js";
129
131
  import {
130
132
  isAntigravityOAuthAgent
131
- } from "./chunk-PGSKWZCB.js";
133
+ } from "./chunk-UZGQNTVW.js";
132
134
  import {
133
135
  resolveClientVersion
134
- } from "./chunk-CMH2SYHX.js";
136
+ } from "./chunk-6OZ36FXI.js";
135
137
  import {
136
138
  DEFAULT_CONTEXT_WINDOW,
137
139
  getModelContextWindow,
138
140
  normalizeUsage
139
- } from "./chunk-DSRXPQWA.js";
141
+ } from "./chunk-NEDZDG3M.js";
140
142
  import {
141
143
  clipCompactText
142
- } from "./chunk-E36HZARC.js";
144
+ } from "./chunk-ASQYTZTR.js";
143
145
  import {
144
146
  findModelConfig
145
- } from "./chunk-UJ63UXGE.js";
147
+ } from "./chunk-OIVSQH2O.js";
146
148
  import {
147
149
  compactWhitespace
148
150
  } from "./chunk-DWLEOOGR.js";
@@ -167,13 +169,14 @@ import {
167
169
  CLIENT_VERSION_TOO_OLD_CODE,
168
170
  NOLO_CLIENT_VERSION_HEADER,
169
171
  buildClientVersionUpgradeMessage
170
- } from "./chunk-AJHEFRGJ.js";
172
+ } from "./chunk-Q67DOFOO.js";
171
173
  import {
172
174
  parsePositiveFiniteNumberOrFallback
173
175
  } from "./chunk-Y5GCAMGP.js";
174
176
  import {
175
- createMemoryKey
176
- } from "./chunk-NHRQCXIQ.js";
177
+ createMemoryKey,
178
+ ulid
179
+ } from "./chunk-VMFTFOWF.js";
177
180
  import {
178
181
  asTrimmedLowercaseString
179
182
  } from "./chunk-QSJ3HFEF.js";
@@ -181,10 +184,13 @@ import {
181
184
  BUILTIN_NOLO_AGENT_KEY,
182
185
  BUILTIN_NOLO_AGENT_NAME,
183
186
  builtinAgentCatalogEntryById
184
- } from "./chunk-5J7W2VWW.js";
187
+ } from "./chunk-BNGW5ASC.js";
185
188
  import {
186
189
  parsePublicAgentId
187
- } from "./chunk-BJIRLHJR.js";
190
+ } from "./chunk-M2EJHDJP.js";
191
+ import {
192
+ isLevelNotFoundError
193
+ } from "./chunk-OW765XBU.js";
188
194
  import {
189
195
  asTrimmedString
190
196
  } from "./chunk-3EUW3WEO.js";
@@ -9815,6 +9821,14 @@ function formatCompactionSummaryLine(event) {
9815
9821
  return `${STYLE.dim}\u81EA\u52A8\u4E0A\u4E0B\u6587\u538B\u7F29\u5931\u8D25${reason}\uFF0C\u672C\u8F6E\u4EE5\u672A\u538B\u7F29\u4E0A\u4E0B\u6587\u7EE7\u7EED\u3002\u82E5\u53CD\u590D\u51FA\u73B0\u53EF\u624B\u52A8 /compact\u3002${STYLE.reset}
9816
9822
  `;
9817
9823
  }
9824
+ if (event.skipped) {
9825
+ if (event.skipReason === "adapter-missing-summary-methods" || event.skipReason === "load-summary-failed") {
9826
+ return `${STYLE.dim}\u81EA\u52A8\u4E0A\u4E0B\u6587\u538B\u7F29\u4E0D\u53EF\u7528\uFF08${event.skipReason}\uFF09\uFF0C\u672C\u8F6E\u4E0D\u538B\u7F29\u3002${STYLE.reset}
9827
+ `;
9828
+ }
9829
+ return "";
9830
+ }
9831
+ if (!event.summaryGenerated) return "";
9818
9832
  let detail = "\u751F\u6210\u5386\u53F2\u6458\u8981";
9819
9833
  const saved = typeof event.savedTokens === "number" ? event.savedTokens : void 0;
9820
9834
  let line = `\u5DF2\u538B\u7F29\u4E0A\u4E0B\u6587\uFF1A${detail}`;
@@ -9984,9 +9998,15 @@ ${options.agentName}${IDENTITY_LABEL_SEPARATOR}`);
9984
9998
  markThinkingDelta(chunk);
9985
9999
  },
9986
10000
  handleToolEvent,
9987
- /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。 */
10001
+ /** 记录一条 compaction 观测事件(TUI 在 turn 结束时渲染一行 dim 摘要)。
10002
+ * 一轮内可能来多条(轮开始 + 每个 round),按显著性保留最高者:
10003
+ * 失败 > 新生成摘要 > 投影复用 > 跳过,避免末尾的例行跳过事件
10004
+ * 覆盖掉中途真正发生的压缩。 */
9988
10005
  recordCompaction(event) {
9989
- compactionEvent = event;
10006
+ const significance = (e) => e.failed ? 4 : e.summaryGenerated ? 3 : e.compressed ? 2 : 1;
10007
+ if (!compactionEvent || significance(event) >= significance(compactionEvent)) {
10008
+ compactionEvent = event;
10009
+ }
9990
10010
  },
9991
10011
  showWorking(label) {
9992
10012
  const activeLabel = label ?? workingLabel;
@@ -10411,9 +10431,9 @@ function findCollapsedPasteSpanAt(buffer, pos, opts = {}) {
10411
10431
  }
10412
10432
 
10413
10433
  // packages/cli/client/agentRun.ts
10414
- import { ulid } from "ulid";
10434
+ import { ulid as ulid2 } from "ulid";
10415
10435
  async function loadRunLocalAgentTurn() {
10416
- const { runLocalAgentTurn } = await import("./agentRuntimeLocal-ZOHB7OOO.js");
10436
+ const { runLocalAgentTurn } = await import("./agentRuntimeLocal-IW3IM5P6.js");
10417
10437
  return runLocalAgentTurn;
10418
10438
  }
10419
10439
  var stripDebugNoise = (s) => s.replace(/\s*raw="[\s\S]*"/g, "").replace(/\s*raw=\S+/g, "").replace(/\s*headers=\[[^\]]*\]/g, "").replace(/\s*headers=\S+/g, "").trim();
@@ -10676,27 +10696,62 @@ function isMissingLocalAgentConfigError(error, agentRef) {
10676
10696
  }
10677
10697
  var PROVIDER_HTTP_FAILED_RE = /(.+?) provider failed:\s*HTTP\s+(\d+)\b/i;
10678
10698
  var PLATFORM_TRANSPORT_RE = /\bplatform provider failed\b/i;
10699
+ var EXTRA_RATE_LIMIT_TEXT_RE = /\brate[\s_-]?limit(?:ed|ing|s)?\b|\bresource[_\s-]?exhausted\b|\bmax_concurrent_reached\b/i;
10700
+ function looksLikeRateLimitedText(message) {
10701
+ return EXTRA_RATE_LIMIT_TEXT_RE.test(message) || QUOTA_ERROR_PATTERNS.some((pattern) => pattern.test(message));
10702
+ }
10703
+ var AUTH_TEXT_SIGNAL_RE = /\b401\b|unauthori[sz]ed|invalid[_\s-]?(?:api[_\s-]?key|token|credential)s?|(?:api[_\s-]?key|token|credential)s?[_\s-](?:invalid|expired|rejected|missing|not[_\s-]?found)|authentication[_\s-]?(?:error|failed|required)/i;
10704
+ var QUOTA_EXHAUSTED_EXTRA_RE = /insufficient[_\s-]?(?:quota|balance|credits?)|余额不足|额度已?用尽/i;
10705
+ function looksLikeQuotaExhaustedText(message) {
10706
+ return isQuotaLimited403Body(message) || QUOTA_EXHAUSTED_EXTRA_RE.test(message);
10707
+ }
10708
+ var BARE_UPSTREAM_5XX_RE = /\bHTTP[:\s]+(5\d\d)\b|\bstatus[:\s=]+(5\d\d)\b|\breturned error\s+(5\d\d)\b/i;
10679
10709
  function classifyLocalRunError(message) {
10680
10710
  const m = message.match(PROVIDER_HTTP_FAILED_RE);
10681
- if (!m) return { kind: "generic" };
10682
- const status = Number(m[2]);
10683
- const transport = PLATFORM_TRANSPORT_RE.test(message) ? "platform" : "local";
10684
- if (status === 401) {
10685
- return { kind: "auth", transport, status };
10686
- }
10687
- if (status === 403) {
10688
- return isQuotaLimited403Body(message) ? { kind: "rate-limit", transport, status } : { kind: "auth", transport, status };
10689
- }
10690
- if (status === 400 || status === 422) {
10691
- return { kind: "rejected-payload", transport, status };
10711
+ if (m) {
10712
+ const status = Number(m[2]);
10713
+ const transport2 = PLATFORM_TRANSPORT_RE.test(message) ? "platform" : "local";
10714
+ const quotaExhausted = looksLikeQuotaExhaustedText(message);
10715
+ if (status === 401) {
10716
+ return { kind: "auth", transport: transport2, status };
10717
+ }
10718
+ if (status === 403) {
10719
+ return quotaExhausted ? { kind: "rate-limit", transport: transport2, status, quotaExhausted: true } : { kind: "auth", transport: transport2, status };
10720
+ }
10721
+ if (status === 400 || status === 422) {
10722
+ return { kind: "rejected-payload", transport: transport2, status };
10723
+ }
10724
+ if (status === 429) {
10725
+ return {
10726
+ kind: "rate-limit",
10727
+ transport: transport2,
10728
+ status,
10729
+ ...quotaExhausted ? { quotaExhausted: true } : {}
10730
+ };
10731
+ }
10732
+ if (status >= 500 && status <= 599) {
10733
+ return { kind: "transient", transport: transport2, status };
10734
+ }
10735
+ return { kind: "upstream", transport: transport2, status };
10692
10736
  }
10693
- if (status === 429) {
10694
- return { kind: "rate-limit", transport, status };
10737
+ const transport = PLATFORM_TRANSPORT_RE.test(message) ? "platform" : "local";
10738
+ if (AUTH_TEXT_SIGNAL_RE.test(message)) return { kind: "generic" };
10739
+ if (looksLikeRateLimitedText(message)) {
10740
+ const quotaExhausted = looksLikeQuotaExhaustedText(message);
10741
+ return {
10742
+ kind: "rate-limit",
10743
+ transport,
10744
+ status: 429,
10745
+ statusInferred: true,
10746
+ ...quotaExhausted ? { quotaExhausted: true } : {}
10747
+ };
10695
10748
  }
10696
- if (status >= 500 && status <= 599) {
10749
+ const bare5xx = message.match(BARE_UPSTREAM_5XX_RE);
10750
+ if (bare5xx) {
10751
+ const status = Number(bare5xx[1] ?? bare5xx[2] ?? bare5xx[3]);
10697
10752
  return { kind: "transient", transport, status };
10698
10753
  }
10699
- return { kind: "upstream", transport, status };
10754
+ return { kind: "generic" };
10700
10755
  }
10701
10756
  var HISTORY_REPLAY_REJECTION_RE = /invalid_request_error|invalid\s+tool\s+call\s+arguments?/i;
10702
10757
  var RUN_UNAVAILABLE_PREFIX = "[nolo] auto runtime: local run unavailable";
@@ -10717,9 +10772,18 @@ function buildRejectedPayloadFailure(ctx) {
10717
10772
  return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, the provider rejected the request body \u2014 this is NOT a local credential/config issue). Detail: ${ctx.message}${cause} ${NO_FALLBACK} Use --server to run on the server explicitly, or start a fresh dialog.
10718
10773
  `;
10719
10774
  }
10775
+ var RATE_LIMIT_RESET_HINT_RE = /retry[-_\s]?after\s*[:=]?\s*\d[\w:-]*|resets?\s+(?:in|at)\s+\d[\w:-]*(?:[ T]\d[\w:-]*)?/i;
10776
+ function extractRateLimitResetHint(message) {
10777
+ const match = message.match(RATE_LIMIT_RESET_HINT_RE);
10778
+ return match ? match[0].trim() : void 0;
10779
+ }
10720
10780
  function buildRateLimitFailure(ctx) {
10721
10781
  const cooldownNote = ctx.cooldownUntil ? ` \u5DF2\u6807\u8BB0\u51B7\u5374\u81F3 ${ctx.cooldownUntil}\uFF0C\u5230\u671F\u524D\u6D3E\u53D1\u4F1A\u88AB\u51B7\u5374\u95E8\u63A7\u62E6\u622A\uFF08\u5230\u671F\u81EA\u52A8 probe \u6062\u590D\uFF09\u3002` : "";
10722
- return `${RUN_UNAVAILABLE_PREFIX} (${ctx.where} returned HTTP ${ctx.status}, rate limited). Detail: ${ctx.message} ${NO_FALLBACK} Retry shortly, ${SERVER_FALLBACK_HINT}.${cooldownNote}
10782
+ const headline = ctx.statusInferred ? `${ctx.where} hit an upstream rate-limit/quota error` : `${ctx.where} returned HTTP ${ctx.status}, rate limited`;
10783
+ const cause = ctx.quotaExhausted ? "The upstream quota/balance for this agent is exhausted \u2014 NOT a local credential/config issue" : "This agent is being throttled by the upstream provider \u2014 NOT a local credential/config issue";
10784
+ const reset = extractRateLimitResetHint(ctx.message);
10785
+ const advice = ctx.quotaExhausted ? `Retry after the upstream quota resets${reset ? ` (${reset})` : ""}` : `Retry shortly${reset ? ` (${reset})` : ""}`;
10786
+ return `${RUN_UNAVAILABLE_PREFIX} (${headline}). Detail: ${ctx.message} ${NO_FALLBACK} ${cause}. ${advice}, switch to another agent (\`nolo agent list\`), ${SERVER_FALLBACK_HINT}${cooldownNote}
10723
10787
  `;
10724
10788
  }
10725
10789
  function buildTransientFailure(ctx) {
@@ -10814,6 +10878,8 @@ function describeLocalRunFailure(message, rawError) {
10814
10878
  message,
10815
10879
  where: cls.transport === "platform" ? "server chat proxy" : "local provider",
10816
10880
  status: cls.status,
10881
+ ...cls.statusInferred ? { statusInferred: true } : {},
10882
+ ...cls.quotaExhausted ? { quotaExhausted: true } : {},
10817
10883
  ...cooldownUntil ? { cooldownUntil } : {}
10818
10884
  };
10819
10885
  return FAILURE_BUILDERS[cls.kind](ctx);
@@ -11078,8 +11144,8 @@ async function runLocalAgentTurnForCli(options, settings) {
11078
11144
  ...options.parentWakeOnTerminal ? { parentWakeOnTerminal: true } : {},
11079
11145
  ...options.parentDialogId ? { parentThreadId: options.parentDialogId } : {}
11080
11146
  } : void 0;
11081
- const currentDialogId = options.continueDialogId ?? ulid();
11082
- const turnId = `turn-${ulid()}`;
11147
+ const currentDialogId = options.continueDialogId ?? ulid2();
11148
+ const turnId = `turn-${ulid2()}`;
11083
11149
  const runtimeContextWithOwnership = {
11084
11150
  ...runtimeContext ?? {},
11085
11151
  dialogId: currentDialogId,
@@ -11239,22 +11305,24 @@ async function checkLocalAvailabilityBeforeHttpDispatch(options) {
11239
11305
  }
11240
11306
  const agentLevelAt = baseRecord.nextAvailableAt;
11241
11307
  const agentLevelNextAvailableAt = typeof agentLevelAt === "number" && Number.isFinite(agentLevelAt) ? agentLevelAt : void 0;
11242
- if (!credentialKey && agentLevelNextAvailableAt === void 0) return null;
11308
+ if (!credentialKey && agentLevelNextAvailableAt === void 0) {
11309
+ return { credentialKey };
11310
+ }
11243
11311
  const env = options.env;
11244
11312
  const now = Date.now();
11245
11313
  const entry = credentialKey ? await readCredentialEntry(credentialKey, env, now).catch(() => void 0) : void 0;
11246
11314
  const entryAt = entry?.nextAvailableAt;
11247
11315
  const effectiveNextAvailableAt = typeof entryAt === "number" ? mergeAvailabilityDeadline(agentLevelNextAvailableAt, entryAt) : agentLevelNextAvailableAt;
11248
- if (typeof effectiveNextAvailableAt !== "number") return null;
11316
+ if (typeof effectiveNextAvailableAt !== "number") return { credentialKey };
11249
11317
  const gateDecision = resolveCooldownGate(
11250
11318
  { nextAvailableAt: effectiveNextAvailableAt, lastProbeAt: entry?.lastProbeAt },
11251
11319
  now
11252
11320
  );
11253
11321
  if (gateDecision === "probe" && credentialKey) {
11254
11322
  await recordCredentialProbe(credentialKey, env, now).catch(() => void 0);
11255
- return null;
11323
+ return { credentialKey };
11256
11324
  }
11257
- if (gateDecision !== "blocked") return null;
11325
+ if (gateDecision !== "blocked") return { credentialKey };
11258
11326
  options.output.write(
11259
11327
  `[nolo] Agent ${options.agentName || options.agentKey} is temporarily unavailable (429 cooldown) until ${new Date(Number(effectiveNextAvailableAt)).toISOString()}.
11260
11328
  Dispatch aborted before reaching the server. Pick another agent via listAgents, or retry after the cooldown.
@@ -11337,11 +11405,18 @@ async function runAgentTurn(options) {
11337
11405
  );
11338
11406
  return { exitCode: 1 };
11339
11407
  }
11340
- const localBlock = await checkLocalAvailabilityBeforeHttpDispatch(options);
11341
- if (localBlock) {
11342
- return { exitCode: localBlock.exitCode };
11408
+ const localAvailability = await checkLocalAvailabilityBeforeHttpDispatch(options);
11409
+ if (localAvailability?.exitCode) {
11410
+ return { exitCode: localAvailability.exitCode };
11411
+ }
11412
+ const httpResult = await runHttpAgentTurn(options, authToken);
11413
+ if (httpResult.exitCode === 0 && !httpResult.streamInterrupted && localAvailability?.credentialKey) {
11414
+ await clearCredentialAvailability(
11415
+ localAvailability.credentialKey,
11416
+ options.env
11417
+ ).catch(() => void 0);
11343
11418
  }
11344
- return runHttpAgentTurn(options, authToken);
11419
+ return httpResult;
11345
11420
  }
11346
11421
 
11347
11422
  // packages/cli/agentRunCommand.ts
@@ -12073,6 +12148,1078 @@ var rankMemoryCandidates = (items, query, context) => {
12073
12148
  });
12074
12149
  };
12075
12150
 
12151
+ // packages/ai/memory/vnext/store.ts
12152
+ var enc = (value) => encodeURIComponent(value).replace(/-/g, "%2D");
12153
+ var rangeOf = (prefix) => ({ gte: prefix, lte: `${prefix}\uFFFF` });
12154
+ var entityKey = (ownerId, id) => `mem2-e-${enc(ownerId)}-${enc(id)}`;
12155
+ var entityOwnerPrefix = (ownerId) => `mem2-e-${enc(ownerId)}-`;
12156
+ var stateKey = (ownerId, id) => `mem2-s-${enc(ownerId)}-${enc(id)}`;
12157
+ var stateEntityIndexKey = (ownerId, entityId, stateId) => `mem2-si-${enc(ownerId)}-${enc(entityId)}-${enc(stateId)}`;
12158
+ var stateEntityIndexPrefix = (ownerId, entityId) => `mem2-si-${enc(ownerId)}-${enc(entityId)}-`;
12159
+ var evidenceKey = (ownerId, id) => `mem2-v-${enc(ownerId)}-${enc(id)}`;
12160
+ var relationKey = (ownerId, id) => `mem2-r-${enc(ownerId)}-${enc(id)}`;
12161
+ var relationFromIndexKey = (ownerId, from, relationId) => `mem2-rf-${enc(ownerId)}-${enc(from)}-${enc(relationId)}`;
12162
+ var relationToIndexKey = (ownerId, to, relationId) => `mem2-rt-${enc(ownerId)}-${enc(to)}-${enc(relationId)}`;
12163
+ var readIndexed = async (db, prefix) => {
12164
+ const refs = [];
12165
+ for await (const [, value] of db.iterator({ ...rangeOf(prefix), reverse: false })) {
12166
+ if (typeof value?.key === "string") refs.push(value.key);
12167
+ }
12168
+ const rows = await Promise.all(refs.map((key) => db.get(key).catch(() => null)));
12169
+ return rows.filter((row) => !!row);
12170
+ };
12171
+ var getMemoryEntityVNext = async (db, ownerId, entityId) => db.get(entityKey(ownerId, entityId)).catch(() => null);
12172
+ var listMemoryEntitiesVNext = async (db, ownerId) => {
12173
+ const rows = [];
12174
+ for await (const [, value] of db.iterator({
12175
+ ...rangeOf(entityOwnerPrefix(ownerId)),
12176
+ reverse: false
12177
+ })) {
12178
+ if (value) rows.push(value);
12179
+ }
12180
+ return rows;
12181
+ };
12182
+ var getMemoryStateVNext = async (db, ownerId, stateId) => db.get(stateKey(ownerId, stateId)).catch(() => null);
12183
+ var listMemoryStatesForEntityVNext = (db, ownerId, entityId) => readIndexed(db, stateEntityIndexPrefix(ownerId, entityId));
12184
+ var putMemoryEvidenceVNext = async (db, evidence) => {
12185
+ await db.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
12186
+ };
12187
+ var getMemoryEvidenceVNext = async (db, ownerId, evidenceId) => db.get(evidenceKey(ownerId, evidenceId)).catch(() => null);
12188
+ var getMemoryEvidenceVNextStrict = async (db, ownerId, evidenceId) => {
12189
+ try {
12190
+ return await db.get(evidenceKey(ownerId, evidenceId));
12191
+ } catch (error) {
12192
+ if (isLevelNotFoundError(error)) return null;
12193
+ throw error;
12194
+ }
12195
+ };
12196
+ var _appendEntityBatch = (batch, entity) => {
12197
+ batch.put(entityKey(entity.ownerId, entity.id), entity);
12198
+ };
12199
+ var _appendEvidenceBatch = (batch, evidence) => {
12200
+ batch.put(evidenceKey(evidence.ownerId, evidence.id), evidence);
12201
+ };
12202
+ var _appendStateBatch = (batch, state2) => {
12203
+ const key = stateKey(state2.ownerId, state2.id);
12204
+ batch.put(key, state2);
12205
+ batch.put(stateEntityIndexKey(state2.ownerId, state2.entityId, state2.id), { key });
12206
+ };
12207
+ var _appendRetiredStateBatch = (batch, state2) => {
12208
+ batch.put(stateKey(state2.ownerId, state2.id), state2);
12209
+ };
12210
+ var _appendRelationBatch = (batch, relation) => {
12211
+ const key = relationKey(relation.ownerId, relation.id);
12212
+ batch.put(key, relation);
12213
+ batch.put(relationFromIndexKey(relation.ownerId, relation.from, relation.id), { key });
12214
+ batch.put(relationToIndexKey(relation.ownerId, relation.to, relation.id), { key });
12215
+ };
12216
+
12217
+ // packages/ai/memory/vnext/recall.ts
12218
+ var MAX_RECALL_REFS = 6;
12219
+ var stripFence = (raw) => {
12220
+ const trimmed = raw.trim();
12221
+ const match = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);
12222
+ return match ? match[1].trim() : trimmed;
12223
+ };
12224
+ var parseSelection = (raw) => {
12225
+ let parsed;
12226
+ try {
12227
+ parsed = JSON.parse(stripFence(raw));
12228
+ } catch {
12229
+ throw new Error("memory recall selector output is not valid JSON");
12230
+ }
12231
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
12232
+ throw new Error("memory recall selector output must be an object");
12233
+ }
12234
+ const obj = parsed;
12235
+ if (!Array.isArray(obj.refs) || !obj.refs.every((item) => typeof item === "string")) {
12236
+ throw new Error("memory recall selector refs must be string[]");
12237
+ }
12238
+ if (typeof obj.reason !== "string") {
12239
+ throw new Error("memory recall selector reason must be string");
12240
+ }
12241
+ return {
12242
+ refs: [...new Set(obj.refs)].slice(0, MAX_RECALL_REFS),
12243
+ reason: obj.reason
12244
+ };
12245
+ };
12246
+ var buildCatalog = async (db, ownerId) => {
12247
+ const entities = await listMemoryEntitiesVNext(db, ownerId);
12248
+ const states = [];
12249
+ for (const entity of entities) {
12250
+ states.push(...await listMemoryStatesForEntityVNext(db, ownerId, entity.id));
12251
+ }
12252
+ return { entities, states };
12253
+ };
12254
+ var catalogText = (entities, states) => JSON.stringify(
12255
+ {
12256
+ entities: entities.map((entity) => ({
12257
+ id: entity.id,
12258
+ type: entity.type,
12259
+ name: entity.name,
12260
+ ...entity.subtype ? { subtype: entity.subtype } : {},
12261
+ ...entity.aliases?.length ? { aliases: entity.aliases } : {}
12262
+ })),
12263
+ states: states.map((state2) => ({
12264
+ id: state2.id,
12265
+ entityId: state2.entityId,
12266
+ facet: state2.facet,
12267
+ text: state2.text,
12268
+ // Retired (superseded) States stay listed as recoverable history; the
12269
+ // boolean — not the retiredAt timestamp — enters the prompt so no
12270
+ // timestamps reach LLM text.
12271
+ ...state2.retiredAt ? { retired: true } : {}
12272
+ }))
12273
+ },
12274
+ null,
12275
+ 2
12276
+ );
12277
+ var createMemoryVNextRecall = (input) => async (query) => {
12278
+ const startedAt = performance.now();
12279
+ const { entities, states } = await buildCatalog(input.db, input.ownerId);
12280
+ if (entities.length === 0 && states.length === 0) {
12281
+ return {
12282
+ query,
12283
+ refs: [],
12284
+ entities: [],
12285
+ states: [],
12286
+ reason: "memory catalog is empty",
12287
+ trace: {
12288
+ candidateEntities: 0,
12289
+ candidateStates: 0,
12290
+ selectedRefs: 0,
12291
+ elapsedMs: Math.round((performance.now() - startedAt) * 10) / 10
12292
+ }
12293
+ };
12294
+ }
12295
+ const result = await input.provider.complete(
12296
+ [
12297
+ {
12298
+ role: "system",
12299
+ content: [
12300
+ "Select the smallest useful set of long-lived memory entrances for the user query.",
12301
+ 'Return ONLY JSON: {"refs":["exact-id"],"reason":"short explanation"}.',
12302
+ `Select at most ${MAX_RECALL_REFS} exact ids from the supplied catalog.`,
12303
+ "Prefer State ids when current durable understanding answers the query.",
12304
+ "Select an Entity id when it is a useful navigation anchor and no single State is enough.",
12305
+ "Do not select unrelated memories merely because they are personal or interesting.",
12306
+ "Historical-detail questions may select the relevant current State/Entity as an entrance; deeper evidence is handled by inspect, not here."
12307
+ ].join("\n")
12308
+ },
12309
+ {
12310
+ role: "user",
12311
+ content: `Query:
12312
+ ${query}
12313
+
12314
+ Memory catalog:
12315
+ ${catalogText(entities, states)}`
12316
+ }
12317
+ ],
12318
+ input.timeoutMs ? { timeoutMs: input.timeoutMs } : void 0
12319
+ );
12320
+ const selected = parseSelection(result.content);
12321
+ const entityById = new Map(entities.map((entity) => [entity.id, entity]));
12322
+ const stateById = new Map(states.map((state2) => [state2.id, state2]));
12323
+ const validRefs = selected.refs.filter((ref) => entityById.has(ref) || stateById.has(ref));
12324
+ return {
12325
+ query,
12326
+ refs: validRefs,
12327
+ entities: validRefs.flatMap((ref) => {
12328
+ const entity = entityById.get(ref);
12329
+ return entity ? [entity] : [];
12330
+ }),
12331
+ states: validRefs.flatMap((ref) => {
12332
+ const state2 = stateById.get(ref);
12333
+ return state2 ? [state2] : [];
12334
+ }),
12335
+ reason: selected.reason,
12336
+ trace: {
12337
+ candidateEntities: entities.length,
12338
+ candidateStates: states.length,
12339
+ selectedRefs: validRefs.length,
12340
+ elapsedMs: Math.round((performance.now() - startedAt) * 10) / 10
12341
+ }
12342
+ };
12343
+ };
12344
+
12345
+ // packages/ai/memory/vnext/legacyMigration.ts
12346
+ import { createHash } from "crypto";
12347
+ var LEGACY_MEMORY_SOURCE_REF_PREFIX = "legacy-memory";
12348
+ var LEGACY_MEMORY_EVIDENCE_ID_PREFIX = "mem-legacy-";
12349
+ var resolveLegacyMemoryPrincipal = (item) => ({
12350
+ ownerType: item.ownerType,
12351
+ ownerId: item.ownerId,
12352
+ principalId: `${item.ownerType}:${encodeURIComponent(item.ownerId)}`
12353
+ });
12354
+ var buildLegacyMemorySourceRef = (item) => {
12355
+ const { principalId } = resolveLegacyMemoryPrincipal(item);
12356
+ return `${LEGACY_MEMORY_SOURCE_REF_PREFIX}:${principalId}:${encodeURIComponent(item.id)}`;
12357
+ };
12358
+ var legacyEvidenceSeed = (principalId, itemId) => JSON.stringify([principalId, itemId]);
12359
+ var buildLegacyEvidenceId = (item) => {
12360
+ const { principalId } = resolveLegacyMemoryPrincipal(item);
12361
+ const digest = createHash("sha256").update(legacyEvidenceSeed(principalId, item.id)).digest("hex");
12362
+ return `${LEGACY_MEMORY_EVIDENCE_ID_PREFIX}${digest.slice(0, 32)}`;
12363
+ };
12364
+ var clampLegacyConfidence = (value) => {
12365
+ if (typeof value !== "number" || !Number.isFinite(value)) return 0;
12366
+ if (value < 0) return 0;
12367
+ if (value > 1) return 1;
12368
+ return value;
12369
+ };
12370
+ var buildLegacyMemoryEvidence = (item) => {
12371
+ const { principalId } = resolveLegacyMemoryPrincipal(item);
12372
+ return {
12373
+ id: buildLegacyEvidenceId(item),
12374
+ ownerId: principalId,
12375
+ text: item.content,
12376
+ sourceRef: buildLegacyMemorySourceRef(item),
12377
+ confidence: clampLegacyConfidence(item.confidence),
12378
+ createdAt: item.createdAt
12379
+ };
12380
+ };
12381
+
12382
+ // packages/ai/memory/vnext/shadowRead.ts
12383
+ var SHADOW_TIMEOUT_MS = 2e4;
12384
+ var ERROR_MESSAGE_MAX = 120;
12385
+ var normalizeTextKey = (text) => text.trim().replace(/\s+/g, " ").toLowerCase();
12386
+ var legacyItemKeys = (item) => {
12387
+ const keys = [normalizeTextKey(item.content ?? "")];
12388
+ return keys.filter((key) => key.length > 0);
12389
+ };
12390
+ var vnextResultKeys = (result) => {
12391
+ const keys = [];
12392
+ for (const entity of result.entities) {
12393
+ if (entity.name) keys.push(normalizeTextKey(entity.name));
12394
+ }
12395
+ for (const state2 of result.states) {
12396
+ if (state2.text) keys.push(normalizeTextKey(state2.text));
12397
+ }
12398
+ return keys.filter((key) => key.length > 0);
12399
+ };
12400
+ var vnextContextChars = (result) => result.entities.reduce(
12401
+ (sum, entity) => sum + (entity.name?.length ?? 0),
12402
+ result.states.reduce((sum, state2) => sum + (state2.text?.length ?? 0), 0)
12403
+ );
12404
+ var shortError = (error) => {
12405
+ const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
12406
+ return message.length > ERROR_MESSAGE_MAX ? `${message.slice(0, ERROR_MESSAGE_MAX)}\u2026` : message;
12407
+ };
12408
+ var withTimeout = async (promise, timeoutMs, label) => {
12409
+ let timer;
12410
+ const timeout = new Promise((_, reject) => {
12411
+ timer = setTimeout(() => reject(new Error(label)), timeoutMs);
12412
+ });
12413
+ try {
12414
+ return await Promise.race([promise, timeout]);
12415
+ } finally {
12416
+ if (timer) clearTimeout(timer);
12417
+ }
12418
+ };
12419
+ var runMemoryVNextShadowRead = async (input) => {
12420
+ const now = input.ctx.now ?? (() => performance.now());
12421
+ const defaultEmit = (observation2) => {
12422
+ const payload = {
12423
+ event: "memory_vnext_shadow_read",
12424
+ ...observation2
12425
+ };
12426
+ console.info("[memory] vnext shadow read", payload);
12427
+ };
12428
+ const emit = input.emit ?? defaultEmit;
12429
+ const legacyKeys = new Set(
12430
+ input.legacyItems.flatMap((item) => legacyItemKeys(item))
12431
+ );
12432
+ const vnextStartedAt = now();
12433
+ let vnextHitCount = 0;
12434
+ let vnextChars = 0;
12435
+ const vnextKeys = /* @__PURE__ */ new Set();
12436
+ let vnextError;
12437
+ try {
12438
+ const shadowTimeoutMs = input.ctx.shadowTimeoutMs ?? SHADOW_TIMEOUT_MS;
12439
+ const perOwner = async (owner) => {
12440
+ const principal = resolveLegacyMemoryPrincipal({
12441
+ ownerType: owner.ownerType,
12442
+ ownerId: owner.ownerId
12443
+ });
12444
+ const recall = createMemoryVNextRecall({
12445
+ db: input.ctx.db,
12446
+ ownerId: principal.principalId,
12447
+ provider: input.ctx.provider,
12448
+ timeoutMs: input.ctx.timeoutMs
12449
+ });
12450
+ return recall(input.ctx.query);
12451
+ };
12452
+ const results = await withTimeout(
12453
+ Promise.all(input.ctx.owners.map((owner) => perOwner(owner))),
12454
+ shadowTimeoutMs,
12455
+ `memory vnext shadow read timed out after ${shadowTimeoutMs}ms`
12456
+ );
12457
+ for (const result of results) {
12458
+ vnextHitCount += result.refs.length;
12459
+ vnextChars += vnextContextChars(result);
12460
+ for (const key of vnextResultKeys(result)) vnextKeys.add(key);
12461
+ }
12462
+ } catch (error) {
12463
+ vnextError = shortError(error);
12464
+ }
12465
+ const vnextLatencyMs = Math.round((now() - vnextStartedAt) * 10) / 10;
12466
+ let overlapCount = null;
12467
+ let legacyOnlyCount = null;
12468
+ let vnextOnlyCount = null;
12469
+ if (!vnextError) {
12470
+ let overlap = 0;
12471
+ for (const key of vnextKeys) if (legacyKeys.has(key)) overlap += 1;
12472
+ overlapCount = overlap;
12473
+ legacyOnlyCount = Math.max(0, legacyKeys.size - overlap);
12474
+ vnextOnlyCount = Math.max(0, vnextKeys.size - overlap);
12475
+ }
12476
+ const observation = {
12477
+ legacyHitCount: input.legacyItems.length,
12478
+ vnextHitCount,
12479
+ overlapCount,
12480
+ legacyOnlyCount,
12481
+ vnextOnlyCount,
12482
+ legacyLatencyMs: input.legacyLatencyMs,
12483
+ vnextLatencyMs,
12484
+ legacyContextChars: input.legacyContextChars,
12485
+ vnextContextChars: vnextChars,
12486
+ ...vnextError ? { vnextError } : {}
12487
+ };
12488
+ emit(observation);
12489
+ return observation;
12490
+ };
12491
+ var isMemoryVNextShadowReadEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_SHADOW_READ === "1" || env.NOLO_MEMORY_VNEXT_SHADOW_READ === "true";
12492
+
12493
+ // packages/ai/memory/vnext/applyMutation.ts
12494
+ async function validateMutation(db, ownerId, mutation) {
12495
+ const pending = {
12496
+ evidenceIds: /* @__PURE__ */ new Set(),
12497
+ entityIds: /* @__PURE__ */ new Set(),
12498
+ stateIds: /* @__PURE__ */ new Set(),
12499
+ relationIds: /* @__PURE__ */ new Set()
12500
+ };
12501
+ for (const ev of mutation.evidence ?? []) {
12502
+ if (!ev.id || typeof ev.id !== "string") {
12503
+ throw new Error("evidence id must be a non-empty string");
12504
+ }
12505
+ if (pending.evidenceIds.has(ev.id)) {
12506
+ throw new Error(`duplicate evidence id in mutation: ${ev.id}`);
12507
+ }
12508
+ pending.evidenceIds.add(ev.id);
12509
+ }
12510
+ for (const ent of mutation.entities ?? []) {
12511
+ if (!ent.id || typeof ent.id !== "string") {
12512
+ throw new Error("entity id must be a non-empty string");
12513
+ }
12514
+ if (pending.entityIds.has(ent.id)) {
12515
+ throw new Error(`duplicate entity id in mutation: ${ent.id}`);
12516
+ }
12517
+ pending.entityIds.add(ent.id);
12518
+ }
12519
+ for (const st of mutation.states ?? []) {
12520
+ if (!st.id || typeof st.id !== "string") {
12521
+ throw new Error("state id must be a non-empty string");
12522
+ }
12523
+ if (pending.stateIds.has(st.id)) {
12524
+ throw new Error(`duplicate state id in mutation: ${st.id}`);
12525
+ }
12526
+ pending.stateIds.add(st.id);
12527
+ }
12528
+ for (const rel of mutation.relations ?? []) {
12529
+ if (!rel.id || typeof rel.id !== "string") {
12530
+ throw new Error("relation id must be a non-empty string");
12531
+ }
12532
+ if (pending.relationIds.has(rel.id)) {
12533
+ throw new Error(`duplicate relation id in mutation: ${rel.id}`);
12534
+ }
12535
+ pending.relationIds.add(rel.id);
12536
+ }
12537
+ const supersededIds = /* @__PURE__ */ new Set();
12538
+ for (const sid of mutation.supersededStateIds ?? []) {
12539
+ if (supersededIds.has(sid)) {
12540
+ throw new Error(`duplicate supersededStateId in mutation: ${sid}`);
12541
+ }
12542
+ supersededIds.add(sid);
12543
+ }
12544
+ for (const ev of mutation.evidence ?? []) {
12545
+ if (ev.ownerId !== ownerId) {
12546
+ throw new Error(
12547
+ `evidence ${ev.id} has ownerId ${ev.ownerId}, expected ${ownerId}`
12548
+ );
12549
+ }
12550
+ }
12551
+ for (const ent of mutation.entities ?? []) {
12552
+ if (ent.ownerId !== ownerId) {
12553
+ throw new Error(
12554
+ `entity ${ent.id} has ownerId ${ent.ownerId}, expected ${ownerId}`
12555
+ );
12556
+ }
12557
+ }
12558
+ for (const st of mutation.states ?? []) {
12559
+ if (st.ownerId !== ownerId) {
12560
+ throw new Error(
12561
+ `state ${st.id} has ownerId ${st.ownerId}, expected ${ownerId}`
12562
+ );
12563
+ }
12564
+ }
12565
+ for (const rel of mutation.relations ?? []) {
12566
+ if (rel.ownerId !== ownerId) {
12567
+ throw new Error(
12568
+ `relation ${rel.id} has ownerId ${rel.ownerId}, expected ${ownerId}`
12569
+ );
12570
+ }
12571
+ }
12572
+ for (const st of mutation.states ?? []) {
12573
+ if (supersededIds.has(st.id)) {
12574
+ throw new Error(
12575
+ `state ${st.id} appears in both states and supersededStateIds; a record cannot be created and retired in the same mutation`
12576
+ );
12577
+ }
12578
+ }
12579
+ const facetSlots = /* @__PURE__ */ new Set();
12580
+ for (const st of mutation.states ?? []) {
12581
+ const slot = `${st.entityId} ${st.facet}`;
12582
+ if (facetSlots.has(slot)) {
12583
+ throw new Error(
12584
+ `mutation writes parallel current states for entity ${st.entityId} facet ${st.facet}`
12585
+ );
12586
+ }
12587
+ facetSlots.add(slot);
12588
+ }
12589
+ for (const ev of mutation.evidence ?? []) {
12590
+ const existing = await getMemoryEvidenceVNext(db, ownerId, ev.id);
12591
+ if (existing) {
12592
+ throw new Error(
12593
+ `evidence ${ev.id} already exists (owner ${ownerId}); use a unique id`
12594
+ );
12595
+ }
12596
+ }
12597
+ for (const ent of mutation.entities ?? []) {
12598
+ const existing = await getMemoryEntityVNext(db, ownerId, ent.id);
12599
+ if (existing) {
12600
+ throw new Error(
12601
+ `entity ${ent.id} already exists (owner ${ownerId}); use a unique id`
12602
+ );
12603
+ }
12604
+ }
12605
+ for (const st of mutation.states ?? []) {
12606
+ if (!pending.entityIds.has(st.entityId)) {
12607
+ const entity = await getMemoryEntityVNext(db, ownerId, st.entityId);
12608
+ if (!entity) {
12609
+ throw new Error(
12610
+ `memory state ${st.id} references missing entity ${st.entityId} (owner ${ownerId})`
12611
+ );
12612
+ }
12613
+ }
12614
+ for (const evidenceId of st.evidenceIds) {
12615
+ if (!pending.evidenceIds.has(evidenceId)) {
12616
+ const ev = await getMemoryEvidenceVNext(db, ownerId, evidenceId);
12617
+ if (!ev) {
12618
+ throw new Error(
12619
+ `memory state ${st.id} references missing evidence ${evidenceId} (owner ${ownerId})`
12620
+ );
12621
+ }
12622
+ }
12623
+ }
12624
+ const existing = await getMemoryStateVNext(db, ownerId, st.id);
12625
+ if (existing) {
12626
+ if (existing.retiredAt) {
12627
+ throw new Error(
12628
+ `cannot update retired memory state ${st.id} (owner ${ownerId})`
12629
+ );
12630
+ }
12631
+ if (existing.entityId !== st.entityId || existing.facet !== st.facet) {
12632
+ throw new Error(
12633
+ `state ${st.id} already exists with different entity/facet (${existing.entityId}/${existing.facet} vs ${st.entityId}/${st.facet}); use supersede instead`
12634
+ );
12635
+ }
12636
+ }
12637
+ if (!existing) {
12638
+ const existingStates = await listMemoryStatesForEntityVNext(db, ownerId, st.entityId);
12639
+ for (const es of existingStates) {
12640
+ if (es.facet === st.facet && !es.retiredAt) {
12641
+ if (!supersededIds.has(es.id)) {
12642
+ throw new Error(
12643
+ `entity ${st.entityId} facet ${st.facet} already has current state ${es.id}; supersede it or use a different facet`
12644
+ );
12645
+ }
12646
+ }
12647
+ }
12648
+ }
12649
+ }
12650
+ for (const sid of mutation.supersededStateIds ?? []) {
12651
+ const existing = await getMemoryStateVNext(db, ownerId, sid);
12652
+ if (!existing) {
12653
+ throw new Error(
12654
+ `cannot supersede missing memory state: ${sid} (owner ${ownerId})`
12655
+ );
12656
+ }
12657
+ if (existing.retiredAt) {
12658
+ throw new Error(
12659
+ `cannot supersede already retired memory state: ${sid} (owner ${ownerId})`
12660
+ );
12661
+ }
12662
+ const replacement = (mutation.states ?? []).find(
12663
+ (st) => st.entityId === existing.entityId && st.facet === existing.facet
12664
+ );
12665
+ if (!replacement) {
12666
+ throw new Error(
12667
+ `superseded state ${sid} (entity ${existing.entityId} facet ${existing.facet}) has no replacement in this mutation`
12668
+ );
12669
+ }
12670
+ }
12671
+ for (const rel of mutation.relations ?? []) {
12672
+ for (const [side, ref] of [
12673
+ ["from", rel.from],
12674
+ ["to", rel.to]
12675
+ ]) {
12676
+ if (pending.entityIds.has(ref) || pending.stateIds.has(ref) || pending.evidenceIds.has(ref)) {
12677
+ continue;
12678
+ }
12679
+ const resolved = await getMemoryEntityVNext(db, ownerId, ref) ?? await getMemoryStateVNext(db, ownerId, ref) ?? await getMemoryEvidenceVNext(db, ownerId, ref);
12680
+ if (!resolved) {
12681
+ throw new Error(
12682
+ `memory relation ${rel.id} references missing ${side} ${ref} (owner ${ownerId})`
12683
+ );
12684
+ }
12685
+ }
12686
+ }
12687
+ }
12688
+ var applyMemoryInterpreterMutation = async (db, ownerId, mutation) => {
12689
+ await validateMutation(db, ownerId, mutation);
12690
+ const batch = db.batch();
12691
+ for (const ev of mutation.evidence ?? []) {
12692
+ _appendEvidenceBatch(batch, ev);
12693
+ }
12694
+ for (const ent of mutation.entities ?? []) {
12695
+ _appendEntityBatch(batch, ent);
12696
+ }
12697
+ for (const st of mutation.states ?? []) {
12698
+ _appendStateBatch(batch, st);
12699
+ }
12700
+ for (const sid of mutation.supersededStateIds ?? []) {
12701
+ const existing = await getMemoryStateVNext(db, ownerId, sid);
12702
+ if (!existing) {
12703
+ throw new Error(
12704
+ `cannot supersede missing memory state: ${sid} (owner ${ownerId})`
12705
+ );
12706
+ }
12707
+ const replacement = (mutation.states ?? []).find(
12708
+ (st) => st.entityId === existing.entityId && st.facet === existing.facet
12709
+ );
12710
+ const retired = {
12711
+ ...existing,
12712
+ retiredAt: replacement?.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString()
12713
+ };
12714
+ _appendRetiredStateBatch(batch, retired);
12715
+ }
12716
+ for (const rel of mutation.relations ?? []) {
12717
+ _appendRelationBatch(batch, rel);
12718
+ }
12719
+ await batch.write();
12720
+ };
12721
+
12722
+ // packages/ai/memory/vnext/legacyMigrationApply.ts
12723
+ var isSameLegacyMemoryEvidence = (left, right) => left.id === right.id && left.ownerId === right.ownerId && left.text === right.text && left.sourceRef === right.sourceRef && left.confidence === right.confidence && left.createdAt === right.createdAt;
12724
+ var applyLegacyMemoryEvidence = async (db, item) => {
12725
+ const incoming = buildLegacyMemoryEvidence(item);
12726
+ const existing = await getMemoryEvidenceVNextStrict(db, incoming.ownerId, incoming.id);
12727
+ if (existing) {
12728
+ return isSameLegacyMemoryEvidence(existing, incoming) ? { status: "already_exists", evidence: existing } : { status: "conflict", existing, incoming };
12729
+ }
12730
+ await putMemoryEvidenceVNext(db, incoming);
12731
+ return { status: "created", evidence: incoming };
12732
+ };
12733
+
12734
+ // packages/ai/memory/vnext/types.ts
12735
+ var MEMORY_ENTITY_TYPES = [
12736
+ "person",
12737
+ "organization",
12738
+ "project",
12739
+ "place",
12740
+ "object",
12741
+ "activity",
12742
+ "concept"
12743
+ ];
12744
+ var MEMORY_RELATION_TYPES = [
12745
+ "related_to",
12746
+ "part_of",
12747
+ "uses",
12748
+ "involves",
12749
+ "supersedes"
12750
+ ];
12751
+
12752
+ // packages/ai/memory/vnext/interpreterWireProtocol.ts
12753
+ var isObject = (value) => !!value && typeof value === "object" && !Array.isArray(value);
12754
+ var isString = (value) => typeof value === "string" && value.trim().length > 0;
12755
+ var isStringArray = (value) => Array.isArray(value) && value.every(isString);
12756
+ var optionalArray = (value, validate2) => value === void 0 || Array.isArray(value) && value.every(validate2);
12757
+ var ACTIONS = /* @__PURE__ */ new Set([
12758
+ "no_op",
12759
+ "create",
12760
+ "update",
12761
+ "specialize",
12762
+ "supersede",
12763
+ "ambiguous"
12764
+ ]);
12765
+ var validateEvidence = (value) => {
12766
+ if (!isObject(value)) return false;
12767
+ return isString(value.key) && isString(value.text) && typeof value.confidence === "number" && Number.isFinite(value.confidence) && value.confidence >= 0 && value.confidence <= 1 && (value.sourceRef === void 0 || isString(value.sourceRef));
12768
+ };
12769
+ var validateEntity = (value) => {
12770
+ if (!isObject(value)) return false;
12771
+ return isString(value.key) && MEMORY_ENTITY_TYPES.includes(value.type) && isString(value.name) && (value.subtype === void 0 || isString(value.subtype)) && (value.aliases === void 0 || isStringArray(value.aliases));
12772
+ };
12773
+ var validateState = (value) => {
12774
+ if (!isObject(value)) return false;
12775
+ return (value.stateId === void 0 || isString(value.stateId)) && (value.supersedes === void 0 || isString(value.supersedes)) && isString(value.entityRef) && isString(value.facet) && "value" in value && isString(value.text) && isStringArray(value.evidenceRefs);
12776
+ };
12777
+ var validateRelation = (value) => {
12778
+ if (!isObject(value)) return false;
12779
+ return isString(value.fromRef) && MEMORY_RELATION_TYPES.includes(value.type) && isString(value.toRef);
12780
+ };
12781
+ var stripJsonFence = (raw) => {
12782
+ const trimmed = raw.trim();
12783
+ const match = trimmed.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);
12784
+ return match ? match[1].trim() : trimmed;
12785
+ };
12786
+ var parseMemoryInterpreterWireMutation = (raw) => {
12787
+ let parsed;
12788
+ try {
12789
+ parsed = JSON.parse(stripJsonFence(raw));
12790
+ } catch {
12791
+ return { ok: false, error: "interpreter output is not valid JSON" };
12792
+ }
12793
+ if (!isObject(parsed)) return { ok: false, error: "interpreter output must be an object" };
12794
+ if (!isString(parsed.action) || !ACTIONS.has(parsed.action)) {
12795
+ return { ok: false, error: "invalid reconciliation action" };
12796
+ }
12797
+ if (!isString(parsed.reason)) return { ok: false, error: "reason is required" };
12798
+ if (!optionalArray(parsed.evidence, validateEvidence)) return { ok: false, error: "invalid evidence array" };
12799
+ if (!optionalArray(parsed.entities, validateEntity)) return { ok: false, error: "invalid entities array" };
12800
+ if (!optionalArray(parsed.states, validateState)) return { ok: false, error: "invalid states array" };
12801
+ if (!optionalArray(parsed.relations, validateRelation)) return { ok: false, error: "invalid relations array" };
12802
+ return { ok: true, value: parsed };
12803
+ };
12804
+ var buildMemoryInterpreterWireContract = () => `
12805
+ Return ONLY one JSON object:
12806
+ {
12807
+ "action": "no_op|create|update|specialize|supersede|ambiguous",
12808
+ "reason": "short explanation",
12809
+ "evidence": [{ "key": "e1", "text": "...", "confidence": 0.9, "sourceRef": "optional" }],
12810
+ "entities": [{ "key": "n1", "type": "person|organization|project|place|object|activity|concept", "name": "...", "subtype": "optional", "aliases": [] }],
12811
+ "states": [{ "stateId": "optional-existing-state-id", "supersedes": "optional-existing-state-id-this-statement-replaces", "entityRef": "existing-entity-id-or-new-entity-key", "facet": "...", "value": {}, "text": "...", "evidenceRefs": ["e1"] }],
12812
+ "relations": [{ "fromRef": "existing-id-or-local-key", "type": "related_to|part_of|uses|involves|supersedes", "toRef": "existing-id-or-local-key" }]
12813
+ }
12814
+
12815
+ Do not generate persistent ids, owner ids, timestamps or storage keys. Runtime owns identity and time.
12816
+ Use short local keys only to connect records created in the SAME response. Every local key must be unique across evidence/entities.
12817
+ State evidenceRefs may reference Evidence emitted in this response. Evidence ids marked referenceable in the supplied memory context may be referenced directly. Do not reference any other prior Evidence id.
12818
+ When updating an existing State, reuse its exact stateId, exact entityRef and exact facet. Runtime preserves that State's original entity/facet/createdAt and appends new Evidence provenance.
12819
+ When creating a new State, omit stateId.
12820
+ For supersede: emit the replacing statement as a NEW State (omit stateId) and set supersedes to the exact id of the replaced current State. Runtime retires the replaced State \u2014 it stays recoverable as history but is no longer current, and the new State becomes the only current one for that facet. Never update or supersede an already retired State.
12821
+ supersedes and stateId are mutually exclusive on one State.
12822
+ Do not emit an existing Entity again merely to update its State; reference its exact id in entityRef.
12823
+ Relations may reference only known persisted Entity/State/Evidence ids or local Entity/Evidence keys emitted in the same response.
12824
+ Do not invent new Entity or Relation types. Keep expressive detail in subtype/facet/value/text.
12825
+ `.trim();
12826
+ var assertUniqueLocalKeys = (wire) => {
12827
+ const seen = /* @__PURE__ */ new Set();
12828
+ for (const item of [...wire.evidence ?? [], ...wire.entities ?? []]) {
12829
+ if (seen.has(item.key)) throw new Error(`duplicate local key: ${item.key}`);
12830
+ seen.add(item.key);
12831
+ }
12832
+ };
12833
+ var materializeMemoryInterpreterMutation = (input) => {
12834
+ assertUniqueLocalKeys(input.wire);
12835
+ const now = input.now ?? (/* @__PURE__ */ new Date()).toISOString();
12836
+ const nextId = input.nextId ?? ulid;
12837
+ const existingStates = new Map((input.existingStates ?? []).map((state2) => [state2.id, state2]));
12838
+ const existingStateIds = new Set(existingStates.keys());
12839
+ const existingEvidenceIds = new Set(
12840
+ [...existingStates.values()].flatMap((state2) => state2.evidenceIds)
12841
+ );
12842
+ const existingEntityIds = new Set(input.existingEntityIds ?? []);
12843
+ const entityRefs = /* @__PURE__ */ new Map();
12844
+ const evidenceRefs = /* @__PURE__ */ new Map();
12845
+ const evidence = (input.wire.evidence ?? []).map((item) => {
12846
+ const id = nextId();
12847
+ evidenceRefs.set(item.key, id);
12848
+ return {
12849
+ id,
12850
+ ownerId: input.ownerId,
12851
+ text: item.text,
12852
+ ...item.sourceRef ? { sourceRef: item.sourceRef } : {},
12853
+ confidence: item.confidence,
12854
+ createdAt: now
12855
+ };
12856
+ });
12857
+ const entities = (input.wire.entities ?? []).map((item) => {
12858
+ const id = nextId();
12859
+ entityRefs.set(item.key, id);
12860
+ return {
12861
+ id,
12862
+ ownerId: input.ownerId,
12863
+ type: item.type,
12864
+ name: item.name,
12865
+ ...item.subtype ? { subtype: item.subtype } : {},
12866
+ ...item.aliases ? { aliases: item.aliases } : {},
12867
+ createdAt: now,
12868
+ updatedAt: now
12869
+ };
12870
+ });
12871
+ const resolveEntityRef = (ref) => {
12872
+ const created = entityRefs.get(ref);
12873
+ if (created) return created;
12874
+ if (existingEntityIds.has(ref)) return ref;
12875
+ throw new Error(`unknown entity ref: ${ref}`);
12876
+ };
12877
+ const supersededStateIds = [];
12878
+ const referenceableEvidenceIds = new Set(input.referenceableEvidenceIds ?? []);
12879
+ const resolveEvidenceRef = (ref) => {
12880
+ const created = evidenceRefs.get(ref);
12881
+ if (created) return created;
12882
+ if (referenceableEvidenceIds.has(ref)) return ref;
12883
+ throw new Error(`unknown evidence ref: ${ref}`);
12884
+ };
12885
+ const states = (input.wire.states ?? []).map((item) => {
12886
+ const prior = item.stateId ? existingStates.get(item.stateId) : void 0;
12887
+ if (item.stateId && !prior) {
12888
+ throw new Error(`unknown existing state: ${item.stateId}`);
12889
+ }
12890
+ if (prior?.retiredAt) {
12891
+ throw new Error(`retired state cannot be updated: ${item.stateId}`);
12892
+ }
12893
+ if (prior && item.entityRef !== prior.entityId) {
12894
+ throw new Error(`existing state entityRef changed: ${item.stateId}`);
12895
+ }
12896
+ if (prior && item.facet !== prior.facet) {
12897
+ throw new Error(`existing state facet changed: ${item.stateId}`);
12898
+ }
12899
+ let supersededStateId;
12900
+ if (item.supersedes !== void 0) {
12901
+ if (input.wire.action !== "supersede") {
12902
+ throw new Error(
12903
+ `supersedes is only valid for the supersede action, got ${input.wire.action}`
12904
+ );
12905
+ }
12906
+ if (item.stateId !== void 0) {
12907
+ throw new Error("supersedes and stateId are mutually exclusive on one state");
12908
+ }
12909
+ const superseded = existingStates.get(item.supersedes);
12910
+ if (!superseded) {
12911
+ throw new Error(`unknown superseded state id: ${item.supersedes}`);
12912
+ }
12913
+ if (superseded.retiredAt) {
12914
+ throw new Error(`retired state cannot be superseded: ${item.supersedes}`);
12915
+ }
12916
+ if (supersededStateIds.includes(item.supersedes)) {
12917
+ throw new Error(`duplicate superseded state id: ${item.supersedes}`);
12918
+ }
12919
+ supersededStateId = item.supersedes;
12920
+ }
12921
+ const newEvidenceIds = item.evidenceRefs.map(resolveEvidenceRef);
12922
+ const id = prior?.id ?? nextId();
12923
+ if (supersededStateId !== void 0) supersededStateIds.push(supersededStateId);
12924
+ return {
12925
+ id,
12926
+ ownerId: input.ownerId,
12927
+ entityId: prior?.entityId ?? resolveEntityRef(item.entityRef),
12928
+ facet: prior?.facet ?? item.facet,
12929
+ value: item.value,
12930
+ text: item.text,
12931
+ evidenceIds: [.../* @__PURE__ */ new Set([...prior?.evidenceIds ?? [], ...newEvidenceIds])],
12932
+ createdAt: prior?.createdAt ?? now,
12933
+ updatedAt: now
12934
+ };
12935
+ });
12936
+ const resolveRelationRef = (ref) => {
12937
+ const createdEntity = entityRefs.get(ref);
12938
+ if (createdEntity) return createdEntity;
12939
+ const createdEvidence = evidenceRefs.get(ref);
12940
+ if (createdEvidence) return createdEvidence;
12941
+ if (existingEntityIds.has(ref) || existingStateIds.has(ref) || existingEvidenceIds.has(ref)) {
12942
+ return ref;
12943
+ }
12944
+ throw new Error(`unknown relation ref: ${ref}`);
12945
+ };
12946
+ const relations = (input.wire.relations ?? []).map((item) => ({
12947
+ id: nextId(),
12948
+ ownerId: input.ownerId,
12949
+ from: resolveRelationRef(item.fromRef),
12950
+ type: item.type,
12951
+ to: resolveRelationRef(item.toRef),
12952
+ createdAt: now
12953
+ }));
12954
+ return {
12955
+ action: input.wire.action,
12956
+ reason: input.wire.reason,
12957
+ ...evidence.length ? { evidence } : {},
12958
+ ...entities.length ? { entities } : {},
12959
+ ...states.length ? { states } : {},
12960
+ ...supersededStateIds.length ? { supersededStateIds } : {},
12961
+ ...relations.length ? { relations } : {}
12962
+ };
12963
+ };
12964
+
12965
+ // packages/ai/memory/vnext/interpreterPrompt.ts
12966
+ var MEMORY_VNEXT_ENTITY_CREATION_CONTRACT = `
12967
+ Entity creation is NOT named-entity recognition.
12968
+
12969
+ Create a new long-lived Entity only when the subject has future continuity value.
12970
+ A mention alone is insufficient.
12971
+
12972
+ Prefer leaving information as Evidence until at least one strong continuity signal exists:
12973
+ 1. The subject recurs across independent dialogs, or the user explicitly describes it as enduring.
12974
+ 2. The user connects it to their own preferences, relationships, goals, identity, worldview, ongoing work, or repeated activity.
12975
+ 3. Future conversations are likely to refer back to it under different wording, so a stable anchor materially improves cross-dialog continuity.
12976
+ 4. Creating the anchor is necessary to update or relate existing long-lived State.
12977
+
12978
+ Do NOT create an Entity merely because the text contains a named person, product, place, historical event, book, philosopher, food, device, or concept.
12979
+ When uncertain, keep Evidence and defer Entity creation.
12980
+
12981
+ Concept-specific rule:
12982
+ - concept is for abstract subjects that become part of the user's personal meaning world, such as freedom, absurdism, privacy, modernity, beauty, loneliness, safety, or maintainability.
12983
+ - Do not create a Concept Entity for every topic discussed or external fact queried.
12984
+ - Promote a concept only when it recurs, carries a durable user stance/interest/tension, connects multiple memories, or is likely to become a future recall/navigation anchor.
12985
+ - A one-off question such as "when was Kant born?" should normally create no long-lived Concept or Person Entity. Repeated discussion about Kant, freedom, and the user's own values may justify them.
12986
+ `.trim();
12987
+ var MEMORY_VNEXT_THIRD_PARTY_RELEVANCE_CONTRACT = `
12988
+ Third-party relevance test:
12989
+ - A fact about another person is durable only when it concerns the user's own world. Observation-only third-party facts \u2014 someone's appearance, news, habits, or the doings of a person the user merely encounters \u2014 stay Evidence, no matter how often they recur.
12990
+ - Closeness of that person, and repeated mentions across independent dialogs, do not by themselves make such an observation durable: never invent a user-world consequence to justify promotion (for example "the user keeps watching this person").
12991
+ - Matters that are part of the user's own shared life \u2014 household or family arrangements the user takes part in, a family member's health, or what the user relies on someone for \u2014 do belong to the user's world: state the user-world side (caregiving, changed time, changed plans, a sustained constraint) instead of a chronicle of the other person's doings.
12992
+ `.trim();
12993
+ var MEMORY_VNEXT_RECONCILIATION_CONTRACT = `
12994
+ When durable understanding changes, choose the smallest correct reconciliation:
12995
+ - no_op: no durable change.
12996
+ - create: genuinely new durable state/entity.
12997
+ - update: advance an existing state without changing its scope.
12998
+ - specialize: add a scoped exception/qualification; do not replace the broader state.
12999
+ - supersede: a newer statement explicitly replaces old current state. Emit the replacement as a NEW State and name the replaced current State in its supersedes field; runtime retires the old one (kept as recoverable history, no longer current).
13000
+ - ambiguous: evidence conflicts with current state, but replacement vs exception cannot be determined reliably.
13001
+
13002
+ Examples:
13003
+ - "\u56DE\u7B54\u7B80\u5355" then "\u5B89\u5168\u548C bug \u6392\u67E5\u8BE6\u7EC6" => specialize, not supersede.
13004
+ - "\u6211\u6709 Ollama Pro" then "\u6211\u5DF2\u7ECF\u4E0D\u7528 Ollama Pro \u4E86" => supersede.
13005
+ - Repeatedly choosing thin noodles without explicitly rejecting thick noodles => update or ambiguous, not automatic supersession.
13006
+
13007
+ Preserve ambiguity. Do not ask the user merely to clean memory. A later task may ask only if the unresolved state materially changes the answer.
13008
+ `.trim();
13009
+ var buildMemoryVNextInterpreterPrompt = () => [
13010
+ "You maintain long-lived adaptive relationship memory backed by evidence.",
13011
+ "External dialogs/files/web facts remain authoritative outside memory.",
13012
+ "Prefer a small stable set of Entities and updateable States over an ever-growing bag of facts.",
13013
+ MEMORY_VNEXT_ENTITY_CREATION_CONTRACT,
13014
+ MEMORY_VNEXT_THIRD_PARTY_RELEVANCE_CONTRACT,
13015
+ MEMORY_VNEXT_RECONCILIATION_CONTRACT,
13016
+ buildMemoryInterpreterWireContract()
13017
+ ].join("\n\n");
13018
+
13019
+ // packages/ai/memory/vnext/legacyMigrationShadow.ts
13020
+ var LEGACY_MIGRATION_SHADOW_INSTRUCTION = `
13021
+ This Evidence came from a legacy memory record.
13022
+ Legacy kind and subject metadata are advisory hints only.
13023
+ Re-evaluate it under the current vNext contract.
13024
+ Do not mechanically map:
13025
+ - semantic -> State
13026
+ - procedural -> procedure State
13027
+ - subjectType=agent -> agent Entity
13028
+ - visibility -> scope
13029
+ Prefer Evidence-only when durable semantic value is unclear.
13030
+ `.trim();
13031
+ var serializeExisting = (existing) => JSON.stringify({
13032
+ entityIds: existing?.entityIds ?? [],
13033
+ states: (existing?.states ?? []).map((state2) => ({
13034
+ stateId: state2.id,
13035
+ entityId: state2.entityId,
13036
+ facet: state2.facet,
13037
+ text: state2.text
13038
+ }))
13039
+ });
13040
+ var buildLegacyMigrationInterpreterInput = (input) => [
13041
+ LEGACY_MIGRATION_SHADOW_INSTRUCTION,
13042
+ `The legacy record's Evidence is marked referenceable with id "${input.evidence.id}" and sourceRef "${input.evidence.sourceRef}". Evidence ids marked referenceable in the supplied memory context may be referenced directly. When a State cites it, reference that exact id in evidenceRefs. Do not emit another Evidence for this legacy record.`,
13043
+ `Imported Evidence (text is the authoritative legacy content, referenceable directly):
13044
+ ${JSON.stringify(
13045
+ {
13046
+ ...input.evidence,
13047
+ referenceable: true
13048
+ },
13049
+ null,
13050
+ 2
13051
+ )}`,
13052
+ `Legacy metadata (advisory hints only, NOT vNext semantics):
13053
+ ${JSON.stringify(
13054
+ {
13055
+ kind: input.item.kind,
13056
+ visibility: input.item.visibility,
13057
+ subjectType: input.item.subjectType,
13058
+ subjectId: input.item.subjectId,
13059
+ facet: input.item.facet,
13060
+ importance: input.item.importance,
13061
+ resident: input.item.resident
13062
+ },
13063
+ null,
13064
+ 2
13065
+ )}`,
13066
+ `Existing vNext context for this principal (caller-supplied shadow snapshot):
13067
+ ${serializeExisting(
13068
+ input.existing
13069
+ )}`
13070
+ ].join("\n\n");
13071
+ var mergeImportedEvidence = (mutation, imported) => {
13072
+ const emitted = mutation.evidence ?? [];
13073
+ const duplicatedIds = new Set(
13074
+ emitted.filter(
13075
+ (item) => item.sourceRef === imported.sourceRef || // A re-emitted copy that drops sourceRef is still the same legacy record:
13076
+ // text equality is the only identity left on the wire to catch it.
13077
+ item.sourceRef === void 0 && item.text === imported.text
13078
+ ).map((item) => item.id)
13079
+ );
13080
+ const rewrite = (id) => duplicatedIds.has(id) ? imported.id : id;
13081
+ return {
13082
+ ...mutation,
13083
+ evidence: [imported, ...emitted.filter((item) => !duplicatedIds.has(item.id))],
13084
+ ...mutation.states ? {
13085
+ states: mutation.states.map((state2) => ({
13086
+ ...state2,
13087
+ evidenceIds: [...new Set(state2.evidenceIds.map(rewrite))]
13088
+ }))
13089
+ } : {},
13090
+ ...mutation.relations ? {
13091
+ relations: mutation.relations.map((relation) => ({
13092
+ ...relation,
13093
+ from: rewrite(relation.from),
13094
+ to: rewrite(relation.to)
13095
+ }))
13096
+ } : {}
13097
+ };
13098
+ };
13099
+ var runLegacyMemoryMigrationShadow = async (input) => {
13100
+ const principal = resolveLegacyMemoryPrincipal(input.item);
13101
+ const evidence = buildLegacyMemoryEvidence(input.item);
13102
+ const completion = await input.provider.complete(
13103
+ [
13104
+ { role: "system", content: buildMemoryVNextInterpreterPrompt() },
13105
+ {
13106
+ role: "user",
13107
+ content: buildLegacyMigrationInterpreterInput({
13108
+ item: input.item,
13109
+ evidence,
13110
+ ...input.existing ? { existing: input.existing } : {}
13111
+ })
13112
+ }
13113
+ ],
13114
+ input.timeoutMs === void 0 ? void 0 : { timeoutMs: input.timeoutMs }
13115
+ );
13116
+ const parsed = parseMemoryInterpreterWireMutation(completion.content);
13117
+ if (!parsed.ok) {
13118
+ throw new Error(`legacy migration shadow: unparsable interpreter response (${parsed.error})`);
13119
+ }
13120
+ const candidate = materializeMemoryInterpreterMutation({
13121
+ // The principal identity (user:/space:/system:<id>) is the migration owner
13122
+ // space, so a space migration can never land in a user space.
13123
+ ownerId: evidence.ownerId,
13124
+ wire: parsed.value,
13125
+ ...input.existing?.states ? { existingStates: [...input.existing.states] } : {},
13126
+ ...input.existing?.entityIds ? { existingEntityIds: [...input.existing.entityIds] } : {},
13127
+ referenceableEvidenceIds: [evidence.id],
13128
+ ...input.now === void 0 ? {} : { now: input.now },
13129
+ ...input.nextId ? { nextId: input.nextId } : {}
13130
+ });
13131
+ const mutation = mergeImportedEvidence(candidate, evidence);
13132
+ return {
13133
+ principal,
13134
+ evidence,
13135
+ wire: parsed.value,
13136
+ mutation,
13137
+ action: mutation.action,
13138
+ reason: mutation.reason
13139
+ };
13140
+ };
13141
+
13142
+ // packages/ai/memory/vnext/lazyPromotion.ts
13143
+ var ERROR_MESSAGE_MAX2 = 120;
13144
+ var inFlight = /* @__PURE__ */ new Set();
13145
+ var shortError2 = (error) => {
13146
+ const message = error instanceof Error ? `${error.name}: ${error.message}` : String(error);
13147
+ return message.length > ERROR_MESSAGE_MAX2 ? `${message.slice(0, ERROR_MESSAGE_MAX2)}\u2026` : message;
13148
+ };
13149
+ var loadExistingContext = async (db, ownerId) => {
13150
+ const entities = await listMemoryEntitiesVNext(db, ownerId);
13151
+ const states = (await Promise.all(
13152
+ entities.map((entity) => listMemoryStatesForEntityVNext(db, ownerId, entity.id))
13153
+ )).flat();
13154
+ return {
13155
+ entityIds: entities.map((entity) => entity.id),
13156
+ states
13157
+ };
13158
+ };
13159
+ var withoutImportedEvidence = (mutation, importedEvidenceId) => ({
13160
+ ...mutation,
13161
+ evidence: (mutation.evidence ?? []).filter((evidence) => evidence.id !== importedEvidenceId)
13162
+ });
13163
+ var hasWrites = (mutation) => (mutation.evidence?.length ?? 0) > 0 || (mutation.entities?.length ?? 0) > 0 || (mutation.states?.length ?? 0) > 0 || (mutation.supersededStateIds?.length ?? 0) > 0 || (mutation.relations?.length ?? 0) > 0;
13164
+ var runMemoryVNextLazyPromotion = async (input) => {
13165
+ const clock = input.clock ?? (() => performance.now());
13166
+ const startedAt = clock();
13167
+ const emit = input.emit ?? ((observation) => console.info("[memory] vnext lazy promotion", {
13168
+ event: "memory_vnext_lazy_promotion",
13169
+ ...observation
13170
+ }));
13171
+ const finish = (partial) => {
13172
+ const observation = {
13173
+ ...partial,
13174
+ latencyMs: Math.round((clock() - startedAt) * 10) / 10
13175
+ };
13176
+ try {
13177
+ emit(observation);
13178
+ } catch {
13179
+ }
13180
+ return observation;
13181
+ };
13182
+ const deterministicEvidence = buildLegacyMemoryEvidence(input.item);
13183
+ const flightKey = `${deterministicEvidence.ownerId}\0${deterministicEvidence.id}`;
13184
+ if (inFlight.has(flightKey)) {
13185
+ return finish({ status: "in_flight" });
13186
+ }
13187
+ inFlight.add(flightKey);
13188
+ try {
13189
+ const evidenceResult = await applyLegacyMemoryEvidence(input.db, input.item);
13190
+ if (evidenceResult.status === "conflict") {
13191
+ return finish({ status: "conflict" });
13192
+ }
13193
+ const evidence = evidenceResult.evidence;
13194
+ const existing = await loadExistingContext(input.db, evidence.ownerId);
13195
+ const alreadyCovered = (existing.states ?? []).some(
13196
+ (state2) => !state2.retiredAt && state2.evidenceIds.includes(evidence.id)
13197
+ );
13198
+ if (alreadyCovered) {
13199
+ return finish({ status: "already_covered" });
13200
+ }
13201
+ const interpreted = await runLegacyMemoryMigrationShadow({
13202
+ item: input.item,
13203
+ provider: input.provider,
13204
+ existing,
13205
+ ...input.timeoutMs === void 0 ? {} : { timeoutMs: input.timeoutMs },
13206
+ ...input.now === void 0 ? {} : { now: input.now },
13207
+ ...input.nextId ? { nextId: input.nextId } : {}
13208
+ });
13209
+ const semanticMutation = withoutImportedEvidence(interpreted.mutation, evidence.id);
13210
+ if (!hasWrites(semanticMutation)) {
13211
+ return finish({ status: "no_op", action: semanticMutation.action });
13212
+ }
13213
+ await applyMemoryInterpreterMutation(input.db, evidence.ownerId, semanticMutation);
13214
+ return finish({ status: "promoted", action: semanticMutation.action });
13215
+ } catch (error) {
13216
+ return finish({ status: "error", error: shortError2(error) });
13217
+ } finally {
13218
+ inFlight.delete(flightKey);
13219
+ }
13220
+ };
13221
+ var isMemoryVNextLazyPromotionEnabled = (env = typeof process !== "undefined" ? process.env : {}) => env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "1" || env.NOLO_MEMORY_VNEXT_LAZY_PROMOTION === "true";
13222
+
12076
13223
  // packages/ai/memory/runtime.ts
12077
13224
  var COLD_STORAGE_CONFIDENCE = 0.3;
12078
13225
  var MEMORY_OVERLAY_TOKEN_BUDGET = DEFAULT_MEMORY_OVERLAY_TOKEN_BUDGET;
@@ -12196,6 +13343,7 @@ var resolveMemoryRuntime = async (input) => {
12196
13343
  return { selectedItems: [], promptBlock: null };
12197
13344
  }
12198
13345
  const policy = resolveAgentMemoryPolicy({ agentKey: input.agentKey });
13346
+ const legacyStartedAt = performance.now();
12199
13347
  const candidates = await loadMemoryCandidatesFromDb(input.db, {
12200
13348
  owners,
12201
13349
  subjects: buildMemorySubjectsForAgent({
@@ -12222,13 +13370,40 @@ var resolveMemoryRuntime = async (input) => {
12222
13370
  input.userInput
12223
13371
  );
12224
13372
  const selected = [...residentItems, ...ranked];
13373
+ const legacyLatencyMs = Math.round((performance.now() - legacyStartedAt) * 10) / 10;
13374
+ const promptBlock = selected.length === 0 ? null : buildMemoryOverlay(selected, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET });
13375
+ const shadowEnabled = input.vNextShadowProvider != null && isMemoryVNextShadowReadEnabled();
13376
+ if (shadowEnabled) {
13377
+ await runMemoryVNextShadowRead({
13378
+ ctx: {
13379
+ db: input.db,
13380
+ owners,
13381
+ query: input.userInput,
13382
+ provider: input.vNextShadowProvider
13383
+ },
13384
+ legacyItems: selected,
13385
+ legacyLatencyMs,
13386
+ legacyContextChars: promptBlock?.length ?? 0
13387
+ });
13388
+ }
13389
+ const promotionCandidate = selected[0];
13390
+ const lazyPromotionEnabled = input.vNextShadowProvider != null && isMemoryVNextLazyPromotionEnabled();
13391
+ if (lazyPromotionEnabled && promotionCandidate) {
13392
+ void runMemoryVNextLazyPromotion({
13393
+ db: input.db,
13394
+ item: promotionCandidate,
13395
+ provider: input.vNextShadowProvider,
13396
+ ...input.lazyPromotionEmit ? { emit: input.lazyPromotionEmit } : {}
13397
+ }).catch(() => {
13398
+ });
13399
+ }
12225
13400
  if (selected.length === 0) {
12226
13401
  return { selectedItems: [], promptBlock: null };
12227
13402
  }
12228
13403
  await touchMemoryItemsInDb(input.db, selected);
12229
13404
  return {
12230
13405
  selectedItems: selected,
12231
- promptBlock: buildMemoryOverlay(selected, { maxTokens: MEMORY_OVERLAY_TOKEN_BUDGET })
13406
+ promptBlock
12232
13407
  };
12233
13408
  };
12234
13409
 
@@ -12272,7 +13447,8 @@ var queryLocalMemory = async (env, agentKey, userInput, spaceId) => {
12272
13447
  userId: machineId,
12273
13448
  agentKey,
12274
13449
  userInput,
12275
- ...spaceId ? { spaceId } : {}
13450
+ ...spaceId ? { spaceId } : {},
13451
+ ...isMemoryVNextShadowReadEnabled(env) ? { vNextShadowProvider: void 0 } : {}
12276
13452
  });
12277
13453
  return resolution.promptBlock;
12278
13454
  };