@leuduan/lagent 0.0.0-stage → 0.1.2

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 (327) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +144 -2
  3. package/dist/chunks/2O7ZGEIT.js +1 -0
  4. package/dist/chunks/2OSESBIL.js +1 -0
  5. package/dist/chunks/34KW6VNQ.js +1 -0
  6. package/dist/chunks/37YOGDGY.js +1 -0
  7. package/dist/chunks/3LQHQRIU.js +6 -0
  8. package/dist/chunks/3QCW4WDJ.js +1 -0
  9. package/dist/chunks/4XVRUSCQ.js +1 -0
  10. package/dist/chunks/6ECI2GGV.js +1 -0
  11. package/dist/chunks/74HKUGRR.js +1 -0
  12. package/dist/chunks/ADHERZLW.js +2 -0
  13. package/dist/chunks/AP6Q4EPT.js +36 -0
  14. package/dist/chunks/BM3S37EZ.js +1 -0
  15. package/dist/chunks/C5LYCXJG.js +1 -0
  16. package/dist/chunks/CDQG7RKA.js +1 -0
  17. package/dist/chunks/D7E6EWIE.js +3 -0
  18. package/dist/chunks/DDANMY45.js +3 -0
  19. package/dist/chunks/DRYAN665.js +1 -0
  20. package/dist/chunks/DXFXAYDN.js +17 -0
  21. package/dist/chunks/EGZI4XQX.js +24 -0
  22. package/dist/chunks/ENWFSU27.js +41 -0
  23. package/dist/chunks/G6RXC3AL.js +1 -0
  24. package/dist/chunks/G74AGRAJ.js +15 -0
  25. package/dist/chunks/GQGNVSKB.js +1 -0
  26. package/dist/chunks/IJ2WNMD5.js +7 -0
  27. package/dist/chunks/J5S4URAW.js +1 -0
  28. package/dist/chunks/JPZFKSWT.js +1 -0
  29. package/dist/chunks/KESCTXGO.js +5 -0
  30. package/dist/chunks/L3N4FIEN.js +1 -0
  31. package/dist/chunks/NAOUTU7A.js +4 -0
  32. package/dist/chunks/NDIM7MEW.js +1 -0
  33. package/dist/chunks/O4PPOM5Z.js +2 -0
  34. package/dist/chunks/OVZFGILJ.js +1 -0
  35. package/dist/chunks/P5ZHHOOM.js +6 -0
  36. package/dist/chunks/PUSUPTAT.js +1 -0
  37. package/dist/chunks/QMMLQJBS.js +1 -0
  38. package/dist/chunks/RK3VP2Q4.js +3 -0
  39. package/dist/chunks/SGGMBSBA.js +1 -0
  40. package/dist/chunks/SL2YLB2F.js +1 -0
  41. package/dist/chunks/TOOIB6J2.js +1 -0
  42. package/dist/chunks/TYTQRLTX.js +1 -0
  43. package/dist/chunks/UC3FVVJ2.js +5 -0
  44. package/dist/chunks/UCTEU62F.js +1 -0
  45. package/dist/chunks/UD3VJER6.js +1 -0
  46. package/dist/chunks/UKXMCHHT.js +1 -0
  47. package/dist/chunks/WUUKTSRT.js +7 -0
  48. package/dist/chunks/X65X4KP5.js +7 -0
  49. package/dist/chunks/YIR5MYGU.js +1 -0
  50. package/dist/chunks/YLNJXQ3Z.js +1 -0
  51. package/dist/context.d.ts +101 -0
  52. package/dist/index.d.ts +47 -0
  53. package/dist/index.js +77 -0
  54. package/dist/journal/catalog.d.ts +112 -0
  55. package/dist/journal/forkChain.d.ts +16 -0
  56. package/dist/journal/index.d.ts +15 -0
  57. package/dist/journal/journal.d.ts +475 -0
  58. package/dist/journal/projection.d.ts +87 -0
  59. package/dist/journal/store.d.ts +181 -0
  60. package/dist/kit/claim.d.ts +13 -0
  61. package/dist/kit/drain.d.ts +10 -0
  62. package/dist/kit/extension.d.ts +180 -0
  63. package/dist/kit/grants.d.ts +9 -0
  64. package/dist/kit/modes.d.ts +65 -0
  65. package/dist/kit/retries.d.ts +25 -0
  66. package/dist/kit/scope.d.ts +32 -0
  67. package/dist/kit/service.d.ts +7 -0
  68. package/dist/kit/strategy.d.ts +10 -0
  69. package/dist/kit/timers.d.ts +43 -0
  70. package/dist/kit/tool.d.ts +72 -0
  71. package/dist/llm/client.d.ts +135 -0
  72. package/dist/llm/content.d.ts +52 -0
  73. package/dist/llm/door.d.ts +21 -0
  74. package/dist/llm/door.js +1 -0
  75. package/dist/llm/failure.d.ts +82 -0
  76. package/dist/llm/index.d.ts +16 -0
  77. package/dist/llm/primitives.d.ts +286 -0
  78. package/dist/llm/prompt.d.ts +21 -0
  79. package/dist/llm/provider.d.ts +63 -0
  80. package/dist/llm/readLedger.d.ts +24 -0
  81. package/dist/llm/request.d.ts +58 -0
  82. package/dist/loop/agent.d.ts +134 -0
  83. package/dist/loop/auxiliary.d.ts +54 -0
  84. package/dist/loop/chain.d.ts +46 -0
  85. package/dist/loop/chunks.d.ts +27 -0
  86. package/dist/loop/continuation.d.ts +166 -0
  87. package/dist/loop/decide.d.ts +64 -0
  88. package/dist/loop/errors.d.ts +162 -0
  89. package/dist/loop/forks.d.ts +61 -0
  90. package/dist/loop/holds.d.ts +104 -0
  91. package/dist/loop/hooks.d.ts +241 -0
  92. package/dist/loop/inbox.d.ts +188 -0
  93. package/dist/loop/index.d.ts +37 -0
  94. package/dist/loop/limits.d.ts +14 -0
  95. package/dist/loop/opening.d.ts +42 -0
  96. package/dist/loop/prepare.d.ts +30 -0
  97. package/dist/loop/projections.d.ts +307 -0
  98. package/dist/loop/replace.d.ts +33 -0
  99. package/dist/loop/requests.d.ts +129 -0
  100. package/dist/loop/route.d.ts +53 -0
  101. package/dist/loop/runtime.d.ts +85 -0
  102. package/dist/loop/state.d.ts +70 -0
  103. package/dist/loop/strategy.d.ts +71 -0
  104. package/dist/loop/summary.d.ts +3 -0
  105. package/dist/loop/surface.d.ts +153 -0
  106. package/dist/loop/threadState.d.ts +72 -0
  107. package/dist/loop/tool.d.ts +101 -0
  108. package/dist/loop/toolCalls.d.ts +42 -0
  109. package/dist/loop/wake.d.ts +32 -0
  110. package/dist/models/config/agent.d.ts +18 -0
  111. package/dist/models/config/prompt.d.ts +18 -0
  112. package/dist/models/door.d.ts +12 -0
  113. package/dist/models/door.js +1 -0
  114. package/dist/models/index.d.ts +7 -0
  115. package/dist/models/jsonSchema.d.ts +7 -0
  116. package/dist/models/wire/journal.d.ts +2772 -0
  117. package/dist/models/wire/primitives.d.ts +65 -0
  118. package/dist/plugin.d.ts +53 -0
  119. package/dist/plugin.js +1 -0
  120. package/dist/plugins/agentsMd.d.ts +76 -0
  121. package/dist/plugins/agentsMd.js +1 -0
  122. package/dist/plugins/ask/askQuestion.d.ts +9 -0
  123. package/dist/plugins/ask/index.d.ts +26 -0
  124. package/dist/plugins/ask/index.js +1 -0
  125. package/dist/plugins/ask/service.d.ts +125 -0
  126. package/dist/plugins/commands/background.d.ts +8 -0
  127. package/dist/plugins/commands/foreground.d.ts +4 -0
  128. package/dist/plugins/commands/index.d.ts +40 -0
  129. package/dist/plugins/commands/index.js +1 -0
  130. package/dist/plugins/commands/output.d.ts +115 -0
  131. package/dist/plugins/commands/record.d.ts +549 -0
  132. package/dist/plugins/commands/service.d.ts +314 -0
  133. package/dist/plugins/commands/shell.d.ts +25 -0
  134. package/dist/plugins/compaction/checkpoint.d.ts +91 -0
  135. package/dist/plugins/compaction/config.d.ts +133 -0
  136. package/dist/plugins/compaction/estimate.d.ts +29 -0
  137. package/dist/plugins/compaction/index.d.ts +2 -0
  138. package/dist/plugins/compaction/index.js +7 -0
  139. package/dist/plugins/compaction/log.d.ts +61 -0
  140. package/dist/plugins/compaction/planner.d.ts +207 -0
  141. package/dist/plugins/compaction/preset.d.ts +86 -0
  142. package/dist/plugins/compaction/prune.d.ts +9 -0
  143. package/dist/plugins/compaction/records.d.ts +227 -0
  144. package/dist/plugins/compaction/segments.d.ts +23 -0
  145. package/dist/plugins/compaction/shared.d.ts +14 -0
  146. package/dist/plugins/compaction/summarize.d.ts +13 -0
  147. package/dist/plugins/dateAndBranch.d.ts +47 -0
  148. package/dist/plugins/dateAndBranch.js +1 -0
  149. package/dist/plugins/delegations/answers.d.ts +39 -0
  150. package/dist/plugins/delegations/assignmentKey.d.ts +22 -0
  151. package/dist/plugins/delegations/cleanup.d.ts +161 -0
  152. package/dist/plugins/delegations/constraint.d.ts +76 -0
  153. package/dist/plugins/delegations/index.d.ts +39 -0
  154. package/dist/plugins/delegations/index.js +1 -0
  155. package/dist/plugins/delegations/notices.d.ts +261 -0
  156. package/dist/plugins/delegations/obligations.d.ts +210 -0
  157. package/dist/plugins/delegations/record.d.ts +632 -0
  158. package/dist/plugins/delegations/request.d.ts +381 -0
  159. package/dist/plugins/delegations/role.d.ts +30 -0
  160. package/dist/plugins/delegations/service.d.ts +562 -0
  161. package/dist/plugins/delegations/standing.d.ts +19 -0
  162. package/dist/plugins/delegations/stopCheck.d.ts +21 -0
  163. package/dist/plugins/delegations/testing.d.ts +16 -0
  164. package/dist/plugins/delegations/tools.d.ts +71 -0
  165. package/dist/plugins/delegations/waitBook.d.ts +116 -0
  166. package/dist/plugins/delegations/waits.d.ts +118 -0
  167. package/dist/plugins/diagnostics/digest.d.ts +14 -0
  168. package/dist/plugins/diagnostics/index.d.ts +68 -0
  169. package/dist/plugins/diagnostics/index.js +1 -0
  170. package/dist/plugins/historyRecall/history.d.ts +9 -0
  171. package/dist/plugins/historyRecall/index.d.ts +31 -0
  172. package/dist/plugins/historyRecall/index.js +1 -0
  173. package/dist/plugins/historyRecall/render.d.ts +34 -0
  174. package/dist/plugins/historyRecall/tools.d.ts +4 -0
  175. package/dist/plugins/mcp/catalog.d.ts +36 -0
  176. package/dist/plugins/mcp/config.d.ts +63 -0
  177. package/dist/plugins/mcp/connection.d.ts +53 -0
  178. package/dist/plugins/mcp/errors.d.ts +32 -0
  179. package/dist/plugins/mcp/index.d.ts +33 -0
  180. package/dist/plugins/mcp/index.js +5 -0
  181. package/dist/plugins/mcp/mount.d.ts +98 -0
  182. package/dist/plugins/mcp/names.d.ts +25 -0
  183. package/dist/plugins/mcp/render.d.ts +29 -0
  184. package/dist/plugins/mcp/slots.d.ts +15 -0
  185. package/dist/plugins/mcp/stdio.d.ts +49 -0
  186. package/dist/plugins/mcp/tool.d.ts +41 -0
  187. package/dist/plugins/providers/anthropic.d.ts +175 -0
  188. package/dist/plugins/providers/anthropicMessages.d.ts +65 -0
  189. package/dist/plugins/providers/codex.d.ts +60 -0
  190. package/dist/plugins/providers/codexAuth.d.ts +116 -0
  191. package/dist/plugins/providers/deepseek.d.ts +55 -0
  192. package/dist/plugins/providers/door.d.ts +61 -0
  193. package/dist/plugins/providers/door.js +1 -0
  194. package/dist/plugins/providers/failure.d.ts +23 -0
  195. package/dist/plugins/providers/gateway.d.ts +23 -0
  196. package/dist/plugins/providers/index.d.ts +6 -0
  197. package/dist/plugins/providers/openaiChat.d.ts +62 -0
  198. package/dist/plugins/providers/openaiResponses.d.ts +100 -0
  199. package/dist/plugins/providers/opencodeCopilot.d.ts +23 -0
  200. package/dist/plugins/providers/opencodeGo.d.ts +98 -0
  201. package/dist/plugins/providers/shared.d.ts +104 -0
  202. package/dist/plugins/providers/stream.d.ts +154 -0
  203. package/dist/plugins/routeContext.d.ts +22 -0
  204. package/dist/plugins/routeContext.js +1 -0
  205. package/dist/plugins/schedules/index.d.ts +21 -0
  206. package/dist/plugins/schedules/index.js +5 -0
  207. package/dist/plugins/schedules/record.d.ts +396 -0
  208. package/dist/plugins/schedules/service.d.ts +120 -0
  209. package/dist/plugins/schedules/time.d.ts +26 -0
  210. package/dist/plugins/schedules/tools.d.ts +6 -0
  211. package/dist/plugins/skills/discovery.d.ts +54 -0
  212. package/dist/plugins/skills/index.d.ts +31 -0
  213. package/dist/plugins/skills/index.js +1 -0
  214. package/dist/plugins/skills/tool.d.ts +11 -0
  215. package/dist/plugins/store/durableObject.d.ts +23 -0
  216. package/dist/plugins/store/durableObject.js +1 -0
  217. package/dist/plugins/store/durableObjectConnection.d.ts +27 -0
  218. package/dist/plugins/store/memory.d.ts +29 -0
  219. package/dist/plugins/store/sql.d.ts +59 -0
  220. package/dist/plugins/store/sqlite.d.ts +31 -0
  221. package/dist/plugins/store/sqlite.js +1 -0
  222. package/dist/plugins/subAgents/availableRoutes.d.ts +53 -0
  223. package/dist/plugins/subAgents/fork.d.ts +32 -0
  224. package/dist/plugins/subAgents/index.d.ts +67 -0
  225. package/dist/plugins/subAgents/index.js +1 -0
  226. package/dist/plugins/subAgents/tool.d.ts +38 -0
  227. package/dist/plugins/toolPolicy/index.d.ts +61 -0
  228. package/dist/plugins/toolPolicy/index.js +1 -0
  229. package/dist/plugins/tools/editFiles.d.ts +128 -0
  230. package/dist/plugins/tools/fsRead.d.ts +17 -0
  231. package/dist/plugins/tools/html.d.ts +23 -0
  232. package/dist/plugins/tools/index.d.ts +59 -0
  233. package/dist/plugins/tools/index.js +1 -0
  234. package/dist/plugins/tools/network.d.ts +23 -0
  235. package/dist/plugins/tools/ripgrep.d.ts +20 -0
  236. package/dist/plugins/tools/textEdit.d.ts +67 -0
  237. package/dist/plugins/tools/web.d.ts +32 -0
  238. package/dist/plugins/truncateToolOutput.d.ts +26 -0
  239. package/dist/plugins/truncateToolOutput.js +1 -0
  240. package/dist/plugins/usage/index.d.ts +24 -0
  241. package/dist/plugins/usage/index.js +1 -0
  242. package/dist/plugins/usage/tracker.d.ts +34 -0
  243. package/dist/plugins/verify/facts.d.ts +356 -0
  244. package/dist/plugins/verify/index.d.ts +75 -0
  245. package/dist/plugins/verify/index.js +1 -0
  246. package/dist/plugins/verify/service.d.ts +90 -0
  247. package/dist/plugins/workflows/assignment.d.ts +16 -0
  248. package/dist/plugins/workflows/bindings.d.ts +95 -0
  249. package/dist/plugins/workflows/cleanup.d.ts +38 -0
  250. package/dist/plugins/workflows/definition.d.ts +184 -0
  251. package/dist/plugins/workflows/fold.d.ts +373 -0
  252. package/dist/plugins/workflows/index.d.ts +28 -0
  253. package/dist/plugins/workflows/index.js +6 -0
  254. package/dist/plugins/workflows/observations.d.ts +81 -0
  255. package/dist/plugins/workflows/participants.d.ts +143 -0
  256. package/dist/plugins/workflows/policy.d.ts +112 -0
  257. package/dist/plugins/workflows/providers.d.ts +146 -0
  258. package/dist/plugins/workflows/record.d.ts +2863 -0
  259. package/dist/plugins/workflows/routing.d.ts +116 -0
  260. package/dist/plugins/workflows/schema.d.ts +26 -0
  261. package/dist/plugins/workflows/service.d.ts +477 -0
  262. package/dist/plugins/workflows/submit.d.ts +8 -0
  263. package/dist/plugins/workflows/view.d.ts +103 -0
  264. package/dist/plugins/workflows/work.d.ts +21 -0
  265. package/dist/plugins/workspaceContext.d.ts +38 -0
  266. package/dist/plugins/workspaceContext.js +1 -0
  267. package/dist/presets/agents.d.ts +7 -0
  268. package/dist/presets/base.d.ts +10 -0
  269. package/dist/presets/codex.d.ts +60 -0
  270. package/dist/presets/index.d.ts +4 -0
  271. package/dist/presets/prompts.d.ts +56 -0
  272. package/dist/sandbox/absent.d.ts +32 -0
  273. package/dist/sandbox/client.d.ts +39 -0
  274. package/dist/sandbox/files.d.ts +28 -0
  275. package/dist/sandbox/index.d.ts +49 -0
  276. package/dist/sandbox/index.js +4 -0
  277. package/dist/sandbox/mode.d.ts +57 -0
  278. package/dist/sandbox/policy.d.ts +86 -0
  279. package/dist/sandbox/protocol.d.ts +107 -0
  280. package/dist/sandbox/service.d.ts +143 -0
  281. package/dist/sandbox/worker.d.ts +12 -0
  282. package/dist/sandbox/worker.js +1 -0
  283. package/dist/services/admission.d.ts +174 -0
  284. package/dist/services/agents.d.ts +37 -0
  285. package/dist/services/birth.d.ts +220 -0
  286. package/dist/services/contributions.d.ts +73 -0
  287. package/dist/services/core.d.ts +34 -0
  288. package/dist/services/journal.d.ts +26 -0
  289. package/dist/services/launches.d.ts +104 -0
  290. package/dist/services/llm.d.ts +80 -0
  291. package/dist/services/owner.d.ts +367 -0
  292. package/dist/services/preset.d.ts +154 -0
  293. package/dist/services/presets.d.ts +139 -0
  294. package/dist/services/prompts.d.ts +67 -0
  295. package/dist/services/runEvents.d.ts +79 -0
  296. package/dist/services/thread.d.ts +267 -0
  297. package/dist/services/threadActivation.d.ts +100 -0
  298. package/dist/services/threadDirs.d.ts +38 -0
  299. package/dist/services/threadView.d.ts +92 -0
  300. package/dist/services/threads.d.ts +449 -0
  301. package/dist/services/tools.d.ts +41 -0
  302. package/dist/sys/environment.d.ts +47 -0
  303. package/dist/sys/git.d.ts +60 -0
  304. package/dist/sys/paths.d.ts +56 -0
  305. package/dist/sys/spawn.d.ts +176 -0
  306. package/dist/testing/clock.d.ts +17 -0
  307. package/dist/testing/fakeLlm.d.ts +74 -0
  308. package/dist/testing/fedLlm.d.ts +32 -0
  309. package/dist/testing/helpers.d.ts +344 -0
  310. package/dist/testing/index.d.ts +13 -0
  311. package/dist/testing/index.js +1 -0
  312. package/dist/testing/processes.d.ts +13 -0
  313. package/dist/testing/sandbox.d.ts +71 -0
  314. package/dist/testing/settlement.d.ts +6 -0
  315. package/dist/testing/tmpDirs.d.ts +17 -0
  316. package/dist/util/async.d.ts +8 -0
  317. package/dist/util/diff.d.ts +25 -0
  318. package/dist/util/dispatch.d.ts +8 -0
  319. package/dist/util/errors.d.ts +28 -0
  320. package/dist/util/foldState.d.ts +17 -0
  321. package/dist/util/freeze.d.ts +2 -0
  322. package/dist/util/ids.d.ts +2 -0
  323. package/dist/util/json.d.ts +37 -0
  324. package/dist/util/log.d.ts +6 -0
  325. package/dist/util/text.d.ts +21 -0
  326. package/dist/util/version.d.ts +2 -0
  327. package/package.json +175 -3
package/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ PROPRIETARY LICENSE
2
+
3
+ Copyright (c) 2026 Duan Leu. All rights reserved.
4
+
5
+ This software is proprietary and confidential. It is published to the npm
6
+ registry solely so that it can be installed by its owner and by parties the
7
+ owner has authorized in writing. No license or right is granted to any other
8
+ person to use, copy, modify, merge, publish, distribute, sublicense, sell,
9
+ reverse engineer, or create derivative works of this software, in whole or in
10
+ part, without the prior written permission of the owner.
11
+
12
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
15
+ OWNER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY ARISING FROM, OUT OF
16
+ OR IN CONNECTION WITH THE SOFTWARE OR ITS USE.
package/README.md CHANGED
@@ -1,3 +1,145 @@
1
- # Temporary Holding Version
1
+ # @leuduan/lagent
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ A plugin-based agent execution engine built on [Cordis](../cordis). One application owns one
4
+ append-only journal; conversations are threads in that journal. The host chooses providers,
5
+ capabilities, credentials and user-interface policy.
6
+
7
+ The journal is the state. Reopening reconstructs conversation history and unfinished work from
8
+ recorded facts. Plugins and process resources are mounted again by the application.
9
+
10
+ ## Quick start
11
+
12
+ This creates a chat thread using a host-owned Codex login. Run on Node 22 or newer for SQLite.
13
+
14
+ ```ts
15
+ import { homedir } from 'node:os'
16
+ import { resolve } from 'node:path'
17
+ import { Context } from '@leuduan/cordis'
18
+ import { base, core, heldOrSettled, registerProvider, waitForRun } from '@leuduan/lagent'
19
+ import { codexAuthPath, codexProvider } from '@leuduan/lagent/providers'
20
+ import { SqliteJournalStore } from '@leuduan/lagent/sqlite'
21
+
22
+ const root = new Context()
23
+ const cwd = process.cwd()
24
+ const dataDir = resolve('.lagent')
25
+
26
+ try {
27
+ await root.plugin(core, {
28
+ store: new SqliteJournalStore(`${dataDir}/journal`, { lockDirectory: `${dataDir}/locks`, busyTimeoutMs: 1_000 }),
29
+ cwd,
30
+ dataDir,
31
+ retention: 'retire',
32
+ chainLimit: 10,
33
+ })
34
+ registerProvider(
35
+ root,
36
+ codexProvider({
37
+ authPath: codexAuthPath(process.env, homedir()),
38
+ refreshTimeoutMs: 30_000,
39
+ streamIdleTimeoutMs: 300_000,
40
+ }),
41
+ { retry: { maxAttempts: 3, baseDelayMs: 500, maxDelayMs: 10_000 } },
42
+ )
43
+ await root.plugin(base)
44
+ // Nothing runs before this: every plugin a thread needs is mounted.
45
+ await root.threads.start({ resume: 'none', startLimit: 4 })
46
+
47
+ // Every thread is born on a complete route: which model runs is the application's choice. A creation
48
+ // also says where its configuration comes from (`birth.from`) and what an existing id must match (`reuse`).
49
+ const thread = await root.threads.create('main', {
50
+ id: 'main',
51
+ reuse: 'identity',
52
+ birth: { from: 'defaults', route: { provider: 'codex', model: 'gpt-6-luna', thinking_effort: 'medium' } },
53
+ })
54
+ thread.onChunk(({ chunk }) => process.stdout.write(chunk.text_delta))
55
+ const sent = await thread.send('Say hello.', { wake: {} })
56
+ if (sent.status === 'queued' && sent.runId !== null) {
57
+ await waitForRun(root.threads, thread.id, sent.runId, heldOrSettled)
58
+ // A cause that landed as that run ended belongs to its successor, when there is one.
59
+ const successor = thread.summary.pending_run?.run_id
60
+ if (successor !== undefined) await waitForRun(root.threads, thread.id, successor, heldOrSettled)
61
+ }
62
+ } finally {
63
+ await root.fiber.dispose()
64
+ }
65
+ ```
66
+
67
+ `base` supplies plumbing and a `main` agent with no granted tools. For coding, the host registers
68
+ workspace, command and other capability plugins, then installs `codexPreset` on a thread, or mounts
69
+ it on the root for an agent selector, to grant them to that thread's agent. Composition and required host configuration are explained in [Plugin authoring](docs/plugins.md).
70
+
71
+ ## Core model
72
+
73
+ | Concept | Responsibility |
74
+ | ---------- | ------------------------------------------------------------------------- |
75
+ | Root | Shared journal, core services and application-owned plugins. |
76
+ | Thread | Durable conversation on an agent, with its environment, prompt and route. |
77
+ | Activation | Reconstructible scope owning a thread's plugins, readiness and resources. |
78
+ | Origin | The caller a delegated thread sits under, and its call or assignment. |
79
+ | Fork | A conversation continuing another thread's history at a settled cut. |
80
+
81
+ Creating or reading a thread does not activate its plugins. Work activates it lazily and waits for
82
+ readiness. One exclusive operation holds a thread at a time; conflicting work fails busy, and a run
83
+ waits its turn. The engine runs a thread when a recorded request asks it to and nothing holds it.
84
+
85
+ Tools and grants are live registrations. Prompts are rendered once after readiness and recorded;
86
+ plugin guidance uses that same prompt. Rebuild explicitly when a conversation should receive new
87
+ instructions. Dynamic thread facts enter the conversation as sourced notices.
88
+
89
+ ## Reading and driving threads
90
+
91
+ ```ts
92
+ await thread.send('Another message', { wake: {} })
93
+ const { state } = root.threads.inspect(thread.id, { basis: 'catalog' })!
94
+ const transcript = await thread.read((view) => view.transcript())
95
+ ```
96
+
97
+ `send` queues durable input; with `wake` it also asks for a run, which the engine serves once
98
+ nothing holds the thread, and its outcome names that run (`runId`). Without it, input waits for the
99
+ next run. `waitForRun(root.threads, id, runId, heldOrSettled)` waits for that run, as the quick
100
+ start does, not for the input to be answered or the thread to go quiet: a cause that lands while an
101
+ execution finishes is carried to a successor request, so after the wait the answer may belong to
102
+ the run `thread.summary.pending_run` then names, which is the one to wait for next.
103
+
104
+ The host records what a person did, presents confirmations, failures and background work from
105
+ `threads.inspect` and run events, and decides when to `start`. [Threads and recovery](docs/lifecycle.md)
106
+ explains holds, cancellation, input ordering, forks, read lifetimes and recovery.
107
+
108
+ The host supplies environment-dependent configuration. Lagent does not choose a workspace,
109
+ credential file, skill root or subprocess environment from its own process, and refuses a relative
110
+ core `cwd`, `dataDir`, thread `cwd` or read root rather than resolve it against the process directory. Core's
111
+ `dataDir` is required either way; `null` turns thread directories off for a host without a filesystem of its
112
+ own, and the plugins that need them (`truncateToolOutput`, `commands`, `sandbox`) then refuse to mount. One process holds one
113
+ journal; incompatible journal formats and extension payloads are refused rather than migrated.
114
+
115
+ ## Imports
116
+
117
+ Use the explicit [package entry points](package.json). The root serves applications;
118
+ `@leuduan/lagent/plugin` serves plugin authors; `llm` and `models` expose their contracts, the provider
119
+ contract included; `providers` holds the shipped providers; `sqlite` holds the SQLite store, the one
120
+ door that needs `node:sqlite`; `durable-object` holds the store over a Cloudflare Durable Object's SQLite storage; `sandbox` holds the optional OS sandbox for shell commands, the launch handler of `ctx.launches`, whose
121
+ worker thread is the one module that loads `@anthropic-ai/sandbox-runtime`; `plugins/<name>` exposes a feature; `testing` holds test helpers. Each
122
+ door lists its names; implementation subpaths are private.
123
+
124
+ In Cloudflare Workers with `nodejs_compat`, every door imports except `sandbox`, which also needs
125
+ `new_module_registry`. Features that need a filesystem outside `/tmp`, processes or `node:sqlite` fail
126
+ when used. The Workers tests run in workerd with `pnpm -F @leuduan/lagent run test:workers`.
127
+
128
+ MCP clients identify themselves with the version statically imported from the package metadata,
129
+ so bundled hosts carry the same version as source and `dist/` consumers.
130
+
131
+ ## Guides
132
+
133
+ Start with the [documentation map](docs/README.md). It distinguishes usage contracts from the design
134
+ records explaining decisions. [Architecture](docs/architecture.md) gives the ownership model.
135
+ The Works host is an application example, documented in [its guide](../../apps/works/docs/agent.md).
136
+
137
+ ## Scripts
138
+
139
+ Run from the repository root:
140
+
141
+ ```sh
142
+ pnpm -F @leuduan/lagent run ts-check
143
+ pnpm -F @leuduan/lagent run test
144
+ pnpm -F @leuduan/lagent run build
145
+ ```
@@ -0,0 +1 @@
1
+ import{b as wt}from"./4XVRUSCQ.js";import{a as mt}from"./UD3VJER6.js";import{a as lt}from"./SGGMBSBA.js";import{a as ct}from"./3QCW4WDJ.js";import{a as ft}from"./RK3VP2Q4.js";import{a as dt,b as ut}from"./74HKUGRR.js";import{a as pt}from"./YIR5MYGU.js";import{a as be}from"./NDIM7MEW.js";import{a as j,b as le}from"./34KW6VNQ.js";import{e as g}from"./G6RXC3AL.js";import{d as ht}from"./GQGNVSKB.js";import{b as ot,c as at}from"./2OSESBIL.js";import{$ as Ze,A as Ne,B as We,D as re,F as Ge,G as k,I as x,J as b,K as Je,L as P,M as Ve,N as Ke,O as $,P as F,Q as ie,R as Qe,T as Xe,V as ne,W as M,X as L,Y as O,Z as Ye,_ as se,aa as Ie,b as _e,ba as et,ca as B,d as ke,da as tt,e as qe,ea as rt,f as T,fa as it,g as xe,ga as nt,k as Re,l as $e,m as Fe,ma as st,n as Me,o as h,p as q,q as Le,s as v,t as y,u as Oe,v as Be,x as He,y as ze,z as Ue}from"./YLNJXQ3Z.js";import{a as w,f as oe,h as ae}from"./DDANMY45.js";import{a as m,c as Te,d as _,g as A,k as Ce,l as Ae,n as De,o as D,p as Pe,r as ee,s as te}from"./37YOGDGY.js";import{d as C,j as je,l as Se,n as Ee}from"./KESCTXGO.js";import{b as we,c as ge,e as I,g as ye}from"./TYTQRLTX.js";import{k as ve}from"./D7E6EWIE.js";import{Service as Ct}from"@leuduan/cordis";import{z as H}from"zod";var At=H.strictObject({maxAttempts:H.number().int().min(1).max(100),baseDelayMs:H.number().int().min(0).max(le),maxDelayMs:H.number().int().min(0).max(le)}).refine(a=>a.baseDelayMs<=a.maxDelayMs,{message:"baseDelayMs must not exceed maxDelayMs"}),Dt=new Set(["rate_limit","overloaded","transport","timeout","empty"]),gt=Symbol("register"),Zt=(a,e,t)=>{let r=At.parse(t.retry);return a.effect(()=>a.llm[gt](e,r))},z=class extends Ct{providers=new Map;policies=new Map;clients=new Map;constructor(e){super(e,"llm"),e.effect(()=>()=>this.disposeClients(this.detachClients(()=>!0)))}get providerNames(){return C(this.providers.keys())}[gt](e,t){if(this.providers.has(e.name))throw new Error(`LLM provider already registered for name: ${e.name}`);return this.providers.set(e.name,e),this.policies.set(e.name,t),async()=>{this.providers.get(e.name)===e&&(this.providers.delete(e.name),this.policies.delete(e.name),await this.disposeClients(this.detachClients(r=>r===e.name)))}}provider(e){let t=this.providers.get(e);if(t===void 0)throw new x({provider:e});return t}unavailable(e){return this.providers.has(e.provider)?null:new x(e).message}resolveRoute(e,t){let r=e.thinkingEffort,i=r==null?r:ve.parse(r);if(e.provider===void 0||e.provider===t.provider)return this.provider(t.provider),{provider:t.provider,model:e.model??t.model,thinking_effort:i===void 0?t.thinking_effort:i};let n=ye(this.provider(e.provider),e.model,i??void 0);return i===null?{...n,thinking_effort:null}:n}capacity(e){return this.provider(e.provider).capacity(e.model)}clientFor(e){let t=this.provider(e.provider),r=this.clients.get(t.name);return r===void 0&&(r=new de(t,t.createClient(),this.policies.get(t.name)),this.clients.set(t.name,r)),r}detachClients(e){let t=[];for(let[r,i]of this.clients)e(r)&&(this.clients.delete(r),t.push(i));return t}async disposeClients(e){let r=(await Promise.allSettled(e.map(async({inner:i})=>i.dispose?.()))).flatMap(i=>i.status==="rejected"?[i.reason]:[]);if(r.length)throw new AggregateError(r,"LLM client cleanup failed")}},de=class{providerName;provider;inner;policy;constructor(e,t,r){this.provider=e,this.inner=t,this.policy=r,this.providerName=t.providerName}call(e){return new ue(this,e)}failure(e,t){let{kind:r,retryAfterMs:i}=ge(this.provider,e);return new we(this.provider.name,r,t,i??null,{cause:e})}},ue=class{response;calls=0;current;yielded=!1;claimed=!1;entered=!1;ledger=new be;outcome;client;request;constructor(e,t){this.client=e,this.request=t,this.response=this.attempt().then(r=>(this.current=r,this))}get attempts(){return this.calls}[Symbol.asyncIterator](){this.claim();let e=this.read(!0),t,r=()=>this.entered?Promise.resolve():(t??=(async()=>{try{await this.current?.[Symbol.asyncIterator]().return?.()}catch(i){let n=this.final(i);throw this.outcome={error:n},n}finally{this.ledger.finish()}})(),t);return{next:()=>this.ledger.operation(()=>e.next()),return:i=>this.ledger.operation(async()=>{let n=e.return(i);return await r(),n}),throw:i=>this.ledger.operation(async()=>{let n=e.throw(i);return n.catch(()=>{}),await r(),n})}}claim(){if(this.claimed)throw new Error("A model call is read once: it has been claimed already");this.claimed=!0}async*read(e){this.entered=!0;try{for(;;)try{for await(let t of this.current)e&&(this.yielded=!0,yield t);this.outcome={response:await this.current.completed()};return}catch(t){try{await this.recover(t),this.current=await this.attempt()}catch(r){throw this.outcome={error:r},r}}}finally{this.ledger.finish()}}async completed(){if(this.claimed){if(!this.ledger.ended)throw new Error("A model call is settled before its read or after it, not while the read is under way")}else{this.claim();for await(let e of this.read(!1));}if(this.outcome!==void 0){if("error"in this.outcome)throw this.outcome.error;return this.outcome.response}try{let e=await this.current.completed();return this.outcome={response:e},e}catch(e){let t=this.final(e);throw this.outcome={error:t},t}}final(e){return ae(this.request.signal,e)?e:this.client.failure(e,this.calls)}async attempt(){for(;;){this.request.signal.throwIfAborted(),this.calls+=1;try{return await this.client.inner.chat(this.request)}catch(e){await this.recover(e)}}}async recover(e){let{signal:t}=this.request;if(ae(t,e))throw e;let r=this.calls,i=this.client.failure(e,r),{maxAttempts:n,baseDelayMs:s,maxDelayMs:o}=this.client.policy;if(!(!t.aborted&&!this.yielded&&this.request.providerTools.length===0&&Dt.has(i.kind)&&r<n&&(i.retryAfterMs===null||i.retryAfterMs<=o)))throw i;let l=Math.min(o,s*2**(r-1));await Pt(i.retryAfterMs??Math.floor(Math.random()*(l+1)),t)}};function Pt(a,e){return new Promise((t,r)=>{if(e.aborted){r(e.reason);return}let i=()=>{clearTimeout(n),r(e.reason)},n=setTimeout(()=>{e.removeEventListener("abort",i),t()},a);e.addEventListener("abort",i,{once:!0})})}var $t={releases:!1,chain:"person"},U=class{inbox;service;admission;id;journal;constructor(e,t,r,i){this.service=e,this.admission=t,this.id=r,this.journal=i,this.inbox=new P(i,r)}async read(e){let t=await this.service.retain(()=>[this.id],{lastRelease:"keep"});try{let r=e(this.service.view(this.id));if(typeof r?.then=="function")throw new TypeError("thread.read takes a synchronous reader; to read across awaits, hold the thread with ctx.threads.retain");return r}finally{t.release()}}get ctx(){return this.service.contextOf(this.id)}get signal(){return this.service.signalOf(this.id)}whenReady(){return this.service.whenReady(this.id)}configure(e){return this.service.configure(this.id,e)}close(){return this.service.close(this.id)}get summary(){let e=this.journal.summary(this.id);if(e===void 0)throw new ReferenceError(`Unknown thread: ${this.id}`);return e}get agentName(){return this.summary.agent_name}get metadata(){return this.summary.metadata}get origin(){return this.summary.origin}get depth(){return this.journal.origins.callers(this.id).threads.filter(e=>e.origin!==null).length}get originRoot(){let{threads:e,chain:t}=this.journal.origins.callers(this.id);return t==="complete"&&e.length>0?e[e.length-1].thread_id:null}get environment(){return this.summary.environment}get forkedFrom(){let{fork:e}=this.summary;return e===null?null:{threadId:e.thread_id,seq:e.seq}}get lineageRoot(){return Te(this.journal.summaryMap(),this.id).at(-1)?.thread_id??this.id}lastOutcome(){return this.summary.last_reason}fork(e){return this.service.fork(this.id,e)}rebuildPrompt(){return this.service.rebuildPrompt(this.id)}on(e){return this.journal.subscribe(t=>t.thread_id===this.id?e(t):void 0)}onChunk(e){return this.service.chunks.subscribe(t=>{t.thread_id===this.id&&e(t)})}send(e,t={}){return this.inbox.send(e,()=>this.admission.inputTarget(this.id),t,this.service.routes)}withdraw(e,t={}){return this.inbox.withdraw(e,t)}async answer(e,t={}){await this.journal.transact(this.id,()=>{let{confirmations:r}=this.journal.state(h,this.id),i=new Set(T(r,this.id).map(o=>o.request_id)),n=new Set;for(let{request_id:o}of e){if(n.has(o))throw new Error(`A batch of answers names request_id=${o} twice on thread ${this.id}`);if(n.add(o),i.has(o))continue;let d=r.get(o)?.resolution;throw d!=null?new Ne(this.id,o,d):new Error(`Unknown pending confirmation request_id=${o} on thread ${this.id}`)}let s=t.wake===!0?b(this.id,this.pendingRun(),$t,null).rows:[];return{rows:[...vt(this.id,e),...s],value:void 0}})}async resume(e={}){let t=e.route===void 0?{}:{route:e.route},{value:r}=await this.journal.transact(this.id,()=>{let i=b(this.id,this.pendingRun(),t,null,this.service.routes);return{rows:i.rows,value:i.runId}});return r}closeWaitRows(e){return ke(this.journal.state(h,this.id).waits).map(({declaration:t})=>{let r=this.journal.eventAt(t.call_seq);if(r?.type!=="tool/call")throw new Error(`The wait at ${t.seq} on thread ${this.id} cites no call at ${t.call_seq}`);return{type:"tool/result",data:{turn:t.turn,step:t.step,result:{call_id:t.call_id,name:r.data.name,output:`The call was cancelled while it waited: ${e}`,is_error:!0,notes:null,metadata:{wait_cancelled:!0}}},options:{threadId:this.id,sourceSeqs:[t.call_seq,t.seq]}}})}pendingRun(){return this.journal.state(h,this.id).requests.pending}async revokeApprovals(e,t=null){await this.journal.transact(this.id,()=>{if(this.admission.isRunning(this.id))throw new y(this.id);let r=new Map(F(this.journal,this.id).map(n=>[n.request_id,n])),i=[...new Set(e)];for(let n of i)if(r.get(n)?.resolution?.approved!==!0)throw new Error(`No approved, unfinished confirmation request_id=${n} on thread ${this.id}`);return{rows:vt(this.id,i.map(n=>({request_id:n,approved:!1,rejection_message:t}))),value:void 0}})}compact(e={}){return this.service.compact(this.id,e)}async cancel(e,t){let{intent:r}=t,i=this.admission.cancel(this.id,e,r),n=this.journal.transact(this.id,()=>{let s=Ie(this.pendingRun(),i.capturedSettles()?i.capturedRunId:null);return{rows:[{type:"thread/cancel",data:{cancel_id:k("cancel"),intent:r,run_id:i.capturedRunId,reason:e},options:{threadId:this.id}},...this.inbox.clearRows(),...this.closeWaitRows(e),...t.rows?.(this.id)??[],...s===null?[]:[{type:"run/settled",data:{run_id:s,outcome:O(r),reason:"cancel",error_text:null,through:this.journal.head,residual:[]},options:{threadId:this.id}}]],value:void 0}});if(i.wrote(n),t.until==="recorded"){await n;return}try{await n}finally{await i.settled}}},vt=(a,e)=>e.map(t=>({type:"confirm/resolved",data:{request_id:t.request_id,approved:t.approved,rejection_message:t.rejection_message??null},options:{threadId:a}}));import{mkdirSync as Ft}from"node:fs";import{join as yt}from"node:path";import{Service as Mt}from"@leuduan/cordis";var N=class extends Mt{dataDir;root;constructor(e,t){super(e,"threadDirs"),this.dataDir=t.dataDir===null?null:g(t.dataDir,"The data directory"),this.root=this.dataDir===null?null:yt(this.dataDir,"threads"),this.root!==null&&e.on("lagent/thread/activate",r=>{this.ensure(r.id)})}require(e){if(this.dataDir===null)throw new Error(`${e} needs thread directories; core was mounted with \`dataDir: null\``);return this.dataDir}dirFor(e){if(this.root===null)throw new Error("Thread directories are off; core was mounted with `dataDir: null`");let t=encodeURIComponent(e);if(t===""||t==="."||t==="..")throw new Error(`Invalid thread id: ${e}`);return yt(this.root,t)}ensure(e){let t=this.dirFor(e);return Ft(t,{recursive:!0,mode:448}),t}};import{Service as Ht}from"@leuduan/cordis";var W=class{admitted=new Map;cancels=new Map;listeners=new Set;closing;report;constructor(e,t){this.closing=e,this.report=t}requireFree(e){this.closing.throwIfAborted();let t=this.admitted.get(e);if(t!==void 0)throw new y(e,t.kind)}admit(e,t,r={}){this.closing.throwIfAborted(),r.signal?.throwIfAborted(),this.requireFree(e);let i=Promise.withResolvers(),n=this.operation(e,t,i,r);return this.admitted.set(e,n),this.publish({thread_id:e,kind:t,phase:"admitted"}),n}operation(e,t,r,i){let n=new AbortController,s=this.admitted,o={threadId:e,kind:t,runId:i.runId??null,controller:n,signal:AbortSignal.any([this.closing,n.signal,...i.signal?[i.signal]:[]]),settled:r.promise,settle:r.resolve,releasing:t==="configure",releasingStarted:Promise.withResolvers(),cancelIntent:null,settlementBuilt:!1,lease:{get held(){return s.get(e)===o}}};return o}async hold(e,t,r={}){let i=this.holding(e),n=!1;try{return await t()}catch(s){throw n=!0,s}finally{try{let l=r.cleanup?.();l!==void 0&&await l}catch(l){this.report(l)}if(r.finalize!==void 0)for(this.setReleasing(i,!0);;){let l=i.cancelIntent;if(await Promise.resolve().then(r.finalize).catch(this.report),i.cancelIntent===l)break}let{threadId:s}=i;this.admitted.get(s)===i&&this.admitted.delete(s);let o=this.cancels.get(s);o?.captured===i&&(o.captured=null,o.writes>0&&this.holdForCancel(s,o)),i.settle();let d=i.kind!=="release"&&i.signal.aborted?"cancelled":n?"failed":"completed";this.publish({thread_id:s,kind:i.kind,phase:"settled",ended:d}),o?.operation!=null&&this.publish({thread_id:s,kind:"cancel",phase:"admitted"}),o!==void 0&&this.finishCancel(s,o)}}setReleasing(e,t){let r=this.holding(e);r.releasing!==t&&(r.releasing=t,t?r.releasingStarted.resolve():r.releasingStarted=Promise.withResolvers())}cancel(e,t,r){let i=this.cancels.get(e);i===void 0&&(i={captured:null,writes:0,operation:null,failed:!1,done:Promise.withResolvers()},this.cancels.set(e,i));let n=this.admitted.get(e),s=n===void 0;s?this.holdForCancel(e,i):n!==i.operation&&(i.captured=n,n.cancelIntent??=r),i.writes+=1;let o=i,d=o.captured;return{capturedRunId:d?.runId??null,settled:o.done.promise,capturedSettles:()=>d!==null&&!d.settlementBuilt,wrote:l=>{l.then(()=>this.wroteCancel(e,o,!1),()=>this.wroteCancel(e,o,!0)),s&&this.publish({thread_id:e,kind:"cancel",phase:"admitted"}),d!==null&&d.kind!=="release"&&d.controller.abort(new Error(t))}}}cancelIntent(e){return e.cancelIntent}settlementBuilt(e){e.settlementBuilt=!0}holdForCancel(e,t){let r=this.operation(e,"cancel",t.done,{});t.operation=r,this.admitted.set(e,r)}wroteCancel(e,t,r){t.writes-=1,r&&(t.failed=!0),this.finishCancel(e,t)}finishCancel(e,t){if(t.writes>0||t.captured!==null)return;this.cancels.get(e)===t&&this.cancels.delete(e);let{operation:r}=t;if(r!==null&&this.admitted.get(e)===r&&this.admitted.delete(e),t.done.resolve(),r===null)return;let i=t.failed?"failed":"completed";this.publish({thread_id:e,kind:"cancel",phase:"settled",ended:i})}holder(e){let t=this.admitted.get(e);return t===void 0?null:Object.freeze({kind:t.kind,runId:t.runId})}isAdmitted(e){return this.admitted.has(e)}isRunning(e){let t=this.admitted.get(e)?.kind;return t==="run"||t==="compact"}isReleasing(e){let t=this.admitted.get(e);return t?.kind==="release"||t?.releasing===!0}inputTarget(e){let t=this.admitted.get(e);return t?.kind==="run"&&!t.signal.aborted&&!t.releasing?"next-step":"next-turn"}settlement(e){return this.admitted.get(e)?.settled??Promise.resolve()}async whenSettled(e){for(;;){let t=this.admitted.get(e);if(t===void 0||this.isReleasing(e))return;await Promise.race([t.settled,t.releasingStarted.promise])}}async drain(){for(;;){let e=[...[...this.admitted.values()].map(t=>t.settled),...[...this.cancels.values()].map(t=>t.done.promise)];if(e.length===0)return;await Promise.all(e)}}onOperation(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}holding(e){let t=this.admitted.get(e.threadId);if(t!==e)throw new Error(`The operation does not hold thread ${e.threadId}`);return t}publish(e){this.listeners.size!==0&&A(this.listeners,m(structuredClone(e)),this.report)}};var G=class{started=!1;starting;limit=Number.POSITIVE_INFINITY;counted=0;startupDeclined=new Set;owners=new Map;nextSerial=0;dirty=new Set;scheduled=!1;admitting=new Set;preparations=new Set;executing=new Map;waiting=[];holds=new Map;listeners=new Set;preparation=new Map;host;limits;constructor(e,t){this.host=e,this.limits=t}async start(e){if(this.starting!==void 0)throw new Error("ctx.threads.start was already called");let{resume:t,startLimit:r}=e;if(!Number.isSafeInteger(r)||r<1)throw new Error("startLimit must be a positive integer");let i=Promise.withResolvers();this.starting=i.promise,this.limit=r,await Promise.all([...this.owners.values()].map(s=>this.repair(s))),await this.host.journal.flush();let n=Date.now();for(let s of this.host.journal.summaries()){let o=s.pending_run;o!==null&&Lt(t,o.newest_cause_at,n)&&this.startupDeclined.add(s.thread_id)}this.started=!0,i.resolve();for(let s of this.host.journal.summaries())s.pending_run!==null&&this.schedule(s.thread_id)}registerOwner(e){if(this.owners.has(e.owner))throw new Error(`An owner is already registered for ${e.owner}`);let t={registration:e,serial:this.nextSerial+=1,state:e.repair===void 0?"ready":"repairing"};this.owners.set(e.owner,t),this.scheduleRequiring(e.owner),this.starting!==void 0&&this.starting.then(()=>this.repair(t));let r=()=>this.owners.get(e.owner)===t;return{changed:i=>{r()&&(this.holds.delete(i),this.forgetPreparation(i),this.schedule(i))},resolveWait:(i,n)=>r()?this.resolveWait(e.owner,r,i,n):Promise.reject(new Error(`The registration for ${e.owner} was disposed`)),dispose:()=>{if(r()){this.owners.delete(e.owner),this.scheduleRequiring(e.owner);for(let[i,n]of this.holds)n.hold.reason==="constraint"&&n.hold.owner===e.owner&&(this.holds.delete(i),this.schedule(i))}}}}async repair(e){let{registration:t}=e;if(t.repair===void 0)e.state="ready";else{e.state="repairing";try{await t.repair(),e.state="ready"}catch(r){this.host.report(r),e.state={failed:w(r)}}}this.scheduleRequiring(t.owner)}scheduleRequiring(e){let{journal:t}=this.host,r=new Set;for(let i of t.summaries()){if(!r.has(i.thread_id)&&i.requires.includes(e))for(let s of t.origins.subtree(i.thread_id,{self:!0}))r.add(s.thread_id);!i.waits.some(s=>s.owner===e)&&!r.has(i.thread_id)||(this.forgetDecided(i.thread_id,"missing"),this.forgetDecided(i.thread_id,"constraint"),this.forgetDecided(i.thread_id,"wait"),this.forgetPreparation(i.thread_id),this.schedule(i.thread_id))}}isRegistered(e){return this.owners.has(e)}async resolveWait(e,t,{threadId:r,callSeq:i},n){let{journal:s}=this.host;if(s.summary(r)===void 0)return{status:"unknown"};let{value:o}=await s.transact(r,()=>{if(!t())throw new Error(`The registration for ${e} was disposed`);let d=s.state(h,r),l=d.waits.get(i);if(l===void 0||l.declaration.owner!==e)return{rows:[],value:{status:"unknown"}};if(l.value!==null)return{rows:[],value:{status:"resolved-before",value:l.value}};if(l.answered)return{rows:[],value:{status:"closed"}};let u=n(l.declaration);if(u===null)return{rows:[],value:{status:"declined"}};let c={releases:!1,chain:u.chain??"reactive"};return{rows:[{type:"wait/resolved",data:{call_seq:i,value:u.value},options:{threadId:r,sourceSeqs:[l.declaration.seq,...u.evidence??[]]}},...b(r,d.requests.pending,c,null).rows],value:{status:"resolved"}}});return o}onRow(e,t){if(t.type==="run/cause"&&t.data.releases){this.forgetPreparation(e);for(let r of this.host.journal.origins.subtree(e,{self:!0}))this.startupDeclined.delete(r.thread_id)&&(this.forgetDecided(r.thread_id,"startup"),this.forgetPreparation(r.thread_id),this.schedule(r.thread_id))}if(t.type==="run/requested"&&this.publish({threadId:e,runId:t.data.run_id,state:"requested"}),t.type==="run/settled"){let r=t.data.run_id;this.executing.get(e)?.runId!==r&&this.publishState(e,r)}for(let r of this.host.journal.origins.callers(e).threads)this.holds.delete(r.thread_id),this.schedule(r.thread_id)}onSettled(e,t){let r=this.executing.get(e);t==="run"&&r!==void 0&&(this.executing.delete(e),this.afterExecution(e,r)),this.schedule(e)}async whenIdle(){await Promise.all([...this.preparations])}close(){for(let e of[...this.preparation.keys()])this.forgetPreparation(e);for(let e of this.host.journal.summaries()){let t=e.pending_run;t!==null&&this.executing.get(e.thread_id)?.runId!==t.run_id&&this.publish({threadId:e.thread_id,runId:t.run_id,state:"held",hold:{reason:"shutdown"},basis:"catalog"})}}onRunEvent(e){return this.listeners.add(e),()=>{this.listeners.delete(e)}}runState(e,t){if(this.executing.get(e)?.runId===t)return{state:"running"};let r=this.durable(e,t);if(r.state==="pending"&&this.host.signal.aborted)return{state:"held",hold:{reason:"shutdown"},basis:"catalog"};let i=r.state==="pending"?this.host.journal.summary(e):void 0,n=i===void 0?null:this.idleHold(i,t,this.approvalBlocked(i));return mt({durable:r,executing:!1,held:n})}inspect(e,t){let r=this.host.journal.summary(e);if(r===void 0)return null;t==="loaded"&&this.requireLoaded(e);let i=this.host.admission.holder(e),n=i===null||i.kind==="run"?null:i.kind,s=this.approvalBlocked(r),o=(u,c=null)=>({state:u,operation:n,hold:c,missing:c?.reason==="missing"?this.missingDetail(e):null,approvalBlocked:s,basis:t});if(this.executing.has(e))return o("running");let d=r.pending_run;if(d===null)return o("idle");let l=t==="loaded"?this.loadedHold(r,d.run_id):this.idleHold(r,d.run_id,s)?.hold??null;return l===null?o("requested"):o("held",l)}requireLoaded(e){let{journal:t}=this.host;for(let{thread_id:r}of t.origins.callers(e).threads)if(!t.isLoaded(r))throw new Error(`Thread ${e} cannot be inspected on the loaded basis: thread ${r} is not loaded`)}loadedHold(e,t){if(e.pending_run?.run_id!==t||this.admitting.has(e.thread_id))return null;let r=this.entryDecision(e.thread_id);return r.kind==="hold"?r.hold:null}approvalBlocked(e){return e.last_reason?.kind!=="blocked"?!1:this.host.journal.origins.subtree(e.thread_id,{self:!0}).some(t=>t.unanswered_confirmations.length>0)}idleHold(e,t,r){let i=e.thread_id,n=this.holds.get(i);if(n?.runId===t)return{hold:n.hold,basis:n.basis};if(e.pending_run?.run_id!==t||this.admitting.has(i))return null;let s=this.verdict(e);if(s.kind==="obsolete"||e.pending_run.cancelled)return null;let o=this.catalogHold(e,r);return o!==null?{hold:o,basis:"catalog"}:s.kind==="hold"?{hold:se(s),basis:"catalog"}:null}declined(e){return this.startupDeclined.has(e)}missing(e){let{owners:t,chain:r}=this.missingDetail(e);return[...r==="complete"?[]:[`the callers above ${r.at??e} cannot be read`],...t.map(({owner:n,state:s})=>s==="absent"?`${n} is not registered`:s==="repairing"?`${n} is repairing`:`${n} failed to repair: ${s.failed}`)]}missingDetail(e){let{owners:t,chain:r}=this.host.journal.origins.requiredOwners(e);return{chain:r,owners:t.flatMap(({owner:i,introducedBy:n})=>{let s=this.owners.get(i)?.state;return s==="ready"?[]:[{owner:i,state:s??"absent",introducedBy:n}]})}}requiredRegistrations(e){if(this.missing(e).length>0)return null;let{owners:t}=this.host.journal.origins.requiredOwners(e);return JSON.stringify(t.map(({owner:r})=>r).sort().map(r=>[r,this.owners.get(r).serial]))}verdict(e){let t=null;for(let{registration:r,state:i}of this.owners.values()){if(i!=="ready")continue;let n;try{let{constraint:s}=r;if(s?.applies(e)!==!0)continue;n=s.evaluate(e.thread_id)}catch(s){n={kind:"hold",reason:`${r.owner} could not decide: ${w(s)}`}}if(n.kind==="obsolete")return n;n.kind==="hold"&&(t??={...n,owner:r.owner})}return t??{kind:"allow"}}decide(e,{cancel:t,ending:r,start:i}){let{journal:n}=this.host,s=n.summary(e);if(s===void 0)throw new v(e);let o=n.state(h,e),d=o.requests.pending;if(d===null)throw new Error(`Thread ${e} has no pending run to decide for`);let l=n.origins.subtree(e,{self:!0}),u=o.requests.pendingCancel,c=o.inbox;return Ze({pending:d,ending:r,repairsLeft:Ye(o.requests),work:{hasWork:Ve(n,e,this.limits),nextStepQueued:c["next-step"].length>0,anyQueued:c["next-step"].length+c["next-turn"].length>0,unanswered:qe(o.surface.entries.map(f=>f.message)).length>0},answeredUnder:i!==null&&l.some(f=>f.answered_at!==null&&f.answered_at>i),holds:this.derivedHolds(e,o,l),constraint:this.verdict(s),cancel:t??(u?.runId===d.runId?u.intent:null)})}entryDecision(e){return this.decide(e,{cancel:null,...B(this.host.journal.state(h,e))})}derivedHolds(e,t,r){let i=[...t.waits.values()].find(_e)?.declaration;return ne({approval:t.turnBoundary.lastReason?.kind==="blocked"&&r.some(n=>n.unanswered_confirmations.length>0),failed:M(t.requests),cancelled:L(t.requests),startupDeclined:this.declined(e),missing:this.missing(e),unresolvedWait:i===void 0?null:{callSeq:i.call_seq,reason:i.reason,owner:i.owner,deadlineAt:i.deadline_at,registered:this.isRegistered(i.owner)}})}schedule(e){this.dirty.add(e),!this.scheduled&&(this.scheduled=!0,queueMicrotask(()=>{this.scheduled=!1;let t=[...this.dirty];this.dirty.clear();for(let r of t)this.consider(r)}))}consider(e){if(!this.started||this.host.signal.aborted||this.admitting.has(e)||this.executing.has(e))return;let t=this.host.journal.summary(e),r=t?.pending_run??null;if(t===void 0||r===null){this.holds.delete(e),this.forgetPreparation(e);return}if(this.preparation.get(e)?.runId!==r.run_id&&this.forgetPreparation(e),this.host.admission.isAdmitted(e))return;let i=this.verdict(t);if(!(i.kind==="obsolete"||r.cancelled)){let o=this.catalogHold(t,this.approvalBlocked(t));if(o!==null&&o.reason!=="approval")return this.hold(e,r.run_id,o,{decided:!1});if(o===null&&i.kind==="hold")return this.hold(e,r.run_id,se(i),{decided:!1});let d=this.holds.get(e);if(d?.runId===r.run_id&&d.decided)return}if(this.holds.delete(e),this.preparation.get(e)?.retryAt!=null)return;if(this.counted>=this.limit){this.waiting.includes(e)||this.waiting.push(e);return}if(this.host.signal.aborted)return;let s=this.admit(e).catch(o=>this.host.report(o));this.preparations.add(s),s.then(()=>this.preparations.delete(s))}catalogHold(e,t){let r=e.pending_run;if(r===null)return null;let i=e.waits.find(s=>!s.resolved),[n]=ne({approval:t,failed:e.latest_settlement?.outcome==="failed"&&!r.releasing,cancelled:e.latest_user_cancel!==null&&!e.latest_user_cancel.released,startupDeclined:this.startupDeclined.has(e.thread_id),missing:this.missing(e.thread_id),unresolvedWait:i===void 0?null:{callSeq:i.call_seq,reason:i.reason,owner:i.owner,deadlineAt:i.deadline_at,registered:this.isRegistered(i.owner)}});return n??null}async admit(e){let{admission:t,journal:r}=this.host;this.admitting.add(e),this.counted+=1;let i,n;try{if(i=await this.host.retain(e),this.host.signal.aborted||t.isAdmitted(e))return;let s=r.state(h,e).requests.pending;if(s===null){this.forgetPreparation(e);return}let o=this.entryDecision(e);if(this.forgetPreparation(e),o.kind==="hold"){o.hold.reason!=="shutdown"&&this.hold(e,s.runId,o.hold,{decided:!0});return}this.holds.delete(e),this.admitting.delete(e);let d;n={runId:s.runId,attemptCutoff:r.head,final:null,errorText:null,decide:f=>this.decide(e,{cancel:d===void 0?null:t.cancelIntent(d),...f})},this.executing.set(e,n),d=t.admit(e,"run",{runId:s.runId});let l=d,u=n,c=t.hold(l,()=>this.host.execute(u,l),{finalize:()=>this.finalize(l,u),cleanup:()=>this.host.cleanup(l)});this.publish({threadId:e,runId:s.runId,state:"running"}),await c.catch(f=>this.host.report(f))}catch(s){this.host.report(s),n===void 0&&this.retryLater(e)}finally{this.admitting.delete(e),n!==void 0&&this.executing.get(e)===n&&(this.executing.delete(e),this.afterExecution(e,n)),this.counted-=1,i?.release(),n!==void 0&&this.schedule(e),this.drain()}}async finalize(e,t){let{admission:r,journal:i}=this.host,{threadId:n}=e;if(!i.isLoaded(n)){r.settlementBuilt(e);return}await i.transact(n,()=>{r.settlementBuilt(e);let s=i.state(h,n),o=s.requests.pending;if(o?.runId!==t.runId)return{rows:[],value:void 0};let d=s.requests.pendingCancel?.runId===o.runId?s.requests.pendingCancel:null,l=r.cancelIntent(e)??d?.intent??null,u=l===null?t.final:{kind:"settle",outcome:O(l),reason:"cancel"};if(u?.kind!=="settle")return{rows:[],value:void 0};let c=Me(o,{outcome:u.outcome,reason:u.reason,attemptCutoff:t.attemptCutoff,cancelSeq:d?.seq??null},f=>$(s,f).state);return{rows:[{type:"run/settled",data:{run_id:o.runId,outcome:u.outcome,reason:u.reason,error_text:u.reason==="setup"?t.errorText??"the run failed before a turn":null,through:i.head,residual:c},options:{threadId:n}},...c.length===0?[]:[{type:"run/requested",data:{run_id:k("run")},options:{threadId:n}}]],value:void 0}})}retryLater(e){let t=this.host.journal.summary(e)?.pending_run?.run_id;if(this.host.signal.aborted||t===void 0)return;let r=this.preparation.get(e);r?.timer!=null&&clearTimeout(r.timer);let i=r?.runId===t?r.attempts+1:1,n=Math.min(6e4,500*2**(i-1)),s={runId:t,attempts:i,retryAt:Date.now()+n,timer:null};s.timer=setTimeout(()=>{this.preparation.get(e)===s&&(s.retryAt=null,s.timer=null,this.schedule(e))},n),s.timer.unref?.(),this.preparation.set(e,s)}forgetPreparation(e){let t=this.preparation.get(e);t!==void 0&&(t.timer!==null&&clearTimeout(t.timer),this.preparation.delete(e))}afterExecution(e,{runId:t,final:r}){let i=this.durable(e,t);if(i.state==="settled")return this.publishState(e,t);if(i.state!=="pending")return;if(this.host.signal.aborted)return this.publish({threadId:e,runId:t,state:"held",hold:{reason:"shutdown"},basis:"catalog"});if(r?.kind==="hold"&&r.hold.reason!=="shutdown")return this.hold(e,t,r.hold,{decided:!1,always:!0,basis:"loaded"});let n;try{n=this.entryDecision(e)}catch(s){this.host.report(s);return}n.kind==="hold"&&n.hold.reason!=="shutdown"&&this.hold(e,t,n.hold,{decided:!0,always:!0})}hold(e,t,r,i){let n=this.holds.get(e),s=i.basis??(i.decided?"loaded":"catalog");this.holds.set(e,{runId:t,hold:r,decided:i.decided,basis:s}),!(i.always!==!0&&n?.runId===t&&Xe(n.hold,r))&&this.publish({threadId:e,runId:t,state:"held",hold:r,basis:s})}forgetDecided(e,t){let r=this.holds.get(e);r?.decided===!0&&r.hold.reason===t&&this.holds.delete(e)}drain(){for(;this.counted<this.limit&&this.waiting.length>0;){let e=this.waiting.shift();this.consider(e)}}durable(e,t){let{journal:r}=this.host;if(r.isLoaded(e))return Fe(r.state(h,e).requests,t);let i=r.summary(e);if(i?.pending_run?.run_id===t)return{state:"pending"};let n=i?.latest_settlement;return n?.run_id!==t||n===void 0||n===null?{state:"unknown"}:{state:"settled",settlement:{runId:t,seq:0,outcome:n.outcome,reason:n.reason,errorText:n.error_text,through:0,residual:[]}}}publishState(e,t){let r=this.runState(e,t);r!==null&&this.publish({threadId:e,runId:t,...r})}publish(e){A([...this.listeners],Object.freeze(e),t=>this.host.report(t))}};function Lt(a,e,t){return a==="all"?!1:a==="none"||e===null?!0:t-Date.parse(e)>a.newerThanMs}var S=(a,e)=>_(a)===_(e);function he(a){return[...new Set(a.map(e=>g(e,"A read root")))]}var E=a=>[...new Set(a??[])].sort();function J(a,e){let{agent:t,origin:r,birth:i,reuse:n}=e;if(i.from==="exact"){let{spec:l}=i;return{agent:t,origin:r,spec:{route:I.parse(l.route),environment:{cwd:g(l.environment.cwd,"A thread cwd"),read_roots:he(l.environment.read_roots)},installations:a.presets.initialInstallations(l.installations.map(({installation_id:u,preset_id:c,config:f,lifetime:p})=>({presetId:c,config:f,installationId:u,lifetime:p})),t),requires:E(l.requires)}}}let s=i.installations??[];if(n==="configuration"){let l=s.find(u=>u.installationId===void 0);if(l!==void 0)throw new Error(`A creation reused by configuration must name its installations: ${l.presetId} has no id`)}let o=i.from==="caller"&&r!==null?a.journal.summary(r.caller_thread_id):void 0,d=a.presets.initialInstallations(s,t);return{agent:t,origin:r,spec:{route:I.parse(i.route),environment:{cwd:g(i.environment?.cwd??o?.environment.cwd??a.defaultCwd,"A thread cwd"),read_roots:he(i.environment?.read_roots??o?.environment.read_roots??[])},installations:i.from==="caller"&&r!==null?[...d,...a.handedDown(t,d,r.caller_thread_id)]:d,requires:E(i.requires)}}}function bt(a,e){return{environment:{cwd:g(e.environment?.cwd??a.environment.cwd,"A thread cwd"),read_roots:he(e.environment?.read_roots??a.environment.read_roots)},requires:E(e.requires)}}function _t(a,e){let t=a.stateAt(q("threadRoute"),e.threadId,e.seq);if(t===null)throw new Error(`Thread ${e.threadId} has no route at row ${e.seq}`);let{current:r}=a.stateAt(q("installations"),e.threadId,e.seq);return{route:t,installations:[...r.values()].map(({installationId:i,presetId:n,config:s,lifetime:o})=>({installation_id:i,preset_id:n,config:s,lifetime:o}))}}function kt(a,e){if(a.kind==="fresh"){let{agent:o,origin:d,spec:l}=a.opening;return{agent_name:o,metadata:e,origin:d,environment:{cwd:l.environment.cwd,read_roots:[...l.environment.read_roots]},installations:l.installations.map(u=>({...u})),requires:[...l.requires],route:{...l.route}}}let{agent:t,origin:r,cut:i,environment:n,requires:s}=a.opening;return{agent_name:t,metadata:e,fork:{thread_id:i.threadId,seq:i.seq},origin:r,environment:n,requires:s,route:null}}function V(a,e){let t=[],r=a.fork===null?"fresh":"fork";if(r!==e.kind&&t.push({field:"kind",recorded:r,requested:e.kind}),a.agent_name!==e.agent&&t.push({field:"agent",recorded:a.agent_name,requested:e.agent}),S(a.origin,e.origin)||t.push({field:"origin",recorded:a.origin,requested:e.origin}),a.fork!==null&&e.cut!==void 0){let i={threadId:a.fork.thread_id,seq:a.fork.seq};S(i,e.cut)||t.push({field:"cut",recorded:i,requested:e.cut})}return t}function qt(a,e){let t=[],r=(i,n,s)=>{S(n,s)||t.push({field:i,recorded:n,requested:s})};return r("route",a.route,e.route),r("environment",a.environment,e.environment),r("installations",a.installations??[],e.installations),r("requires",E(a.requires),e.requires),t}function xt(a,e){let t=[];return S(a.environment,e.environment)||t.push({field:"environment",recorded:a.environment,requested:e.environment}),S(E(a.requires),e.requires)||t.push({field:"requires",recorded:[...a.requires],requested:e.requires}),t}function R(a,e){if(e.length>0)throw new He(a,e)}import{createScope as Ot,FiberState as ce,scopeTarget as Bt}from"@leuduan/cordis";var K=class{scope;target;runtime;loop;readiness;controller=new AbortController;failed=!1;prepared=!1;readyTree;staleBecause;draining=!1;closingDone;service;admission;thread;released;constructor(e,t,r,i,n,s){this.service=e,this.admission=t,this.thread=i,this.released=s,this.scope=Ot(r),this.target=Bt(this.scope.ctx),this.runtime={...n(this.scope.key),ctx:this.scope.ctx,target:this.target,signal:this.controller.signal,stale:()=>this.isStale(),strategy:()=>wt(this.scope.ctx,i.id)},this.loop=new st({runtime:this.runtime,threadId:i.id,agentName:i.agentName});let o=this.scope.ctx.fiber;o.beforeUnload(()=>(this.controller.abort(new Error(`Thread ${i.id} context is closing`)),this.admission.whenSettled(i.id))),this.readiness=this.observe(Promise.resolve().then(async()=>{await o.await(),this.controller.signal.throwIfAborted(),await this.service.load(i.id),this.controller.signal.throwIfAborted();let d=r.parallel(this.target,"lagent/thread/activate",i,this.controller.signal);await Promise.resolve();let u=(await Promise.allSettled([d,r.presets.restore(i)])).flatMap(f=>f.status==="fulfilled"?[]:f.reason instanceof AggregateError?f.reason.errors:[f.reason]);if(u.length===1)throw u[0];if(u.length>1)throw new AggregateError(u,`Thread ${i.id} could not be activated`);let c=await this.settle();this.prepared=!0,this.watchTree(c)}))}watchTree(e){this.readyTree=e;for(let t of e.slice(1))t.beforeUnload(()=>this.markStale(`plugin ${t.name} was unloaded`))}markStale(e){this.staleBecause??=e}isStale(){if(this.staleBecause!==void 0)return!0;if(this.readyTree===void 0||this.closingDone!==void 0)return!1;let t=this.scope.ctx.fiber.tree().filter(i=>!this.readyTree.includes(i));if(t.length===0)return!1;let r=t.map(i=>i.name).join(", ");return this.markStale(`${r} mounted after it was ready`),this.scope.ctx.reportError(new Error(`Thread ${this.thread.id}: ${r} mounted through thread.ctx after the thread was ready; a thread's plugins come from its activate listeners and installations, so its next operation activates it afresh without them`)),!0}get activating(){return this.failed?!1:this.prepared?this.scope.ctx.fiber.tree().some(e=>e.transition!==void 0):!0}observe(e){return e.catch(t=>{if(this.failed=!0,!this.admission.isAdmitted(this.thread.id)&&!this.draining){let r=this.scope.ctx.fiber.tree().some(i=>i.state===ce.FAILED&&i.error===t);!this.controller.signal.aborted&&!r&&this.scope.ctx.reportError(t),this.service.releaseFailed(this.thread.id).catch(i=>this.scope.ctx.reportError(i))}}),e}get signal(){return this.controller.signal}get hasFailed(){return this.failed}get closed(){return this.closingDone}async settle(){let e=await this.scope.ctx.fiber.awaitTree();this.controller.signal.throwIfAborted();for(let t of e)if(t.state!==ce.ACTIVE)throw new Error(`Thread ${this.thread.id}: required plugin ${t.name} is ${ce[t.state]}`);return e}async run(e){let t=AbortSignal.any([this.controller.signal,e.signal]);t.throwIfAborted(),await this.ready(t),await this.loop.run({...e,signal:t})}async compact(e){let{lease:t}=e,r=AbortSignal.any([this.controller.signal,e.signal]);try{await this.ready(r)}catch(i){if(!(r.aborted&&Object.is(i,r.reason)))throw i;return{committed:[],ended:"cancelled",reason:w(r.reason)}}return this.loop.compact({signal:r,lease:t,options:e.options??null})}async ready(e){await j(this.readiness,e),e.throwIfAborted(),this.runtime.agent(this.thread.agentName),await this.service.load(this.thread.id),await this.service.recordPromptOnce(this.scope.key)}async whenReady(){await this.readiness,await this.service.load(this.thread.id)}stop(e){this.draining=!0,this.controller.abort(e)}async whenIdle(){await this.readiness.catch(()=>{}),await this.scope.ctx.fiber.awaitTree().catch(()=>{})}release(){if(this.closingDone!==void 0)return this.closingDone;let e=Promise.withResolvers();return this.closingDone=e.promise,this.controller.abort(new Error(`Thread ${this.thread.id} context released`)),(async()=>{try{await this.whenIdle(),await this.scope.dispose()}finally{this.released()}})().then(e.resolve,e.reject),this.closingDone}};var Q=class{inbox;journal;threadId;targetOf;constructor(e,t,r){this.journal=e,this.threadId=t,this.targetOf=r,this.inbox=new P(e,t)}target(){return m(structuredClone(this.targetOf(this.threadId)))}transcript(){return this.journal.state(h,this.threadId).surface.entries.map(e=>e.message)}messageSeqs(){return this.journal.state(h,this.threadId).surface.entries.map(e=>e.row)}requestBehind(e){return nt(this.journal,e)}originalsBehind(e){return Re(this.journal,e)}forkPoints(){return it(this.journal,this.threadId)}finalMessage(){return Qe(this.journal,this.threadId)}outcomeSince(e){return xe(this.journal,this.threadId,e)}prompt(){return this.journal.state(h,this.threadId).threadPrompt??[]}requestTools(e){if(!this.journal.inLineage(this.threadId,e))throw new Error(`Row ${e.seq} is not part of thread ${this.threadId}'s lineage`);return this.journal.stateAt(q("threadTools"),e.thread_id,e.seq)??[]}pendingConfirmations(){return m(structuredClone(T(this.journal.state(h,this.threadId).confirmations,this.threadId)))}waits(e={}){let{owner:t}=e,r=[...this.journal.state(h,this.threadId).waits.values()];return m(structuredClone(t===void 0?r:r.filter(i=>i.declaration.owner===t)))}replay(){return this.journal.rows(this.threadId)}replayLineage(){return this.journal.lineage(this.threadId)}queued(){return this.inbox.pending}input(e){return $(this.journal.state(h,this.threadId),e)}installations(){let{current:e}=this.journal.state(h,this.threadId).installations;return m([...e.values()].map(t=>structuredClone(t)))}};var fe=(a,e)=>a.signal.aborted&&Object.is(e,a.signal.reason),X=class extends Ht{static inject=["journal","agents","tools","llm","prompts","threadDirs","presets"];chunks;limits;defaultCwd;live=new Map;retentions=new Set;retiring=new Map;admission;owner;retention;chainLimit;handles=new Map;reportedCorrupt=new Set;controller=new AbortController;closing;constructor(e,t){super(e,"threads");let r=i=>e.reportError(i);if(this.chunks=new Le(r),this.admission=new W(this.controller.signal,r),this.retention=t.retention,!Number.isInteger(t.chainLimit)||t.chainLimit<1)throw new Error(`chainLimit must be a positive integer, not ${t.chainLimit}`);this.chainLimit=t.chainLimit,this.owner=new G({journal:this.journal,admission:this.admission,signal:this.controller.signal,execute:(i,n)=>this.execute(i,n),cleanup:i=>this.cleanup(i),retain:i=>this.retainExecutionReads(i,{retiring:!0}),report:r},t.limits),e.effect(()=>e.journal.subscribe(i=>this.owner.onRow(i.thread_id,i))),e.effect(()=>this.admission.onOperation(i=>{i.phase==="settled"&&this.owner.onSettled(i.thread_id,i.kind)})),this.limits=t.limits,this.defaultCwd=g(t.cwd,"The core cwd"),pt(e,()=>this.shutdown()),e.effect(()=>this.journal.onRevoked(()=>{this.shutdown().catch(i=>e.reportError(i))}))}get signal(){return this.controller.signal}shutdown(){if(this.closing!==void 0)return this.closing;let e=Promise.withResolvers();this.closing=e.promise;let t=new Error("lagent is closing");this.controller.abort(t),this.owner.close();let r=[...this.live.values()];for(let i of r)i.stop(t);return(async()=>{await this.owner.whenIdle(),await this.admission.drain(),await Promise.all(r.map(i=>i.whenIdle())),await Promise.all(r.map(i=>i.release()))})().then(e.resolve,e.reject),this.closing}list(e={}){let t=e.under===void 0?void 0:this.subtreeIds(e.under),r=e.origin===void 0?void 0:_(e.origin);return this.journal.summaries().filter(i=>!(e.agentName!==void 0&&i.agent_name!==e.agentName||e.callerThreadId!==void 0&&i.origin?.caller_thread_id!==e.callerThreadId||r!==void 0&&_(i.origin)!==r||t!==void 0&&!t.has(i.thread_id))).map(i=>this.handle(i.thread_id))}get(e){return this.journal.summary(e)!==void 0?this.handle(e):void 0}liveThreads(){return[...this.live.keys()].map(e=>this.handle(e))}start(e){return this.owner.start(e)}inspect(e,{basis:t}){return this.owner.inspect(e,t)}onRunEvent(e){return this.owner.onRunEvent(e)}runState(e,t){return this.owner.runState(e,t)}chain(e){return $e(this.journal.state(h,e).chain,this.chainLimit)}registerOwner(e){return this.owner.registerOwner(e)}async releaseUnder(e,t){let r=this.admission.admit(e,"release");await this.under(r,async()=>{await this.settledLive(e),await this.live.get(e)?.release(),await t?.()})}async retain(e,t){let r=[...e()];for(let u of r)this.requireThread(u);let i={members:e};this.retentions.add(i);let n=this.journal.hold(r),s=!1,o=()=>{if(!s&&(s=!0,this.retentions.delete(i),n(),!(t.lastRelease!=="retire"||this.closing!==void 0)))try{for(let u of new Set([...r,...e()]))this.retire(u)}catch(u){this.ctx.reportError(u)}};await Promise.all((t.waitOn??r).map(u=>this.retiring.get(u)));let l=(await Promise.allSettled(r.map(u=>this.load(u)))).find(u=>u.status==="rejected");if(l!==void 0)throw o(),l.reason;return{release:o}}view(e){return new Q(this.journal,e,t=>this.target(t))}covered(){let e=new Set;for(let t of this.retentions)for(let r of t.members())e.add(r);return e}retire(e){if(this.retiring.has(e)||this.closing!==void 0||!this.journal.isLoaded(e)||this.covered().has(e))return;let t=(async()=>{for(;this.admission.isAdmitted(e);)await this.admission.settlement(e);this.covered().has(e)||await this.close(e)})().catch(r=>{r instanceof y||this.ctx.reportError(r)}).finally(()=>{this.retiring.get(e)===t&&this.retiring.delete(e)});this.retiring.set(e,t)}async close(e){if(this.requireThread(e),this.closing!==void 0){await this.closing,this.journal.unload(e);return}await this.releaseUnder(e,()=>{let t=this.journal.hold([...this.covered()]);try{this.journal.unload(e)}finally{t()}})}async fork(e,t){jt(t.id);let r=this.journal.hold([e]);try{return await this.forkHeld(e,t)}finally{r()}}async forkHeld(e,t){this.controller.signal.throwIfAborted();let{journal:r}=this,i=r.summaryMap();if(!i.has(e))throw new v(e);if(t.before===!0&&t.input===void 0)throw new Error("A fork before a turn needs an input");await r.load(e);let n=t.atTurn===void 0?t.at:rt(r,e,t.atTurn,t.before??!1),s=tt(r,e,n),o=t.id,d=i.get(s.threadId),l=i.get(e),u=t.origin??null,c={kind:"fork",agent:d.agent_name,origin:u,cut:s},f=()=>bt(l,t),p=i.get(o);if(p!==void 0)return this.reuseFork(p,c,f,t.reuse);let Z=St(o,t),Rt=await this.originFor(o,t.origin),Tt={kind:"fork",opening:{agent:d.agent_name,origin:Rt,cut:s,...f(),inherits:_t(r,s)}},{value:pe}=await r.transact(o,()=>{let me=r.summary(o);return me!==void 0?{rows:[],value:me}:{rows:this.openingGroup(o,Tt,Z,t),value:void 0}});return pe===void 0?this.handle(o):this.reuseFork(pe,c,f,t.reuse)}reuseFork(e,t,r,i){return R(e.thread_id,V(e,t)),i==="configuration"&&R(e.thread_id,xt(e,r())),this.handle(e.thread_id)}openingGroup(e,t,r,i){let{wake:n}=i,s=n===void 0?null:b(e,null,n,r?.id??null),o=this.journal.head+1,d="next-turn",l=kt(t,i.metadata??{}),u={threadId:e,target:d,runId:s?.runId??null,inputId:r?.id??null},c=i.rows?.(t.kind==="fresh"?{kind:"create",...u,opening:m(structuredClone(t.opening))}:{kind:"fork",...u,opening:m(structuredClone(t.opening))})??[];if(Je(c))throw new ze(c.refuse,t.kind==="fresh"?"create":"fork");return[{type:"thread/spawned",data:l,options:{threadId:e}},...r===null?[]:[{type:"inbox/spliced",data:{target:d,start:0,inserted:[r]},options:{threadId:e,sourceSeqs:[o]}}],...s?.rows??[],...c]}async create(e,t){let r=jt(t.id);this.controller.signal.throwIfAborted();let{journal:i}=this,n=i.summary(r);if(n!==void 0)return this.reuseFresh(n,e,t);this.requireGlobalAgent(e);let s=await this.originFor(r,t.origin),o=J(this.birthContext(r),{agent:e,origin:s,birth:t.birth,reuse:t.reuse}),d=St(r,t),{value:l}=await i.transact(r,()=>{let u=i.summary(r);return u!==void 0?{rows:[],value:u}:{rows:this.openingGroup(r,{kind:"fresh",opening:o},d,t),value:void 0}});return l===void 0?this.handle(r):this.reuseFresh(l,e,t)}birthContext(e){return{journal:this.journal,presets:this.ctx.presets,defaultCwd:this.defaultCwd,handedDown:(t,r,i)=>this.handedDown(e,t,r,i)}}async reuseFresh(e,t,r){let i=r.origin??null;if(R(e.thread_id,V(e,{kind:"fresh",agent:t,origin:i})),r.reuse==="configuration"){let n=J(this.birthContext(e.thread_id),{agent:t,origin:i,birth:r.birth,reuse:"configuration"});R(e.thread_id,await this.specConflictsOf(e,n.spec))}return this.handle(e.thread_id)}async specConflictsOf(e,t){let r=await this.journal.readRow(e.spawn_seq);if(r?.type!=="thread/spawned")throw new Error(`Row ${e.spawn_seq} is not thread ${e.thread_id}'s spawn`);return qt(r.data,t)}async birthConflicts(e,t){let r=this.requireThread(e),i=J(this.birthContext(e),{agent:t.agent,origin:r.origin,birth:{from:"exact",spec:t.spec},reuse:"configuration"}),n=V(r,{kind:"fresh",agent:t.agent,origin:r.origin});return n.length>0?n:this.specConflictsOf(r,i.spec)}async pendingConfirmations(e={}){await this.journal.flush();let t=e.under===void 0?void 0:this.subtreeIds(e.under),r=this.journal.summaries().filter(n=>n.unanswered_confirmations.length>0&&(t===void 0||t.has(n.thread_id))).map(n=>n.thread_id),i=await this.retain(()=>r,{lastRelease:"keep"});try{return Object.freeze(r.flatMap(n=>this.view(n).pendingConfirmations()))}finally{i.release()}}async load(e){let t=this.readSet(e),i=(await Promise.allSettled(t.map(n=>this.journal.load(n)))).find(n=>n.status==="rejected");if(i!==void 0)throw i.reason;this.reportCorrupt(t)}reportCorrupt(e){for(let t of e){if(this.reportedCorrupt.has(t)||!this.journal.isLoaded(t))continue;let r=ie(this.journal,t);r!==null&&(this.reportedCorrupt.add(t),this.ctx.reportError(new re(t,r.row,r.refusal.message)))}}requireExecutable(e){let t=ie(this.journal,e);if(t!==null)throw new re(e,t.row,t.refusal.message)}readSet(e){return this.journal.origins.callers(e).threads.map(t=>t.thread_id)}async retainExecutionReads(e,{retiring:t}){this.requireThread(e);let r=this.readSet(e),i=()=>{if(!(!t||this.retention!=="retire")){if(this.admission.isAdmitted(e)){this.admission.settlement(e).then(i);return}try{this.retire(e)}catch(o){this.ctx.reportError(o)}}},n;try{n=await this.retain(()=>r,{lastRelease:"keep",waitOn:[e]})}catch(o){throw i(),o}let s=!1;return{release:()=>{s||(s=!0,n.release(),i())}}}onChunk(e){return this.chunks.subscribe(e)}subtreeIds(e){return new Set(this.journal.origins.subtree(e,{self:!0}).map(t=>t.thread_id))}handedDown(e,t,r,i){let n=this.live.get(i);if(n===void 0||n.closed!==void 0||this.admission.isReleasing(i))throw new Error(`Thread ${e} cannot be created with an origin on thread ${i}, which has no live activation: a child is created by a call running in its caller`);return this.ctx.presets.handedDown(n.scope.key,e,t,r)}async configure(e,t){this.requireThread(e);let r=this.ctx.presets.installationsFor(t.apply??[],"change"),i=[...t.remove??[]],n=t.rebuildPrompt===!0;if(this.admission.requireFree(e),this.live.get(e)?.activating===!0)throw new Ue(e);let s=this.admission.admit(e,"configure");return this.under(s,async()=>{let o=this.journal.hold([e]);try{await this.journal.load(e),s.signal.throwIfAborted();let d=this.ctx.presets.plan(e,r,i),l=()=>({applied:d.applied,removed:d.removed});if(d.rows.length===0)return l();this.refuseRecording(e);let u=this.live.get(e),c=u!==void 0&&u.closed===void 0&&!u.hasFailed||n&&this.journal.state(h,e).threadPrompt!==null;await this.settledLive(e),await this.live.get(e)?.release();let{value:f}=await this.journal.transact(e,()=>{s.signal.throwIfAborted(),this.refuseRecording(e);let p=this.ctx.presets.plan(e,r,i);return{rows:[...p.rows],value:p}});if(d=f,this.admission.setReleasing(s,!1),!c)return l();try{let p=this.activate(e);if(await j(p.whenReady(),s.signal),n&&this.journal.state(h,e).threadPrompt!==null){s.signal.throwIfAborted();let Z=this.renderPrompt(p.scope.key,e);await this.journal.append("thread/prompt",{blocks:Z},{threadId:e})}}catch(p){if(fe(s,p))return l();throw new Oe(e,p)}return l()}finally{o()}})}refuseRecording(e){this.controller.signal.throwIfAborted();let t=F(this.journal,e);if(t.length>0){let r=t.map(i=>i.request_id).join(", ");throw new We(e,`it has unfinished confirmations (${r}); answer them, let their calls run, or revoke their approvals first`)}}requireGlobalAgent(e){at(e)||this.ctx.agents.require(void 0,e)}async originFor(e,t){if(t===void 0)return null;let r=Ee.parse(t);if(this.journal.summary(r.caller_thread_id)===void 0)throw new v(r.caller_thread_id);if(this.handle(r.caller_thread_id).depth+1>this.limits.maxThreadDepth)throw new Be(e,this.limits.maxThreadDepth);return await this.journal.origins.validate(r),r}renderPrompt(e,t){let r=this.journal.summary(t);if(r===void 0)throw new v(t);return this.ctx.prompts.render(e,r.agent_name,{environment:r.environment})}async recordPromptOnce(e){let t=[...this.live.values()].find(i=>i.scope.key===e);if(t===void 0)return;let r=t.thread.id;await this.journal.transact(r,()=>({rows:this.journal.state(h,r).threadPrompt!==null?[]:[{type:"thread/prompt",data:{blocks:this.renderPrompt(e,r)},options:{threadId:r}}],value:void 0}))}async rebuildPrompt(e){this.requireThread(e);let t=this.admission.admit(e,"rebuild");return this.under(t,async()=>{let r=await this.activationFor(e,t);await j(r.whenReady(),t.signal),t.signal.throwIfAborted();let i=this.renderPrompt(r.scope.key,e);return await this.journal.append("thread/prompt",{blocks:i},{threadId:e}),i})}async whenReady(e){for(this.requireThread(e);;){await this.settledLive(e);let r=this.admission.holder(e);if(r?.kind==="release"||r?.kind==="configure"){await this.admission.settlement(e);continue}let i=this.live.get(e);if(i?.closed===void 0){if(i?.isStale()===!0){r===null?await this.releaseUnder(e):await this.admission.settlement(e);continue}break}}let t=this.activate(e);try{await t.whenReady()}catch(r){throw await this.releaseFailed(e),r}}contextOf(e){return this.activate(e).scope.ctx}signalOf(e){return this.activate(e).signal}activate(e){let t=this.live.get(e);if(t?.closed!==void 0)throw new y(e,"release");if(t===void 0){this.controller.signal.throwIfAborted();let r=this.admission.holder(e);if(r!==null&&this.admission.isReleasing(e))throw new y(e,r.kind);if(this.journal.summary(e)===void 0)throw new v(e);let i=new K(this,this.admission,this.ctx,this.handle(e),n=>this.loopServices(n),()=>{this.live.get(e)===i&&this.live.delete(e)});this.live.set(e,i),t=i}return t}async execute(e,t){let{threadId:r}=t,{decide:i}=e,n;try{if(this.requireExecutable(r),this.requireGlobalAgent(this.requireThread(r).agent_name),n=this.journal.state(h,r).turnBoundary.lastTurn,await this.settledLive(r),this.live.has(r)?await this.journal.flush():await Ke(this.journal,r,this.limits),t.signal.throwIfAborted(),this.journal.state(h,r).requests.pending?.runId!==e.runId)return;let s=B(this.journal.state(h,r)),o=i(s);if(e.final=o,o.kind!=="advance"&&o.kind!=="repair"){s.resumed!==null&&(e.attemptCutoff=s.resumed.attemptCutoff);return}let d={id:e.runId,attemptCutoff:e.attemptCutoff,continueAfter:(l,u)=>i({ending:l,start:u}).kind==="advance"};for(;o.kind==="advance"||o.kind==="repair";){await(await this.activationFor(r,t)).run({signal:t.signal,lease:t.lease,served:d}),t.signal.throwIfAborted();let u=et(this.journal.state(h,r),e.runId);o=i({ending:u?.ending??null,start:u?.start??null}),e.final=o}}catch(s){if(fe(t,s)){this.journal.isLoaded(r)&&(e.final=i({ending:{kind:"aborted"},start:null}));return}if(s instanceof x){e.final={kind:"settle",outcome:"failed",reason:"setup"},e.errorText=oe(s);return}let o=this.journal.isLoaded(r)?this.journal.state(h,r).turnBoundary:null;if(n===void 0||o?.lastTurn===n){e.final={kind:"settle",outcome:"failed",reason:"setup"},e.errorText=oe(s);return}throw e.final={kind:"settle",outcome:"failed",reason:"turn"},s}}target(e){let{threadRoute:t,requests:r}=this.journal.state(h,e);if(t===null)throw new Error(`Thread ${e} has no route`);let i=this.ctx.llm.unavailable(t),{pending:n}=r,s=this.admission.holder(e);return s?.kind==="run"&&n!==null&&s.runId===n.runId?{route:t,blocked:i,selectable:!1}:n===null||i!==null?{route:t,blocked:i,selectable:!0}:{route:t,blocked:i,selectable:M(r)||L(r)}}routes={target:e=>this.target(e),resolve:(e,t)=>this.ctx.llm.resolveRoute(e,t)};async compact(e,t){let r=this.requireThread(e);this.requireGlobalAgent(r.agent_name);let i=t;if(t.signal?.aborted===!0)return this.admission.requireFree(e),{committed:[],ended:"cancelled",reason:w(t.signal.reason)};let n=this.admission.admit(e,"compact",{signal:t.signal}),s,o;try{o=await this.under(n,async()=>{try{return s=await this.retainExecutionReads(e,{retiring:!1}),n.signal.throwIfAborted(),this.requireExecutable(e),await(await this.activationFor(e,n)).compact({...i,signal:n.signal,lease:n.lease})}catch(d){if(!fe(n,d))throw d;return{committed:[],ended:"cancelled",reason:w(n.signal.reason)}}})}finally{s?.release()}return!n.signal.aborted||o.ended==="cancelled"||o.ended==="failed"?o:{committed:o.committed,ended:"cancelled",reason:w(n.signal.reason)}}async releaseFailed(e){if(this.closing!==void 0)return;let t=this.admission.holder(e);if(t!==null){t.kind==="release"&&await this.admission.settlement(e);return}let r=this.live.get(e);r===void 0||!r.hasFailed||await this.releaseUnder(e)}async activationFor(e,t){await this.settledLive(e);let r=this.live.get(e);if(r!==void 0&&r.isStale()){this.admission.setReleasing(t,!0);try{await r.release()}finally{this.admission.setReleasing(t,!1)}}return this.activate(e)}async settledLive(e){let t=this.live.get(e)?.closed;t!==void 0&&await t.catch(()=>{})}loopServices(e){let{ctx:t}=this;return{journal:this.journal,chunks:this.chunks,limits:this.limits,unavailable:r=>t.llm.unavailable(r),resolveRoute:(r,i)=>t.llm.resolveRoute(r,i),client:r=>t.llm.clientFor(r),agent:r=>t.agents.require(e,r),toolsFor:r=>t.tools.toolsFor(e,r),tool:(r,i)=>t.tools.toolFor(e,r,i),waitOwner:r=>this.owner.isRegistered(r),requiredRegistrations:r=>this.owner.requiredRegistrations(r)}}get journal(){return ut(this.ctx)}under(e,t){return this.admission.hold(e,t,{cleanup:()=>this.cleanup(e)})}cleanup(e){let t=this.live.get(e.threadId);if(!(!(t!==void 0&&(t.hasFailed||t.isStale()))||e.kind==="release"||this.closing!==void 0))return this.admission.setReleasing(e,!0),t.release()}requireThread(e){let t=this.journal.summary(e);if(t===void 0)throw new v(e);return t}handle(e){let t=this.handles.get(e);return t===void 0&&(t=new U(this,this.admission,e,this.journal),this.handles.set(e,t)),t}};function jt(a){if(typeof a!="string"||a.length===0)throw new TypeError("A non-empty thread id is required");return a}function St(a,e){if(e.input!==void 0)return Se(e.input,e.inputId??k("in"));if(e.inputId!==void 0)throw new Error(`Thread ${a} was given an input id but no input`);return null}import{ScopeLayers as zt,Service as Ut}from"@leuduan/cordis";var Y=class extends Ut{static inject=["agents"];layers=new zt(()=>({entries:new Map,grants:[]}));constructor(e){super(e,"tools")}names(e){let t=new Set;for(let r of this.layers.closestFirst(e))for(let i of r.entries.keys())t.add(i);return C(t)}has(e,t){return this.get(e,t)!==void 0}get(e,t){for(let r of this.layers.closestFirst(e)){let i=r.entries.get(t);if(i!==void 0)return i}}register(e,t,r){let i=this.layers.layer(e).entries;if(i.has(t))throw new Error(`Tool already registered for name: ${t}`);if(!je.safeParse(r.onInterrupted).success)throw new Error(`Tool ${t} must declare onInterrupted as 'rerun' or 'report'`);if(r.executionMode!=="parallel"&&r.executionMode!=="exclusive")throw new Error(`Tool ${t} must declare executionMode as 'parallel' or 'exclusive'`);let n={name:t,tool:r,spec:m(structuredClone({...r.buildSpec(),name:t}))};return i.set(t,n),()=>{i.get(t)===n&&i.delete(t)}}grant(e,t,r){let i=this.layers.layer(e).grants,n={agents:Array.isArray(t)?[...t]:t,tool:r};return i.push(n),()=>{let s=i.indexOf(n);s>=0&&i.splice(s,1)}}toolsFor(e,t){this.ctx.agents.require(e,t);let r=new Set,i=[],n=s=>{if(r.has(s))return;r.add(s);let o=this.get(e,s);o!==void 0&&i.push(o)};for(let s of this.layers.globalFirst(e))for(let o of s.grants)ot(o.agents,t)&&n(o.tool);return i}toolFor(e,t,r){return this.toolsFor(e,t).find(i=>i.name===r)}mayCall(e,t,r){return this.toolFor(e,t,r)!==void 0}};var wi={name:"lagent:core",async apply(a,e){let t=Ge(e.limits);await a.plugin(dt,{store:e.store,limits:t}),await a.plugin(z),await a.plugin(lt),await a.plugin(Y),await a.plugin(ft),await a.plugin(N,{dataDir:e.dataDir}),await a.plugin(ht),await a.plugin(ct),await a.plugin(X,{cwd:e.cwd,limits:t,retention:e.retention,chainLimit:e.chainLimit})}};import{randomUUID as Nt}from"node:crypto";var Et=class extends Ce{rows=[];index=[];threadIndex=new Map;catalog=new Map;attempts=new Map;writer;get size(){return this.rows.length}async acquireWriter(){if(this.writer!==void 0)throw new Ae(this.constructor.name);let e=Nt();return this.writer=e,{identity:this.constructor.name,acquisitionId:e,release:async()=>{this.writer===e&&(this.writer=void 0)}}}async doOpen(){}async doClose(){}async doHead(){return this.headSeq()}async doAppend(e,t){let r=this.attempts.get(e.id);if(r!==void 0){if(r===t)return"duplicate";throw new Pe(e.id)}if(this.writer!==e.writer)throw new D(e.writer);let i=this.headSeq();if(i!==e.baseHead)throw new De(e.baseHead,i);let n=e.rows[0],s=this.threadIndex.get(n.thread_id);if(s===void 0&&n.type!=="thread/spawned")throw new Error(`Thread ${n.thread_id} is not in the store; its first row must be its spawn row`);if(e.rows.some(l=>l.type==="thread/spawned"&&(s!==void 0||l!==n)))throw new Error(`Thread ${n.thread_id} already has a spawn row`);let o=e.rows.map(l=>this.serialize(l));for(let[l,u]of e.rows.entries())this.rows.push(o[l]),this.index.push({seq:u.seq,threadId:u.thread_id});let d=e.rows.at(-1).seq;return this.threadIndex.set(n.thread_id,{spawnSeq:s?.spawnSeq??n.seq,lastSeq:d}),this.attempts.set(e.id,t),"appended"}async doRead(e){let t=[];for(let[r,i]of this.index.entries())i.threadId===e&&t.push(ee(this.rows[r]));return t}async doRowAt(e){let t=this.index.findIndex(r=>r.seq===e);return t<0?void 0:ee(this.rows[t])}async doThreads(){return[...this.threadIndex].map(([e,t])=>({threadId:e,...t})).sort((e,t)=>e.spawnSeq-t.spawnSeq)}async doSummaries(){return[...this.catalog.values()].map(e=>te(e)).sort((e,t)=>e.spawn_seq-t.spawn_seq)}async doPutSummaries(e,t){if(this.writer!==t)throw new D(t);let r=e.map(i=>[i,this.serializeSummary(i)]);for(let[i,n]of r){let s=this.catalog.get(i.thread_id);s!==void 0&&te(s).through_seq>i.through_seq||this.catalog.set(i.thread_id,n)}}async doReplaceCatalog(e,t){if(this.writer!==t)throw new D(t);let r=e.map(i=>[i.thread_id,this.serializeSummary(i)]);this.catalog.clear();for(let[i,n]of r)this.catalog.set(i,n)}headSeq(){return this.index.at(-1)?.seq??0}};export{Zt as a,U as b,wi as c,Et as d};
@@ -0,0 +1 @@
1
+ import{scopeOf as t}from"@leuduan/cordis";import{z as n}from"zod";var a=n.union([n.array(n.string()),n.literal("global"),n.literal("all")]),c=(e,r)=>e==="all"?!0:e==="global"?!o(r):e.includes(r),o=e=>e.includes(".");function p(e,r){if(t(e)!==void 0)throw new Error(`Mount ${r} on an untagged application context, not in a thread's scope`)}export{a,c as b,o as c,p as d};
@@ -0,0 +1 @@
1
+ async function n(t,r){let e;try{return await Promise.race([new Promise((a,o)=>{e=()=>o(r.reason),r.aborted?e():r.addEventListener("abort",e,{once:!0})}),t])}finally{e&&r.removeEventListener("abort",e)}}var b=2**31-1;export{n as a,b};
@@ -0,0 +1 @@
1
+ import{q as y,r as J,t as z}from"./KESCTXGO.js";var m=class extends Error{origin;reason;constructor(e,t){let{caller_thread_id:s,source_seq:r}=e,i={"unknown-caller":`thread ${s} is not in the journal`,"source-missing":`row ${r} does not exist`,"source-off-lineage":`row ${r} is not a row of thread ${s} or of a thread it forks from`,"source-not-a-call":`row ${r} is not a tool call, which a call cause cites`};super(`Invalid origin under thread ${s}: ${i[t]}`),this.name="InvalidOriginError",this.origin=e,this.reason=t}},b=class{summaries=new Map;ranks=new Map;children=new Map;nextRank=0;origins={callers:e=>this.callers(e),root:e=>this.callers(e).threads.at(-1),subtree:(e,t)=>this.subtree(e,t.self),isUnder:(e,t)=>this.callers(e).threads.some(s=>s.thread_id===t),requiredOwners:e=>this.requiredOwners(e)};get(e){return this.summaries.get(e)}has(e){return this.summaries.has(e)}keys(){return this.summaries.keys()}values(){return this.summaries.values()}view(){return this.summaries}set(e,t){if(!this.summaries.has(e)&&(this.ranks.set(e,this.nextRank++),t.origin!==null)){let s=t.origin.caller_thread_id,r=this.children.get(s);r===void 0?this.children.set(s,new Set([e])):r.add(e)}this.summaries.set(e,t)}delete(e){let t=this.summaries.get(e);if(t!==void 0){if(t.origin!==null){let s=this.children.get(t.origin.caller_thread_id);s?.delete(e),s?.size===0&&this.children.delete(t.origin.caller_thread_id)}this.summaries.delete(e),this.ranks.delete(e)}}reset(e){this.summaries.clear(),this.ranks.clear(),this.children.clear(),this.nextRank=0;for(let t of e)this.set(t.thread_id,t)}callers(e){let t=[],s=new Set;for(let r=this.summaries.get(e);r!==void 0&&(s.add(r.thread_id),t.push(r),r.origin!==null);){let i=r.origin.caller_thread_id,n=this.summaries.get(i);if(n===void 0)return{threads:t,chain:{broken:"missing",at:r.thread_id}};if(s.has(i))return{threads:t,chain:{broken:"cycle",at:r.thread_id}};r=n}return{threads:t,chain:"complete"}}subtree(e,t){let s=this.summaries.get(e);if(s===void 0)return[];let r=new Set([e]),i=[e];for(let c=i.pop();c!==void 0;c=i.pop())for(let l of this.children.get(c)??[])r.has(l)||(r.add(l),i.push(l));r.delete(e);let a=[...r].sort((c,l)=>this.ranks.get(c)-this.ranks.get(l)).map(c=>this.summaries.get(c));return t?[s,...a]:a}requiredOwners(e){let t=new Map,s=(i,n)=>{let a=t.get(i);a===void 0&&t.set(i,a=[]),n!==null&&!a.includes(n)&&a.push(n)},r;if(typeof e=="string")r=this.callers(e);else{for(let n of e.requires)s(n,null);let i=e.origin?.caller_thread_id;i===void 0?r={threads:[],chain:"complete"}:this.summaries.has(i)?r=this.callers(i):r={threads:[],chain:{broken:"missing",at:null}}}for(let i of r.threads)for(let n of i.requires)s(n,i.thread_id);return{owners:[...t].map(([i,n])=>({owner:i,introducedBy:n})),chain:r.chain}}};function te(o,e){let t=[],s=new Set;for(let r=o.get(e);r!==void 0&&!s.has(r.thread_id);)s.add(r.thread_id),t.push(r),r=r.fork===null?void 0:o.get(r.fork.thread_id);return t}import{z as G}from"zod";function L(o){return Array.isArray(o)?`[${o.map(e=>L(e)).join(",")}]`:o!==null&&typeof o=="object"?`{${Object.entries(o).filter(([,t])=>t!==void 0).sort(([t],[s])=>t<s?-1:t>s?1:0).map(([t,s])=>`${JSON.stringify(t)}:${L(s)}`).join(",")}}`:JSON.stringify(o)}var F=G.json();function P(o){return Array.isArray(o)?o.map(e=>P(e)):typeof o=="object"&&o!==null?Object.fromEntries(Object.entries(o).map(([e,t])=>[e,P(t)])):o}function N(o,e){let{key:t,init:s,apply:r}=e;return e.onFork!=="reset"?{key:t,failureMode:o,init:s,apply:r}:{key:t,failureMode:o,init:s,apply:(i,n)=>J(n)?s():r(i,n)}}var ne=o=>Object.freeze(N("isolate",o)),ae=o=>N("fatal",o),k=class extends Error{projectionKey;threadId;cause;constructor(e,t,s){super(`Projection '${e}' failed on thread ${t}`),this.projectionKey=e,this.threadId=t,this.cause=s,this.name="ProjectionFailedError"}};import{createHash as Q}from"node:crypto";import{z as U}from"zod";var C=class{opened=!1;get isOpen(){return this.opened}async open(){this.opened||(await this.doOpen(),this.opened=!0)}async close(){this.opened&&(await this.doClose(),this.opened=!1)}async head(){return this.requireOpen(),this.doHead()}async append(e){if(this.requireOpen(),e.rows.length===0)throw new Error("An attempt holds at least one row");let t=e.rows[0].thread_id,s=e.baseHead;for(let r of e.rows){if(r.thread_id!==t)throw new Error("An attempt holds rows of one thread");if(r.seq<=s)throw new Error(`Row ${r.seq} does not follow ${s} in attempt ${e.id}`);s=r.seq}return this.doAppend(e,X(e))}async read(e){return this.requireOpen(),this.doRead(e)}async rowAt(e){return this.requireOpen(),this.doRowAt(e)}async threads(){return this.requireOpen(),this.doThreads()}async summaries(){return this.requireOpen(),this.doSummaries()}async putSummaries(e,t){this.requireOpen(),e.length>0&&await this.doPutSummaries(e,t)}async replaceCatalog(e,t){this.requireOpen(),await this.doReplaceCatalog(e,t)}serialize(e){return JSON.stringify(e)}serializeSummary(e){return JSON.stringify(e)}requireOpen(){if(!this.opened)throw new Error(`${this.constructor.name} is not open`)}};function X(o){return Q("sha256").update(JSON.stringify([o.baseHead,o.writer,o.rows])).digest("hex")}var B=class extends Error{location;constructor(e){super(`Journal is busy: ${e}. Close its current writer before opening another.`),this.location=e,this.name="JournalBusyError"}},H=class extends Error{location;waitedMs;constructor(e,t){super(`Journal store ${e} stayed locked by another connection for ${t} ms`),this.location=e,this.waitedMs=t,this.name="StoreBusyError"}},W=class extends Error{expected;actual;constructor(e,t){super(`The journal's head is ${t}, not ${e}; another write landed first`),this.expected=e,this.actual=t,this.name="JournalConflictError"}},x=class extends Error{acquisitionId;constructor(e){super(`Writer ${e} no longer holds the journal`),this.acquisitionId=e,this.name="WriterLostError"}},D=class extends Error{attemptId;constructor(e){super(`Attempt ${e} was already written with different rows`),this.attemptId=e,this.name="AttemptMismatchError"}},q=class extends Error{payload;cause;constructor(e,t){super(`Unparsable journal row: ${e.slice(0,200)}`),this.payload=e,this.cause=t,this.name="CorruptJournalError"}};function fe(o,e=t=>t){try{return y(e(JSON.parse(o)))}catch(t){throw t instanceof SyntaxError||t instanceof U.ZodError?new q(o,t):t}}function de(o){try{return z.parse(JSON.parse(o))}catch(e){throw e instanceof SyntaxError||e instanceof U.ZodError?new q(o,e):e}}var V=38,O=class extends Error{found;location;constructor(e,t){super(`Journal at ${t} is ${e===0?"unstamped":`format v${e}`}; this build reads v${V}. Start a new journal directory; the existing journal has been preserved.`),this.found=e,this.location=t,this.name="IncompatibleJournalError"}};function pe(o,e,t){if(!(o===V||!e))throw new O(o,t)}import{randomUUID as I}from"node:crypto";function R(o,e,t){for(let s of o)try{let r=s(e);Y(r)&&Promise.resolve(r).catch(t)}catch(r){t(r)}}var Y=o=>(typeof o=="object"||typeof o=="function")&&o!==null&&typeof o.then=="function";function w(o){if(o!==null&&typeof o=="object"&&!Object.isFrozen(o)){Object.freeze(o);for(let e of Object.values(o))w(e)}return o}function S(o,e){let t=o.get(e);return t===void 0&&o.set(e,t=new Map),t}var Z=o=>o.type==="thread/spawned"?o.data.fork:null,K=class{projections=new Map;coreFolds;states=new Map;failures=new Map;pendingReports=[];dirty=new Set;listeners=new Set;revokedListeners=new Set;contributors=new Map;catalog=new b;loaded=new Map;loading=new Map;rowReads=new Map;generations=new Map;bySeq=new Map;holds=new Map;folded=new Set;summarizer;onListenerError;lease;ownsStore=!1;seq=0;writable=!0;revokedBy;queue=Promise.resolve();writing=!1;closing=!1;store;constructor(e,t){this.store=e,this.summarizer=t.summarize,this.onListenerError=t.onListenerError??(s=>{console.error(s)}),this.coreFolds=new Set(t.coreFolds);for(let s of this.coreFolds)this.register(s)}revokeWrites(){this.writable=!1}onRevoked(e){return this.revokedListeners.add(e),()=>this.revokedListeners.delete(e)}async open(){this.lease=await this.store.acquireWriter();try{this.store.isOpen||(await this.store.open(),this.ownsStore=!0),this.seq=await this.store.head(),this.catalog.reset((await this.store.summaries()).map(i=>w(i))),this.loaded.clear(),this.bySeq.clear(),this.folded.clear(),this.states.clear(),this.failures.clear(),this.pendingReports.length=0,this.dirty.clear();let e=await this.store.threads(),t=e.filter(({threadId:i,lastSeq:n})=>this.catalog.get(i)?.through_seq!==n),s=new Set(e.map(({threadId:i})=>i)),r=[...this.catalog.keys()].some(i=>!s.has(i));(t.length>0||r)&&await this.repair(e,new Set(t.map(({threadId:i})=>i)),{replace:r,opening:!0})}catch(e){throw await this.close(),e}}async close(){this.closing=!0,await this.queue,this.writable=!1;let e=this.lease;this.lease=void 0;try{await e?.release()}finally{this.ownsStore&&await this.store.close(),this.ownsStore=!1}}get head(){return this.seq}summary(e){return this.catalog.get(e)}summaries(){return[...this.catalog.values()]}summaryMap(){return this.catalog.view()}origins={...this.catalog.origins,validate:async e=>{let{caller_thread_id:t,source_seq:s,cause:r}=e;if(!this.catalog.has(t))throw new m(e,"unknown-caller");let i=await this.readRow(s);if(i===void 0)throw new m(e,"source-missing");if(!this.inLineage(t,i))throw new m(e,"source-off-lineage");if(r.kind==="call"&&i.type!=="tool/call")throw new m(e,"source-not-a-call")}};contribute(e,t,s={}){if(this.contributors.has(e))throw new TypeError(`Duplicate summary contributor: ${e}`);this.contributors.set(e,t);let r=s.refresh??(n=>!Object.hasOwn(n.contributions,e)),i=this.enqueue(async()=>{if(this.requireWritable(),this.contributors.get(e)!==t)return[];let n=await this.store.threads(),a=new Set;for(let{threadId:c}of n){let l=this.catalog.get(c);l!==void 0&&r(l)&&a.add(c)}return a.size===0?[]:await this.repair(n,a,{replace:!1,opening:!1})});return i.catch(n=>{n instanceof g||this.reportError(n)}),{withdraw:()=>{this.contributors.get(e)===t&&this.contributors.delete(e)},refreshed:i}}rebuildCatalog(){return this.enqueue(async()=>{this.requireWritable();let e=await this.store.threads();await this.repair(e,new Set(e.map(({threadId:t})=>t)),{replace:!0,opening:!1})})}async repair(e,t,s){let{replace:r,opening:i}=s,n=new Map(this.catalog.view()),a=new Set(this.loaded.keys()),c=new Set,l=u=>(a.has(u)||c.add(u),this.loadRows(u)),d=[];this.writing=!0;try{if(i)for(let h of t)this.catalog.delete(h);for(let h of t)await l(h);for(let h of t)for(let p of this.hops(h,1/0))await l(p.threadId);let u=new Map;for(let{threadId:h}of e)if(t.has(h))try{this.ensureFolded(h),u.set(h,w(structuredClone(this.summarize(h))))}catch(p){this.pendingReports.push(new A(h,p)),d.push(h);let T=n.get(h);T!==void 0&&u.set(h,this.withRegisteredContributions(T))}let f=new Map;for(let{threadId:h}of e){let p=u.get(h)??n.get(h);p!==void 0&&f.set(h,p)}let $=[...this.dirty].flatMap(h=>{let p=u.has(h)?void 0:this.catalog.get(h);return p===void 0?[]:[p]});try{r?await this.store.replaceCatalog([...f.values()],this.writer()):await this.store.putSummaries([...u.values(),...$],this.writer()),this.dirty.clear()}catch(h){throw i?h:this.revoke("(catalog)",h)}this.catalog.reset(f.values())}catch(u){throw this.catalog.reset(n.values()),u}finally{for(let u of c)this.unload(u);this.writing=!1}return this.flushReports(),d}withRegisteredContributions(e){let t=Object.entries(e.contributions).filter(([s])=>this.contributors.has(s));return w({...e,contributions:Object.fromEntries(t)})}requireWritable(){if(!this.writable||this.closing)throw new g(this.revokedBy)}loadedThreads(){return[...this.loaded.keys()]}flush(){return this.queue.then(()=>{})}hold(e){for(let s of e)this.holds.set(s,(this.holds.get(s)??0)+1);let t=!1;return()=>{if(!t){t=!0;for(let s of e){let r=(this.holds.get(s)??1)-1;r>0?this.holds.set(s,r):this.holds.delete(s)}}}}load(e){if(this.folded.has(e)||!this.catalog.has(e))return Promise.resolve();let t=this.loading.get(e);return t===void 0&&(t=(async()=>{let s=this.hops(e,1/0).map(i=>i.threadId),r=this.hold(s);try{for(let i of s)await this.loadRows(i);this.ensureFolded(e)}finally{r()}this.flushReports()})().finally(()=>this.loading.delete(e)),this.loading.set(e,t)),t}isLoaded(e){return this.folded.has(e)}unload(e){if(this.holds.has(e))return!1;let t=[...this.loaded.keys()].filter(s=>s!==e&&this.hops(s,1/0).some(r=>r.threadId===e));if(t.some(s=>this.holds.has(s)))return!1;this.drop(e);for(let s of t)this.drop(s);return!0}drop(e){this.generations.set(e,(this.generations.get(e)??0)+1);let t=this.loaded.get(e);if(t!==void 0)for(let s of t)this.bySeq.delete(s.seq);this.loaded.delete(e),this.folded.delete(e),this.dropStates(e)}eventAt(e){let t=this.bySeq.get(e);if(t===void 0&&e>=1&&e<=this.seq)throw new j(e);return t}async readRow(e){let t=this.bySeq.get(e);if(t!==void 0)return t;let s=await this.store.rowAt(e);return s===void 0?void 0:w(s)}rows(e,t=1/0){let s=this.own(e);return t===1/0?s:s.slice(0,this.firstAfter(s,t))}rowsAfter(e,t){let s=this.own(e);return s.slice(this.firstAfter(s,t))}lineage(e,t=1/0){return this.hops(e,t).reverse().flatMap(s=>this.rows(s.threadId,s.upTo))}inLineage(e,t){return this.hops(e,1/0).some(s=>s.threadId===t.thread_id&&t.seq<=s.upTo)}stateAt(e,t,s){let r=e.init();for(let i of this.lineage(t,s))r=e.apply(r,i);return r}hops(e,t){let s=[],r={threadId:e,upTo:t};for(;r!==void 0;){s.push(r);let i=this.spawnOf(r.threadId);r=i===void 0||i.fork===null||i.seq>r.upTo?void 0:{threadId:i.fork.thread_id,upTo:Math.min(i.fork.seq,r.upTo)}}return s}spawnOf(e){let t=this.catalog.get(e);if(t!==void 0)return{seq:t.spawn_seq,fork:t.fork};let s=this.loaded.get(e)?.[0];if(s?.type==="thread/spawned")return{seq:s.seq,fork:s.data.fork}}own(e){let t=this.loaded.get(e);if(t!==void 0)return t;if(this.catalog.has(e))throw new E(e);return[]}loadRows(e){if(this.loaded.has(e))return Promise.resolve();let t=this.rowReads.get(e);return t===void 0&&(t=this.readRows(e).finally(()=>this.rowReads.delete(e)),this.rowReads.set(e,t)),t}async readRows(e){for(;;){let t=this.generations.get(e)??0,s=await this.store.read(e);if(this.loaded.has(e))return;if((this.generations.get(e)??0)===t){for(let r of s)w(r);this.loaded.set(e,s);for(let r of s)this.bySeq.set(r.seq,r);return}}}firstAfter(e,t){let s=0,r=e.length;for(;s<r;){let i=s+r>>>1;e[i].seq<=t?s=i+1:r=i}return s}async append(e,t,s){let[r]=await this.appendAll([{type:e,data:t,options:s}]);return r}appendAll(e){if(e.length===0)return!this.writable||this.closing?Promise.reject(new g(this.revokedBy)):Promise.resolve([]);if(this.closing)return Promise.reject(new g(this.revokedBy));let t=e[0].options.threadId;return this.enqueue(()=>this.write(t,()=>({rows:e,value:void 0}),s=>s))}transact(e,t){return this.closing?Promise.reject(new g(this.revokedBy)):this.enqueue(()=>this.write(e,t,(s,r)=>({events:s,value:r})))}enqueue(e){let t=this.queue.then(e);return this.queue=t.catch(()=>{}),t}async write(e,t,s){if(!this.writable)throw new g(this.revokedBy);let r=this.hold([e]);try{return await this.writeHeld(e,t,s)}finally{r()}}async writeHeld(e,t,s){let r=this.catalog.has(e);r&&await this.load(e);let i=t();if(typeof i.then=="function")throw new TypeError("A transact callback is synchronous: it may not await, since it runs inside the write queue");let{rows:n,value:a}=i;if(n.length===0)return s([],a);if(n.some(f=>f.options.threadId!==e))throw new Error(`A group holds rows of one thread, ${e}`);let c=n.filter(f=>f.type==="thread/spawned").length;if(!r&&(n[0].type!=="thread/spawned"||c!==1))throw new Error(`Thread ${e} does not exist: its first group must begin with its one spawn row`);if(r&&c>0)throw new Error(`Thread ${e} already exists; a second spawn row is refused`);let l=n.map((f,$)=>w(y({seq:this.seq+$+1,type:f.type,thread_id:e,data:JSON.parse(JSON.stringify(f.data)),source_seqs:f.options.sourceSeqs??[]}))),d=Z(l[0]);if(d!==null){if(d.seq>=l[0].seq)throw new Error(`A fork's spawn row must name an earlier row, not ${d.seq}`);await this.load(d.thread_id)}let u=d===null?()=>{}:this.hold([d.thread_id]);try{return s(await this.commit(e,r,l),a)}finally{u()}}async commit(e,t,s){t||(this.loaded.set(e,[]),this.folded.delete(e));try{this.ensureFolded(e)}catch(r){throw t||this.drop(e),r}this.writing=!0;try{try{await this.store.append({id:I(),baseHead:this.seq,writer:this.writer(),rows:s})}catch(n){throw t||this.drop(e),this.revoke(e,n)}this.seq=s.at(-1).seq;let r;try{let n=this.loaded.get(e);for(let a of s)n.push(a),this.bySeq.set(a.seq,a),this.fold(a);r=w(structuredClone(this.summarize(e)))}catch(n){throw this.drop(e),this.revoke(e,n)}this.catalog.set(e,r);for(let n of s)this.publish(n);this.dirty.add(e);let i=[...this.dirty].flatMap(n=>{let a=this.catalog.get(n);return a===void 0?[]:[a]});try{await this.store.putSummaries(i,this.writer()),this.dirty.clear()}catch(n){if(n instanceof x)throw this.revoke(e,n);this.pendingReports.push(new v([...this.dirty],n))}}finally{this.writing=!1}return this.flushReports(),s}writer(){if(this.lease===void 0)throw new Error("The journal is not open");return this.lease.acquisitionId}revoke(e,t){let s=new _(e,t);return this.writable=!1,this.revokedBy=s,R(this.revokedListeners,s,r=>this.reportError(r)),s}publish(e){R(this.listeners,e,t=>this.reportError(t))}summarize(e){let t=this.summarizer(this,e),s={};for(let[r,i]of this.contributors)try{let n=i(e,t);n!==void 0&&(s[r]=F.parse(n))}catch(n){this.pendingReports.push(new M(r,e,n))}return{...t,contributions:s}}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}register(e){let t=e;if(t.failureMode==="fatal"&&!this.coreFolds.has(t))throw new TypeError(`Projection '${t.key}' is fatal but is not one of the journal's core folds; a plugin's fold isolates`);let s=this.projections.get(t.key);if(s===t)return()=>{};if(s!==void 0)throw new TypeError(`Duplicate projection key: ${t.key}`);this.projections.set(t.key,t);let r=()=>{if(this.projections.get(t.key)===t){this.projections.delete(t.key);for(let i of this.states.values())i.delete(t.key);for(let i of this.failures.values())i.delete(t.key)}};try{for(let i of this.folded)this.foldLineage(t,i,this.lineage(i))}catch(i){throw r(),i}return this.flushReports(),r}state(e,t){if(this.register(e),!this.folded.has(t))if(this.loaded.has(t))this.ensureFolded(t);else{if(this.catalog.has(t))throw new E(t);return e.init()}let s=this.failures.get(t)?.get(e.key);if(s!==void 0)throw s;let r=S(this.states,t);if(!r.has(e.key))try{r.set(e.key,e.init())}catch(i){let n=this.failProjection(e,t,i);throw this.flushReports(),n}return r.get(e.key)}ensureFolded(e){if(!this.folded.has(e)){try{let t=this.lineage(e);for(let s of this.projections.values())this.foldLineage(s,e,t)}catch(t){throw this.dropStates(e),this.holds.has(e)||this.drop(e),t}this.folded.add(e)}}dropStates(e){this.states.delete(e),this.failures.delete(e)}foldLineage(e,t,s){try{let r=e.init();for(let i of s)r=e.apply(r,i);S(this.states,t).set(e.key,r)}catch(r){this.failProjection(e,t,r)}}fold(e){for(let t of this.projections.values())this.foldOne(t,e)}foldOne(e,t){let s=t.thread_id;if(this.failures.get(s)?.has(e.key)===!0)return;let r=S(this.states,s);try{if(Z(t)!==null){this.foldLineage(e,s,this.lineage(s,t.seq));return}let i=r.has(e.key)?r.get(e.key):e.init();r.set(e.key,e.apply(i,t))}catch(i){this.failProjection(e,s,i)}}failProjection(e,t,s){if(e.failureMode!=="isolate")throw s;let r=new k(e.key,t,s);return S(this.failures,t).set(e.key,r),this.states.get(t)?.delete(e.key),this.pendingReports.push(r),r}flushReports(){if(!this.writing)for(let e of this.pendingReports.splice(0))this.reportError(e)}reportError(e){try{this.onListenerError(e)}catch(t){console.error(t)}}},_=class extends Error{threadId;cause;constructor(e,t){super(`A group on thread ${e} could not be committed; the journal refuses every later write and the owner must exit`),this.threadId=e,this.cause=t,this.name="JournalCommitError"}},g=class extends Error{cause;constructor(e){super(e===void 0?"Journal writes have been revoked":`Journal writes have been revoked: ${e.message}`),this.cause=e,this.name="JournalRevokedError"}},E=class extends Error{threadId;constructor(e){super(`Thread ${e} is not loaded; read it inside thread.read or a retention`),this.threadId=e,this.name="ThreadNotLoadedError"}},j=class extends Error{seq;constructor(e){super(`Row ${e} belongs to a thread that is not loaded`),this.seq=e,this.name="RowNotLoadedError"}},v=class extends Error{threadIds;cause;constructor(e,t){super(`The catalog could not record the summaries of ${e.join(", ")}; the next write carries them`),this.threadIds=e,this.cause=t,this.name="CatalogWriteError"}},A=class extends Error{threadId;cause;constructor(e,t){super(`The summary of thread ${e} could not be recomputed from its rows`),this.threadId=e,this.cause=t,this.name="RepairError"}},M=class extends Error{key;threadId;cause;constructor(e,t,s){super(`Summary contributor '${e}' failed on thread ${t}`),this.key=e,this.threadId=t,this.cause=s,this.name="ContributionError"}};export{w as a,m as b,te as c,L as d,F as e,P as f,R as g,ne as h,ae as i,k as j,C as k,B as l,H as m,W as n,x as o,D as p,q,fe as r,de as s,V as t,O as u,pe as v,K as w,_ as x,g as y,E as z,j as A};
@@ -0,0 +1,6 @@
1
+ import{ja as g}from"./YLNJXQ3Z.js";import{c}from"./KESCTXGO.js";import{randomBytes as _}from"node:crypto";import{mkdir as T,writeFile as O}from"node:fs/promises";import{join as f}from"node:path";import{z as d}from"zod";var $=/[^A-Za-z0-9_.-]+/g,w="tool-outputs",x=String(Number.MAX_SAFE_INTEGER).length,s=t=>`
2
+ [\u2026 ${t} characters omitted \u2026]
3
+ `,m=s("9".repeat(x)).length+2,A=d.object({maxToolOutputLength:d.number().int().min(m,{message:`maxToolOutputLength must hold the gap marker and some head and tail: at least ${m}`}).default(1e4)}),P={name:"lagent:truncate-tool-output",inject:["threadDirs"],apply(t,n){t.threadDirs.require("truncateToolOutput");let{maxToolOutputLength:o}=A.parse(n??{});t.on("lagent/tool/execute",async(e,a)=>{let r=await a();if(g(r))return r;let u=f(t.threadDirs.dirFor(e.threadId),w);return await E(r,o,u)})}};async function E(t,n,o){let e=await M(t,n,o),a=[...t.notes??[]];return e.note!==null&&a.push(e.note),{...t,output:e.output,notes:a.length>0?a:null,metadata:{...t.metadata,truncation:e.metadata}}}async function M(t,n,o){let e=t.output;if(t.metadata.no_truncation===!0)return{output:e,note:null,metadata:{was_truncated:!1,limit:n,original_length:e.length,returned_length:e.length,no_truncation:!0}};if(e.length<=n)return{output:e,note:null,metadata:{was_truncated:!1,limit:n,original_length:e.length,returned_length:e.length}};let a=await I(e,t,o),r=e.split(`
4
+ `).length,{head:u,tail:l}=S(e,n),i=e.length-u.length-l.length,h=`${u}${s(String(i))}${l}`;return{output:h,note:`Output truncated to its first ${u.length} and last ${l.length} of ${e.length} characters (${r} lines). The full output is written to ${a}.`,metadata:{was_truncated:!0,limit:n,original_length:e.length,returned_length:h.length,omitted_length:i,full_output_path:a}}}function S(t,n){let o=n-s(String(t.length)).length,e=Math.ceil(o/2),a=o-e,r=e,u=t.lastIndexOf(`
5
+ `,r-1);u>=Math.floor(e/2)?r=u+1:r=c(t,r,"end");let l=t.length-a,i=t.indexOf(`
6
+ `,l);return i!==-1&&i+1<=l+Math.floor(a/2)?l=i+1:l=c(t,l,"start"),{head:t.slice(0,r),tail:t.slice(l)}}async function I(t,n,o){let e=`${p(n.name||"tool")}-${p(n.call_id||"call")}-`,a=f(o,`${e}${_(6).toString("hex")}.txt`);return await T(o,{recursive:!0,mode:448}),await O(a,t,{encoding:"utf8",flag:"wx",mode:384}),a}var p=t=>t.replace($,"-").slice(0,F).replace(/^[.-]+|[.-]+$/g,"")||"value",F=40;export{w as a,m as b,A as c,P as d,E as e};
@@ -0,0 +1 @@
1
+ import{b as h}from"./74HKUGRR.js";import{c as I,d as $,e as y,f as p}from"./L3N4FIEN.js";import{G as m,o as f}from"./YLNJXQ3Z.js";import{a as g}from"./DDANMY45.js";import{a as w,d as c}from"./37YOGDGY.js";import{h as u}from"./KESCTXGO.js";import{ScopeLayers as E,Service as _,scopeOf as v}from"@leuduan/cordis";var b=class extends _{static inject=["journal"];registry=new Map;handDowns=new E(()=>[]);constructor(e){super(e,"presets")}register(e){if(this.registry.has(e.id))throw new Error(`Preset already registered: ${e.id}`);return this.registry.set(e.id,e),()=>{this.registry.get(e.id)===e&&this.registry.delete(e.id)}}has(e){return this.registry.has(e)}installationsFor(e,t,i){let r=new Set;return e.map(o=>{let s=this.requireRegistered(o.presetId);if(s.placement==="creation"&&t==="change")throw new Error(`Preset ${s.id} is recorded only when a thread is created; it cannot be applied later`);let n=y(s,o.config);p(s,n,`Preset ${s.id}: its schema must parse its own output back unchanged`);let a=o.installationId??m("preset");if(a==="")throw new Error("An installation id must be non-empty");if(r.has(a))throw new Error(`Installation id ${a} is given twice`);r.add(a);let l=i===void 0?void 0:s.definesAgent?.(n);if(l!==void 0&&l!==i)throw new Error(`Installation ${a} defines agent ${l}, but the thread runs on ${i}`);return{installation_id:a,preset_id:s.id,config:n}})}initialInstallations(e,t){let i=e.map(r=>u.parse(r.lifetime));return this.installationsFor(e,"creation",t).map((r,o)=>{let s=i[o];if(s!=="defining"&&this.requireRegistered(r.preset_id).placement==="creation")throw new Error(`Preset ${r.preset_id} is recorded only when a thread is created; it must be defining`);return{...r,lifetime:s}})}plan(e,t,i){let r=h(this.ctx).state(f,e).installations,o=[],s=[];for(let n of new Set(i)){let a=r.current.get(n);if(a?.lifetime==="defining")throw new Error(`Installation ${n} on thread ${e} defines the thread and cannot be removed`);a!==void 0&&(o.push({type:"installation/removed",data:{installation_id:n},options:{threadId:e}}),s.push(n))}for(let n of t){if(s.includes(n.installation_id))throw new Error(`Installation id ${n.installation_id} is removed by this change and cannot be reused`);this.alreadyApplied(r,e,n)||o.push({type:"installation/applied",data:n,options:{threadId:e}})}return{rows:o,applied:t.map(n=>n.installation_id),removed:s}}handDown(e,t){if(e===void 0)throw new Error(`Preset ${t.presetId} cannot be handed down from the global layer: only a thread's own scope hands down`);let[i]=this.installationsFor([t],"creation"),r=this.handDowns.layer(e),o=r.find(n=>n.installationId===t.installationId);if(o!==void 0)throw new Error(`Installation id ${t.installationId} is already handed down from this scope, by preset ${o.presetId}`);let s={presetId:t.presetId,config:i.config,installationId:t.installationId};return r.push(s),()=>{let n=r.indexOf(s);n>=0&&r.splice(n,1)}}handedDown(e,t,i,r){let o=new Map;for(let n of this.handDowns.closestFirst(e))for(let a of n)o.has(a.installationId)||o.set(a.installationId,a);if(o.size===0)return[];let s=new Set(r.map(n=>n.installation_id));for(let n of o.keys())if(s.has(n))throw new Error(`Thread ${t} is created with installation ${n}, which its caller's scope also hands down`);return this.initialInstallations([...o.values()].map(n=>({...n,lifetime:"defining"})),i)}async restore(e){let{signal:t}=e;for(let i of[...h(this.ctx).state(f,e.id).installations.current.values()]){t.throwIfAborted();let r=this.requireRegistered(i.presetId);p(r,i.config,`Installation ${i.installationId} on thread ${e.id} no longer validates`);let o=e.ctx.plugin($(r),I(w(structuredClone(i.config)),{thread:e,installationId:i.installationId,lifetime:i.lifetime,signal:t}));await x(o,i.installationId,e.id)}t.throwIfAborted()}requireRegistered(e){let t=this.registry.get(e);if(t===void 0)throw new Error(`Unknown preset: ${e}`);return t}alreadyApplied(e,t,i){let{installation_id:r}=i,o=e.current.get(r);if(o===void 0){if(e.used.has(r))throw new Error(`Installation id ${r} was removed from thread ${t} and cannot be reused`);return!1}if(o.presetId!==i.preset_id)throw new Error(`Installation ${r} on thread ${t} is preset ${o.presetId}, not ${i.preset_id}`);if(c(o.config)!==c(i.config))throw new Error(`Installation ${r} on thread ${t} was applied with a different configuration`);return!0}};async function x(d,e,t){try{await d.awaitTree()}catch(i){throw new Error(`Installation ${e} on thread ${t} could not be mounted: ${g(i)}`,{cause:i})}}var j=(d,e)=>d.effect(()=>d.presets.register(e));function z(d,e){let t=d.get("presets");return d.effect(()=>t.handDown(v(d),e))}export{b as a,j as b,z as c};
@@ -0,0 +1 @@
1
+ var o=new WeakMap;function i(t,e,s){let r=o.get(t.root);r===void 0&&(r=new Map,o.set(t.root,r));let a=r.get(e);if(a!==void 0)throw new Error(`Thread ${e} already runs the ${a.name} strategy; a thread runs one strategy. Mount strategies on the root with disjoint agent selectors, or install one per thread, never two.`);let n=r;t.effect(()=>(n.set(e,s),()=>{n.get(e)===s&&n.delete(e)}))}function g(t,e){return o.get(t.root)?.get(e)}export{i as a,g as b};
@@ -0,0 +1 @@
1
+ var s=new WeakMap;function c(o,d,n,a,l){let e=s.get(o.root);e===void 0&&(e=new Map,s.set(o.root,e));let t=e.get(d);t===void 0&&(t=new Map,e.set(d,t));let f=t.get(n);if(f!==void 0)throw new Error(l(f.holder));let i={holder:a},r=t;o.effect(()=>(r.set(n,i),()=>{r.get(n)===i&&r.delete(n)}))}export{c as a};
@@ -0,0 +1 @@
1
+ import{S as t,o as l}from"./YLNJXQ3Z.js";import{w as a}from"./37YOGDGY.js";var d={name:"lagent:journal",async apply(r,i){let{store:s,limits:p}=i,e=new a(s,{summarize:(o,n)=>t(o,n,p),onListenerError:o=>r.reportError(o),coreFolds:[l]});e.onRevoked(o=>{r.parallel("lagent/journal/revoked",o).catch(n=>r.reportError(n))}),await e.open(),r.provide("journal",e),r.effect(()=>()=>e.close())}},c=r=>r.journal;export{d as a,c as b};
@@ -0,0 +1,2 @@
1
+ import{b as a}from"./RK3VP2Q4.js";import{b as d,e as p}from"./DRYAN665.js";import{a as i}from"./KESCTXGO.js";import{existsSync as m}from"node:fs";import{resolve as u}from"node:path";import{z as n}from"zod";var l=n.strictObject({cwd:n.string(),read_roots:n.array(n.string())}),f=d({plugin:"lagent:workspace-context",kind:"workspace-notice",version:3,schema:l}),$={name:"lagent:workspace-context",inject:["prompts","journal"],apply(e){a(e,{tag:"workspace",slot:"context",agents:"global",render:()=>i("environment_info",w())}),p(e,{event:f,current(r){let o=e.journal.summary(r.threadId);if(o===void 0)return;let{cwd:t,read_roots:s}=o.environment;return{cwd:t,read_roots:s}},render:g})}};function g(e,r){let o=u(e.cwd),t=m(o)?"":" (does not exist)",s=r===null||r.cwd===e.cwd?"":` (previously ${r.cwd})`,c=[`Working directory: ${o}${t}${s}`];return e.read_roots.length>0&&c.push(`Read roots: ${e.read_roots.join(", ")}. File tools read under these too, but change files only under the working directory and the application data directory.`),i("workspace",c.join(`
2
+ `))}function w(){return`Operating system: ${process.platform}`}export{$ as a,g as b,w as c};
@@ -0,0 +1,36 @@
1
+ import{k as h,n as u,o,p as c,q as E,r as N,s as l,t as R,v as S}from"./37YOGDGY.js";import{randomUUID as q}from"node:crypto";var O=`
2
+ CREATE TABLE IF NOT EXISTS meta (
3
+ one INTEGER PRIMARY KEY CHECK (one = 1),
4
+ format INTEGER NOT NULL
5
+ ) STRICT;
6
+ CREATE TABLE IF NOT EXISTS events (
7
+ seq INTEGER PRIMARY KEY,
8
+ type TEXT NOT NULL,
9
+ created_at TEXT NOT NULL,
10
+ thread_id TEXT NOT NULL,
11
+ payload BLOB NOT NULL
12
+ ) STRICT;
13
+ DROP INDEX IF EXISTS idx_events_type;
14
+ CREATE INDEX IF NOT EXISTS idx_events_thread_seq ON events(thread_id, seq);
15
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_events_thread_spawn ON events(thread_id) WHERE type = 'thread/spawned';
16
+ CREATE TABLE IF NOT EXISTS summaries (
17
+ thread_id TEXT PRIMARY KEY,
18
+ spawn_seq INTEGER NOT NULL,
19
+ through_seq INTEGER NOT NULL,
20
+ payload BLOB NOT NULL
21
+ ) STRICT;
22
+ CREATE TABLE IF NOT EXISTS threads (
23
+ thread_id TEXT PRIMARY KEY,
24
+ spawn_seq INTEGER NOT NULL,
25
+ last_seq INTEGER NOT NULL
26
+ ) STRICT;
27
+ CREATE INDEX IF NOT EXISTS idx_threads_spawn ON threads(spawn_seq);
28
+ CREATE TABLE IF NOT EXISTS attempts (
29
+ id TEXT PRIMARY KEY,
30
+ digest TEXT NOT NULL
31
+ ) STRICT;
32
+ CREATE TABLE IF NOT EXISTS writer (
33
+ one INTEGER PRIMARY KEY CHECK (one = 1),
34
+ acquisition_id TEXT NOT NULL
35
+ ) STRICT;
36
+ `,I=["meta","events","summaries","threads","attempts","writer"],_=class extends h{db;acquisition;location;constructor(e){super(),this.location=e}async acquireWriter(){let e=await this.exclusive(),t=q();this.acquisition=t;try{this.db!==void 0&&this.recordWriter(this.db)}catch(r){throw this.acquisition=void 0,e.release(),r}let s=!1;return{identity:e.identity,acquisitionId:t,release:async()=>{if(!s){s=!0;try{this.acquisition===t&&(this.acquisition=void 0,this.db?.run("DELETE FROM writer WHERE acquisition_id = ?",t))}finally{e.release()}}}}}requireWriter(e,t){if(this.acquisition!==t)throw new o(t);if(e.all("SELECT acquisition_id FROM writer WHERE one = 1")[0]?.acquisition_id!==t)throw new o(t)}recordWriter(e){this.acquisition!==void 0&&e.run("INSERT INTO writer (one, acquisition_id) VALUES (1, ?) ON CONFLICT(one) DO UPDATE SET acquisition_id = excluded.acquisition_id",this.acquisition)}async doOpen(){let e=this.connect();try{let t=i=>Number(e.all("SELECT COUNT(*) AS present FROM sqlite_master WHERE type = 'table' AND name = ?",i)[0].present)>0,s=t("events")&&Number(e.all("SELECT COUNT(*) AS rows FROM events")[0].rows)>0,r=s&&t("meta")?e.all("SELECT format FROM meta WHERE one = 1")[0]?.format:0;if(S(Number(r??0),s,this.location),!s)for(let i of I)e.exec(`DROP TABLE IF EXISTS ${i}`);e.exec(O),s||e.run("INSERT INTO meta (one, format) VALUES (1, ?)",R),this.recordWriter(e),this.db=e}catch(t){throw e.close(),t}}async doClose(){this.db!==void 0&&(this.db.close(),this.db=void 0)}requireDb(){if(this.db===void 0)throw new Error(`${this.constructor.name} is not open`);return this.db}async doHead(){return this.headOf(this.requireDb())}headOf(e){return Number(e.all("SELECT COALESCE(MAX(seq), 0) AS head FROM events")[0].head)}async doAppend(e,t){let s=await this.requireDb().transaction(()=>{let r=this.requireDb(),i=r.all("SELECT digest FROM attempts WHERE id = ?",e.id)[0];if(i!==void 0)return i.digest===t?"duplicate":"mismatch";this.requireWriter(r,e.writer);let n=this.headOf(r);if(n!==e.baseHead)throw new u(e.baseHead,n);let a=e.rows[0],T=r.all("SELECT spawn_seq FROM threads WHERE thread_id = ?",a.thread_id)[0];if(T===void 0&&a.type!=="thread/spawned")throw new Error(`Thread ${a.thread_id} is not in the store; its first row must be its spawn row`);for(let d of e.rows)r.run("INSERT INTO events (seq, type, created_at, thread_id, payload) VALUES (?, ?, ?, ?, jsonb(?))",d.seq,d.type,d.timestamp,d.thread_id,JSON.stringify({data:d.data,source_seqs:d.source_seqs}));return r.run("INSERT INTO threads (thread_id, spawn_seq, last_seq) VALUES (?, ?, ?) ON CONFLICT(thread_id) DO UPDATE SET last_seq = excluded.last_seq",a.thread_id,T?.spawn_seq??a.seq,e.rows.at(-1).seq),r.run("INSERT INTO attempts (id, digest) VALUES (?, ?)",e.id,t),"appended"});if(s==="mismatch")throw new c(e.id);return s}async doRead(e){return this.rows("WHERE thread_id = ? ORDER BY seq",e)}async doRowAt(e){return this.rows("WHERE seq = ?",e)[0]}async doThreads(){return this.requireDb().all("SELECT thread_id, spawn_seq, last_seq FROM threads ORDER BY spawn_seq").map(t=>({threadId:t.thread_id,spawnSeq:Number(t.spawn_seq),lastSeq:Number(t.last_seq)}))}async doSummaries(){let e;try{e=this.requireDb().all("SELECT json(payload) AS payload FROM summaries ORDER BY spawn_seq")}catch(t){throw new E("[invalid SQLite JSONB summary]",t)}return e.map(t=>l(t.payload))}doPutSummaries(e,t){return this.writeSummaries(e,t,!1)}doReplaceCatalog(e,t){return this.writeSummaries(e,t,!0)}writeSummaries(e,t,s){return this.requireDb().transaction(()=>{let r=this.requireDb();this.requireWriter(r,t),s&&r.exec("DELETE FROM summaries");for(let i of e)r.run("INSERT INTO summaries (thread_id, spawn_seq, through_seq, payload) VALUES (?, ?, ?, jsonb(?)) ON CONFLICT(thread_id) DO UPDATE SET spawn_seq = excluded.spawn_seq, through_seq = excluded.through_seq, payload = excluded.payload WHERE excluded.through_seq >= summaries.through_seq",i.thread_id,i.spawn_seq,i.through_seq,this.serializeSummary(i))})}rows(e,...t){let s;try{s=this.requireDb().all(`SELECT seq, type, created_at, thread_id, json(payload) AS payload FROM events ${e}`,...t)}catch(r){throw new E("[invalid SQLite JSONB payload]",r)}return s.map(r=>N(r.payload,i=>{let{data:n,source_seqs:a}=i;return{seq:r.seq,type:r.type,timestamp:r.created_at,thread_id:r.thread_id,data:n,source_seqs:a}}))}};export{_ as a};
@@ -0,0 +1 @@
1
+ import{a as y}from"./CDQG7RKA.js";import{b as m,c as p,e as v}from"./DRYAN665.js";import{b as c}from"./2OSESBIL.js";import{z as h}from"zod";var g=new WeakMap;function j(o){let i=g.get(o);return i===void 0&&(i=m({plugin:"lagent:tool-policy",instanceId:o.name,kind:"mode-notice",version:1,schema:h.strictObject({mode:h.enum(o.modes)})}),g.set(o,i)),i}var z={name:"lagent:tool-policy",inject:["journal","threads"],apply(o,i){let{agents:r,confirm:l,approve:a,deny:u,modes:d,rules:s,notice:E}=i,w=e=>r===void 0||c(r,e),f=e=>o.on("lagent/tool/authorize",({toolCall:n,agent:t,threadId:_})=>w(t.name)?e(n.name,_):void 0);if(l!==void 0){let e=typeof l=="function"?l:n=>l.includes(n);f(n=>e(n)?"confirm":void 0)}if(a!==void 0&&f(e=>a==="all"||a.includes(e)?"approve":void 0),u!==void 0&&f(e=>u.includes(e)?"deny":void 0),d===void 0)return;for(let e of d.modes)if(!Object.hasOwn(s,e)||s[e]===void 0)throw new Error(`toolPolicy: modes ${d.name} have no rules for ${e}`);let O=j(d);f((e,n)=>{let t=s[d.of(o,n)];return t.allow!==void 0&&!t.allow.includes(e)?t.denial===void 0?"deny":{decision:"deny",reason:t.denial}:t.approve==="all"?"approve":void 0}),v(o,{event:O,...r===void 0?{}:{agents:r},rank:1,current:e=>{try{return{mode:d.of(o,e.threadId)}}catch(n){if(n instanceof y)return;throw n}},render:({mode:e},n,{notices:t})=>E(e,{seen:n?.mode??null,last:p(t)?.value.mode??null})})}},A=["run_command","start_command","edit_files"];export{z as a,A as b};
@@ -0,0 +1 @@
1
+ import{c as d,d as a}from"./J5S4URAW.js";function f(s,c){let t=new Map,r=a(s,c),n=!1,o=e=>{t.delete(e),r.delete(e)};return{failed(e,u){if(n)return;let i=(t.get(e)??0)+1;t.set(e,i),r.set(e,s.now()+d(i),u)},succeeded:o,clear:o,pending:e=>t.has(e),dispose(){n=!0,t.clear(),r.dispose()}}}export{f as a};
@@ -0,0 +1 @@
1
+ import{b as l}from"./DRYAN665.js";import{z as p}from"zod";var m=class extends Error{constructor(s,d){super(`Thread ${s} has no conversation root to read its ${d} mode from`)}},w=new Set;function $(e){if(w.has(e.name))throw new Error(`Modes ${e.name} are already defined`);if(w.add(e.name),!e.modes.includes(e.initial))throw new Error(`Modes ${e.name}: the initial mode ${e.initial} is not one of them`);let s=p.enum(e.modes),d=l({plugin:"lagent:modes",instanceId:e.name,kind:"mode-changed",version:1,policyState:!0,schema:p.strictObject({mode:s})}),i=d.projection({key:"mode",init:()=>null,apply:(r,{mode:o})=>o}),u=(r,o)=>r.state(i,o),c=(r,o)=>{if(e.authority==="thread")return o;let t=r.threads.get(o);if(t===void 0)return o;let n=t.originRoot;if(n===null)throw new m(o,e.name);return n},h=(r,o)=>u(r.journal,c(r,o))??e.initial;return{...e,of:h,authorityOf:c,recorded:u,async set(r,o,t){let n=s.parse(t),a=c(r,o);if(r.journal.summary(a)===void 0)throw new Error(`Unknown thread: ${a}`);await r.journal.transact(a,()=>({rows:n===h(r,a)?[]:[d.entry({mode:n},{threadId:a})],value:void 0}))},opening(r){let o=s.parse(r);return t=>{if(t.kind==="send")throw new Error(`Modes ${e.name}: opening rows only open a thread`);let{threadId:n,opening:a}=t;if(e.authority==="conversation"&&a.origin!==null)throw new Error(`Modes ${e.name}: thread ${n} is in its conversation's mode`);return[d.entry({mode:o},{threadId:n})]}}}}export{m as a,$ as b};
@@ -0,0 +1,3 @@
1
+ var u=class extends Error{provider;feature;constructor(r,n){super(`Provider '${r}' cannot do ${n}`),this.provider=r,this.feature=n,this.name="ProviderUnsupportedError"}},d=class extends Error{provider;constructor(r,n){super(`Provider '${r}' refused the request: it exceeds the model's context window`,n),this.provider=r,this.name="ContextOverflowError"}},c=class extends Error{provider;kind;partial;providerMetadata;constructor(r,n,s,a,S){super(`${n}: ${S}`),this.provider=r,this.kind=n,this.partial=s,this.providerMetadata=a,this.name="ResponseSettlementError"}},p=class extends Error{provider;idleMs;constructor(r,n){super(`'${r}' sent nothing for ${n} ms`),this.provider=r,this.idleMs=n,this.name="StreamIdleError"}},m=class extends Error{provider;partial;providerMetadata;constructor(r,n,s,a){super(`the response of '${r}' failed after it had begun`,a),this.provider=r,this.partial=n,this.providerMetadata=s,this.name="ResponseInterruptedError"}};import{z as o}from"zod";var f=(...t)=>t.some(r=>r!==null&&r!==""),y=o.discriminatedUnion("type",[o.object({type:o.literal("text"),text:o.string()}),o.object({type:o.literal("image"),url:o.string().nullable().default(null),data:o.string().nullable().default(null),media_type:o.string().nullable().default(null),detail:o.enum(["auto","low","high"]).default("auto")}).refine(t=>f(t.url,t.data),{message:"An image part needs a url or base64 data"}),o.object({type:o.literal("file"),file_id:o.string().nullable().default(null),url:o.string().nullable().default(null),data:o.string().nullable().default(null),filename:o.string().nullable().default(null),media_type:o.string().nullable().default(null)}).refine(t=>f(t.file_id,t.url,t.data),{message:"A file part needs a file_id, a url or base64 data"})]),g=o.preprocess(t=>t==null?[]:typeof t=="string"?[{type:"text",text:t}]:t,o.array(y).default([])),R=t=>({type:"text",text:t}),h=t=>t.filter(r=>r.type==="text").map(r=>r.text).join("");import{z as e}from"zod";var j=["none","low","medium","high","max"],L=e.enum(j),l=e.record(e.string(),e.unknown()),x=()=>({type:"object",properties:{},additionalProperties:!0}),q=e.object({name:e.string(),description:e.string().default(""),input_schema:l.default(x)}).transform((t,r)=>{let n={...t.input_schema};if(Object.keys(n).length===0)return{...t,input_schema:x()};if(n.type!=="object")return r.addIssue({code:"custom",message:"ToolSpec.input_schema must describe an object"}),e.NEVER;let s=n.properties;if(s==null)n.properties={};else if(typeof s!="object"||Array.isArray(s))return r.addIssue({code:"custom",message:"ToolSpec.input_schema.properties must be a mapping"}),e.NEVER;let a=n.required;return a!=null&&!Array.isArray(a)?(r.addIssue({code:"custom",message:"ToolSpec.input_schema.required must be a list when present"}),e.NEVER):{...t,input_schema:n}}),E=e.looseObject({call_id:e.string(),name:e.string(),arguments:l.default({})}),v=e.looseObject({call_id:e.string(),name:e.string(),arguments:e.null(),malformed:e.strictObject({raw:e.string(),error:e.string()})}),T=e.union([E,v]),F=t=>t.arguments!==null,V=t=>t.arguments===null?t.malformed.raw:JSON.stringify(t.arguments),k=e.object({input_tokens:e.number().int().default(0),output_tokens:e.number().int().default(0),cache_read_input_tokens:e.number().int().default(0),cache_write_input_tokens:e.number().int().default(0),reasoning_output_tokens:e.number().int().default(0)});var b=e.looseObject({id:e.string(),type:e.string(),name:e.string().nullable().default(null),status:e.enum(["in_progress","completed","failed"]).default("completed"),summary:e.string().nullable().default(null)}),z=e.object({text_delta:e.string().default(""),reasoning_delta:e.string().default(""),provider_call:b.nullable().default(null)}),M=e.object({provider:e.string(),data:l.default({})}),P=["system","developer","user","assistant","tool"],_=e.object({role:e.enum(P),content:g,reasoning_content:e.string().nullable().default(null),tool_calls:e.array(T).default([]),provider_calls:e.array(b).default([]),tool_call_id:e.string().nullable().default(null),usage:k.nullable().default(null),provider_state:M.nullable().default(null)}),U=t=>_.parse(t),B=t=>h(t.content),C=["completed","length","other"],O=e.enum(C),G=e.object({message:_,finish:O,provider_metadata:l.default({})}).refine(t=>t.message.role==="assistant",{message:"ModelResponse.message must have role assistant"});import{z as i}from"zod";var K=i.object({kind:i.enum(["base","instruction","context"]),tag:i.string().nullable(),text:i.string()}),D=t=>t.map(r=>r.text).join(`
2
+
3
+ `);export{u as a,d as b,c,p as d,m as e,y as f,g,R as h,h as i,j,L as k,l,q as m,E as n,T as o,F as p,V as q,k as r,b as s,z as t,_ as u,U as v,B as w,O as x,G as y,K as z,D as A};
@@ -0,0 +1,3 @@
1
+ import{z as c}from"zod";var a=t=>t instanceof Error?t.message||t.constructor.name:String(t);function u(t){let n=[a(t)],e=t instanceof Error?t.cause:void 0;for(;e instanceof Error;){let o=a(e);n.some(r=>r.includes(o))||n.push(o),e=e.cause}return n.length===1?n[0]:`${n[0]} Caused by: ${n.slice(1).join(": ")}`}var f=t=>t?.code,d=(t,...n)=>n.includes(f(t)??"");function l(t){let n=t.issues.map(e=>`${e.path.length>0?e.path.join("."):"(root)"}: ${e.message}`);return`${t.issues.length} validation error${t.issues.length===1?"":"s"}
2
+ ${n.join(`
3
+ `)}`}var h=t=>t instanceof c.ZodError?l(t):u(t);function s(t,n,e=0){if(Object.is(n,t.reason))return!0;if(typeof n!="object"||n===null||e===4)return!1;let{cause:o,errors:r}=n;return s(t,o,e+1)?!0:Array.isArray(r)&&r.length>0&&r.every(i=>s(t,i,e+1))}function m(t,n){return t.aborted?s(t,n)?!0:n instanceof Error&&n.name==="AbortError":!1}export{a,u as b,f as c,d,l as e,h as f,s as g,m as h};
@@ -0,0 +1 @@
1
+ import{b as x}from"./2OSESBIL.js";import{la as b}from"./YLNJXQ3Z.js";import{h}from"./37YOGDGY.js";import{g as y,m as S}from"./KESCTXGO.js";import{isDeepStrictEqual as _}from"node:util";var g=class extends Error{record;supportedVersion;constructor(n,i){super(`Unsupported ${n.plugin}/${n.kind} payload version ${n.version}; expected ${i}`),this.record=n,this.supportedVersion=i,this.name="ExtensionVersionError"}};function $(r){let n=y.omit({data:!0}).parse({plugin:r.plugin,instance_id:r.instanceId,kind:r.kind,version:r.version});r.policyState===!0&&b(n);let i=e=>e.plugin===n.plugin&&e.instance_id===n.instance_id&&e.kind===n.kind,d=e=>e.type==="ext"&&i(e.data),p=e=>{if(e.version!==n.version)throw new g(e,n.version);return r.schema.parse(structuredClone(e.data))},o=e=>y.parse({...n,data:r.schema.parse(e)}),a=e=>e!==null&&i(e)?p(e):void 0,l=e=>e.type==="input/message"?a(e.data.source):void 0,f=h({key:`told:${JSON.stringify([n.plugin,n.instance_id,n.kind])}`,init:()=>({notices:[]}),apply(e,t){let s=e.notices;if(t.type==="surface/replaced"){let k=null;for(let m of s)m.visible&&(k??=new Set(t.source_seqs),k.has(m.row.seq)&&(m.visible=!1));return e}let c=l(t);return c===void 0||s.push({row:{threadId:t.thread_id,seq:t.seq},value:c,visible:!0}),e}}),u=(e,t)=>({type:"ext",data:o(e),options:t});return{record:o,parse:e=>r.schema.parse(e),entry:u,append(e,t,s){let c=u(t,s);return e.append(c.type,c.data,c.options)},read(e){return d(e)?p(e.data):void 0},contribution(e,t,s={}){return S({...e,source:o(t),source_seqs:[...s.sourceSeqs??[]]})},matchesSource(e){return i(e)},rejection(e,t){return{decision:"reject",reason:e,source:o(t)}},readContribution:l,readSource:a,told:f,projection(e){return h({key:JSON.stringify([n.plugin,n.instance_id,n.kind,e.key]),init:e.init,onFork:e.onFork,apply:(t,s)=>d(s)?e.apply(t,p(s.data),s):t})}}}function C(r){return r.notices.at(-1)??null}function q(r){for(let n=r.notices.length-1;n>=0;n-=1){let i=r.notices[n];if(i.visible)return i.value}return null}function N(r,n){let{event:i,agents:d,rank:p}=n;r.on("lagent/llm/step",o=>{if(d!==void 0){let t=r.journal.summary(o.threadId);if(t===void 0||!x(d,t.agent_name))return}let a=n.current(o);if(a===void 0)return;let l=i.parse(a),f=r.journal.state(i.told,o.threadId),u=q(f);if(u!==null&&_(u,l))return;let e=n.render(l,u,{step:o,notices:f});e!==null&&o.contribute(i.contribution({content:e},a),p)})}export{g as a,$ as b,C as c,q as d,N as e};
@@ -0,0 +1,17 @@
1
+ import{d as v}from"./DDANMY45.js";import{c as k}from"./KESCTXGO.js";import{spawn as D}from"node:child_process";import{StringDecoder as E}from"node:string_decoder";var M=3e3,T="IFS= read -r go <&3 || exit 125; exec 3<&-; ",_="exec 2>&1; ";async function A(t){if(t.signal.throwIfAborted(),t.env===void 0||t.env===null)throw new TypeError("spawnCommand needs an env");let e=t.stdio==="pipes",s=e?T:T+_,n=typeof t.command=="string"?["-c",`${s}exec /bin/sh -c "$1"`,"sh",t.command]:["-c",`${s}exec "$@"`,"sh",...t.command],r=D("/bin/sh",n,{cwd:t.cwd,detached:!0,env:t.env,stdio:e?["pipe","pipe","pipe","pipe"]:["ignore","pipe","ignore","pipe"]}),a=r.stdio[3];a.on("error",()=>{});let o=r.pid;if(o===void 0)throw await new Promise(c=>r.once("error",c));r.on("error",()=>{});let u=new Promise(c=>r.once("exit",(w,m)=>c({code:w,signal:m}))),l=e?[r.stdout,r.stderr]:[r.stdout];for(let c of[...l,...e?[r.stdin]:[]])c.on("error",()=>{});let h=Promise.all(l.map(c=>new Promise(w=>c.once("close",w)))).then(()=>{}),p=Date.now();try{await $.register(o),t.signal.throwIfAborted(),await t.beforeRelease?.(o),t.signal.throwIfAborted()}catch(c){throw a.destroy(),L(o,"SIGKILL"),$.unregister(o),c}a.end(`go
2
+ `);let f={readables:l,stdin:e?r.stdin:null},x=new I({pid:o,streams:f,exited:u,outputClosed:h,startedAt:p},t);return e?Object.assign(x,{stdin:r.stdin,stdout:r.stdout,stderr:r.stderr}):Object.assign(x,{output:r.stdout})}async function z(t){let e=await A(t),s=new E("utf8"),n="";return e.output.on("data",a=>{n+=s.write(a)}),{...await e.result,output:n+s.end()}}var C=4096;async function H(t){let{onLine:e,maxLineChars:s,delimiter:n,...r}=t,a=await A({...r,stdio:"pipes"});a.stdin.end();let o="",u=new E("utf8");a.stderr.on("data",i=>{o=(o+u.write(i)).slice(-C)});let l=new E("utf8"),h="",p=!1,f=!1,x=i=>{if(p)return;let d=s-h.length;if(i.length<=d){h+=i;return}h+=i.slice(0,k(i,d,"end")),p=!0},c=()=>{let i=h,d=p;h="",p=!1,e(i,d)===!1&&(f=!0,a.stop())},w=i=>{let d=0;for(;!f;){let g=i.indexOf(n,d);if(g===-1){x(i.slice(d));return}x(i.slice(d,g)),c(),d=g+1}};a.stdout.on("data",i=>{f||w(l.write(i))});let m=await a.result;return f||(w(l.end()),!f&&(h.length>0||p)&&c()),{...m,stderr:o+u.end()}}var I=class{pid;result;requestStop;constructor({pid:e,streams:s,exited:n,outputClosed:r,startedAt:a},o){this.pid=e;let u=o.killGraceMs??M,l=Promise.withResolvers();this.requestStop=l.resolve;let h=()=>l.resolve("abort");o.signal.addEventListener("abort",h,{once:!0});let p=o.timeoutMs===void 0?void 0:setTimeout(()=>l.resolve("timeout"),o.timeoutMs),f=async()=>{let x=await Promise.race([n.then(g=>({kind:"exit",exit:g})),l.promise.then(g=>({kind:"stop",cause:g}))]);clearTimeout(p),o.signal.removeEventListener("abort",h);let c=null,w=!1,m=!0,i;x.kind==="stop"?(c=x.cause,i=Date.now()+2*u,m=await P(e,u)):S(e)?(w=!0,i=Date.now()+2*u,m=await P(e,u)):i=Date.now()+u;let d=await b(n,i-Date.now());m&&await b(r,Math.min(u,i-Date.now()));for(let g of s.readables)g.destroy();return s.stdin?.destroy(),m?$.unregister(e):$.watchUntilEmpty(e),{exitCode:d?.code??null,exitSignal:d?.signal??null,stoppedBy:c,leftoversStopped:w,stopFailed:!m,durationMs:Date.now()-a}};this.result=f()}stop(){return this.requestStop("stop"),this.result}};function S(t){try{return process.kill(-t,0),!0}catch(e){return v(e,"EPERM")}}function L(t,e){try{process.kill(-t,e)}catch{}}var G=50;async function P(t,e){let s=Date.now(),n=!1;for(L(t,"SIGTERM");S(t);){let r=Date.now()-s;if(!n&&r>=e)L(t,"SIGKILL"),n=!0;else if(n&&r>=2*e)return!1;await K(G)}return!0}var K=t=>new Promise(e=>setTimeout(e,t));async function b(t,e){let s,n=new Promise(r=>s=setTimeout(()=>r(void 0),Math.max(0,e)));try{return await Promise.race([t,n])}finally{clearTimeout(s)}}var O=`trap '' INT TERM HUP
3
+ groups=' '
4
+ while IFS= read -r line; do
5
+ g=\${line#?}
6
+ case $line in
7
+ +*) case $groups in *" $g "*) ;; *) groups="$groups$g " ;; esac ;;
8
+ -*) case $groups in *" $g "*) groups="\${groups%% $g *} \${groups#* $g }" ;; esac ;;
9
+ esac
10
+ done
11
+ [ "$groups" = ' ' ] && exit 0
12
+ for g in $groups; do kill -TERM -$g 2>/dev/null; done
13
+ sleep 1
14
+ for g in $groups; do kill -KILL -$g 2>/dev/null; done
15
+ `,y=class{child;stdin;exited=!1;constructor(e,s){this.child=D("/bin/sh",["-c",O],{detached:!0,stdio:["pipe","ignore","ignore"]}),this.stdin=this.child.stdin,this.stdin.on("error",()=>{});let n=()=>{this.exited||(this.exited=!0,s(this))};this.child.once("exit",n),this.child.once("error",n),this.child.unref(),this.stdin.unref?.();for(let r of e)this.stdin.write(`+${r}
16
+ `)}get pid(){return this.child.pid}write(e){return this.exited?Promise.reject(new Error("The process reaper has exited")):new Promise((s,n)=>this.stdin.write(`${e}
17
+ `,r=>r?n(r):s()))}kill(){this.child.kill("SIGKILL")}},R=class{groups=new Set;stuck=new Set;reaper;exitListener=!1;watcher;async register(e){this.installExitListener(),this.groups.add(e);let s;for(let n=0;n<2;n++){let r=this.ensureReaper();try{await r.write(`+${e}`);return}catch(a){s=a,this.reaper===r&&(this.reaper=void 0)}}throw this.groups.delete(e),new Error("Could not register the command with the process reaper",{cause:s})}unregister(e){this.stuck.delete(e),this.groups.delete(e)&&this.reaper?.write(`-${e}`).catch(()=>{})}watchUntilEmpty(e){this.stuck.add(e),this.watcher===void 0&&(this.watcher=setInterval(()=>{for(let s of this.stuck)S(s)||this.unregister(s);this.stuck.size===0&&(clearInterval(this.watcher),this.watcher=void 0)},1e3),this.watcher.unref())}tracked(){return[...this.groups]}reaperPid(){return this.reaper?.pid}killReaper(){this.reaper?.kill()}ensureReaper(){return this.reaper??=new y(this.groups,e=>this.onReaperExit(e)),this.reaper}onReaperExit(e){this.reaper===e&&(this.reaper=void 0,this.groups.size>0&&e.pid!==void 0&&this.ensureReaper())}installExitListener(){this.exitListener||(this.exitListener=!0,process.on("exit",()=>{for(let e of this.groups)L(e,"SIGKILL")}))}},$=new R;export{M as a,A as b,z as c,H as d};