@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,139 @@
1
+ import type { ReadonlyJsonValue } from '../util/json.js';
2
+ import type { Refusal, RowRef } from '../state/index.js';
3
+ /** What holds a thread while an operation on it is refused busy. */
4
+ export type ThreadHolding = 'run' | 'compact' | 'rebuild' | 'configure' | 'release' | 'cancel';
5
+ /** A human's answer to an approval request. */
6
+ export type ApprovalDecision = {
7
+ readonly approved: boolean;
8
+ readonly rejection_message: string | null;
9
+ };
10
+ /** No agent is registered under this name. */
11
+ export declare class UnknownAgentError extends ReferenceError {
12
+ readonly agentName: string;
13
+ constructor(agentName: string);
14
+ }
15
+ /**
16
+ * An operation already holds this thread: a run, compaction, prompt rebuild, configuration change,
17
+ * release or cancel (`holding`), admitted one at a time.
18
+ */
19
+ export declare class ThreadBusyError extends Error {
20
+ readonly threadId: string;
21
+ readonly holding?: ThreadHolding;
22
+ /** @param holding - what holds the thread, when known: `run`, `compact`, `rebuild`, `configure`, `release` or `cancel`. */
23
+ constructor(threadId: string, holding?: ThreadHolding);
24
+ }
25
+ /**
26
+ * A configuration change was recorded, but the thread's plugins could not be restored from it: the
27
+ * thread is configured as asked and cannot run until a later change lets it restore. `cause` is
28
+ * the setup's error.
29
+ */
30
+ export declare class RestoreFailedError extends Error {
31
+ readonly threadId: string;
32
+ constructor(threadId: string, cause: unknown);
33
+ }
34
+ /** Creating this thread would nest deeper than `maxThreadDepth` allows. */
35
+ export declare class DepthExceededError extends Error {
36
+ readonly threadId: string;
37
+ readonly limit: number;
38
+ constructor(threadId: string, limit: number);
39
+ }
40
+ /**
41
+ * Thrown inside a step whose activation went stale before its dispatch, or by a judgment once the
42
+ * activation went stale under it: the turn ends `interrupted` (`activation-changed`).
43
+ */
44
+ export declare class StaleActivation extends Error {
45
+ constructor();
46
+ }
47
+ /**
48
+ * Thrown by a judgment whose fence broke while the activation stayed valid (`TurnRunner.fenced`): a
49
+ * required registration is gone or was replaced, or a fact a stop check declared it observed
50
+ * changed. The turn ends `interrupted` (`judgment-invalidated`), the answer still owed its checks.
51
+ */
52
+ export declare class JudgmentInvalidated extends Error {
53
+ constructor();
54
+ }
55
+ /** A turn that failed after appending its own `turn/end`; the journal already says what happened. */
56
+ export declare class RecordedTurnFailure extends Error {
57
+ readonly cause: unknown;
58
+ constructor(cause: unknown);
59
+ }
60
+ /** What a thread's recorded birth says about one field of a request that differs from it. */
61
+ export type BirthConflict = {
62
+ readonly field: 'agent' | 'origin' | 'kind' | 'cut' | 'route' | 'environment' | 'installations' | 'requires';
63
+ /** What the thread recorded: for `kind`, `fresh` or `fork`. */
64
+ readonly recorded: ReadonlyJsonValue;
65
+ readonly requested: ReadonlyJsonValue;
66
+ };
67
+ /**
68
+ * A creation or fork asked for an id a thread already holds, and the request is not that thread:
69
+ * under `identity` reuse its agent, origin, kind or cut differ, under `configuration` its birth
70
+ * does too. Never adopted, nothing was written; `conflicts` name every field that differs.
71
+ */
72
+ export declare class BirthConflictError extends Error {
73
+ readonly threadId: string;
74
+ readonly conflicts: readonly BirthConflict[];
75
+ constructor(threadId: string, conflicts: readonly BirthConflict[]);
76
+ }
77
+ /**
78
+ * A `create` or `fork` whose write-time `rows` callback vetoed it: nothing was recorded. The
79
+ * callback's own {@link Refusal} is `refusal`; an error the callback threw is not this, it propagates
80
+ * as it was thrown.
81
+ */
82
+ export declare class WriteRefusedError extends Error {
83
+ readonly refusal: Refusal;
84
+ readonly operation: 'create' | 'fork';
85
+ constructor(refusal: Refusal, operation: 'create' | 'fork');
86
+ }
87
+ /**
88
+ * A change of a thread's installations was asked while its activation is still getting ready: the
89
+ * change would wait on the setup it came from. Nothing was recorded; `whenReady()` or `close()` the
90
+ * thread first.
91
+ */
92
+ export declare class ThreadActivatingError extends Error {
93
+ readonly threadId: string;
94
+ constructor(threadId: string);
95
+ }
96
+ /**
97
+ * An answer to a confirmation that already has one, which it carries. Core compares nothing: a retry
98
+ * that repeats the recorded answer is refused like any other, and the caller decides whether the
99
+ * recorded decision is the one it meant. A revoked approval is a recorded rejection.
100
+ */
101
+ export declare class ConfirmationAnsweredError extends Error {
102
+ readonly threadId: string;
103
+ readonly requestId: string;
104
+ readonly decision: ApprovalDecision;
105
+ constructor(threadId: string, requestId: string, decision: ApprovalDecision);
106
+ }
107
+ /**
108
+ * The thread is not settled enough for what was asked: a request to prepare its surface or a change
109
+ * of its installations met a tool call without a result, a confirmation unfinished (open, or
110
+ * approved and not yet executed; the reason names its request ids) or an answer its stop checks have
111
+ * not judged. Nothing was recorded: no replacement or auxiliary call, no installation change.
112
+ */
113
+ export declare class ThreadUnsettledError extends Error {
114
+ readonly threadId: string;
115
+ constructor(threadId: string, reason: string);
116
+ }
117
+ /**
118
+ * A thread whose surface refused a replacement row, one written past `replaceSurface`: a bug or a
119
+ * hand-edited store. Its history can be read, and forked before that row, but nothing executes on
120
+ * it: not a run, not a compaction, not the close of an interrupted turn. What only records, a
121
+ * configuration change or a prompt rebuild, is not execution and is not refused.
122
+ */
123
+ export declare class CorruptHistoryError extends Error {
124
+ readonly threadId: string;
125
+ readonly row: RowRef;
126
+ readonly reason: string;
127
+ constructor(threadId: string,
128
+ /** The first refused row; it may belong to the lineage a fork inherited. */
129
+ row: RowRef, reason: string);
130
+ }
131
+ /**
132
+ * An auxiliary call the engine refused to send, because of how it was asked for: a prefix that does
133
+ * not end on a row of the current surface or that separates a tool call from its result, no
134
+ * instructions, or no route. Nothing was recorded or sent; it is the caller's error, never the
135
+ * model's.
136
+ */
137
+ export declare class AuxiliaryRefusedError extends Error {
138
+ constructor(message: string);
139
+ }
@@ -0,0 +1,274 @@
1
+ import type { AgentDefinition } from './agent.js';
2
+ import type { ExtensionRecord, JournalEvent, JournalEventInput, QueuedInput, Seq, StepContribution, StepContributionInput, TurnRejection } from '../records/journal.js';
3
+ import type { ModelCallClient } from '../llm/failure.js';
4
+ import type { JsonObject, ParsedToolCall, ResponseFinish, ThinkingEffort } from '../llm/primitives.js';
5
+ import type { ModelRequest, RequestPurpose } from '../llm/request.js';
6
+ import type { ModelRoute } from '../llm/provider.js';
7
+ import type { StreamingLLMResponse } from '../llm/client.js';
8
+ import type { LoopRuntime } from './runtime.js';
9
+ import type { RowRef } from '../state/index.js';
10
+ import type { InvocationContext, Tool, ToolOutcome } from './tool.js';
11
+ /**
12
+ * Every point at which the loop hands control to a plugin.
13
+ *
14
+ * Dispatches are named here so there is one place to read what a plugin can intercept — and the
15
+ * only place in the loop that reaches for `runtime.ctx`. They are thin on purpose: the cordis event
16
+ * *is* the seam, and wrapping it in an interface the engine implements would put a third hop between
17
+ * the loop and the listener without making either easier to read.
18
+ */
19
+ /** A tool call about to run; `lagent/tool/execute` listeners may wrap, replace or short-circuit it. */
20
+ export interface ToolInvocation {
21
+ readonly tool: Tool;
22
+ readonly call: ParsedToolCall;
23
+ readonly context: InvocationContext;
24
+ readonly toolName: string;
25
+ readonly threadId: string;
26
+ }
27
+ /** A tool call, before it is dispatched or held for confirmation. */
28
+ export interface ToolAuthorizationRequest {
29
+ readonly toolCall: ParsedToolCall;
30
+ readonly agent: AgentDefinition;
31
+ readonly threadId: string;
32
+ /** Runtime provenance is explicit; an absent origin is an ordinary model tool call. */
33
+ readonly origin?: {
34
+ readonly owner: string;
35
+ readonly candidateSeq: Seq;
36
+ readonly requestSeq: Seq;
37
+ };
38
+ }
39
+ /** A denial that tells the model why, so it can change course rather than retry the call. */
40
+ export interface ToolDenial {
41
+ readonly decision: 'deny';
42
+ readonly reason: string;
43
+ }
44
+ /**
45
+ * One policy's say on a call. `deny` refuses it, `confirm` requires confirmation before it runs,
46
+ * and `approve` satisfies such a requirement — a policy vouching for the call, as the user would.
47
+ * A {@link ToolDenial} refuses it with a reason. No answer has no opinion.
48
+ */
49
+ export type ToolPolicyDecision = 'deny' | 'confirm' | 'approve' | ToolDenial;
50
+ /**
51
+ * What authorization concluded: the reasons every denying policy gave, and who satisfied a
52
+ * confirmation requirement when one was met.
53
+ */
54
+ export type ToolAuthorization = {
55
+ decision: 'deny';
56
+ confirmedBy: null;
57
+ reasons: string[];
58
+ } | {
59
+ decision: 'confirm';
60
+ confirmedBy: null;
61
+ } | {
62
+ decision: 'allow';
63
+ confirmedBy: 'policy' | 'user' | null;
64
+ };
65
+ /**
66
+ * Every policy contributes, and the outcome is independent of registration order: denial wins over
67
+ * everything; a confirmation requirement holds the call unless the user approved it or a policy
68
+ * approves it. Approval can therefore satisfy a confirmation, never override a denial.
69
+ */
70
+ export declare function authorizeToolCall(runtime: LoopRuntime, request: ToolAuthorizationRequest, options: {
71
+ userApproved: boolean;
72
+ }): Promise<ToolAuthorization>;
73
+ /** A model step about to record its input. `lagent/llm/step` listeners may contribute to it. */
74
+ export interface ModelStep {
75
+ readonly threadId: string;
76
+ readonly turn: number;
77
+ readonly step: number;
78
+ /** The route the turn recorded on `turn/start`, which every request it sends through lagent uses. */
79
+ readonly route: ModelRoute;
80
+ /** The inbox input this step will record after the contributions. */
81
+ readonly claimed: readonly QueuedInput[];
82
+ /**
83
+ * Adds a message ahead of the claimed input. Valid only while the listener runs. Lower `rank`s
84
+ * are recorded first and equal ones keep listener order; it is any finite number, and omitted it
85
+ * is 0, so an environment fact needs none and a notice that must sit before or after it says so
86
+ * (`1`, `-1`, `0.5`). A rank is presentation order only. A contribution identical to one the step
87
+ * already carries, source and message alike, is recorded once, so a plugin mounted in two layers
88
+ * that reach one thread tells it once; the same contribution at two different ranks throws.
89
+ */
90
+ contribute(message: StepContributionInput, rank?: number): void;
91
+ }
92
+ /**
93
+ * What plugins add to a model step, validated, by ascending rank and then listener order, each
94
+ * identical one once.
95
+ *
96
+ * Synchronous on purpose: the loop records the result with no await in between, so a contribution
97
+ * always matches the plugin state it was read from. A throwing listener, or an invalid
98
+ * contribution, fails the step before any of its input is recorded.
99
+ */
100
+ export declare function collectStepContributions(runtime: LoopRuntime, step: Omit<ModelStep, 'contribute'>): StepContribution[];
101
+ /**
102
+ * How one request to prepare the surface settled: the replacement rows it committed, and how it
103
+ * ended. `completed` when the strategy's plan replaced something, with its reason; `skipped` when
104
+ * it planned nothing, or no strategy prepares the thread; `failed` when it planned a failure or
105
+ * threw, the error's text as the reason; `cancelled` when the request's signal aborted.
106
+ */
107
+ export type SurfacePrepareOutcome = {
108
+ readonly committed: RowRef[];
109
+ readonly ended: 'completed' | 'skipped' | 'failed' | 'cancelled';
110
+ readonly reason?: string;
111
+ };
112
+ /** A provisional answer, awaiting the stop checks' judgement. */
113
+ export interface TurnStop {
114
+ readonly threadId: string;
115
+ readonly turn: number;
116
+ /**
117
+ * A frozen copy, so a listener cannot alter what it judges. `seq` is its row: the reply's
118
+ * `assistant/message`, or the concluding `tool/result`. `text` is the reply's text parts, or the
119
+ * concluding result's output. A reply also says why the model stopped: `length` is a reply cut at
120
+ * the output cap, which a check may send back to be continued.
121
+ */
122
+ readonly answer: {
123
+ readonly seq: Seq;
124
+ readonly kind: 'reply';
125
+ readonly text: string;
126
+ readonly finish: ResponseFinish;
127
+ } | {
128
+ readonly seq: Seq;
129
+ readonly kind: 'concluded';
130
+ readonly text: string;
131
+ };
132
+ /** Steps this turn may still take; a continuation with none left ends the turn `max-steps`. */
133
+ readonly stepsLeft: number;
134
+ /** The turn's signal; a slow check should honour it. */
135
+ readonly signal: AbortSignal;
136
+ /**
137
+ * Declares a fact the check's verdict, an abstention included, rests on. `read` returns a token
138
+ * for it that differs whenever the fact does: synchronous, read-only and cheap, since core calls
139
+ * it again inside the write that records the judgment, and an answer whose declared facts read
140
+ * differently then is not judged, whatever the other checks said: the turn ends interrupted and a
141
+ * later run judges it again. Call it in the same synchronous step that reads the fact, before the
142
+ * check awaits anything, and before its promise settles at the latest; a call after the judgment
143
+ * ended throws. A read that throws counts as a change. Only declared facts are covered: what a
144
+ * check reads from the filesystem or the network stays its own to judge.
145
+ */
146
+ observe(read: () => string): void;
147
+ }
148
+ /** A fact a stop check declared, with the token it read when it declared it. */
149
+ export type StopObservation = {
150
+ readonly read: () => string;
151
+ readonly value: string | null;
152
+ };
153
+ /** One check's say on an answer. No answer accepts it. */
154
+ export type StopVerdict = {
155
+ decision: 'continue';
156
+ message: StepContributionInput;
157
+ } | {
158
+ decision: 'reject';
159
+ reason: string;
160
+ source: ExtensionRecord;
161
+ } | {
162
+ decision: 'prepare';
163
+ request: CompletionRequest;
164
+ };
165
+ /** A pure plan. Core owns its durable dispatch after every stop check permits preparation. */
166
+ export type CompletionRequest = {
167
+ readonly owner: string;
168
+ readonly key: string;
169
+ readonly operation: {
170
+ readonly name: string;
171
+ readonly arguments: JsonObject;
172
+ };
173
+ };
174
+ /** What the checks concluded together. */
175
+ export type StopJudgement = {
176
+ kind: 'accept';
177
+ } | {
178
+ kind: 'continue';
179
+ messages: StepContribution[];
180
+ } | {
181
+ kind: 'reject';
182
+ rejections: TurnRejection[];
183
+ } | {
184
+ kind: 'prepare';
185
+ requests: CompletionRequest[];
186
+ };
187
+ /**
188
+ * Asks every stop check about an answer. The outcome is independent of registration order: any
189
+ * rejection ends the turn, otherwise any continuation sends the model back, otherwise a preparation
190
+ * plan runs before rejudgment, otherwise the answer is accepted. A throwing check, or an invalid
191
+ * verdict, fails the check without deciding anything.
192
+ * The facts the checks declare they observed collect in `observations`, which the caller validates
193
+ * when it records the outcome.
194
+ */
195
+ export declare function judgeAnswer(runtime: LoopRuntime, stop: Omit<TurnStop, 'observe'>, observations: StopObservation[]): Promise<StopJudgement>;
196
+ /**
197
+ * Runs `use` with the confinement operation of one tool execution, opened for it and ended when it
198
+ * settles, whatever it did: the file access its tool was given dies with the call, and what it still
199
+ * had open is closed.
200
+ */
201
+ export declare function withOperation<T>(runtime: LoopRuntime, threadId: string, signal: AbortSignal, use: (operation: InvocationContext['operation']) => Promise<T>): Promise<T>;
202
+ /** Runs middleware and binds its final result to the dispatched call, for every execution path. */
203
+ export declare const executeTool: (runtime: LoopRuntime, invocation: ToolInvocation, run: () => Promise<ToolOutcome>) => Promise<ToolOutcome>;
204
+ /**
205
+ * A model request as `lagent/llm/request` middleware sees it. The turn's route is fixed, so `model`
206
+ * and `thinkingEffort` are read-only: assigning or deleting either throws, as it does for the
207
+ * correlation ids, `purpose` and `signal`. On an auxiliary request
208
+ * (`purpose: 'auxiliary'`) the caller's `toolChoice` and `maxOutputTokens` are fixed the same way,
209
+ * which the type cannot say.
210
+ */
211
+ export type ModelRequestDraft = Omit<ModelRequest, 'model' | 'thinkingEffort'> & {
212
+ readonly model: string;
213
+ readonly thinkingEffort?: ThinkingEffort;
214
+ };
215
+ /** Fields of a draft a caller may fix beside the route; see {@link modelSend}. */
216
+ export type FixedRequestField = 'toolChoice' | 'maxOutputTokens';
217
+ /** The rows that record a model request before it is sent. */
218
+ type RequestRowType = 'llm/request' | 'auxiliary/request';
219
+ /** What a caller says of its request row: where it was made and why; the terminal adds what was sent, and the tools. */
220
+ type RequestRowFields<K extends RequestRowType> = Omit<JournalEventInput[K], 'llm_call_id' | 'model' | 'message_count'>;
221
+ /** One model call's send, from {@link modelSend}: what the terminal recorded and how far the client got. */
222
+ export interface ModelSend<K extends RequestRowType> {
223
+ /** Sends `request`, once. The stream is the client's; see {@link modelSend}. */
224
+ call(request: ModelRequest): Promise<StreamingLLMResponse>;
225
+ /** The request row the terminal recorded; none while it has not, or when middleware answered without calling `next()`. */
226
+ readonly row: JournalEvent<K> | undefined;
227
+ /** The attempts the client made, kept before its call is awaited so a refusal or cancellation still has them; 0 until one starts. */
228
+ readonly attempts: number;
229
+ }
230
+ /**
231
+ * The fields every model request of a thread's agent carries the same way, a step's and an
232
+ * auxiliary call's alike: the route's model and effort, the tools the agent is granted now, the
233
+ * thread's recorded prompt, and the correlation. A caller adds what differs: its `messages`, its
234
+ * `toolChoice`, an output cap.
235
+ */
236
+ export declare function baseRequest(runtime: LoopRuntime, call: {
237
+ readonly threadId: string;
238
+ readonly agentName: string;
239
+ readonly route: ModelRoute;
240
+ readonly signal: AbortSignal;
241
+ readonly llmCallId: string;
242
+ readonly purpose: RequestPurpose;
243
+ }): Omit<ModelRequest, 'messages' | 'toolChoice' | 'maxOutputTokens'>;
244
+ /**
245
+ * The send of one model request, which a step's call and an auxiliary call share; they differ in the
246
+ * row they record (`type`, with the `fields` they say of it) and in how they read the stream.
247
+ *
248
+ * Middleware gets a draft of its own whose fields it may replace, never the data in them, and never
249
+ * the route: the model and effort the step was told are the ones sent, and never what the caller
250
+ * fixed beside it. The builder's data is frozen where it is made (surface messages, registry specs,
251
+ * prompt rows, auxiliary instructions); the fields the builder made for this call are frozen here, so
252
+ * the draft shares all of it without a copy. The terminal takes the {@link snapshot} that the journal
253
+ * recorder, the observers and the provider all receive.
254
+ *
255
+ * The terminal records the request row, with a `thread/tools` row before it when the tools differ
256
+ * from the thread's latest, shows it to `lagent/llm/sent` listeners and starts the call,
257
+ * and it checks for cancellation twice: before it records anything, so a cancel during middleware
258
+ * leaves no row, and after the row is recorded and observed, so a cancel there leaves the row and
259
+ * sends nothing.
260
+ */
261
+ export declare function modelSend<K extends RequestRowType>(runtime: LoopRuntime, client: ModelCallClient, type: K, fields: RequestRowFields<K>, fixed?: readonly FixedRequestField[]): ModelSend<K>;
262
+ /** A model request as it was sent: the prepared request, with no signal. */
263
+ export type SentModelRequest = Omit<ModelRequest, 'signal'>;
264
+ /** What `lagent/llm/sent` listeners see: the request as sent, and the row that recorded it. */
265
+ export interface SentRequest {
266
+ readonly request: SentModelRequest;
267
+ readonly row: JournalEvent<'llm/request'> | JournalEvent<'auxiliary/request'>;
268
+ }
269
+ /**
270
+ * Hands a problem that does not fail the turn to `internal/error` listeners, or the console. Kept
271
+ * here rather than inlined so `hooks.ts` stays the loop's only use of cordis (architecture test).
272
+ */
273
+ export declare function reportError(runtime: LoopRuntime, error: unknown): void;
274
+ export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * What the rest of the package may use from the loop: live execution against an activation. A live
3
+ * thread activation drives execution through TurnRunner; plugins extend it through tools and hooks.
4
+ * What the journal records, without a runtime, is `state/`.
5
+ */
6
+ export * from './chunks.js';
7
+ export * from './errors.js';
8
+ export * from './runtime.js';
9
+ export * from './hooks.js';
10
+ export type { AuxiliaryCall, AuxiliaryReply } from './auxiliary.js';
11
+ export * from './agent.js';
12
+ export * from './strategy.js';
13
+ export * from './tool.js';
14
+ export { declarePolicyState } from './authorization.js';
15
+ export { TurnRunner } from './runner.js';
16
+ export type { CompactOptions, ServedRun } from './runner.js';
@@ -0,0 +1,134 @@
1
+ import type { Seq, TurnEndReason } from '../records/journal.js';
2
+ import type { DeepReadonly, JsonValue } from '../util/json.js';
3
+ import type { SurfacePrepareOutcome } from './hooks.js';
4
+ import type { Lease, LoopRuntime } from './runtime.js';
5
+ /**
6
+ * What one `compact()` is given: a cancellation signal, and options for the strategy, which the
7
+ * engine passes on as they are and never reads.
8
+ */
9
+ export type CompactOptions = {
10
+ readonly signal?: AbortSignal;
11
+ readonly options?: JsonValue;
12
+ };
13
+ /**
14
+ * The run request an execution serves, as its turns see it: the id every `turn/start` records, the
15
+ * attempt cutoff of the execution, and the continuation decision, asked after each turn whether to
16
+ * open another.
17
+ */
18
+ export type ServedRun = {
19
+ readonly id: string;
20
+ readonly attemptCutoff: Seq;
21
+ continueAfter(ending: DeepReadonly<TurnEndReason>, turnStart: Seq): boolean;
22
+ };
23
+ /** Executes journal-driven turns. Admission, readiness and cancellation ownership live outside the loop. */
24
+ export declare class TurnRunner {
25
+ private readonly runtime;
26
+ private readonly threadId;
27
+ private readonly agentName;
28
+ private readonly inbox;
29
+ constructor(options: {
30
+ runtime: LoopRuntime;
31
+ threadId: string;
32
+ agentName: string;
33
+ });
34
+ private stepsTaken;
35
+ /**
36
+ * The caller already owns the lease, has resolved the agent in a ready runtime, has decided the
37
+ * run should advance, and supplies a combined turn signal and the run it serves. Opens a turn,
38
+ * then another for as long as the run's continuation decision says to advance.
39
+ */
40
+ run(options: {
41
+ signal: AbortSignal;
42
+ lease: Lease;
43
+ served: ServedRun;
44
+ }): Promise<void>;
45
+ /**
46
+ * One turn: decide, do it, append what happened, decide again.
47
+ *
48
+ * Every branch of the decision lives in {@link nextAction}; this only carries out what it asked
49
+ * for.
50
+ */
51
+ private turn;
52
+ /**
53
+ * Why a judgment made under `fence` may not stand, or `null` when it does. `activation-changed`:
54
+ * the activation's plugins changed since readiness, and takes precedence. `judgment-invalidated`:
55
+ * the constraint registrations the thread requires, by origin too, are not those it was judged
56
+ * under, one missing or replaced, or a fact a check declared it observed reads differently now.
57
+ * Such a registration's owner, or a plugin of the activation, can be the checker that would
58
+ * object, and core accepts whatever no check objects to; one that came back meanwhile did not
59
+ * judge it; and a verdict resting on a fact that moved while another check awaited is no verdict
60
+ * on the answer as it stands. Read inside the write that records the judgment.
61
+ */
62
+ private fenced;
63
+ /**
64
+ * Records how a judged turn ends, `ending` the checks' verdict or their failure, decided inside
65
+ * the write: one whose fence broke ends the turn `interrupted` instead, the answer still owed its
66
+ * checks, so a later run judges it again, held while a required owner is missing, rather than
67
+ * accepting it unchecked or failing the task because its checker was briefly gone or a fact it
68
+ * read moved. Returns the reason recorded.
69
+ */
70
+ private endJudged;
71
+ /**
72
+ * Records `turn/start` with the thread's route and the run the turn serves, decided in the write's
73
+ * builder, the turn's opening point: a cancel that landed while the loop awaited opens nothing,
74
+ * and a route whose provider is not registered opens nothing either, claims no input, and throws
75
+ * `RouteUnavailableError`, which fails the run before the turn. A provider lost once the row is
76
+ * built, its append still waiting on storage included, fails the opened turn.
77
+ *
78
+ * The route is the turn's for good, since every model step builds its client from it; it cannot
79
+ * change under an execution, which holds the thread while its request is pending.
80
+ */
81
+ private openTurn;
82
+ /** The thread's route as its rows stand. */
83
+ private threadRoute;
84
+ /**
85
+ * Asks the thread's strategy for a plan for a caller between turns (the `request` trigger): no turn
86
+ * opens, no step hook runs and no queued input is claimed; the route is resolved as a turn's would
87
+ * be. The caller owns the lease, as for a run, and composed the signal as a run's is. An
88
+ * interrupted open turn is closed first, as a run closes it; a thread with a tool call unanswered,
89
+ * a confirmation open or an answer unjudged is refused with `ThreadUnsettledError`. Resolves with
90
+ * the outcome, cancellation included.
91
+ */
92
+ compact(options: {
93
+ signal: AbortSignal;
94
+ lease: Lease;
95
+ options: JsonValue | null;
96
+ }): Promise<SurfacePrepareOutcome>;
97
+ /** One request to the thread's strategy, carried out by the engine. */
98
+ private prepare;
99
+ /**
100
+ * Asks the stop checks about the provisional answer. Returns how the turn ends — accepted as
101
+ * `completed`, or `rejected` — or `null` once their continuation messages are recorded.
102
+ *
103
+ * An acceptance ends the turn at once. Steering that arrived while the checks ran is still in the
104
+ * `next-step` inbox, and `run()` opens another turn for it.
105
+ */
106
+ private judge;
107
+ /**
108
+ * Lets the surface be prepared (`pressure`), then records plugin contributions and the claimed
109
+ * input, then asks the model.
110
+ *
111
+ * The dispatch is the first `await` between deciding this step and recording its input, and the
112
+ * lease does not exclude `send()` or `withdraw()`. So once it settles the signal is checked and the
113
+ * inbox read again: only input this step was decided on that is still queued is claimed, so a
114
+ * withdrawn input stays withdrawn, and input that arrived meanwhile waits for the next step. A step
115
+ * left with nothing to claim and no reply owed ends without a model call, and the decider decides
116
+ * again.
117
+ */
118
+ private askModel;
119
+ /** Reports a dispatch a listener ended in failure; one that was cancelled is the turn's to report. */
120
+ private reportFailedDispatch;
121
+ /** Runs a step's tool calls. What they did — answered, waited, ended the turn — lands in the journal. */
122
+ private answerCalls;
123
+ /**
124
+ * One model call. What it produced goes to the journal — `assistant/message`, or
125
+ * `assistant/attempt` when the stream gave nothing usable, which keeps it off the conversation.
126
+ *
127
+ * A request the provider refused as longer than the context window is recorded as an attempt
128
+ * marked `overflow`, and the thread's strategy is asked with `overflow` inside this step, before
129
+ * any `error` row. The rule is one sentence: an overflow fails the turn unless that request
130
+ * committed a replacement, however it ended. When it did, the step ends without an error and the
131
+ * decider asks the model again, from the replaced surface, in a new step.
132
+ */
133
+ private callModel;
134
+ }
@@ -0,0 +1,76 @@
1
+ import type { Context, Scoped } from '@leuduan/cordis';
2
+ import type { ModelCallClient } from '../llm/failure.js';
3
+ import type { ModelRoute, ModelSelection } from '../llm/provider.js';
4
+ import type { ToolSpec } from '../llm/primitives.js';
5
+ import type { DeepReadonly } from '../util/json.js';
6
+ import type { Journal } from '../journal/index.js';
7
+ import type { AgentDefinition } from './agent.js';
8
+ import type { ChunkChannel } from './chunks.js';
9
+ import type { TurnLimits } from '../state/index.js';
10
+ import type { SurfaceStrategy } from './strategy.js';
11
+ import type { Tool } from './tool.js';
12
+ /** Anything advertised to the model — a registered tool or a sub-agent. */
13
+ export type ToolEntry = {
14
+ readonly name: string;
15
+ readonly tool: Tool;
16
+ /**
17
+ * `tool.buildSpec()` with `name` forced to the registered name: the registry's own deep copy,
18
+ * frozen, shared by every request that advertises the tool.
19
+ */
20
+ readonly spec: DeepReadonly<ToolSpec>;
21
+ };
22
+ /**
23
+ * What the loop runs against.
24
+ *
25
+ * The journal says what happened; the registries say what a thread can do right now. Every lookup
26
+ * here is live — resolved when the loop asks, never captured at start — which is the whole of how a
27
+ * registry change reaches a running conversation. There is no turn signal: it is carried by
28
+ * value on each turn, so two concurrent turns cannot see each other's.
29
+ */
30
+ export interface LoopServices {
31
+ readonly journal: Journal;
32
+ /** The model's output as it streams. Ephemeral — see {@link ChunkChannel}. */
33
+ readonly chunks: ChunkChannel;
34
+ readonly limits: TurnLimits;
35
+ /** The registered definition, or a thrown `UnknownAgentError`. */
36
+ agent(name: string): AgentDefinition;
37
+ /** What `agentName` may call, in grant order, as the registries stand right now. */
38
+ toolsFor(agentName: string): ToolEntry[];
39
+ /** One tool `agentName` may call, or `undefined` when it is unknown or not granted. */
40
+ tool(agentName: string, toolName: string): ToolEntry | undefined;
41
+ /** Why `route` cannot run now, its provider not registered, or `null`. Registry lookup only. */
42
+ unavailable(route: ModelRoute): string | null;
43
+ /** `selection` folded over `base`; throws `RouteUnavailableError` when its provider is not registered. */
44
+ resolveRoute(selection: ModelSelection, base: ModelRoute): ModelRoute;
45
+ /** A client for a resolved route; throws when its provider is gone or the client cannot be built. */
46
+ client(route: ModelRoute): ModelCallClient;
47
+ /** Whether a constraint registration under `owner` is live now: what a call's wait may name. */
48
+ waitOwner(owner: string): boolean;
49
+ /**
50
+ * The constraint registrations `threadId`'s run needs, its own `requires` and every thread's above
51
+ * it by origin, as a token equal only for the same registrations, all ready; `null` while one is
52
+ * missing. A judgment is fenced on it: a required owner may be a checker of the answer.
53
+ */
54
+ requiredRegistrations(threadId: string): string | null;
55
+ }
56
+ /** Only a live activation can supply an execution runtime. There is no passive/no-op runtime. */
57
+ export interface LoopRuntime extends LoopServices {
58
+ readonly ctx: Context;
59
+ readonly target: Scoped;
60
+ readonly signal: AbortSignal;
61
+ /**
62
+ * Whether the activation's plugins have changed since it was ready: the loop dispatches nothing
63
+ * new once they have, and ends the turn as `interrupted` at its next boundary.
64
+ */
65
+ stale(): boolean;
66
+ /** The strategy that prepares the thread's surface, if one is provided (`registerSurfaceStrategy`). */
67
+ strategy(): SurfaceStrategy | undefined;
68
+ }
69
+ /**
70
+ * A thread's exclusive execution lease, as one holder holds it: a run, or a request to prepare the
71
+ * surface. `held` is read on every use of something the holder handed out, so a callback that
72
+ * escapes its holder does nothing under a later one's lease.
73
+ */
74
+ export interface Lease {
75
+ readonly held: boolean;
76
+ }