@leuduan/lagent 0.0.0-stage → 44.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. package/LICENSE +16 -0
  2. package/README.md +157 -2
  3. package/dist/chunks/2GCIWSOA.js +5 -0
  4. package/dist/chunks/2P47AHNK.js +7 -0
  5. package/dist/chunks/34KW6VNQ.js +1 -0
  6. package/dist/chunks/3UMZMPWW.js +1 -0
  7. package/dist/chunks/5IRF47YB.js +1 -0
  8. package/dist/chunks/6DRCKZ2C.js +1 -0
  9. package/dist/chunks/6FRNHMCV.js +1 -0
  10. package/dist/chunks/7LI64H5X.js +17 -0
  11. package/dist/chunks/7VAPNE3L.js +1 -0
  12. package/dist/chunks/ASSQZH3F.js +1 -0
  13. package/dist/chunks/B4FXK5ER.js +77 -0
  14. package/dist/chunks/BBCW2FZK.js +1 -0
  15. package/dist/chunks/BPRCULZH.js +1 -0
  16. package/dist/chunks/CANPZYTH.js +24 -0
  17. package/dist/chunks/CQEVREBT.js +1 -0
  18. package/dist/chunks/CUK7CGC7.js +1 -0
  19. package/dist/chunks/D4PQP5MA.js +3 -0
  20. package/dist/chunks/DDANMY45.js +3 -0
  21. package/dist/chunks/DDZ7YF26.js +1 -0
  22. package/dist/chunks/EMRB4KCN.js +6 -0
  23. package/dist/chunks/EPYQ5M3B.js +3 -0
  24. package/dist/chunks/FJLU4UH3.js +1 -0
  25. package/dist/chunks/G44LG6VL.js +1 -0
  26. package/dist/chunks/GGSVIIWJ.js +2 -0
  27. package/dist/chunks/HK6ZSONF.js +1 -0
  28. package/dist/chunks/IAAEP6VL.js +30 -0
  29. package/dist/chunks/JCTBX33H.js +36 -0
  30. package/dist/chunks/JFX2MXBA.js +4 -0
  31. package/dist/chunks/JFZZXVWD.js +15 -0
  32. package/dist/chunks/KUZCL2SH.js +1 -0
  33. package/dist/chunks/MHC6VPB4.js +7 -0
  34. package/dist/chunks/MMNNZCBO.js +5 -0
  35. package/dist/chunks/MNJ4SRF7.js +1 -0
  36. package/dist/chunks/N6IXG2VL.js +1 -0
  37. package/dist/chunks/OCBPT7KE.js +1 -0
  38. package/dist/chunks/OL5A6ITQ.js +1 -0
  39. package/dist/chunks/PUSUPTAT.js +1 -0
  40. package/dist/chunks/Q75FUN7D.js +2 -0
  41. package/dist/chunks/Q7S5LFGN.js +1 -0
  42. package/dist/chunks/RCIHV3KG.js +1 -0
  43. package/dist/chunks/S34ZA2R6.js +1 -0
  44. package/dist/chunks/SS3B5W34.js +12 -0
  45. package/dist/chunks/VYMT4TXD.js +1 -0
  46. package/dist/chunks/W57RW55W.js +1 -0
  47. package/dist/compositions/base.d.ts +11 -0
  48. package/dist/compositions/codex.d.ts +66 -0
  49. package/dist/compositions/codexPrompts.d.ts +56 -0
  50. package/dist/context.d.ts +109 -0
  51. package/dist/index.d.ts +55 -0
  52. package/dist/index.js +1 -0
  53. package/dist/journal/catalog.d.ts +112 -0
  54. package/dist/journal/forkChain.d.ts +16 -0
  55. package/dist/journal/index.d.ts +15 -0
  56. package/dist/journal/journal.d.ts +475 -0
  57. package/dist/journal/projection.d.ts +87 -0
  58. package/dist/journal/store.d.ts +181 -0
  59. package/dist/llm/client.d.ts +135 -0
  60. package/dist/llm/content.d.ts +52 -0
  61. package/dist/llm/failure.d.ts +82 -0
  62. package/dist/llm/index.d.ts +22 -0
  63. package/dist/llm/index.js +1 -0
  64. package/dist/llm/primitives.d.ts +286 -0
  65. package/dist/llm/prompt.d.ts +21 -0
  66. package/dist/llm/provider.d.ts +74 -0
  67. package/dist/llm/readLedger.d.ts +24 -0
  68. package/dist/llm/request.d.ts +58 -0
  69. package/dist/loop/agent.d.ts +18 -0
  70. package/dist/loop/authorization.d.ts +41 -0
  71. package/dist/loop/auxiliary.d.ts +58 -0
  72. package/dist/loop/chunks.d.ts +27 -0
  73. package/dist/loop/completion.d.ts +17 -0
  74. package/dist/loop/errors.d.ts +139 -0
  75. package/dist/loop/hooks.d.ts +274 -0
  76. package/dist/loop/index.d.ts +16 -0
  77. package/dist/loop/runner.d.ts +134 -0
  78. package/dist/loop/runtime.d.ts +76 -0
  79. package/dist/loop/strategy.d.ts +80 -0
  80. package/dist/loop/surfacePrepare.d.ts +30 -0
  81. package/dist/loop/tool.d.ts +106 -0
  82. package/dist/loop/toolCalls.d.ts +35 -0
  83. package/dist/plugin.d.ts +50 -0
  84. package/dist/plugin.js +1 -0
  85. package/dist/plugins/agentsMd.d.ts +80 -0
  86. package/dist/plugins/agentsMd.js +1 -0
  87. package/dist/plugins/ask/index.d.ts +26 -0
  88. package/dist/plugins/ask/index.js +1 -0
  89. package/dist/plugins/ask/service.d.ts +125 -0
  90. package/dist/plugins/ask/tools.d.ts +9 -0
  91. package/dist/plugins/commands/index.d.ts +43 -0
  92. package/dist/plugins/commands/index.js +1 -0
  93. package/dist/plugins/commands/output.d.ts +115 -0
  94. package/dist/plugins/commands/record.d.ts +558 -0
  95. package/dist/plugins/commands/service.d.ts +321 -0
  96. package/dist/plugins/commands/shell.d.ts +25 -0
  97. package/dist/plugins/commands/tools.d.ts +10 -0
  98. package/dist/plugins/compaction/checkpoint.d.ts +94 -0
  99. package/dist/plugins/compaction/config.d.ts +133 -0
  100. package/dist/plugins/compaction/estimate.d.ts +37 -0
  101. package/dist/plugins/compaction/index.d.ts +87 -0
  102. package/dist/plugins/compaction/index.js +7 -0
  103. package/dist/plugins/compaction/planner.d.ts +207 -0
  104. package/dist/plugins/compaction/prune.d.ts +9 -0
  105. package/dist/plugins/compaction/record.d.ts +227 -0
  106. package/dist/plugins/compaction/segments.d.ts +23 -0
  107. package/dist/plugins/compaction/state.d.ts +68 -0
  108. package/dist/plugins/compaction/summarize.d.ts +13 -0
  109. package/dist/plugins/dateAndBranch.d.ts +47 -0
  110. package/dist/plugins/dateAndBranch.js +1 -0
  111. package/dist/plugins/delegations/answers.d.ts +39 -0
  112. package/dist/plugins/delegations/assignmentKey.d.ts +22 -0
  113. package/dist/plugins/delegations/cleanup.d.ts +161 -0
  114. package/dist/plugins/delegations/constraint.d.ts +76 -0
  115. package/dist/plugins/delegations/index.d.ts +39 -0
  116. package/dist/plugins/delegations/index.js +1 -0
  117. package/dist/plugins/delegations/notices.d.ts +261 -0
  118. package/dist/plugins/delegations/obligations.d.ts +210 -0
  119. package/dist/plugins/delegations/record.d.ts +633 -0
  120. package/dist/plugins/delegations/request.d.ts +384 -0
  121. package/dist/plugins/delegations/role.d.ts +30 -0
  122. package/dist/plugins/delegations/service.d.ts +563 -0
  123. package/dist/plugins/delegations/standing.d.ts +19 -0
  124. package/dist/plugins/delegations/stopCheck.d.ts +21 -0
  125. package/dist/plugins/delegations/tools.d.ts +71 -0
  126. package/dist/plugins/delegations/waitContracts.d.ts +118 -0
  127. package/dist/plugins/delegations/waitResolver.d.ts +116 -0
  128. package/dist/plugins/diagnostics/digest.d.ts +14 -0
  129. package/dist/plugins/diagnostics/index.d.ts +68 -0
  130. package/dist/plugins/diagnostics/index.js +1 -0
  131. package/dist/plugins/fileTools/config.d.ts +10 -0
  132. package/dist/plugins/fileTools/editFiles.d.ts +117 -0
  133. package/dist/plugins/fileTools/fsRead.d.ts +17 -0
  134. package/dist/plugins/fileTools/gitDiscovery.d.ts +9 -0
  135. package/dist/plugins/fileTools/index.d.ts +18 -0
  136. package/dist/plugins/fileTools/index.js +1 -0
  137. package/dist/plugins/fileTools/ripgrep.d.ts +20 -0
  138. package/dist/plugins/fileTools/textEdit.d.ts +67 -0
  139. package/dist/plugins/fileTools/tools.d.ts +6 -0
  140. package/dist/plugins/historyRecall/history.d.ts +9 -0
  141. package/dist/plugins/historyRecall/index.d.ts +31 -0
  142. package/dist/plugins/historyRecall/index.js +1 -0
  143. package/dist/plugins/historyRecall/render.d.ts +34 -0
  144. package/dist/plugins/historyRecall/tools.d.ts +4 -0
  145. package/dist/plugins/mcp/catalog.d.ts +36 -0
  146. package/dist/plugins/mcp/config.d.ts +63 -0
  147. package/dist/plugins/mcp/connection.d.ts +53 -0
  148. package/dist/plugins/mcp/errors.d.ts +32 -0
  149. package/dist/plugins/mcp/index.d.ts +33 -0
  150. package/dist/plugins/mcp/index.js +5 -0
  151. package/dist/plugins/mcp/mount.d.ts +98 -0
  152. package/dist/plugins/mcp/names.d.ts +25 -0
  153. package/dist/plugins/mcp/render.d.ts +29 -0
  154. package/dist/plugins/mcp/slots.d.ts +15 -0
  155. package/dist/plugins/mcp/stdio.d.ts +49 -0
  156. package/dist/plugins/mcp/tools.d.ts +41 -0
  157. package/dist/plugins/mcp/version.d.ts +2 -0
  158. package/dist/plugins/routeNotice.d.ts +22 -0
  159. package/dist/plugins/routeNotice.js +1 -0
  160. package/dist/plugins/sandbox/absent.d.ts +33 -0
  161. package/dist/plugins/sandbox/client.d.ts +39 -0
  162. package/dist/plugins/sandbox/files.d.ts +28 -0
  163. package/dist/plugins/sandbox/index.d.ts +52 -0
  164. package/dist/plugins/sandbox/index.js +4 -0
  165. package/dist/plugins/sandbox/mode.d.ts +57 -0
  166. package/dist/plugins/sandbox/policy.d.ts +163 -0
  167. package/dist/plugins/sandbox/protocol.d.ts +107 -0
  168. package/dist/plugins/sandbox/service.d.ts +153 -0
  169. package/dist/plugins/sandbox/worker.d.ts +12 -0
  170. package/dist/plugins/sandbox/worker.js +1 -0
  171. package/dist/plugins/schedules/index.d.ts +21 -0
  172. package/dist/plugins/schedules/index.js +5 -0
  173. package/dist/plugins/schedules/record.d.ts +396 -0
  174. package/dist/plugins/schedules/service.d.ts +120 -0
  175. package/dist/plugins/schedules/time.d.ts +26 -0
  176. package/dist/plugins/schedules/tools.d.ts +6 -0
  177. package/dist/plugins/skills/discovery.d.ts +83 -0
  178. package/dist/plugins/skills/index.d.ts +31 -0
  179. package/dist/plugins/skills/index.js +1 -0
  180. package/dist/plugins/skills/tools.d.ts +11 -0
  181. package/dist/plugins/subAgents/availableRoutes.d.ts +53 -0
  182. package/dist/plugins/subAgents/index.d.ts +67 -0
  183. package/dist/plugins/subAgents/index.js +1 -0
  184. package/dist/plugins/subAgents/tools.d.ts +67 -0
  185. package/dist/plugins/threadDirs.d.ts +36 -0
  186. package/dist/plugins/threadDirs.js +1 -0
  187. package/dist/plugins/toolPolicy/index.d.ts +61 -0
  188. package/dist/plugins/toolPolicy/index.js +1 -0
  189. package/dist/plugins/truncateToolOutput.d.ts +30 -0
  190. package/dist/plugins/truncateToolOutput.js +6 -0
  191. package/dist/plugins/usage/index.d.ts +26 -0
  192. package/dist/plugins/usage/index.js +1 -0
  193. package/dist/plugins/usage/tracker.d.ts +34 -0
  194. package/dist/plugins/verify/index.d.ts +27 -0
  195. package/dist/plugins/verify/index.js +6 -0
  196. package/dist/plugins/verify/judgement.d.ts +16 -0
  197. package/dist/plugins/verify/record.d.ts +382 -0
  198. package/dist/plugins/verify/service.d.ts +93 -0
  199. package/dist/plugins/verify/state.d.ts +58 -0
  200. package/dist/plugins/webTools/html.d.ts +23 -0
  201. package/dist/plugins/webTools/index.d.ts +34 -0
  202. package/dist/plugins/webTools/index.js +1 -0
  203. package/dist/plugins/webTools/network.d.ts +23 -0
  204. package/dist/plugins/webTools/web.d.ts +32 -0
  205. package/dist/plugins/workflows/assignment.d.ts +20 -0
  206. package/dist/plugins/workflows/cleanup.d.ts +38 -0
  207. package/dist/plugins/workflows/definition.d.ts +184 -0
  208. package/dist/plugins/workflows/entryPlan.d.ts +95 -0
  209. package/dist/plugins/workflows/hostBindings.d.ts +146 -0
  210. package/dist/plugins/workflows/index.d.ts +28 -0
  211. package/dist/plugins/workflows/index.js +11 -0
  212. package/dist/plugins/workflows/observations.d.ts +81 -0
  213. package/dist/plugins/workflows/participantModels.d.ts +28 -0
  214. package/dist/plugins/workflows/participants.d.ts +143 -0
  215. package/dist/plugins/workflows/policy.d.ts +112 -0
  216. package/dist/plugins/workflows/record.d.ts +2849 -0
  217. package/dist/plugins/workflows/routing.d.ts +116 -0
  218. package/dist/plugins/workflows/schema.d.ts +26 -0
  219. package/dist/plugins/workflows/service.d.ts +477 -0
  220. package/dist/plugins/workflows/state.d.ts +373 -0
  221. package/dist/plugins/workflows/stopCheck.d.ts +13 -0
  222. package/dist/plugins/workflows/tools.d.ts +13 -0
  223. package/dist/plugins/workflows/view.d.ts +103 -0
  224. package/dist/plugins/workflows/workStatus.d.ts +21 -0
  225. package/dist/plugins/workspaceNotice.d.ts +36 -0
  226. package/dist/plugins/workspaceNotice.js +1 -0
  227. package/dist/providers/anthropic.d.ts +178 -0
  228. package/dist/providers/anthropicMessages.d.ts +66 -0
  229. package/dist/providers/codex.d.ts +71 -0
  230. package/dist/providers/codexAuth.d.ts +116 -0
  231. package/dist/providers/deepseek.d.ts +59 -0
  232. package/dist/providers/failure.d.ts +23 -0
  233. package/dist/providers/gateway.d.ts +24 -0
  234. package/dist/providers/index.d.ts +18 -0
  235. package/dist/providers/index.js +6 -0
  236. package/dist/providers/openaiChat.d.ts +73 -0
  237. package/dist/providers/openaiResponses.d.ts +109 -0
  238. package/dist/providers/opencodeCopilot.d.ts +23 -0
  239. package/dist/providers/opencodeGo.d.ts +109 -0
  240. package/dist/providers/shared.d.ts +112 -0
  241. package/dist/providers/stream.d.ts +156 -0
  242. package/dist/records/index.d.ts +13 -0
  243. package/dist/records/index.js +1 -0
  244. package/dist/records/journal.d.ts +2968 -0
  245. package/dist/records/toolResult.d.ts +65 -0
  246. package/dist/services/agents.d.ts +62 -0
  247. package/dist/services/catalogContributions.d.ts +73 -0
  248. package/dist/services/confinement/files.d.ts +118 -0
  249. package/dist/services/confinement/service.d.ts +219 -0
  250. package/dist/services/core.d.ts +28 -0
  251. package/dist/services/extensionEvents.d.ts +181 -0
  252. package/dist/services/journal.d.ts +26 -0
  253. package/dist/services/llm.d.ts +82 -0
  254. package/dist/services/modes.d.ts +65 -0
  255. package/dist/services/plugins.d.ts +34 -0
  256. package/dist/services/presets/definition.d.ts +154 -0
  257. package/dist/services/presets/installations.d.ts +139 -0
  258. package/dist/services/prompts.d.ts +85 -0
  259. package/dist/services/threads/activation.d.ts +100 -0
  260. package/dist/services/threads/admission.d.ts +174 -0
  261. package/dist/services/threads/birth.d.ts +219 -0
  262. package/dist/services/threads/index.d.ts +14 -0
  263. package/dist/services/threads/runEvents.d.ts +79 -0
  264. package/dist/services/threads/runOwner.d.ts +368 -0
  265. package/dist/services/threads/service.d.ts +450 -0
  266. package/dist/services/threads/thread.d.ts +268 -0
  267. package/dist/services/threads/view.d.ts +93 -0
  268. package/dist/services/tools.d.ts +118 -0
  269. package/dist/state/birth.d.ts +62 -0
  270. package/dist/state/chain.d.ts +46 -0
  271. package/dist/state/confirmations.d.ts +64 -0
  272. package/dist/state/continuation.d.ts +167 -0
  273. package/dist/state/decide.d.ts +72 -0
  274. package/dist/state/dispatches.d.ts +54 -0
  275. package/dist/state/errors.d.ts +26 -0
  276. package/dist/state/forks.d.ts +61 -0
  277. package/dist/state/holds.d.ts +104 -0
  278. package/dist/state/inbox.d.ts +188 -0
  279. package/dist/state/index.d.ts +31 -0
  280. package/dist/state/inputs.d.ts +58 -0
  281. package/dist/state/installations.d.ts +28 -0
  282. package/dist/state/limits.d.ts +14 -0
  283. package/dist/state/prompt.d.ts +13 -0
  284. package/dist/state/recovery.d.ts +7 -0
  285. package/dist/state/replace.d.ts +33 -0
  286. package/dist/state/requests.d.ts +129 -0
  287. package/dist/state/route.d.ts +61 -0
  288. package/dist/state/summary.d.ts +16 -0
  289. package/dist/state/surface.d.ts +153 -0
  290. package/dist/state/surfaceRead.d.ts +20 -0
  291. package/dist/state/thread.d.ts +73 -0
  292. package/dist/state/turns.d.ts +87 -0
  293. package/dist/state/waits.d.ts +38 -0
  294. package/dist/state/wake.d.ts +32 -0
  295. package/dist/stores/durableObject.d.ts +23 -0
  296. package/dist/stores/durableObject.js +1 -0
  297. package/dist/stores/durableObjectConnection.d.ts +27 -0
  298. package/dist/stores/memory.d.ts +29 -0
  299. package/dist/stores/sql.d.ts +59 -0
  300. package/dist/stores/sqlite.d.ts +31 -0
  301. package/dist/stores/sqlite.js +1 -0
  302. package/dist/sys/environment.d.ts +42 -0
  303. package/dist/sys/git.d.ts +47 -0
  304. package/dist/sys/paths.d.ts +9 -0
  305. package/dist/sys/spawn.d.ts +186 -0
  306. package/dist/testing/clock.d.ts +17 -0
  307. package/dist/testing/fakeLlm.d.ts +76 -0
  308. package/dist/testing/fedLlm.d.ts +34 -0
  309. package/dist/testing/helpers.d.ts +362 -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/settlement.d.ts +6 -0
  314. package/dist/testing/tmpDirs.d.ts +17 -0
  315. package/dist/util/async.d.ts +8 -0
  316. package/dist/util/diff.d.ts +25 -0
  317. package/dist/util/dispatch.d.ts +8 -0
  318. package/dist/util/errors.d.ts +28 -0
  319. package/dist/util/foldState.d.ts +17 -0
  320. package/dist/util/freeze.d.ts +2 -0
  321. package/dist/util/ids.d.ts +2 -0
  322. package/dist/util/json.d.ts +37 -0
  323. package/dist/util/jsonSchema.d.ts +7 -0
  324. package/dist/util/log.d.ts +6 -0
  325. package/dist/util/retries.d.ts +25 -0
  326. package/dist/util/text.d.ts +21 -0
  327. package/dist/util/timers.d.ts +43 -0
  328. package/package.json +183 -3
@@ -0,0 +1,107 @@
1
+ /**
2
+ * The messages between the sandbox service on the host's main thread and its worker thread
3
+ * (`worker.ts`), which holds sandbox-runtime. Types only, so the worker, which runs from the sources
4
+ * under Node's type stripping as from `dist`, imports nothing of lagent.
5
+ */
6
+ /** A path as sandbox-runtime takes it: a pattern when it reads as one, or a name marked literal. */
7
+ export type PathEntry = string | {
8
+ readonly path: string;
9
+ readonly literal: true;
10
+ };
11
+ export type ParentProxy = {
12
+ readonly http?: string;
13
+ readonly https?: string;
14
+ readonly noProxy?: string;
15
+ };
16
+ /** The configuration sandbox-runtime is initialized with, once, for the worker's life. */
17
+ export type SrtConfig = {
18
+ readonly network: {
19
+ readonly allowedDomains: readonly string[];
20
+ readonly deniedDomains: readonly string[];
21
+ /** Absent without a configured proxy: sandbox-runtime then reads its environment, which carries none. */
22
+ readonly parentProxy?: ParentProxy;
23
+ }
24
+ /** No `allowedDomains`: sandbox-runtime restricts the network only when it is defined. */
25
+ | {
26
+ readonly allowedDomains?: never;
27
+ readonly deniedDomains: readonly [];
28
+ readonly parentProxy?: never;
29
+ };
30
+ readonly filesystem: {
31
+ readonly denyRead: readonly PathEntry[];
32
+ readonly allowWrite: readonly PathEntry[];
33
+ readonly denyWrite: readonly PathEntry[];
34
+ };
35
+ /** The private copy of its JVM proxy agent: an existing explicit path ends sandbox-runtime's own search. */
36
+ readonly javaAgentJarPath: string;
37
+ };
38
+ /** A command's filesystem policy: complete lists, which replace the initialized ones for the call. */
39
+ export type CallConfig = {
40
+ readonly filesystem: {
41
+ readonly allowWrite: readonly PathEntry[];
42
+ readonly denyWrite: readonly PathEntry[];
43
+ readonly denyRead: readonly PathEntry[];
44
+ };
45
+ };
46
+ /** What the worker found when it started sandbox-runtime. */
47
+ export type InitReport = {
48
+ readonly version: string;
49
+ readonly supported: boolean;
50
+ readonly errors: readonly string[];
51
+ readonly warnings: readonly string[];
52
+ /** The paths under the home directory that sandbox-runtime keeps writable for its own uses. */
53
+ readonly conveniences: readonly string[];
54
+ /** How many JVM agent flags a wrapped command carries, and whether the one is the private copy. */
55
+ readonly javaAgent: {
56
+ readonly flags: number;
57
+ readonly isCopy: boolean;
58
+ };
59
+ };
60
+ export type WorkerRequest = {
61
+ readonly type: 'init';
62
+ readonly id: number;
63
+ readonly config: SrtConfig;
64
+ /** What the worker's own environment must say: its private temporary directory and its home. */
65
+ readonly expect: {
66
+ readonly tmpdir: string;
67
+ readonly home: string;
68
+ };
69
+ } | {
70
+ readonly type: 'wrap';
71
+ readonly id: number;
72
+ readonly command: string;
73
+ readonly commandId: string;
74
+ /** The command the wrap stands for, bounded, for sandbox-runtime's reports. */
75
+ readonly commandText: string;
76
+ readonly config: CallConfig;
77
+ }
78
+ /** Abandons the wrap sent with the same id; handled on arrival, not behind queued wraps. */
79
+ | {
80
+ readonly type: 'cancel';
81
+ readonly id: number;
82
+ } | {
83
+ readonly type: 'violations';
84
+ readonly id: number;
85
+ readonly commandId: string;
86
+ } | {
87
+ readonly type: 'reset';
88
+ readonly id: number;
89
+ };
90
+ /** A request as a caller writes it: the client assigns the id. */
91
+ export type WorkerMessage = WorkerRequest extends infer R ? (R extends WorkerRequest ? Omit<R, 'id'> : never) : never;
92
+ /** What each request's reply carries. */
93
+ export type WorkerValues = {
94
+ init: InitReport;
95
+ wrap: string;
96
+ violations: readonly string[];
97
+ reset: null;
98
+ };
99
+ export type WorkerReply = {
100
+ readonly id: number;
101
+ } & ({
102
+ readonly ok: true;
103
+ readonly value: unknown;
104
+ } | {
105
+ readonly ok: false;
106
+ readonly error: string;
107
+ });
@@ -0,0 +1,153 @@
1
+ import { Service, type Context } from '@leuduan/cordis';
2
+ import { z } from 'zod';
3
+ import type { WriteRows } from '../../state/index.js';
4
+ import { type ConfinementHandler, type ConfinementSnapshot } from '../../services/confinement/service.js';
5
+ import { type SandboxMode } from './mode.js';
6
+ export declare const SandboxConfigSchema: z.ZodObject<{
7
+ worker: z.ZodUnion<readonly [z.ZodCustom<import("url").URL, import("url").URL>, z.ZodString]>;
8
+ searchPath: z.ZodString;
9
+ tmpRoot: z.ZodString;
10
+ javaAgentJar: z.ZodString;
11
+ unconfined: z.ZodEnum<{
12
+ refused: "refused";
13
+ allowed: "allowed";
14
+ }>;
15
+ filesystem: z.ZodObject<{
16
+ allowWrite: z.ZodArray<z.ZodString>;
17
+ denyRead: z.ZodArray<z.ZodString>;
18
+ denyWrite: z.ZodArray<z.ZodString>;
19
+ }, z.core.$strict>;
20
+ network: z.ZodDiscriminatedUnion<[z.ZodObject<{
21
+ mode: z.ZodLiteral<"allowlist">;
22
+ allowedDomains: z.ZodArray<z.ZodString>;
23
+ deniedDomains: z.ZodArray<z.ZodString>;
24
+ parentProxy: z.ZodUnion<readonly [z.ZodLiteral<"none">, z.ZodObject<{
25
+ http: z.ZodOptional<z.ZodURL>;
26
+ https: z.ZodOptional<z.ZodURL>;
27
+ noProxy: z.ZodOptional<z.ZodString>;
28
+ }, z.core.$strict>]>;
29
+ }, z.core.$strict>, z.ZodObject<{
30
+ mode: z.ZodLiteral<"unrestricted">;
31
+ }, z.core.$strict>], "mode">;
32
+ drainTimeoutMs: z.ZodDefault<z.ZodNumber>;
33
+ }, z.core.$strict>;
34
+ export type SandboxConfigInput = z.input<typeof SandboxConfigSchema>;
35
+ /** Whether the sandbox can confine a launch now: `failed` once its worker died or its start failed, for good. */
36
+ export type SandboxHealth = 'ready' | 'failed';
37
+ declare module '@leuduan/cordis' {
38
+ interface Context {
39
+ /** The OS sandbox for shell commands, the confinement handler of `ctx.confinement` (optional plugin, `@leuduan/lagent/plugins/sandbox`). */
40
+ sandbox: SandboxService;
41
+ }
42
+ interface Events {
43
+ /**
44
+ * The sandbox can no longer confine a launch, so it refuses every one, confined or not: its
45
+ * worker died or it failed to start. For a host that shows conversations' sandbox state.
46
+ */
47
+ 'lagent/sandbox/health'(health: SandboxHealth): void;
48
+ }
49
+ }
50
+ /**
51
+ * The OS sandbox for shell commands, as a service and as the one confinement handler of `ctx.confinement`.
52
+ * sandbox-runtime runs on a worker thread of this process (`./worker.ts`), started once, and this
53
+ * service owns it: the policy built for each command, the worker's messages and deadlines, and the
54
+ * order of teardown.
55
+ *
56
+ * Each conversation is confined or unconfined, as its durable mode says (`mode`, `setMode`, `opening`),
57
+ * unless the host's `unconfined: 'refused'` confines them all. The mode is read once, in the snapshot
58
+ * an operation takes at its first use: a switch applies to operations not yet used, and one already
59
+ * used keeps the policy it selected, its file access and launches included. An unconfined launch is
60
+ * still the sandbox's handler's, so it stops with it and a failed sandbox refuses it too. The model is
61
+ * told the mode as a notice, never in the prompt.
62
+ *
63
+ * The handler is registered before the worker starts and refuses every launch until the self-check
64
+ * passed, so a sandbox that fails to start never leaves a window in which launches run plain.
65
+ * Teardown releases the handle first, so what it confined ends before its proxy does. sandbox-runtime
66
+ * starts at most once per process, so a failed or disposed service is never restarted. The teardown
67
+ * order and its failure cases are in `docs/records/sandbox.md`.
68
+ */
69
+ export declare class SandboxService extends Service<SandboxConfigInput> implements ConfinementHandler {
70
+ static inject: string[];
71
+ /** What the model is told about confined commands: part of the notice's fact, so a changed one is told again. */
72
+ private readonly guidance;
73
+ private readonly config;
74
+ private state;
75
+ private failure;
76
+ private admitting;
77
+ private client;
78
+ private host;
79
+ private readonly handle;
80
+ private releasing;
81
+ constructor(ctx: Context, config: SandboxConfigInput);
82
+ [Service.init](): Promise<() => Promise<void>>;
83
+ /** The host's gate: whether any conversation may run its commands unconfined. */
84
+ get unconfined(): 'allowed' | 'refused';
85
+ /** Whether the sandbox can confine a launch now. */
86
+ get health(): SandboxHealth;
87
+ /**
88
+ * The mode `threadId` runs its commands in: its conversation's recorded mode, `confined` before
89
+ * one is recorded, and `confined` whatever was recorded when the host refuses unconfined. The one
90
+ * value preparation, the notice and a host's display read.
91
+ */
92
+ mode(threadId: string): SandboxMode;
93
+ /**
94
+ * Records `mode` for `threadId`'s conversation, when it changes it. Refuses a mode the host's gate
95
+ * refuses, a thread the journal does not hold, and a thread with an origin, which is in its
96
+ * conversation's mode: switch the conversation.
97
+ */
98
+ setMode(threadId: string, mode: SandboxMode): Promise<void>;
99
+ /**
100
+ * The rows that record `mode` in the write that creates or forks a conversation (`Opening.rows`),
101
+ * always one, so an opening leaves evidence of the choice. The mode and the host's gate are judged
102
+ * here, before anything is written; a thread with an origin is refused inside the write.
103
+ */
104
+ opening(mode: SandboxMode): WriteRows;
105
+ private refuseGated;
106
+ /**
107
+ * Admits one operation for `threadId` and reads its mode, once: the operation's launches and its
108
+ * file policy keep the mode selected here, whatever switch lands while they prepare or run.
109
+ */
110
+ snapshot(threadId: string): Promise<ConfinementSnapshot>;
111
+ private prepare;
112
+ /**
113
+ * An unconfined launch: what core would have run with no handler, with the provenance that says so.
114
+ * None of the confined machinery runs: no scratch directory, policy, digest, worker request or
115
+ * violation lookup.
116
+ */
117
+ private plain;
118
+ private start;
119
+ /** Runs a fixed command through the path every command takes, so a sandbox that cannot confine never serves. */
120
+ private selfCheck;
121
+ private requireOpen;
122
+ /**
123
+ * A confined launch from its geometry alone, never a thread, so the self-check builds one with none.
124
+ * `trusted` skips the root checks, for the one launch whose root lies in the temporary root.
125
+ */
126
+ private build;
127
+ /**
128
+ * The filesystem policy for a root and a scratch key, the one value both a launch's confinement
129
+ * and the file tools' policy are rendered from. `trusted` skips the root's own checks, for the
130
+ * one launch whose root lies in the temporary root.
131
+ */
132
+ private policyFor;
133
+ /** What sandbox-runtime recorded against one command: best-effort, from its global tail of recent events. */
134
+ private violationsOf;
135
+ private onWorkerDeath;
136
+ /** Tells the host's listeners the sandbox failed; a listener that throws is reported and never interrupts the caller. */
137
+ private announceFailure;
138
+ /** The unload guard: closes admission at once, then releases what the handler confined. */
139
+ private closeAndRelease;
140
+ /**
141
+ * Releases the handle once, whoever asks: core stops admitting through the handler, aborts what it
142
+ * prepared and waits for the groups. `false`, with the error reported, when a group could not be
143
+ * confirmed stopped, or one still ran at the bound: a confined process may still run, so the worker
144
+ * stays.
145
+ */
146
+ private releaseHandle;
147
+ /**
148
+ * Resets sandbox-runtime and ends the worker, once the handle was released: freeing its proxy port
149
+ * while a confined process may still run would hand the port to a listener without the
150
+ * allowlist, which that process's profile still permits.
151
+ */
152
+ private release;
153
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * The sandbox worker: a message interface over Anthropic's sandbox-runtime (`SandboxManager`) on a
3
+ * worker thread of the host, and nothing else. It is the one module that loads sandbox-runtime, so
4
+ * the library's process-wide state, its proxies and its signal handlers live here: signals are not
5
+ * delivered to worker threads, and the proxy runs on an event loop that does nothing else.
6
+ *
7
+ * The service (`./service.ts`) starts it with an explicit environment, sends `init` once, then
8
+ * `wrap` for each command, and `reset` last. Self-contained: it imports sandbox-runtime and Node
9
+ * only (types aside), so it runs from the sources under Node's type stripping as from `dist`, and
10
+ * bundles into a single-file executable as an extra entry point.
11
+ */
12
+ export {};
@@ -0,0 +1 @@
1
+ import{homedir as c,tmpdir as y}from"node:os";import{sep as u}from"node:path";import{parentPort as P}from"node:worker_threads";import{getDefaultWritePaths as S,NetworkConfigSchema as _,SandboxManager as n}from"@anthropic-ai/sandbox-runtime";import b from"@anthropic-ai/sandbox-runtime/package.json"with{type:"json"};var A=20,E=500,T=2e3,j=["HTTP_PROXY","HTTPS_PROXY","NO_PROXY","http_proxy","https_proxy","no_proxy"],a=P;if(a===null)throw new Error("lagent sandbox worker: started outside a worker thread");var d=new Map;a.on("message",e=>{I(e)});async function I(e){try{switch(e.type){case"init":return i(e.id,await O(e));case"wrap":{let o=new AbortController;d.set(e.id,o);try{let t=await n.wrapWithSandbox(e.command,"/bin/sh",e.config,o.signal,{commandId:e.commandId,commandText:e.commandText});return i(e.id,t)}finally{d.delete(e.id)}}case"cancel":d.get(e.id)?.abort();return;case"violations":{let o=n.getSandboxViolationStore().getViolationsForCommand(e.commandId);return i(e.id,o.slice(-A).map(t=>t.line.slice(0,E)))}case"reset":{let o;return await Promise.race([n.reset().catch(()=>{}),new Promise(t=>{o=setTimeout(t,T)})]),clearTimeout(o),i(e.id,null)}}}catch(o){let t={id:e.id,ok:!1,error:o instanceof Error?o.message:String(o)};a.postMessage(t)}}function i(e,o){let t={id:e,ok:!0,value:o};a.postMessage(t)}async function O(e){let{config:o,expect:t}=e;if(o.network.allowedDomains!==void 0){let r=_.safeParse(o.network);if(!r.success){let v=r.error.issues.map(g=>`${g.path.join(".")}: ${g.message}`);throw new Error(`sandbox-runtime rejects the network configuration: ${v.join("; ")}`)}}if(y()!==t.tmpdir)throw new Error(`the worker's temporary directory is ${y()}, not the private directory ${t.tmpdir}`);if(c()!==t.home)throw new Error(`the worker's home directory is ${c()}, not ${t.home}`);let m=o.network.parentProxy===void 0?j.filter(r=>r in process.env):[];if(m.length>0)throw new Error(`the worker's environment sets ${m.join(", ")} but no parent proxy is configured`);let p=n.isSupportedPlatform(),{errors:l,warnings:x}=n.checkDependencies(),h={version:b.version,supported:p,errors:l,warnings:x,conveniences:[],javaAgent:{flags:0,isCopy:!1}};if(!p||l.length>0)return h;await n.initialize(o);let s=c(),k=S({denyRead:o.filesystem.denyRead}).filter(r=>r.startsWith(s.endsWith(u)?s:s+u)),w=await n.wrapWithSandbox("true","/bin/sh"),f=w.split("-javaagent:").length-1;return{...h,conveniences:k,javaAgent:{flags:f,isCopy:f===1&&w.includes(`-javaagent:${o.javaAgentJarPath}`)}}}
@@ -0,0 +1,21 @@
1
+ import type { Plugin } from '@leuduan/cordis';
2
+ import { type SchedulesConfig } from './service.js';
3
+ /**
4
+ * Scheduled wakes of root threads: `schedule_wake`, `list_wakes` and `cancel_wake`, registered for
5
+ * a grant, and `ctx.schedules` for the host (`list`, `create`, `cancel`, and `cancelRows` for a
6
+ * thread `cancel` that should stop them too). A wake fires once, after `in_seconds` or `at` a time,
7
+ * and is created only in a person's turn or by the host; it delivers its prompt as sourced user
8
+ * input waiting for a turn of its own, under a `fresh` cause.
9
+ *
10
+ * Its configuration is required: the `clock`, the `timeZone` a local `at` is read in, and the
11
+ * bounds `maxDelayMs` and `maxPendingPerThread`.
12
+ *
13
+ * Root-only. Mounted before `ctx.threads.start`, the wakes that fell due while the process was down
14
+ * fire inside its barrier, judged by its startup policy; mounted after, they are new causes.
15
+ */
16
+ export declare const schedules: Plugin.Object<SchedulesConfig>;
17
+ export { readScheduledWake } from './record.js';
18
+ export type { ScheduledWake, ScheduleStatus } from './record.js';
19
+ export { ScheduleRefusedError } from './service.js';
20
+ export type { ScheduleInfo, ScheduleRequest, SchedulesConfig, SchedulesService } from './service.js';
21
+ export { SCHEDULE_TOOLS } from './tools.js';
@@ -0,0 +1,5 @@
1
+ import{a as I}from"../../chunks/MNJ4SRF7.js";import{a as H,d as B}from"../../chunks/HK6ZSONF.js";import{a as Q}from"../../chunks/7VAPNE3L.js";import{b as z}from"../../chunks/EPYQ5M3B.js";import"../../chunks/5IRF47YB.js";import{b as y,c as G}from"../../chunks/JFX2MXBA.js";import{b as R,c as Z,d as L}from"../../chunks/S34ZA2R6.js";import{b as T}from"../../chunks/6FRNHMCV.js";import"../../chunks/CUK7CGC7.js";import{x as P}from"../../chunks/BPRCULZH.js";import"../../chunks/FJLU4UH3.js";import"../../chunks/DDANMY45.js";import"../../chunks/BBCW2FZK.js";import"../../chunks/MMNNZCBO.js";import"../../chunks/G44LG6VL.js";import"../../chunks/D4PQP5MA.js";import{Service as he}from"@leuduan/cordis";import{z as A}from"zod";import{z as c}from"zod";var x=c.number().int().nonnegative(),ae=c.discriminatedUnion("op",[c.strictObject({op:c.literal("created"),id:c.string().min(1),due_at:x,prompt:c.string().min(1),reason:c.string().min(1),time_zone:c.string().min(1),created_at:x,call_seq:c.number().int().positive().nullable()}),c.strictObject({op:c.literal("fired"),id:c.string().min(1),input_id:c.string().min(1)}),c.strictObject({op:c.literal("cancelled"),id:c.string().min(1),reason:c.string()})]),g=T({plugin:"lagent:schedules",kind:"schedule",version:1,schema:ae}),w=n=>n.cancelled?"cancelled":n.delivered===null?"pending":"fired",h=g.projection({key:"schedules",onFork:"reset",init:()=>new Map,apply(n,e){if(e.op==="created")return n.has(e.id)||n.set(e.id,{created:e,delivered:null,cancelled:!1}),n;let t=n.get(e.id);return t===void 0||n.set(e.id,e.op==="fired"?{...t,delivered:e.input_id}:{...t,cancelled:!0}),n}}),j=Q({key:"lagent:schedules",version:1,schema:c.strictObject({next_wake_at:x.nullable()}),applies:()=>!0,compute(n,e){let t=null;for(let r of n.state(h,e).values())w(r)==="pending"&&(t=t===null?r.created.due_at:Math.min(t,r.created.due_at));return{next_wake_at:t}}});function O(n,e){let t=j.read(n,e);return t.status==="available"?t.value.next_wake_at:null}var ce=c.strictObject({schedule_id:c.string().min(1),due_at:x,summary:c.string()}),$=T({plugin:"lagent:schedules",kind:"wake",version:1,schema:ce}),ue=n=>$.readSource(n);function J(n){try{return new Intl.DateTimeFormat("en-US",{timeZone:n}),!0}catch{return!1}}var Y=new Map;function le(n){let e=Y.get(n);return e===void 0&&(e=new Intl.DateTimeFormat("en-US",{timeZone:n,hourCycle:"h23",year:"numeric",month:"numeric",day:"numeric",hour:"numeric",minute:"numeric",second:"numeric"}),Y.set(n,e)),e}function M(n,e){let t={};for(let r of le(e).formatToParts(n))r.type!=="literal"&&(t[r.type]=Number(r.value));return{year:t.year,month:t.month,day:t.day,hour:t.hour,minute:t.minute,second:t.second}}function U(n,e){let t=M(n,e);return Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,t.second)-Math.floor(n/1e3)*1e3}var K=(n,e)=>n.year===e.year&&n.month===e.month&&n.day===e.day&&n.hour===e.hour&&n.minute===e.minute;function de(n,e){let t=Date.UTC(n.year,n.month-1,n.day,n.hour,n.minute),r=U(t-54e6,e),s=U(t+54e6,e),u=[...new Set([t-r,t-s])].sort((a,l)=>a-l);for(let a of u)if(K(M(a,e),n))return a;let o=Math.min(t-r,t-s),i=Math.max(t-r,t-s);for(;i-o>1e3;){let a=Math.floor((o+i)/2e3)*1e3;U(a,e)===s?i=a:o=a}return i}function V(n,e){let t=/^(\d{4})-(\d{2})-(\d{2})[T ](\d{2}):(\d{2})(?::(\d{2}))?(?:(Z)|([+-])(\d{2}):?(\d{2}))?$/.exec(n.trim());if(t===null)return null;let[r,s,u,o,i,a]=t.slice(1,7).map(_=>Number(_??0)),l=new Date(Date.UTC(r,s-1,u));if(l.getUTCFullYear()!==r||l.getUTCMonth()!==s-1||l.getUTCDate()!==u||o>23||i>59||a>59)return null;let[,,,,,,,d,p,S,ie]=t;if(d!==void 0||p!==void 0){let _=Number(S??0),q=Number(ie??0);if(_>14||q>59)return null;let oe=(p==="-"?-1:1)*(_*60+q)*6e4;return Date.UTC(r,s-1,u,o,i,a)-oe}let C={year:r,month:s,day:u,hour:o,minute:i},b=de(C,e);return K(M(b,e),C)?b+a*1e3:b}var X=A.number().int().positive(),me=A.strictObject({clock:H,timeZone:A.string().refine(J,"timeZone must be an IANA time zone"),maxDelayMs:X,maxPendingPerThread:X}),m=class extends Error{constructor(e){super(e),this.name="ScheduleRefusedError"}},D="Scheduled wakes are for conversations a person talks to; an agent working for another agent cannot schedule one.",fe="A scheduled wake can be created only in a turn a person started, not from a wake or a notice. Tell the person what to schedule, or ask them.",pe=n=>`sch-${n}`,ee=n=>`wake_${n}`,W=n=>n.replaceAll("&","&amp;").replaceAll('"',"&quot;").replaceAll("<","&lt;"),k=n=>new Date(n).toISOString().replace(".000Z","Z"),te=(n,e)=>`A scheduled wake may be due at most ${Math.round(n/6e4)} minutes from now, by ${k(e+n)}.`;function E(n,e,t){let{created:r}=e,s=e.delivered!==null&&!e.cancelled&&t.input(e.delivered).state==="queued";return{id:r.id,threadId:n,dueAt:r.due_at,timeZone:r.time_zone,prompt:r.prompt,reason:r.reason,status:w(e),unread:s,createdAt:r.created_at}}var v=class extends he{static inject=["threads","journal"];config;queue;inFlight=new Set;refreshed=Promise.resolve([]);armed=!1;retries;closed=!1;constructor(e,t){super(e,"schedules"),this.config=me.parse(t),this.queue=B(this.config.clock,r=>e.reportError(r)),this.retries=I(this.config.clock,r=>e.reportError(r)),e.effect(()=>e.journal.register(h)),e.effect(()=>e.journal.subscribe(r=>{this.armed&&g.read(r)!==void 0&&this.arm(r.thread_id)})),this.refreshed=j.register(e).refreshed,e.effect(()=>{let r=e.threads.registerOwner({owner:"lagent:schedules",repair:()=>this.catchUp()});return()=>r.dispose()}),R(e,()=>this.shutdown())}list({threadId:e}){let t=this.ctx.threads.view(e);return[...this.ctx.journal.state(h,e).values()].map(r=>E(e,r,t))}async create(e,t,r={}){let s=this.thread(e),u=r.callSeq===void 0?P("sch"):pe(r.callSeq),o=await s.read(l=>{let d=this.ctx.journal.state(h,e).get(u);if(d!==void 0)return E(e,d,l);if(s.origin!=null)throw new m(D);if(r.requirePersonTurn===!0&&!this.ctx.threads.chain(e).personTurn)throw new m(fe)});if(o!==void 0)return o;let i=this.createdRow(u,t,r.callSeq??null),{value:a}=await this.ctx.journal.transact(e,()=>{let l=this.ctx.journal.state(h,e);if(l.has(u))return{rows:[],value:null};let d=[...l.values()].filter(S=>w(S)==="pending").length;if(d>=this.config.maxPendingPerThread)return{rows:[],value:`This conversation already has ${d} scheduled wakes waiting, the most it may; cancel one with cancel_wake first.`};let p=this.config.clock.now();return i.due_at<=p?{rows:[],value:`${k(i.due_at)} has already passed; it is now ${k(p)}.`}:i.due_at>p+this.config.maxDelayMs?{rows:[],value:te(this.config.maxDelayMs,p)}:{rows:[g.entry({...i,created_at:p},{threadId:e})],value:null}});if(a!==null)throw new m(a);return s.read(l=>E(e,this.ctx.journal.state(h,e).get(u),l))}cancel(e,t,r="cancelled"){return this.track(async()=>{let s=this.thread(e);if(!await s.read(()=>this.ctx.journal.state(h,e).has(t)))throw new m(`No scheduled wake ${t} in this conversation.`);let o=await s.withdraw(ee(t),{rows:()=>this.ctx.journal.state(h,e).get(t).cancelled?[]:[g.entry({op:"cancelled",id:t,reason:r},{threadId:e})]});if(o.status==="refused")throw new Error(o.refusal.message);return{withdrawn:o.status==="withdrawn"}})}cancelRows(e,t="the conversation was stopped"){return[...this.ctx.journal.state(h,e).values()].filter(r=>w(r)==="pending").map(r=>g.entry({op:"cancelled",id:r.created.id,reason:t},{threadId:e}))}thread(e){let t=this.ctx.threads.get(e);if(t===void 0)throw new m(`No thread ${e}`);return t}createdRow(e,t,r){let{clock:s,timeZone:u,maxDelayMs:o}=this.config,i=s.now(),a=p=>{throw new m(p)};t.prompt.trim()===""&&a("A scheduled wake needs a prompt."),t.reason.trim()===""&&a("A scheduled wake needs a reason.");let{when:l}=t,d;return"in_seconds"in l?((!Number.isInteger(l.in_seconds)||l.in_seconds<1)&&a("in_seconds must be a whole number of at least 1."),d=i+l.in_seconds*1e3):(d=V(l.at,u)??a(`"${l.at}" is not a date and time such as 2026-10-11T14:30 or 2026-10-11T14:30+02:00.`),d<=i&&a(`${l.at} has already passed; it is now ${k(i)}.`)),d>i+o&&a(te(o,i)),{op:"created",id:e,due_at:d,prompt:t.prompt,reason:t.reason,time_zone:u,created_at:i,call_seq:r}}track(e){let t=e(),r=t.then(()=>{},()=>{});return this.inFlight.add(r),r.then(()=>this.inFlight.delete(r)),t}async catchUp(){try{await this.refreshed;let e=this.config.clock.now();await Promise.all(this.ctx.journal.summaries().filter(t=>{let r=O(this.ctx.journal,t.thread_id);return r!==null&&r<=e}).map(t=>this.check(t.thread_id)))}finally{this.armed=!0;for(let e of this.ctx.journal.summaries())this.arm(e.thread_id)}}arm(e){if(this.closed||this.retries.pending(e))return;let t=O(this.ctx.journal,e);t===null?this.queue.delete(e):this.queue.set(e,t,()=>{this.check(e)})}check(e){return this.track(()=>this.deliverDue(e))}async deliverDue(e){if(!this.closed)try{let t=this.ctx.threads.get(e);if(t===void 0)return;let r=this.config.clock.now(),s=await t.read(()=>[...this.ctx.journal.state(h,e).values()].filter(i=>w(i)==="pending"&&i.created.due_at<=r).map(i=>i.created.id)),o=(await Promise.allSettled(s.map(i=>this.fire(e,i)))).find(i=>i.status==="rejected");if(o!==void 0)throw o.reason;this.retries.succeeded(e),this.arm(e)}catch(t){if(this.ctx.reportError(t),this.closed)return;this.queue.delete(e),this.retries.failed(e,()=>{this.check(e)})}}async fire(e,t){if(this.closed)return;let r=this.thread(e),s=await r.read(()=>this.ctx.journal.state(h,e).get(t));if(s===void 0||w(s)!=="pending")return;let{created:u}=s,o=ee(t);await r.send({role:"user",content:we(u)},{id:o,source:$.record({schedule_id:t,due_at:u.due_at,summary:`${t} ${u.reason}`.slice(0,120)}),wake:{releases:!1,chain:"fresh"},target:"next-turn",rows:()=>{let i=this.ctx.journal.state(h,e).get(t);return i===void 0||w(i)!=="pending"?{refuse:{message:`Scheduled wake ${t} is no longer pending`}}:[g.entry({op:"fired",id:t,input_id:o},{threadId:e})]}})}async shutdown(){this.closed=!0,this.queue.dispose(),this.retries.dispose(),await Promise.allSettled([...this.inFlight])}};function we(n){return`<scheduled_wake ${[`schedule="${W(n.id)}"`,`due="${k(n.due_at)}"`,`time_zone="${W(n.time_zone)}"`,`reason="${W(n.reason)}"`].join(" ")}>
2
+ ${n.prompt}
3
+ </scheduled_wake>`}import{z as f}from"zod";function N(n,e){let t=Z(n.ctx,"schedules",e);if(n.ctx.threads.get(n.threadId)?.origin!=null)throw new m(D);return t}var ne=n=>`${n.id} ${n.unread?"delivered, not read yet":n.status} due ${k(n.dueAt)} (${n.timeZone}): ${n.reason}`,ge=f.strictObject({when:f.union([f.strictObject({in_seconds:f.number().int().min(1).describe("Seconds from now.")}),f.strictObject({at:f.string().describe("A date and time, such as 2026-10-11T14:30 (in the conversation\u2019s time zone) or 2026-10-11T14:30+02:00.")})]).describe("When: after in_seconds, or at a time."),prompt:f.string().min(1).describe("What you will be told when it fires: write it for yourself, then."),reason:f.string().min(1).describe("One line for the person, saying why.")}),F=y({name:"schedule_wake",description:"Schedule one wake of this conversation, after a delay or at a time. When it fires, you get its prompt as a new turn, even if nobody is here.",parameters:ge,onInterrupted:"rerun",executionMode:"exclusive",async execute(n,e){let t=await N(e,"schedule_wake").create(e.threadId,n,{callSeq:e.callSeq,requirePersonTurn:!0});return{output:`Scheduled ${ne(t)}`,metadata:{id:t.id,due_at:t.dueAt}}}}),re=y({name:"list_wakes",description:"List the scheduled wakes of this conversation still waiting to fire, and those that fired but whose message you have not read yet.",parameters:f.strictObject({}),onInterrupted:"rerun",executionMode:"parallel",execute:async(n,e)=>{let t=N(e,"list_wakes").list({threadId:e.threadId}),r=t.filter(s=>s.status==="pending"||s.unread);return{output:r.map(ne).join(`
4
+ `)||"No scheduled wakes waiting.",metadata:{pending:r.filter(s=>!s.unread).length,unread:r.filter(s=>s.unread).length,total:t.length}}}}),se=y({name:"cancel_wake",description:"Cancel a scheduled wake of this conversation, or its delivery still waiting to be read.",parameters:f.strictObject({id:f.string().min(1).describe("The id schedule_wake returned, such as sch-42.")}),onInterrupted:"rerun",executionMode:"exclusive",async execute({id:n},e){let{withdrawn:t}=await N(e,"cancel_wake").cancel(e.threadId,n,"cancel_wake");return{output:`Cancelled ${n}.${t?" Its waiting delivery was withdrawn.":""}`,metadata:{id:n,withdrawn:t}}}}),ke=["schedule_wake","list_wakes","cancel_wake"];var _e=["Use schedule_wake only when the person asks for something later, never to wait for what a notice will report, such as a sub-agent or a command started with notify.","A scheduled wake fires once, and can be created only in a turn the person started: never from a wake or a notice, so do not promise follow-ups you cannot schedule then.","When a wake fires you get its prompt as user input in a <scheduled_wake> frame naming its due time; compare it with the current date, since a wake waiting behind a stop is delivered late."].join(`
5
+ `),Ge={name:"lagent:schedules",inject:["tools","prompts","threads","journal"],async apply(n,e){L(n,"schedules"),await n.plugin(v,e);let t=[F,re,se];for(let r of t)G(n,r);z(n,{tag:"schedules",slot:"instruction",agents:"all",render:({tools:r})=>r.some(s=>s.tool===F)?_e:null})}};export{ke as SCHEDULE_TOOLS,m as ScheduleRefusedError,ue as readScheduledWake,Ge as schedules};