@spine-event-engine/server 2.0.0-snapshot.21 → 2.0.0-snapshot.23

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 (168) hide show
  1. package/README.md +104 -7
  2. package/REFERENCE.md +199 -19
  3. package/dist/agent/agent-admission.d.ts +80 -0
  4. package/dist/agent/agent-admission.d.ts.map +1 -0
  5. package/dist/agent/agent-admission.js +127 -0
  6. package/dist/agent/agent-admission.js.map +1 -0
  7. package/dist/agent/agent-ai-binding.d.ts +24 -0
  8. package/dist/agent/agent-ai-binding.d.ts.map +1 -0
  9. package/dist/agent/agent-ai-binding.js +48 -0
  10. package/dist/agent/agent-ai-binding.js.map +1 -0
  11. package/dist/agent/agent-ai-runtime.d.ts +76 -0
  12. package/dist/agent/agent-ai-runtime.d.ts.map +1 -0
  13. package/dist/agent/agent-ai-runtime.js +1269 -0
  14. package/dist/agent/agent-ai-runtime.js.map +1 -0
  15. package/dist/agent/agent-execution-capacity.d.ts +43 -0
  16. package/dist/agent/agent-execution-capacity.d.ts.map +1 -0
  17. package/dist/agent/agent-execution-capacity.js +147 -0
  18. package/dist/agent/agent-execution-capacity.js.map +1 -0
  19. package/dist/agent/agent-execution-fault.d.ts +18 -0
  20. package/dist/agent/agent-execution-fault.d.ts.map +1 -0
  21. package/dist/agent/agent-execution-fault.js +31 -0
  22. package/dist/agent/agent-execution-fault.js.map +1 -0
  23. package/dist/agent/agent-execution-session.d.ts +103 -0
  24. package/dist/agent/agent-execution-session.d.ts.map +1 -0
  25. package/dist/agent/agent-execution-session.js +238 -0
  26. package/dist/agent/agent-execution-session.js.map +1 -0
  27. package/dist/agent/agent-history.d.ts +148 -0
  28. package/dist/agent/agent-history.d.ts.map +1 -0
  29. package/dist/agent/agent-history.js +340 -0
  30. package/dist/agent/agent-history.js.map +1 -0
  31. package/dist/agent/agent-interaction-audit.d.ts +58 -0
  32. package/dist/agent/agent-interaction-audit.d.ts.map +1 -0
  33. package/dist/agent/agent-interaction-audit.js +114 -0
  34. package/dist/agent/agent-interaction-audit.js.map +1 -0
  35. package/dist/agent/agent-interaction-events.d.ts +40 -0
  36. package/dist/agent/agent-interaction-events.d.ts.map +1 -0
  37. package/dist/agent/agent-interaction-events.js +129 -0
  38. package/dist/agent/agent-interaction-events.js.map +1 -0
  39. package/dist/agent/agent-mcp-budget.d.ts +125 -0
  40. package/dist/agent/agent-mcp-budget.d.ts.map +1 -0
  41. package/dist/agent/agent-mcp-budget.js +566 -0
  42. package/dist/agent/agent-mcp-budget.js.map +1 -0
  43. package/dist/agent/agent-mcp-host.d.ts +125 -0
  44. package/dist/agent/agent-mcp-host.d.ts.map +1 -0
  45. package/dist/agent/agent-mcp-host.js +15 -0
  46. package/dist/agent/agent-mcp-host.js.map +1 -0
  47. package/dist/agent/agent-mcp-runtime.d.ts +199 -0
  48. package/dist/agent/agent-mcp-runtime.d.ts.map +1 -0
  49. package/dist/agent/agent-mcp-runtime.js +621 -0
  50. package/dist/agent/agent-mcp-runtime.js.map +1 -0
  51. package/dist/agent/agent-model-selection.d.ts +129 -0
  52. package/dist/agent/agent-model-selection.d.ts.map +1 -0
  53. package/dist/agent/agent-model-selection.js +342 -0
  54. package/dist/agent/agent-model-selection.js.map +1 -0
  55. package/dist/agent/agent-read-runtime.d.ts +70 -0
  56. package/dist/agent/agent-read-runtime.d.ts.map +1 -0
  57. package/dist/agent/agent-read-runtime.js +320 -0
  58. package/dist/agent/agent-read-runtime.js.map +1 -0
  59. package/dist/agent/agent-revisions.d.ts +35 -0
  60. package/dist/agent/agent-revisions.d.ts.map +1 -0
  61. package/dist/agent/agent-revisions.js +133 -0
  62. package/dist/agent/agent-revisions.js.map +1 -0
  63. package/dist/agent/agent-scheduler.d.ts +99 -0
  64. package/dist/agent/agent-scheduler.d.ts.map +1 -0
  65. package/dist/agent/agent-scheduler.js +398 -0
  66. package/dist/agent/agent-scheduler.js.map +1 -0
  67. package/dist/bus/command-bus.d.ts +62 -0
  68. package/dist/bus/command-bus.d.ts.map +1 -1
  69. package/dist/bus/command-bus.js +51 -2
  70. package/dist/bus/command-bus.js.map +1 -1
  71. package/dist/bus/event-bus.d.ts +137 -3
  72. package/dist/bus/event-bus.d.ts.map +1 -1
  73. package/dist/bus/event-bus.js +133 -2
  74. package/dist/bus/event-bus.js.map +1 -1
  75. package/dist/bus/saved-dispatcher-binding.d.ts +96 -0
  76. package/dist/bus/saved-dispatcher-binding.d.ts.map +1 -0
  77. package/dist/bus/saved-dispatcher-binding.js +35 -0
  78. package/dist/bus/saved-dispatcher-binding.js.map +1 -0
  79. package/dist/context/bounded-context.d.ts +36 -2
  80. package/dist/context/bounded-context.d.ts.map +1 -1
  81. package/dist/context/bounded-context.js +253 -54
  82. package/dist/context/bounded-context.js.map +1 -1
  83. package/dist/context/entity-inbox.d.ts.map +1 -1
  84. package/dist/context/entity-inbox.js +5 -5
  85. package/dist/context/entity-inbox.js.map +1 -1
  86. package/dist/context/projection-handoff.d.ts.map +1 -1
  87. package/dist/context/projection-handoff.js +2 -1
  88. package/dist/context/projection-handoff.js.map +1 -1
  89. package/dist/context/tenant-index.d.ts +25 -0
  90. package/dist/context/tenant-index.d.ts.map +1 -1
  91. package/dist/context/tenant-index.js +45 -1
  92. package/dist/context/tenant-index.js.map +1 -1
  93. package/dist/delivery/delivery.d.ts.map +1 -1
  94. package/dist/delivery/delivery.js +4 -3
  95. package/dist/delivery/delivery.js.map +1 -1
  96. package/dist/delivery/inbox-records.d.ts +13 -0
  97. package/dist/delivery/inbox-records.d.ts.map +1 -1
  98. package/dist/delivery/inbox-records.js +204 -30
  99. package/dist/delivery/inbox-records.js.map +1 -1
  100. package/dist/delivery/inbox-storage.d.ts.map +1 -1
  101. package/dist/delivery/inbox-storage.js +26 -5
  102. package/dist/delivery/inbox-storage.js.map +1 -1
  103. package/dist/delivery/inbox.d.ts +7 -7
  104. package/dist/delivery/inbox.d.ts.map +1 -1
  105. package/dist/delivery/inbox.js +1 -2
  106. package/dist/delivery/inbox.js.map +1 -1
  107. package/dist/delivery/sharded-work-registry.d.ts +1 -0
  108. package/dist/delivery/sharded-work-registry.d.ts.map +1 -1
  109. package/dist/delivery/sharded-work-registry.js +3 -1
  110. package/dist/delivery/sharded-work-registry.js.map +1 -1
  111. package/dist/entity/entity-transaction.d.ts.map +1 -1
  112. package/dist/entity/entity-transaction.js +2 -6
  113. package/dist/entity/entity-transaction.js.map +1 -1
  114. package/dist/entity/entity.d.ts +82 -3
  115. package/dist/entity/entity.d.ts.map +1 -1
  116. package/dist/entity/entity.js +121 -22
  117. package/dist/entity/entity.js.map +1 -1
  118. package/dist/handler/generated-handler-registry.js +8 -3
  119. package/dist/handler/generated-handler-registry.js.map +1 -1
  120. package/dist/handler/handler-metadata.d.ts +17 -1
  121. package/dist/handler/handler-metadata.d.ts.map +1 -1
  122. package/dist/handler/handler-metadata.js +10 -4
  123. package/dist/handler/handler-metadata.js.map +1 -1
  124. package/dist/index.d.ts +3 -3
  125. package/dist/index.d.ts.map +1 -1
  126. package/dist/index.js +2 -2
  127. package/dist/index.js.map +1 -1
  128. package/dist/integration/third-party-context.d.ts +5 -0
  129. package/dist/integration/third-party-context.d.ts.map +1 -1
  130. package/dist/integration/third-party-context.js +7 -6
  131. package/dist/integration/third-party-context.js.map +1 -1
  132. package/dist/repository/commit-fence.d.ts +11 -0
  133. package/dist/repository/commit-fence.d.ts.map +1 -1
  134. package/dist/repository/commit-fence.js +13 -0
  135. package/dist/repository/commit-fence.js.map +1 -1
  136. package/dist/repository/repository.d.ts +222 -13
  137. package/dist/repository/repository.d.ts.map +1 -1
  138. package/dist/repository/repository.js +2329 -137
  139. package/dist/repository/repository.js.map +1 -1
  140. package/dist/runtime/signal-metadata.d.ts +7 -47
  141. package/dist/runtime/signal-metadata.d.ts.map +1 -1
  142. package/dist/runtime/signal-metadata.js +8 -62
  143. package/dist/runtime/signal-metadata.js.map +1 -1
  144. package/dist/runtime/signal-publisher.d.ts +6 -0
  145. package/dist/runtime/signal-publisher.d.ts.map +1 -1
  146. package/dist/runtime/signal-publisher.js +13 -0
  147. package/dist/runtime/signal-publisher.js.map +1 -1
  148. package/dist/runtime/standalone-handler-runtime.d.ts +7 -0
  149. package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
  150. package/dist/runtime/standalone-handler-runtime.js +148 -11
  151. package/dist/runtime/standalone-handler-runtime.js.map +1 -1
  152. package/dist/server/managed-server-application.d.ts +36 -6
  153. package/dist/server/managed-server-application.d.ts.map +1 -1
  154. package/dist/server/managed-server-application.js +257 -4
  155. package/dist/server/managed-server-application.js.map +1 -1
  156. package/dist/server/server.d.ts +9 -0
  157. package/dist/server/server.d.ts.map +1 -1
  158. package/dist/server/server.js +13 -1
  159. package/dist/server/server.js.map +1 -1
  160. package/dist/stand/subscription-registry.d.ts.map +1 -1
  161. package/dist/stand/subscription-registry.js +9 -8
  162. package/dist/stand/subscription-registry.js.map +1 -1
  163. package/dist/testing/index.d.ts +57 -1
  164. package/dist/testing/index.d.ts.map +1 -1
  165. package/dist/testing/index.js +87 -0
  166. package/dist/testing/index.js.map +1 -1
  167. package/dist/tsconfig.tsbuildinfo +1 -1
  168. package/package.json +14 -12
package/README.md CHANGED
@@ -82,10 +82,12 @@ for the exact contract.
82
82
 
83
83
  An `@Assign`, `@Command`, `@React`, or `@Subscribe` handler may return its
84
84
  usual result directly or through exactly one built-in `Promise<T>` layer. Its
85
- transaction remains open until that promise settles. Nested `Promise<Promise<T>>`
85
+ in-memory Entity draft remains active until that promise settles. Nested `Promise<Promise<T>>`
86
86
  results and structural or imported thenable lookalikes are rejected during handler
87
- analysis. Rejection rolls back framework state and suppresses produced output; it
88
- cannot roll back an external HTTP request or other side effect.
87
+ analysis. Storage writes happen in separate short operations after the handler succeeds.
88
+ A failed handler leaves previous persisted state unchanged and
89
+ suppresses produced output. An external HTTP request or other side effect may
90
+ already have happened.
89
91
 
90
92
  Handler return declarations can use native unions for one of several results,
91
93
  or fixed tuples for several ordered results. For example,
@@ -129,7 +131,11 @@ class TaskAssignee {
129
131
  Place the primary handler decorator first for readability. Reversing the two
130
132
  decorators has the same behavior.
131
133
 
132
- Process Managers, but not Aggregates, have protected read-only `select()` during a handler:
134
+ Process Managers have protected read-only `select()` during a handler. Agents use
135
+ the generated `select(query).read()` form with the same actor, tenant, and
136
+ 1,000-state limits. Aggregates do not expose handler-scoped queries.
137
+
138
+ For Process Manager's schema-and-columns query form:
133
139
 
134
140
  ```ts
135
141
  import { EntityQuery, type EntityColumn } from "@spine-event-engine/core";
@@ -167,11 +173,11 @@ These reads are eventually consistent. `limit()` may not exceed 1,000, and
167
173
  `all()` can be expensive for a large read model; prefer a targeted, ordered,
168
174
  bounded query.
169
175
 
170
- The Entity type identifies its context among those registered with the same
176
+ The Entity type identifies its Bounded Context among those registered with the same
171
177
  `Server`. For example, an order process can query a product in a catalogue
172
- context without naming that context. An Entity in another context must allow
178
+ Bounded Context without naming that Bounded Context. An Entity in another Bounded Context must allow
173
179
  queries (`query` or `full` visibility). Registering the same Entity type in two
174
- contexts causes a startup error.
180
+ Bounded Contexts causes a startup error.
175
181
 
176
182
  The [Orders example](https://github.com/SpineEventEngine/spine-ts/blob/master/examples/orders/README.md#cross-context-order-review)
177
183
  shows this in an Event handler and includes a runnable integration test.
@@ -185,6 +191,97 @@ for the complete tenant rules and empty-result behavior.
185
191
  Use `EntityQuery.all(...)` when every predicate must match and
186
192
  `EntityQuery.either(...)` when any branch may match.
187
193
 
194
+ ## Draft with an Agent
195
+
196
+ An Agent is a stateful Entity that can ask a model for help while handling a
197
+ Command or Event. For example, a support Agent drafts a reply from ticket facts
198
+ and emits an Event for a person to review. It keeps provider credentials out of
199
+ the handler and records the model interaction. Like other Entities, its ID and
200
+ state are declared in Proto and its handlers use generated registration.
201
+
202
+ An Agent can read its recorded interactions and emitted domain Events through
203
+ its repository. See the [Agent execution reference](REFERENCE.md#agent-execution)
204
+ for history methods, paging, and recovery behavior.
205
+
206
+ Declare the Agent ID and state in Proto, with `option (entity).kind = ENTITY;`
207
+ on the state. The [Support example](https://github.com/SpineEventEngine/spine-ts/blob/master/examples/support/README.md) includes
208
+ complete [domain Protos](https://github.com/SpineEventEngine/spine-ts/blob/master/examples/support/proto/spine/examples/support/states.proto),
209
+ [a model definition](https://github.com/SpineEventEngine/spine-ts/blob/master/examples/support/src/model.ts), and
210
+ [an Agent implementation](https://github.com/SpineEventEngine/spine-ts/blob/master/examples/support/src/index.ts).
211
+
212
+ The handler invokes a typed model operation, updates its draft only on success,
213
+ and emits a domain outcome. This abbreviated declaration uses the example's
214
+ actual generated messages:
215
+
216
+ <!-- prettier-ignore-start -->
217
+
218
+ <!-- docs-snippet-path: examples/support/src/index.ts -->
219
+
220
+ ```ts
221
+ import { create } from "@bufbuild/protobuf";
222
+ import { Agent, Assign } from "@spine-event-engine/server";
223
+ import type { DraftSupportReply } from "../generated/spine/examples/support/commands_pb.js";
224
+ import {
225
+ SupportReplySuggestedSchema,
226
+ SupportReplyFailedSchema,
227
+ type SupportReplySuggested,
228
+ type SupportReplyFailed,
229
+ } from "../generated/spine/examples/support/events_pb.js";
230
+ import { SupportDraftStateSchema } from "../generated/spine/examples/support/states_pb.js";
231
+ import type { SupportTicketId } from "../generated/spine/examples/support/types_pb.js";
232
+ import { draftSupportReply } from "./model.js";
233
+
234
+ /** Proposes support replies for a person's review. */
235
+ class SupportDraftAgent extends Agent<SupportTicketId, typeof SupportDraftStateSchema> {
236
+ /**
237
+ * Drafts a reply from the submitted ticket facts.
238
+ *
239
+ * @param command Ticket facts and an explicit conversation.
240
+ * @returns The proposed reply or a recorded failure outcome.
241
+ */
242
+ @Assign
243
+ async draft(command: DraftSupportReply): Promise<SupportReplySuggested | SupportReplyFailed> {
244
+ if (command.conversation === undefined || command.request === undefined)
245
+ throw new TypeError("A draft requires ticket facts and a conversation.");
246
+ const result = await this.ai.invoke(draftSupportReply, {
247
+ call: "draft-support-reply",
248
+ conversation: command.conversation,
249
+ input: command,
250
+ });
251
+ const outcome = {
252
+ id: this.id,
253
+ request: command.request,
254
+ conversation: command.conversation,
255
+ operation: result.operationId,
256
+ };
257
+ if (!result.ok) return create(SupportReplyFailedSchema, outcome);
258
+ this.update((state) =>
259
+ Object.assign(state, {
260
+ id: this.id,
261
+ request: command.request,
262
+ conversation: command.conversation,
263
+ reply: result.value,
264
+ }),
265
+ );
266
+ return create(SupportReplySuggestedSchema, { ...outcome, reply: result.value });
267
+ }
268
+ }
269
+ ```
270
+
271
+ <!-- prettier-ignore-end -->
272
+
273
+ Configure the registry outside the Entity. The Bounded Context requires persisted System
274
+ Events, and the Agent registration supplies its code revision and permitted
275
+ capabilities. The [example Bounded Context factory](https://github.com/SpineEventEngine/spine-ts/blob/master/examples/support/src/index.ts)
276
+ assembles these settings with the generated handler registry. A server-wide
277
+ `withAi()` default can be supplied when building Bounded Contexts through `Server`;
278
+ Bounded Context configuration can provide its registry directly.
279
+
280
+ Posting a Command awaits acceptance. Model work and the resulting domain Event
281
+ arrive asynchronously afterward. The handling operation can await a model without
282
+ keeping a database transaction open. See the [Agent execution reference](REFERENCE.md#agent-execution)
283
+ for defaults, recovery and retained history.
284
+
188
285
  ## Native lifecycle and routing
189
286
 
190
287
  `Server.run()` is the standalone process form: it handles `SIGINT`/`SIGTERM`
package/REFERENCE.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # @spine-event-engine/server reference
2
2
 
3
- This reference gives application developers and coding agents the detailed
4
- server contracts. For an introduction and examples, start with the
3
+ This reference gives coding agents the detailed server contracts. For an introduction and examples, start with the
5
4
  [server README](README.md).
6
5
 
7
6
  ## Testing entry point
@@ -238,11 +237,13 @@ route registration API.
238
237
 
239
238
  Handlers may return their established result directly or through exactly one built-in `Promise<T>`.
240
239
  Nested promises and structural or imported thenable lookalikes are rejected during handler analysis.
241
- The entity transaction remains open until that promise settles; rejection rolls
242
- back framework state and suppresses produced output, but cannot undo external
243
- side effects. Process Managers may use their protected read-only query surface
244
- for eventually consistent Entity state during a handler. Aggregates must not
245
- use these reads for invariants.
240
+ The in-memory Entity draft remains active until that promise settles. Storage
241
+ writes use separate short operations after the handler succeeds; a rejected
242
+ handler leaves no partial persisted state or produced signals, but cannot undo
243
+ external side effects. Process Managers may use their protected read-only query
244
+ surface for eventually consistent Entity state during a handler. Agents expose
245
+ the generated `select(query).read()` form under the same handler scope and
246
+ limits. Aggregates must not use these reads for invariants.
246
247
 
247
248
  `select(schema, columns)` supports `byId`, typed `where`, `orderBy`,
248
249
  `limit`, `read`, `findById`, and `all`. A Process Manager query returns at most
@@ -329,10 +330,11 @@ A command-input `@Command` method is a command substitution receptor: it is
329
330
  the one effective receptor for that Command type (instead of an `@Assign`),
330
331
  commits its Entity state before its one-or-more returned Commands are detached
331
332
  for in-process produced-command enqueue, and receives an optional `CommandContext`.
332
- Only Process Manager repositories support `@Command` handlers. Aggregate and
333
- Projection repositories reject command-input substitutions and event- or
333
+ Process Manager and Agent repositories support `@Command` handlers. Aggregate
334
+ and Projection repositories reject command-input substitutions and event- or
334
335
  rejection-input command reactions during generated metadata ingestion and
335
- repository construction.
336
+ repository construction. Agents reject `@Subscribe`, including Entity-state
337
+ Apply handlers, at generation and runtime registration.
336
338
  Event- and rejection-input `@Command` methods remain Event- or
337
339
  rejection-to-command reactions on Event Bus.
338
340
 
@@ -542,6 +544,11 @@ handler registry for classes registered with `add(EntityClass)`;
542
544
  `buildAsync()` performs that discovery and assembly. `build()` remains for
543
545
  explicit `Repository` registration. A built context contains `CommandBus`,
544
546
  `EventBus`, `Stand`, repositories, and its storage lifecycle.
547
+ Trusted server-side code can call `context.getRepository(EntityClass)` to obtain
548
+ the already registered repository for that exact constructor. The lookup does
549
+ not create a repository or read Entity state; an absent class or closing
550
+ Bounded Context fails explicitly. Application code must authorize users before
551
+ exposing repository reads through a client bridge.
545
552
 
546
553
  Generated writer output is an unversioned receiver collection and records
547
554
  command substitutions explicitly. The ingestor rejects retired versioned
@@ -615,8 +622,10 @@ configuration and Datastore custom record storage registered for
615
622
  `SubscriptionRecord` are used by the registry. The registry uses one
616
623
  record-storage handle, while the context closes the registry.
617
624
 
618
- `Entity` is the state base class. `Aggregate`, `Projection`, and
619
- `ProcessManager` identify the three entity families. Handler decorators are
625
+ `Entity` is the state base class. `Aggregate`, `Projection`,
626
+ `ProcessManager`, and `Agent` identify the four entity families. Agent state
627
+ declares canonical Proto kind `ENTITY` and uses the same Spine `Version`.
628
+ Handler decorators are
620
629
  `@Assign`, `@Command`, `@React`, and `@Subscribe`. A command-accepting
621
630
  handler uses `@Throws(GeneratedRejection)` to declare its possible domain
622
631
  rejections. Write the primary handler decorator first and `@Throws` immediately
@@ -633,6 +642,172 @@ zero. A dispatch that produces Events or changes state or lifecycle advances it
633
642
  once; no-op and rejected dispatches do not. Repositories restore and persist the
634
643
  full Version, including its timestamp, across current state, history, and Stand.
635
644
 
645
+ ## Agent execution
646
+
647
+ Agents extend `Agent<Id, typeof StateSchema>`. The state declares Proto kind
648
+ `ENTITY`; IDs, state, Version, validation and routing use the normal Entity
649
+ contracts. Agents accept `@Assign`, `@React` and `@Command`, including declared
650
+ rejections as inputs. They reject `@Subscribe` and Entity-state Apply handlers.
651
+ The Agent runs only after an accepted signal. A model response or timer cannot
652
+ start a new autonomous Entity loop.
653
+
654
+ ### Configuration
655
+
656
+ Register a factory-created `AiRegistry`, enable `persistSystemEvents()`, and
657
+ configure `agentCodeRevision` plus `ai.models` for each Agent repository. Use
658
+ an empty `models` array when that Agent has no model calls. Readiness requires
659
+ indexed Agent history and execution storage from the selected provider.
660
+ The [Support Bounded Context](../../examples/support/src/index.ts) uses generated
661
+ registration with these options.
662
+
663
+ Configuration has these scopes:
664
+
665
+ | Scope | Setting | Effect |
666
+ | --------------- | ---------------------------------------- | ------------------------------------------------------------------------ |
667
+ | Server | `Server.withAi(registry)` | Default registry for Bounded Context builders assembled by that server. |
668
+ | Bounded Context | `BoundedContextBuilder.withAi(registry)` | Explicit registry replacing the server default for that Bounded Context. |
669
+ | Repository | `ai.defaultModels` | Generation and decision defaults before the registry's defaults. |
670
+ | Repository | `ai.allowedModels` | Deployment references the Agent may use. |
671
+ | Repository | `ai.resolveModel` | Optional accepted-source choice before the Agent handler. |
672
+ | Repository | `ai.authorizeSelection` | Authorizes explicit choices and staged preference changes. |
673
+ | Repository | `ai.invocationLimits` | Limits that can narrow the registry's whole-signal limits. |
674
+ | Instance | `this.ai.select(kind, ref)` | A saved preference applied to later accepted signals. |
675
+
676
+ A prebuilt Bounded Context already has its registry; adding it to a server does not
677
+ reconfigure it. An instance preference takes precedence over its repository
678
+ default, which takes precedence over the effective registry default. Passing
679
+ `undefined` to `select` restores inheritance. Selection must satisfy the
680
+ repository policy and `authorizeSelection` callback; it cannot extend the
681
+ repository's allowed deployments. The current signal keeps its original selection.
682
+
683
+ `resolveModel(kind, scope, sourceMessage, control)` can choose a registered
684
+ deployment from a detached copy of the original accepted Command or Event
685
+ payload. A concrete result overrides preference and default precedence for that
686
+ signal; `undefined` preserves it. This allows an Agent without a configured
687
+ default to start after a deployment is appended to the bound registry. The
688
+ runtime checks repository allowlists, capabilities and `authorizeSelection`
689
+ before saving the selection and connection identity. A saved selection is reused
690
+ on continuation. Resolver and authorization callbacks receive linked cancellation
691
+ and the smaller of the invocation deadline and registry hook timeout. An
692
+ effective `this.ai.select()` change, including reset to inheritance, is
693
+ authorized before the Entity transition and preference Events commit; a no-op
694
+ change skips that callback.
695
+
696
+ Model registrations resolve a credential-free connection identity and authorize
697
+ use for the original actor, tenant, Agent and source signal. Connection callbacks
698
+ can obtain an API key, refreshed token, cloud credential or local model handle
699
+ through application code. The optional adapter supplies a guarded fetch function
700
+ for provider construction. Spine does not implement a provider's login flow.
701
+ See [adapter configuration](../ai-vercel-ax/README.md).
702
+
703
+ ### Acceptance and completion
704
+
705
+ Before acknowledging Agent intake, the runtime saves the original signal,
706
+ recipient, selected handlers and code/schema/policy revisions. The scheduler
707
+ processes one accepted signal at a time per Agent instance, under a provider
708
+ claim. Different instances can run concurrently within configured limits.
709
+ Bounded Contexts using the same registry object share its capacity within the process.
710
+ Signals beyond the bounded in-memory waiting queue remain durably pending.
711
+ Waiting before a fresh execution starts precedes its deadline. Once execution
712
+ starts, recovery continues with the saved deadline and counts. The same deadline
713
+ bounds an awaited application handler. Expiry or Bounded Context shutdown ends that wait
714
+ and prevents late handler results from changing Entity state or emitting signals;
715
+ it cannot stop arbitrary application JavaScript or undo external effects.
716
+
717
+ Newly accepted work supplies its repository and tenant to prompt discovery.
718
+ Periodic discovery reads tenant pages and constructs repository scopes as they
719
+ are needed. It retains at most one page of 16 tenants, four periodic scan scopes,
720
+ and 64 scopes awaiting a prompt scan. A turn requests at most one tenant page
721
+ and reads at most four pending-work pages. It does not load the complete tenant
722
+ catalog or retain a scan position for every tenant.
723
+
724
+ A sweep finishes before another begins. The next starts no earlier than five
725
+ seconds after the preceding sweep started, measured by `Time`; longer sweeps
726
+ restart after completion. This lets discovery reach tenants near the end of a
727
+ large catalog and find later admissions on the next sweep. Periodic scans keep
728
+ their turn during new arrivals, including while execution capacity is full.
729
+ A pending catalog request does not block prompt scans of known scopes.
730
+
731
+ Bounded Context shutdown stops waiting for discovery reads even if a provider ignores
732
+ cancellation. Late results cannot submit work or restart scanning. Built-in
733
+ adapters use their available cancellation and timeout controls; detaching the
734
+ scheduler does not guarantee cancellation of an already issued native request.
735
+
736
+ The signal's matching handlers share one Entity draft. Each handler can await
737
+ `this.ai.invoke()` through the protected Spine facade. Calls in one handler must
738
+ be sequential and finish before it returns. Requests, results and
739
+ validation failures are saved as the operation progresses. The final accepted
740
+ state, Version, history and original outgoing envelopes are committed under the
741
+ same execution claim. A no-op still completes its execution record. Waiting for
742
+ a provider does not hold a database transaction open.
743
+
744
+ Recovery compares the registered handler, schema and policy with accepted work.
745
+ A saved named call can reuse its result; changing that call's input or prepared
746
+ request is a mismatch, not a new attempt. Domain code should derive its decisions
747
+ from accepted signals and recorded reads. Arbitrary external effects performed
748
+ by handler code are outside the model/tool journal.
749
+
750
+ After completion, delivery uses the saved outgoing envelopes and recipient
751
+ bindings. The producing handler and model are not rerun to deliver them.
752
+ Downstream delivery is at least once: a recipient or standalone callback may be
753
+ called again with the same envelope. Application effects must account for that.
754
+ Generated repository and standalone receivers have the required binding metadata.
755
+ Matching raw custom dispatchers without that metadata are rejected for Agent
756
+ output; unrelated dispatchers and ordinary non-Agent posting keep their usual
757
+ behavior.
758
+
759
+ ### Retained history
760
+
761
+ Every Agent records conversations, System Events and its emitted domain Events.
762
+ The paired System Context EventStore also keeps System Events. Agent history
763
+ reads use dedicated repository indexes for that instance and tenant, rather than
764
+ scanning the Bounded Context-wide stores. Memory storage lasts for the process; choose a
765
+ persistent provider when records must survive process termination.
766
+
767
+ | Protected method | Returned `HistoryPage.items` |
768
+ | ------------------------------ | ------------------------------------------------------------------------------ |
769
+ | `fullHistory(request)` | `AgentHistoryEntry` oneof: conversation record, System Event, or domain Event. |
770
+ | `conversationHistory(request)` | `ConversationRecord` for the required `conversation` ID. |
771
+ | `systemEventHistory(request)` | Original System Event envelopes. |
772
+ | `domainEventHistory(request)` | Original domain Event envelopes emitted by this Agent. |
773
+
774
+ All methods return newest entries first. A request supplies positive `pageSize`
775
+ and an optional opaque cursor; `nextCursor` continues toward older entries.
776
+ There is no fixed 100-item or page-byte ceiling. Reads made during a handler count
777
+ toward any configured invocation limits for recorded reads and recovery data. Ordering
778
+ uses the full Spine `Time` timestamp, category and existing record ID. There is
779
+ no repository-managed history counter. Cursors cannot be transferred across
780
+ Agents, tenants, categories or conversations.
781
+
782
+ Recording has no off switch, expiry policy or Agent-specific purge operation.
783
+ Archive and logical deletion retain the history. General physical Entity deletion
784
+ is a separate feature; this API does not introduce it. Authentication callbacks do not become conversation records. Hidden model
785
+ reasoning is not part of the audit API. The records describe the supplied
786
+ requests, received supported content, tool calls and admitted outcomes.
787
+
788
+ Use `BlackBox.readAgentHistory(AgentClass, id, request)` to inspect full
789
+ history in an application test. `BlackBox.readSystemEvents(ids)` reads the paired
790
+ System store by exact Event IDs. See the [testing reference](../testing/REFERENCE.md)
791
+ and [complete support tests](../../examples/support/test/support-blackbox.test.ts).
792
+
793
+ For a trusted application bridge, `context.getRepository(AgentClass)` returns
794
+ the registered Agent `Repository`, which exposes
795
+ `agentHistory(id, scope)` with the same four history methods and page contracts.
796
+ The scope is explicit: pass `{}` in a single-tenant Bounded Context or
797
+ `{ tenantId }` in a multitenant Bounded Context. The repository also exposes
798
+ `agentExecution(id, sourceCommandOrEventId, scope)` for the exact recorded phase:
799
+ `accepted`, `active`, `completed-pending-delivery`, `completed`, or `terminated`.
800
+ An absent record returns `undefined`; it does not establish completion. These
801
+ reads use indexed storage without restoring an Agent. The application bridge
802
+ must authorize access before calling either method; actor metadata does not
803
+ grant read permission.
804
+
805
+ If a selected model's `authorizeUse` callback explicitly returns `false` at
806
+ Agent claim time, the execution becomes `terminated` with one
807
+ `AgentInvocationTerminated` System Event carrying `MODEL_USE_DENIED`. No Agent
808
+ handler runs and no application-domain result Event is emitted. Callback
809
+ exceptions and infrastructure failures remain distinct from this denial.
810
+
636
811
  ## Signals, validation, and rejection behavior
637
812
 
638
813
  `CommandBus` validates every accepted command from Proto validation options
@@ -646,18 +821,18 @@ UUIDs; fixed IDs belong only to existing source envelopes retained through the
646
821
  normal origin chain.
647
822
 
648
823
  An application handler throws a generated core `RejectionThrowable` for a
649
- domain rejection declared with `@Throws`. The repository rolls back state,
650
- version, lifecycle, and output; it schedules the typed rejection event independently. Command service
824
+ domain rejection declared with `@Throws`. The repository discards the unaccepted
825
+ draft and output, retaining the previous state, Version and lifecycle; it schedules the typed rejection event independently. Command service
651
826
  acknowledgement remains an accepted `Ack`. Rejection-event posting can be
652
827
  unobserved by inactive, full, or closed subscriptions and a posting failure is
653
828
  an internal diagnostic, not a retry guarantee.
654
829
 
655
830
  Every domain context has an internal paired System Context. Domain events use
656
831
  the domain `EventBus` and domain `EventStore`. System events use only the
657
- System Context `EventBus`, so they never enter the domain EventStore. System
658
- event persistence is optional: `persistSystemEvents()` enables the paired
659
- System Context's separate storage; otherwise the bus validates, dispatches,
660
- and notifies without appending. Schemas may come from an external dispatcher or
832
+ System Context `EventBus`, so they never enter the domain EventStore.
833
+ `persistSystemEvents()` enables the paired System Context's separate storage.
834
+ Bounded Contexts with Agents must enable it. For other Bounded Contexts it is optional; without
835
+ it, the bus validates, dispatches and notifies without appending. Schemas may come from an external dispatcher or
661
836
  a registered internal repository producer. A producer-only schema is not
662
837
  thereby an external dispatch route.
663
838
 
@@ -822,6 +997,11 @@ updates, and process-manager reactions. Callbacks are at-least-once/replay-safe:
822
997
  lost renewal can prevent stale finalization but cannot undo a callback already
823
998
  run. The package exposes no general raw worker callback API.
824
999
 
1000
+ Inbox reads return `InboxMessage` with a full-precision Protobuf `Timestamp` in
1001
+ `whenReceived`. `InboxMessageInput` requires a precise `Timestamp` for new
1002
+ receipts. Writes, acknowledgements, and exact removals use an `InboxMessage`
1003
+ with the same Timestamp contract.
1004
+
825
1005
  Shard ownership is the only delivery exclusion mechanism and excludes
826
1006
  concurrent delivery within that shard. Pending and delivered `InboxMessage`
827
1007
  rows are direct records; a delivered row is the deduplication fact. A handler
@@ -858,7 +1038,7 @@ const context = BoundedContext.singleTenant("Tasks")
858
1038
  .build();
859
1039
  ```
860
1040
 
861
- Aggregate commands and Process Manager commands/events derive their target shard
1041
+ Aggregate commands and Process Manager or Agent commands/events derive their target shard
862
1042
  internally and persist their envelope in the target Entity Inbox before any
863
1043
  handler runs. Local intake can directly drain the persisted Inbox in the
864
1044
  current request path. Attached `ServerEnvironment` ports acknowledge admission
@@ -0,0 +1,80 @@
1
+ import type { Any } from "@bufbuild/protobuf/wkt";
2
+ import type { ActorContext, Command, Event } from "@spine-event-engine/proto";
3
+ import { type AgentAcceptedInvocation, type AgentHandlerBinding } from "@spine-event-engine/proto/generated/spine/server/agent/execution_record_pb.js";
4
+ import type { RegisteredHandlerMetadata } from "../handler/handler-metadata.js";
5
+ import type { InboxMessage } from "../delivery/inbox.js";
6
+ /**
7
+ * Complete source and selected bindings at one durable Inbox handoff.
8
+ */
9
+ export interface AgentAdmissionInput {
10
+ /**
11
+ * Generated Agent state type.
12
+ */
13
+ readonly stateType: string;
14
+ /**
15
+ * Canonical storage key of the typed recipient.
16
+ */
17
+ readonly agentKey: string;
18
+ /**
19
+ * Original typed recipient from the persisted Inbox row.
20
+ */
21
+ readonly recipientId: Any;
22
+ /**
23
+ * Original Command or Event envelope.
24
+ */
25
+ readonly signal: {
26
+ readonly kind: "command";
27
+ readonly value: Command;
28
+ } | {
29
+ readonly kind: "event";
30
+ readonly value: Event;
31
+ };
32
+ /**
33
+ * Actor selected from the original envelope.
34
+ */
35
+ readonly actor: ActorContext;
36
+ /**
37
+ * Original durable Inbox receipt and order.
38
+ */
39
+ readonly inbox: InboxMessage;
40
+ /**
41
+ * Every matching handler in actual execution order.
42
+ */
43
+ readonly handlers: readonly RegisteredHandlerMetadata[];
44
+ /**
45
+ * Application build revision supplied by Agent registration.
46
+ */
47
+ readonly codeRevision: string;
48
+ /**
49
+ * Descriptor digest of accepted generated schemas.
50
+ */
51
+ readonly schemaRevision: string;
52
+ /**
53
+ * Digest of effective AI policy and configuration.
54
+ */
55
+ readonly policyRevision: string;
56
+ }
57
+ interface AgentAdmissionAccess {
58
+ /**
59
+ * Copies the exact accepted recipient and selected bindings for durable admission.
60
+ *
61
+ * @param input Routed Inbox work and registration revisions.
62
+ * @returns Immutable accepted invocation content.
63
+ */
64
+ create(input: AgentAdmissionInput): AgentAcceptedInvocation;
65
+ /**
66
+ * Compares every persisted handler-binding field with current registration.
67
+ *
68
+ * @param accepted Binding saved with the original invocation.
69
+ * @param registered Current generated handler metadata.
70
+ * @param ordinal Expected position in the accepted handler order.
71
+ * @returns Whether current registration exactly matches the saved binding.
72
+ */
73
+ matchesHandler(accepted: AgentHandlerBinding, registered: RegisteredHandlerMetadata, ordinal: number): boolean;
74
+ }
75
+ /**
76
+ * Materializes provider admission without running application handlers.
77
+ */
78
+ export declare const AgentAdmission: AgentAdmissionAccess;
79
+ export {};
80
+ //# sourceMappingURL=agent-admission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-admission.d.ts","sourceRoot":"","sources":["../../src/agent/agent-admission.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAC;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AAC9E,OAAO,EAYL,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EAEzB,MAAM,+EAA+E,CAAC;AACvF,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,gCAAgC,CAAC;AAChF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,WAAW,EAAE,GAAG,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,MAAM,EACX;QAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,GACrD;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAA;KAAE,CAAC;IAEtD;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAE7B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,SAAS,yBAAyB,EAAE,CAAC;IAExD;;OAEG;IACH,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAE9B;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAEhC;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED,UAAU,oBAAoB;IAC5B;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,uBAAuB,CAAC;IAE5D;;;;;;;OAOG;IACH,cAAc,CACZ,QAAQ,EAAE,mBAAmB,EAC7B,UAAU,EAAE,yBAAyB,EACrC,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;CACZ;AAED;;GAEG;AACH,eAAO,MAAM,cAAc,EAAE,oBA4C3B,CAAC"}
@@ -0,0 +1,127 @@
1
+ /*
2
+ * Copyright 2026, CodeMatters. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
+ * in compliance with the License. You may obtain a copy of the License at
6
+ *
7
+ * https://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
10
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ * or implied. See the License for the specific language governing permissions and limitations under
12
+ * the License.
13
+ */
14
+ import { create, equals } from "@bufbuild/protobuf";
15
+ import { AgentAcceptedInvocationSchema, AgentCodeRevisionSchema, AgentExecutionScopeSchema, AgentHandlerBindingSchema, AgentHandlerKind, AgentHandlerOrigin, AgentInboxOrderSchema, AgentInvocationKeySchema, AgentPolicyRevisionSchema, AgentSchemaRevisionSchema, AgentSignalKeySchema, } from "@spine-event-engine/proto/generated/spine/server/agent/execution_record_pb.js";
16
+ /**
17
+ * Materializes provider admission without running application handlers.
18
+ */
19
+ export const AgentAdmission = Object.freeze({
20
+ matchesHandler(accepted, registered, ordinal) {
21
+ return equals(AgentHandlerBindingSchema, accepted, binding(registered, ordinal));
22
+ },
23
+ create(input) {
24
+ const sourceSignal = signalKey(input.signal);
25
+ const bindings = input.handlers.map((handler, ordinal) => binding(handler, ordinal));
26
+ if (bindings.length === 0)
27
+ throw new TypeError("Agent admission requires a selected handler.");
28
+ return create(AgentAcceptedInvocationSchema, {
29
+ key: create(AgentInvocationKeySchema, {
30
+ scope: create(AgentExecutionScopeSchema, {
31
+ stateType: nonblank(input.stateType, "state type"),
32
+ agentKey: nonblank(input.agentKey, "Agent key"),
33
+ }),
34
+ sourceSignal,
35
+ }),
36
+ recipientId: input.recipientId,
37
+ signal: input.signal.kind === "command"
38
+ ? { case: "command", value: input.signal.value }
39
+ : { case: "event", value: input.signal.value },
40
+ actor: input.actor,
41
+ order: create(AgentInboxOrderSchema, {
42
+ receivedAt: input.inbox.whenReceived,
43
+ inboxVersion: input.inbox.version,
44
+ sourceSignal,
45
+ }),
46
+ handlers: bindings,
47
+ codeRevision: create(AgentCodeRevisionSchema, {
48
+ value: nonblank(input.codeRevision, "code revision"),
49
+ }),
50
+ schemaRevision: create(AgentSchemaRevisionSchema, {
51
+ value: nonblank(input.schemaRevision, "schema revision"),
52
+ }),
53
+ policyRevision: create(AgentPolicyRevisionSchema, {
54
+ value: nonblank(input.policyRevision, "policy revision"),
55
+ }),
56
+ });
57
+ },
58
+ });
59
+ /**
60
+ * Requires the original typed signal identity before constructing its durable key.
61
+ *
62
+ * @param signal Accepted Command or Event envelope.
63
+ * @returns Typed source identity.
64
+ */
65
+ function signalKey(signal) {
66
+ if (signal.kind === "command") {
67
+ const id = signal.value.id;
68
+ if (id === undefined)
69
+ throw new TypeError("Agent admission requires the original typed signal ID.");
70
+ return create(AgentSignalKeySchema, { id: { case: "command", value: id } });
71
+ }
72
+ const id = signal.value.id;
73
+ if (id === undefined)
74
+ throw new TypeError("Agent admission requires the original typed signal ID.");
75
+ return create(AgentSignalKeySchema, {
76
+ id: { case: "event", value: id },
77
+ });
78
+ }
79
+ /**
80
+ * Converts one generated handler identity without reinterpreting its route.
81
+ *
82
+ * @param registered Selected generated handler metadata.
83
+ * @param ordinal Position within this accepted signal.
84
+ * @returns Complete stored binding.
85
+ */
86
+ function binding(registered, ordinal) {
87
+ const handler = registered.handler;
88
+ const kind = handler.kind === "command-assignment"
89
+ ? AgentHandlerKind.AGENT_HANDLER_COMMAND_ASSIGNMENT
90
+ : handler.kind === "command-reaction"
91
+ ? AgentHandlerKind.AGENT_HANDLER_COMMAND_REACTION
92
+ : handler.kind === "event-reaction"
93
+ ? AgentHandlerKind.AGENT_HANDLER_EVENT_REACTION
94
+ : undefined;
95
+ if (kind === undefined)
96
+ throw new TypeError("Agent admission selected an unsupported handler.");
97
+ return create(AgentHandlerBindingSchema, {
98
+ ordinal,
99
+ receiverType: registered.entity.schema.typeName,
100
+ methodName: handler.methodName,
101
+ kind,
102
+ signalType: handler.messageFullTypeName,
103
+ origin: handler.origin === "external"
104
+ ? AgentHandlerOrigin.AGENT_HANDLER_EXTERNAL
105
+ : AgentHandlerOrigin.AGENT_HANDLER_DOMESTIC,
106
+ parameterCount: handler.parameterCount,
107
+ ...(handler.where === undefined
108
+ ? {}
109
+ : {
110
+ whereEventField: handler.where.eventField,
111
+ whereEquals: handler.where.equals,
112
+ }),
113
+ });
114
+ }
115
+ /**
116
+ * Requires a nonblank serialized identity or revision.
117
+ *
118
+ * @param value Text to validate.
119
+ * @param label Diagnostic field name.
120
+ * @returns Original checked text.
121
+ */
122
+ function nonblank(value, label) {
123
+ if (value.trim() === "")
124
+ throw new TypeError(`Agent admission requires ${label}.`);
125
+ return value;
126
+ }
127
+ //# sourceMappingURL=agent-admission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-admission.js","sourceRoot":"","sources":["../../src/agent/agent-admission.ts"],"names":[],"mappings":"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"}