@animalabs/agent-framework 0.29.0 → 0.31.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 (236) hide show
  1. package/README.md +71 -8
  2. package/dist/src/admission/admit.d.ts +90 -0
  3. package/dist/src/admission/admit.d.ts.map +1 -0
  4. package/dist/src/admission/admit.js +43 -0
  5. package/dist/src/admission/admit.js.map +1 -0
  6. package/dist/src/agent.d.ts +50 -9
  7. package/dist/src/agent.d.ts.map +1 -1
  8. package/dist/src/agent.js +125 -23
  9. package/dist/src/agent.js.map +1 -1
  10. package/dist/src/api/mcp-server-core.d.ts.map +1 -1
  11. package/dist/src/api/mcp-server-core.js +10 -3
  12. package/dist/src/api/mcp-server-core.js.map +1 -1
  13. package/dist/src/author-presentation.d.ts +50 -0
  14. package/dist/src/author-presentation.d.ts.map +1 -0
  15. package/dist/src/author-presentation.js +58 -0
  16. package/dist/src/author-presentation.js.map +1 -0
  17. package/dist/src/code-execution/isolate/render.d.ts.map +1 -1
  18. package/dist/src/code-execution/isolate/render.js +7 -6
  19. package/dist/src/code-execution/isolate/render.js.map +1 -1
  20. package/dist/src/code-execution/isolate/scripts.d.ts.map +1 -1
  21. package/dist/src/code-execution/isolate/scripts.js +5 -4
  22. package/dist/src/code-execution/isolate/scripts.js.map +1 -1
  23. package/dist/src/dendrite/index.d.ts +6 -0
  24. package/dist/src/dendrite/index.d.ts.map +1 -0
  25. package/dist/src/dendrite/index.js +3 -0
  26. package/dist/src/dendrite/index.js.map +1 -0
  27. package/dist/src/dendrite/presets.d.ts +60 -0
  28. package/dist/src/dendrite/presets.d.ts.map +1 -0
  29. package/dist/src/dendrite/presets.js +117 -0
  30. package/dist/src/dendrite/presets.js.map +1 -0
  31. package/dist/src/dendrite/registry.d.ts +260 -0
  32. package/dist/src/dendrite/registry.d.ts.map +1 -0
  33. package/dist/src/dendrite/registry.js +742 -0
  34. package/dist/src/dendrite/registry.js.map +1 -0
  35. package/dist/src/dendrite/types.d.ts +392 -0
  36. package/dist/src/dendrite/types.d.ts.map +1 -0
  37. package/dist/src/dendrite/types.js +24 -0
  38. package/dist/src/dendrite/types.js.map +1 -0
  39. package/dist/src/framework.d.ts +806 -118
  40. package/dist/src/framework.d.ts.map +1 -1
  41. package/dist/src/framework.js +4180 -1121
  42. package/dist/src/framework.js.map +1 -1
  43. package/dist/src/gate/event-gate.d.ts +36 -21
  44. package/dist/src/gate/event-gate.d.ts.map +1 -1
  45. package/dist/src/gate/event-gate.js +223 -149
  46. package/dist/src/gate/event-gate.js.map +1 -1
  47. package/dist/src/gate/recipe-reconcile.d.ts.map +1 -1
  48. package/dist/src/gate/recipe-reconcile.js +6 -5
  49. package/dist/src/gate/recipe-reconcile.js.map +1 -1
  50. package/dist/src/host-presentation.d.ts +4 -0
  51. package/dist/src/host-presentation.d.ts.map +1 -1
  52. package/dist/src/host-presentation.js +12 -10
  53. package/dist/src/host-presentation.js.map +1 -1
  54. package/dist/src/index.d.ts +6 -2
  55. package/dist/src/index.d.ts.map +1 -1
  56. package/dist/src/index.js +7 -1
  57. package/dist/src/index.js.map +1 -1
  58. package/dist/src/inference-bounds.d.ts +37 -0
  59. package/dist/src/inference-bounds.d.ts.map +1 -0
  60. package/dist/src/inference-bounds.js +84 -0
  61. package/dist/src/inference-bounds.js.map +1 -0
  62. package/dist/src/line-reader.d.ts +7 -1
  63. package/dist/src/line-reader.d.ts.map +1 -1
  64. package/dist/src/line-reader.js +17 -6
  65. package/dist/src/line-reader.js.map +1 -1
  66. package/dist/src/mcpl/channel-registry.d.ts +84 -9
  67. package/dist/src/mcpl/channel-registry.d.ts.map +1 -1
  68. package/dist/src/mcpl/channel-registry.js +136 -58
  69. package/dist/src/mcpl/channel-registry.js.map +1 -1
  70. package/dist/src/mcpl/errors.d.ts +1 -0
  71. package/dist/src/mcpl/errors.d.ts.map +1 -1
  72. package/dist/src/mcpl/errors.js +3 -0
  73. package/dist/src/mcpl/errors.js.map +1 -1
  74. package/dist/src/mcpl/inbound-source.d.ts +2 -2
  75. package/dist/src/mcpl/inbound-source.js +2 -2
  76. package/dist/src/mcpl/inference-router.d.ts +11 -1
  77. package/dist/src/mcpl/inference-router.d.ts.map +1 -1
  78. package/dist/src/mcpl/inference-router.js +65 -9
  79. package/dist/src/mcpl/inference-router.js.map +1 -1
  80. package/dist/src/mcpl/modern-connection.d.ts +10 -7
  81. package/dist/src/mcpl/modern-connection.d.ts.map +1 -1
  82. package/dist/src/mcpl/modern-connection.js +85 -74
  83. package/dist/src/mcpl/modern-connection.js.map +1 -1
  84. package/dist/src/mcpl/protocol-family.d.ts +1 -1
  85. package/dist/src/mcpl/protocol-family.d.ts.map +1 -1
  86. package/dist/src/mcpl/protocol-family.js +45 -3
  87. package/dist/src/mcpl/protocol-family.js.map +1 -1
  88. package/dist/src/mcpl/push-coalescer.d.ts +11 -7
  89. package/dist/src/mcpl/push-coalescer.d.ts.map +1 -1
  90. package/dist/src/mcpl/push-coalescer.js +21 -0
  91. package/dist/src/mcpl/push-coalescer.js.map +1 -1
  92. package/dist/src/mcpl/references.d.ts +1 -2
  93. package/dist/src/mcpl/references.d.ts.map +1 -1
  94. package/dist/src/mcpl/references.js +3 -3
  95. package/dist/src/mcpl/references.js.map +1 -1
  96. package/dist/src/mcpl/server-connection.d.ts +14 -0
  97. package/dist/src/mcpl/server-connection.d.ts.map +1 -1
  98. package/dist/src/mcpl/server-connection.js +26 -22
  99. package/dist/src/mcpl/server-connection.js.map +1 -1
  100. package/dist/src/mcpl/tool-signature.d.ts +1 -0
  101. package/dist/src/mcpl/tool-signature.d.ts.map +1 -1
  102. package/dist/src/mcpl/tool-signature.js +16 -11
  103. package/dist/src/mcpl/tool-signature.js.map +1 -1
  104. package/dist/src/mcpl/toolsets-module.d.ts.map +1 -1
  105. package/dist/src/mcpl/toolsets-module.js +7 -0
  106. package/dist/src/mcpl/toolsets-module.js.map +1 -1
  107. package/dist/src/mcpl/transport.d.ts +44 -21
  108. package/dist/src/mcpl/transport.d.ts.map +1 -1
  109. package/dist/src/mcpl/transport.js +283 -64
  110. package/dist/src/mcpl/transport.js.map +1 -1
  111. package/dist/src/mcpl/types.d.ts +17 -1
  112. package/dist/src/mcpl/types.d.ts.map +1 -1
  113. package/dist/src/mcpl/types.js.map +1 -1
  114. package/dist/src/module-registry.d.ts +32 -4
  115. package/dist/src/module-registry.d.ts.map +1 -1
  116. package/dist/src/module-registry.js +189 -25
  117. package/dist/src/module-registry.js.map +1 -1
  118. package/dist/src/modules/discord/discord-js-client.d.ts.map +1 -1
  119. package/dist/src/modules/discord/discord-js-client.js +24 -16
  120. package/dist/src/modules/discord/discord-js-client.js.map +1 -1
  121. package/dist/src/modules/sender-name.d.ts +5 -4
  122. package/dist/src/modules/sender-name.d.ts.map +1 -1
  123. package/dist/src/modules/sender-name.js +7 -5
  124. package/dist/src/modules/sender-name.js.map +1 -1
  125. package/dist/src/modules/workspace/disk-agreement.d.ts +16 -8
  126. package/dist/src/modules/workspace/disk-agreement.d.ts.map +1 -1
  127. package/dist/src/modules/workspace/disk-agreement.js +33 -12
  128. package/dist/src/modules/workspace/disk-agreement.js.map +1 -1
  129. package/dist/src/modules/workspace/index.d.ts +6 -3
  130. package/dist/src/modules/workspace/index.d.ts.map +1 -1
  131. package/dist/src/modules/workspace/index.js +61 -15
  132. package/dist/src/modules/workspace/index.js.map +1 -1
  133. package/dist/src/modules/workspace/observe.d.ts +9 -1
  134. package/dist/src/modules/workspace/observe.d.ts.map +1 -1
  135. package/dist/src/modules/workspace/observe.js +50 -10
  136. package/dist/src/modules/workspace/observe.js.map +1 -1
  137. package/dist/src/modules/workspace/reconcile.d.ts +11 -1
  138. package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
  139. package/dist/src/modules/workspace/reconcile.js +19 -8
  140. package/dist/src/modules/workspace/reconcile.js.map +1 -1
  141. package/dist/src/modules/workspace/types.d.ts +8 -0
  142. package/dist/src/modules/workspace/types.d.ts.map +1 -1
  143. package/dist/src/modules/workspace/types.js.map +1 -1
  144. package/dist/src/modules/workspace/watcher.d.ts +7 -0
  145. package/dist/src/modules/workspace/watcher.d.ts.map +1 -1
  146. package/dist/src/modules/workspace/watcher.js +7 -5
  147. package/dist/src/modules/workspace/watcher.js.map +1 -1
  148. package/dist/src/notice-tags.d.ts +2 -0
  149. package/dist/src/notice-tags.d.ts.map +1 -1
  150. package/dist/src/notice-tags.js +2 -0
  151. package/dist/src/notice-tags.js.map +1 -1
  152. package/dist/src/recovery/discord-awareness-outbox.d.ts.map +1 -1
  153. package/dist/src/recovery/discord-awareness-outbox.js +1 -9
  154. package/dist/src/recovery/discord-awareness-outbox.js.map +1 -1
  155. package/dist/src/silent-heartbeat.d.ts +4 -2
  156. package/dist/src/silent-heartbeat.d.ts.map +1 -1
  157. package/dist/src/silent-heartbeat.js +7 -4
  158. package/dist/src/silent-heartbeat.js.map +1 -1
  159. package/dist/src/stored-injections.d.ts +4 -0
  160. package/dist/src/stored-injections.d.ts.map +1 -1
  161. package/dist/src/stored-injections.js +6 -0
  162. package/dist/src/stored-injections.js.map +1 -1
  163. package/dist/src/supplied-text.d.ts +2 -0
  164. package/dist/src/supplied-text.d.ts.map +1 -1
  165. package/dist/src/supplied-text.js +16 -7
  166. package/dist/src/supplied-text.js.map +1 -1
  167. package/dist/src/tool-result-guard.js +1 -1
  168. package/dist/src/tool-result-guard.js.map +1 -1
  169. package/dist/src/tune-out/coordinator.d.ts +368 -16
  170. package/dist/src/tune-out/coordinator.d.ts.map +1 -1
  171. package/dist/src/tune-out/coordinator.js +1224 -136
  172. package/dist/src/tune-out/coordinator.js.map +1 -1
  173. package/dist/src/tune-out/tools.d.ts +115 -7
  174. package/dist/src/tune-out/tools.d.ts.map +1 -1
  175. package/dist/src/tune-out/tools.js +55 -18
  176. package/dist/src/tune-out/tools.js.map +1 -1
  177. package/dist/src/types/agent.d.ts +27 -1
  178. package/dist/src/types/agent.d.ts.map +1 -1
  179. package/dist/src/types/framework.d.ts +153 -15
  180. package/dist/src/types/framework.d.ts.map +1 -1
  181. package/dist/src/types/module.d.ts +42 -3
  182. package/dist/src/types/module.d.ts.map +1 -1
  183. package/dist/src/types/trace.d.ts +140 -3
  184. package/dist/src/types/trace.d.ts.map +1 -1
  185. package/package.json +4 -4
  186. package/src/admission/admit.ts +113 -0
  187. package/src/agent.ts +138 -31
  188. package/src/api/mcp-server-core.ts +10 -3
  189. package/src/author-presentation.ts +81 -0
  190. package/src/code-execution/isolate/render.ts +7 -6
  191. package/src/code-execution/isolate/scripts.ts +5 -4
  192. package/src/dendrite/index.ts +32 -0
  193. package/src/dendrite/presets.ts +149 -0
  194. package/src/dendrite/registry.ts +808 -0
  195. package/src/dendrite/types.ts +397 -0
  196. package/src/framework.ts +4344 -1052
  197. package/src/gate/event-gate.ts +251 -150
  198. package/src/gate/recipe-reconcile.ts +7 -5
  199. package/src/host-presentation.ts +14 -10
  200. package/src/index.ts +16 -2
  201. package/src/inference-bounds.ts +111 -0
  202. package/src/line-reader.ts +22 -5
  203. package/src/mcpl/channel-registry.ts +170 -60
  204. package/src/mcpl/errors.ts +4 -0
  205. package/src/mcpl/inbound-source.ts +2 -2
  206. package/src/mcpl/inference-router.ts +67 -10
  207. package/src/mcpl/modern-connection.ts +83 -68
  208. package/src/mcpl/protocol-family.ts +37 -4
  209. package/src/mcpl/push-coalescer.ts +21 -7
  210. package/src/mcpl/references.ts +3 -4
  211. package/src/mcpl/server-connection.ts +30 -21
  212. package/src/mcpl/tool-signature.ts +18 -11
  213. package/src/mcpl/toolsets-module.ts +7 -0
  214. package/src/mcpl/transport.ts +261 -60
  215. package/src/mcpl/types.ts +18 -1
  216. package/src/module-registry.ts +178 -25
  217. package/src/modules/discord/discord-js-client.ts +33 -29
  218. package/src/modules/sender-name.ts +8 -5
  219. package/src/modules/workspace/disk-agreement.ts +39 -15
  220. package/src/modules/workspace/index.ts +65 -14
  221. package/src/modules/workspace/observe.ts +51 -10
  222. package/src/modules/workspace/reconcile.ts +22 -8
  223. package/src/modules/workspace/types.ts +5 -0
  224. package/src/modules/workspace/watcher.ts +8 -6
  225. package/src/notice-tags.ts +2 -0
  226. package/src/recovery/discord-awareness-outbox.ts +1 -11
  227. package/src/silent-heartbeat.ts +7 -4
  228. package/src/stored-injections.ts +7 -0
  229. package/src/supplied-text.ts +17 -6
  230. package/src/tool-result-guard.ts +1 -1
  231. package/src/tune-out/coordinator.ts +1374 -141
  232. package/src/tune-out/tools.ts +166 -13
  233. package/src/types/agent.ts +30 -1
  234. package/src/types/framework.ts +157 -15
  235. package/src/types/module.ts +42 -3
  236. package/src/types/trace.ts +154 -3
@@ -0,0 +1,397 @@
1
+ /**
2
+ * Dendrite — common agent / context / lifecycle machinery.
3
+ *
4
+ * One registry describes every agent the framework runs: residents, fresh
5
+ * workers and derived agents. The four historical creation paths (resident,
6
+ * subconscious, conversation fork, ephemeral subagent) are PRESETS over the
7
+ * types in this file, not separate engines: the framework never branches on
8
+ * what kind of agent something is, only on what its spec declares.
9
+ *
10
+ * Three things are kept apart on purpose:
11
+ *
12
+ * - **Identity / lifetime** — what persists across activations: the name,
13
+ * the context it owns, its configuration, its relationships.
14
+ * - **Activation** — one bounded run, with an owner for the in-flight work.
15
+ * - **Policy epoch** — a focus / tune-out interval. Ending an epoch is not
16
+ * ending an agent and not cancelling a task; epochs stay owned by the
17
+ * policy coordinator and are only *read* through the registry.
18
+ *
19
+ * Trust: one host trust domain. Context isolation here is NOT process or
20
+ * filesystem isolation — agents sharing a shell, tools or a workspace can
21
+ * affect shared external state. Nothing in this file is a permission check.
22
+ */
23
+
24
+ /** A registered agent's name. Unique among live agents. */
25
+ export type AgentName = string;
26
+
27
+ /**
28
+ * Preset label, for discovery and telemetry. {@link AgentRoles},
29
+ * {@link AgentLifetime} and the relationship fields decide the framework's
30
+ * general behaviour. It also compares two values: 'subconscious-fork'
31
+ * decides a reader fork's tool calls, and 'conversation-fork' picks the
32
+ * agents that stop() and the cleanup after a context manager reinitializes
33
+ * dispose. And it counts derivation notices per kind, for collapsing them.
34
+ */
35
+ export type AgentKind =
36
+ | 'resident'
37
+ | 'subconscious'
38
+ | 'conversation-fork'
39
+ | 'task-fork'
40
+ | 'worker'
41
+ | (string & {});
42
+
43
+ /**
44
+ * Positive capabilities. Each replaces a family of hand-written exclusion
45
+ * filters; a new kind of agent declares these instead of editing every
46
+ * selection site.
47
+ */
48
+ export interface AgentRoles {
49
+ /**
50
+ * Owns default delivery: a framework message with no named recipient lands
51
+ * in this agent's context. Exactly one live agent holds it.
52
+ */
53
+ defaultDelivery: boolean;
54
+ /**
55
+ * Woken by untargeted inbound: a module's `requestInference: true`, a
56
+ * channel message or push event that names no agents, and the default
57
+ * reader set of a coalesced occurrence.
58
+ */
59
+ receivesUntargeted: boolean;
60
+ /**
61
+ * Woken by host-wide gate fan-out (debounce batches, sleep expiry). The
62
+ * gate is host-wide today; this stays a separate capability from
63
+ * `receivesUntargeted` until gating is per recipient, because a
64
+ * channel-bound agent is woken by its own channel's debounced traffic
65
+ * without being a broadcast recipient.
66
+ */
67
+ receivesGateWakes: boolean;
68
+ /**
69
+ * Provider admission belongs to it: it holds the per-agent provider gate
70
+ * for its primary calls and owns rate-limit cooldowns and the requests
71
+ * held behind them. Agents without it run under the established provider
72
+ * policy and never leave a gate or cooldown behind when they end.
73
+ */
74
+ ownsProviderScheduling: boolean;
75
+ }
76
+
77
+ /**
78
+ * How long the IDENTITY lives. Every activation of every agent is bounded
79
+ * separately (see {@link ActivationBounds}); a persistent agent is exempt
80
+ * from ending, not from activation bounds.
81
+ */
82
+ export type AgentLifetime =
83
+ /** Declared in configuration and re-created at boot. */
84
+ | { kind: 'persistent' }
85
+ /** Ends after a period with no inbound on its binding. */
86
+ | { kind: 'idle'; idleTtlMs: number }
87
+ /**
88
+ * A bounded job: must end. At least one of `deadlineMs` (wall clock from
89
+ * creation) and `idleTimeoutMs` (no stream activity) is required — a task
90
+ * with neither is a load-time error.
91
+ */
92
+ | { kind: 'task'; deadlineMs?: number; idleTimeoutMs?: number; maxTurns?: number };
93
+
94
+ /** Bounds on one activation. Informational where the framework has no enforcement yet. */
95
+ export interface ActivationBounds {
96
+ maxTurns?: number;
97
+ maxMs?: number;
98
+ maxInputTokens?: number;
99
+ }
100
+
101
+ /**
102
+ * What ends this agent when the agent that spawned it ends.
103
+ *
104
+ * - `'end'` — attention tenancy: the agent exists to serve its parent and
105
+ * ends with it (a reader of held traffic, a subconscious).
106
+ * - `'orphan'` — bounded task work: it may finish after the parent is gone.
107
+ * It is notified, offered for reparenting, and its result is held as
108
+ * attributed mail until someone can receive it.
109
+ */
110
+ export type ParentEndPolicy = 'end' | 'orphan';
111
+
112
+ /** Where the completion of a bounded job goes. */
113
+ export interface ResultRoute {
114
+ /** Recipient agent. */
115
+ to: AgentName;
116
+ /**
117
+ * - `'message'`: an attributed message in the recipient's context, in the
118
+ * child's own name, plus a wake.
119
+ * - `'tool-result'`: returned to the caller that is awaiting the run; the
120
+ * registry records the route but the caller delivers.
121
+ */
122
+ as: 'message' | 'tool-result';
123
+ }
124
+
125
+ /** Read access to another slot, merged into this agent's view. */
126
+ export interface ObserveEdge {
127
+ /** The agent whose slot is read, when the slot belongs to one. */
128
+ agent?: AgentName;
129
+ /** Message-slot namespace; undefined = the shared un-namespaced slot. */
130
+ slot?: string;
131
+ /** Only messages at or after this sequence. */
132
+ fromSequence?: number;
133
+ /** Whether held (policy-diverted) traffic in that slot is visible. */
134
+ includeHeld?: boolean;
135
+ }
136
+
137
+ /**
138
+ * The four relationships, kept distinct even when one preset connects the
139
+ * same pair through all of them. Spawning does not imply being the sole
140
+ * observer; observing does not imply lifecycle authority.
141
+ */
142
+ export interface AgentRelationships {
143
+ /** Spawn: who created whom. Absent for an independent agent. */
144
+ spawnedBy?: AgentName;
145
+ /** Observe/read: whose streams or retained history this agent inspects. */
146
+ observes: ObserveEdge[];
147
+ /** Message: explicit communication paths this agent has used or was given. */
148
+ messagePeers: AgentName[];
149
+ /** Result route: where the completion of its bounded job returns. */
150
+ resultTo?: ResultRoute;
151
+ }
152
+
153
+ /** How a derived agent's context relates to its parent's. */
154
+ export interface ContextInheritance {
155
+ /** The agent whose context is inherited. */
156
+ from: AgentName;
157
+ /**
158
+ * - `'copy'`: the parent's compiled context re-added as the child's own
159
+ * messages (the historical mechanism). The child can fold what it
160
+ * inherited but loses the parent's memory tree.
161
+ * - `'shared'`: the child reads the parent's messages and fold state at
162
+ * the checkpoint through shared storage and writes only its own
163
+ * (requires store support; refused when unavailable).
164
+ */
165
+ mode: 'copy' | 'shared';
166
+ /** The parent checkpoint (sequence on the parent's branch). Filled at creation. */
167
+ atSequence?: number;
168
+ /** The parent branch the checkpoint is on. Filled at creation. */
169
+ branch?: string;
170
+ /**
171
+ * `'shared'` only: the Chronicle branch that holds everything the child
172
+ * writes. It outlives the child and is what inspection or a later resume
173
+ * opens. Filled at creation.
174
+ */
175
+ ownBranch?: string;
176
+ /**
177
+ * `'shared'` only: the context manager's own record of the derivation
178
+ * (plain data). Kept so the child's context can be reopened after it
179
+ * ended or after a restart — to resume it or to inspect it.
180
+ */
181
+ derivation?: unknown;
182
+ /**
183
+ * `'shared'` only: whether the parent's refusal ledger — what it declined
184
+ * to compress, and why — comes along. Default false: a task fork is free
185
+ * of its parent's refusals. A fork that stands in for the parent's
186
+ * attention is created with it, so it is not asked the thing the parent
187
+ * said no to without knowing. Named in the creation event either way.
188
+ *
189
+ * Consultable, never rendered: the ledger steers what the child's
190
+ * strategy will and will not compress; nothing in it is ever placed in a
191
+ * compiled request. Refusal records are the most classifier-sensitive
192
+ * content in the pipeline, so this is a stated property of the
193
+ * declaration, not an accident of the implementation.
194
+ */
195
+ refusals?: boolean;
196
+ /**
197
+ * - `'reuse'` (default): keep the parent's rendering frontier — prefix,
198
+ * cache markers and solver state — for fast startup.
199
+ * - `'fresh'`: deliberately pay for a new solve, e.g. at another budget;
200
+ * presentation changes and the provider cache misses. An operating
201
+ * choice, not a failure.
202
+ */
203
+ solve?: 'reuse' | 'fresh';
204
+ }
205
+
206
+ /**
207
+ * Declarative description of an agent. Inference configuration (model,
208
+ * prompt, strategy, tools) stays in `AgentConfig`; this is everything the
209
+ * registry and lifecycle need on top of it.
210
+ */
211
+ export interface AgentSpec {
212
+ name: AgentName;
213
+ kind: AgentKind;
214
+ /**
215
+ * The model the agent runs on — "whose weights", next to `inherit.from`
216
+ * for "whose context". Together they are what a consent decision about a
217
+ * derived agent is made on. Filled by the framework from the agent's
218
+ * configuration.
219
+ */
220
+ model?: string;
221
+ roles: AgentRoles;
222
+ lifetime: AgentLifetime;
223
+ activation?: ActivationBounds;
224
+ /** Applies when `spawnedBy` is set. Default `'orphan'`. */
225
+ onParentEnd?: ParentEndPolicy;
226
+ spawnedBy?: AgentName;
227
+ observes?: ObserveEdge[];
228
+ resultTo?: ResultRoute;
229
+ inherit?: ContextInheritance;
230
+ /**
231
+ * Stored participants that render as this agent's own (assistant) turns
232
+ * at request assembly. Stored authorship is never rewritten; this is a
233
+ * model-facing role assignment only.
234
+ */
235
+ selfParticipants?: string[];
236
+ /** The participant name its turns are presented under, when not its own name. */
237
+ presentAs?: string;
238
+ /**
239
+ * A channel this agent is bound to (its speech home and inbound scope), on
240
+ * its server: channel ids are unique only within one server's connection,
241
+ * so two servers' channels with one id are two homes (the channel
242
+ * registry's `ChannelRef`).
243
+ */
244
+ homeChannel?: { serverId: string; channelId: string };
245
+ /**
246
+ * Whether the agent reads the residents' shared un-namespaced message
247
+ * slot (as its own slot or through an observe edge).
248
+ */
249
+ readsSharedSlot?: boolean;
250
+ /** Chronicle namespace owning this agent's context. */
251
+ namespace?: string;
252
+ /** Free-form metadata surfaced in discovery. */
253
+ metadata?: Record<string, unknown>;
254
+ }
255
+
256
+ /** Why an agent identity ended. */
257
+ export type AgentEndReason =
258
+ | 'completed'
259
+ | 'stopped'
260
+ | 'deadline'
261
+ | 'idle-ttl'
262
+ | 'parent-ended'
263
+ | 'host-restart'
264
+ | 'not-configured'
265
+ | 'failed'
266
+ | 'host-stop'
267
+ | 'context-emptied'
268
+ | (string & {});
269
+
270
+ /** Provenance stamp for anything one agent hands another. */
271
+ export interface AgentRef {
272
+ agent: AgentName;
273
+ /** Which instantiation of that identity. */
274
+ incarnation: number;
275
+ }
276
+
277
+ /**
278
+ * One bounded run. The owner is the agent whose in-flight work this is.
279
+ * Derived from the framework's live turn state on request — never stored,
280
+ * so it cannot disagree with what is actually running.
281
+ */
282
+ export interface ActivationRecord {
283
+ id: string;
284
+ owner: AgentRef;
285
+ /** When the triggering request was made (ms), when known. */
286
+ requestedAt?: number;
287
+ reason?: string;
288
+ source?: string;
289
+ /** The channel whose traffic started it, if any. */
290
+ channelId?: string;
291
+ }
292
+
293
+ /** The registry's record of one agent. */
294
+ export interface AgentRecord {
295
+ name: AgentName;
296
+ kind: AgentKind;
297
+ model?: string;
298
+ /**
299
+ * Bumped every time this identity is instantiated: a persistent agent
300
+ * restored at boot is a new incarnation of the same identity.
301
+ */
302
+ incarnation: number;
303
+ roles: AgentRoles;
304
+ lifetime: AgentLifetime;
305
+ activation?: ActivationBounds;
306
+ onParentEnd: ParentEndPolicy;
307
+ relationships: AgentRelationships;
308
+ inherit?: ContextInheritance;
309
+ selfParticipants?: string[];
310
+ presentAs?: string;
311
+ /**
312
+ * The spec's home, on its server. A bare channel id is a record written
313
+ * before homes carried their server: such a record is an ended one, since
314
+ * a conversation fork ends at a restart, and the framework reads its id
315
+ * as a wake that names a channel without its server is.
316
+ */
317
+ homeChannel?: { serverId: string; channelId: string } | string;
318
+ readsSharedSlot: boolean;
319
+ namespace?: string;
320
+ metadata?: Record<string, unknown>;
321
+ createdAt: number;
322
+ /** Set when the identity has ended. Ended records stay inspectable. */
323
+ ended?: { at: number; reason: AgentEndReason; by?: string };
324
+ /**
325
+ * Set while the agent's spawner is gone and nobody has adopted it. The
326
+ * spawn edge is kept as history in `formerParent`.
327
+ */
328
+ orphaned?: {
329
+ since: number;
330
+ formerParent: AgentRef;
331
+ reason: AgentEndReason;
332
+ /** Agents offered as a new parent: nearest live ancestor first, then the primary. */
333
+ candidates: AgentName[];
334
+ };
335
+ }
336
+
337
+ /**
338
+ * A result (or other attributed communication) that could not yet be handed
339
+ * to its recipient. Held durably so a completed job is neither lost nor
340
+ * delivered twice across a restart.
341
+ */
342
+ export interface HeldMail {
343
+ /** Stable id; stamped on the delivered message for de-duplication. */
344
+ id: string;
345
+ kind: 'result' | 'message' | 'notice';
346
+ from: AgentRef;
347
+ to: AgentName;
348
+ /** Message content blocks, verbatim. */
349
+ content: unknown[];
350
+ /** Message ids / activation ids this was caused by. */
351
+ causedBy?: string[];
352
+ createdAt: number;
353
+ /** Why it is still held. */
354
+ heldBecause?: 'recipient-gone' | 'undelivered';
355
+ }
356
+
357
+ /**
358
+ * Persisted shape of the registry (Chronicle snapshot state). Ended records
359
+ * are history and live in a separate append-only log.
360
+ */
361
+ export interface RegistrySnapshot {
362
+ version: 1;
363
+ /** Records of agents that have not ended. */
364
+ records: AgentRecord[];
365
+ /** Highest incarnation issued, for names that can still be referred to. */
366
+ incarnations: Record<AgentName, number>;
367
+ mail: HeldMail[];
368
+ }
369
+
370
+ /** Outcome of ending an agent: who was affected. */
371
+ export interface EndOutcome {
372
+ ended: AgentRecord;
373
+ /** Children that ended with it (attention tenancy), deepest first. */
374
+ cascaded: AgentRecord[];
375
+ /** Children now orphaned, with the candidates offered as new parents. */
376
+ orphaned: Array<{ record: AgentRecord; candidates: AgentName[] }>;
377
+ }
378
+
379
+ /**
380
+ * A policy interval in force (a tune-out hold, a focus). Read from the
381
+ * owning coordinator's durable state — the registry never mirrors it.
382
+ * Ending an epoch ends neither an agent nor a task.
383
+ */
384
+ export interface PolicyEpoch {
385
+ id: string;
386
+ kind: 'tune-out' | (string & {});
387
+ /** What the policy applies to: one channel, or every channel but one. */
388
+ scope:
389
+ | { serverId: string; channelId: string }
390
+ | { kind: 'all-except'; except: { serverId: string; channelId: string } };
391
+ /** The agent whose attention the policy governs. */
392
+ owner?: AgentName;
393
+ /** The agent reading what the policy withholds, if any. */
394
+ reader?: AgentName;
395
+ startedAtSequence?: number;
396
+ expiresAtMs?: number;
397
+ }