@spine-event-engine/server 2.0.0-snapshot.23 → 2.0.0-snapshot.24
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.
- package/REFERENCE.md +89 -23
- package/dist/bus/event-bus.d.ts +65 -100
- package/dist/bus/event-bus.d.ts.map +1 -1
- package/dist/bus/event-bus.js +46 -116
- package/dist/bus/event-bus.js.map +1 -1
- package/dist/bus/saved-dispatcher-binding.d.ts +1 -44
- package/dist/bus/saved-dispatcher-binding.d.ts.map +1 -1
- package/dist/bus/saved-dispatcher-binding.js +0 -8
- package/dist/bus/saved-dispatcher-binding.js.map +1 -1
- package/dist/context/bounded-context.d.ts +9 -10
- package/dist/context/bounded-context.d.ts.map +1 -1
- package/dist/context/bounded-context.js +64 -43
- package/dist/context/bounded-context.js.map +1 -1
- package/dist/context/entity-inbox.d.ts.map +1 -1
- package/dist/context/entity-inbox.js +21 -7
- package/dist/context/entity-inbox.js.map +1 -1
- package/dist/context/local-inbox-handoff.d.ts +1 -0
- package/dist/context/local-inbox-handoff.d.ts.map +1 -1
- package/dist/context/local-inbox-handoff.js +31 -1
- package/dist/context/local-inbox-handoff.js.map +1 -1
- package/dist/context/projection-handoff.d.ts.map +1 -1
- package/dist/context/projection-handoff.js +2 -0
- package/dist/context/projection-handoff.js.map +1 -1
- package/dist/delivery/delivery-monitor.d.ts +12 -9
- package/dist/delivery/delivery-monitor.d.ts.map +1 -1
- package/dist/delivery/delivery-monitor.js +15 -9
- package/dist/delivery/delivery-monitor.js.map +1 -1
- package/dist/delivery/delivery-ports.d.ts +6 -13
- package/dist/delivery/delivery-ports.d.ts.map +1 -1
- package/dist/delivery/delivery-run-control.d.ts +15 -0
- package/dist/delivery/delivery-run-control.d.ts.map +1 -1
- package/dist/delivery/delivery-run-control.js.map +1 -1
- package/dist/delivery/delivery-supervisor.d.ts +33 -5
- package/dist/delivery/delivery-supervisor.d.ts.map +1 -1
- package/dist/delivery/delivery-supervisor.js +150 -22
- package/dist/delivery/delivery-supervisor.js.map +1 -1
- package/dist/delivery/delivery.d.ts.map +1 -1
- package/dist/delivery/delivery.js +128 -54
- package/dist/delivery/delivery.js.map +1 -1
- package/dist/delivery/inbox-storage.d.ts +8 -11
- package/dist/delivery/inbox-storage.d.ts.map +1 -1
- package/dist/delivery/inbox-storage.js +33 -76
- package/dist/delivery/inbox-storage.js.map +1 -1
- package/dist/delivery/inbox.d.ts +9 -12
- package/dist/delivery/inbox.d.ts.map +1 -1
- package/dist/delivery/inbox.js +10 -13
- package/dist/delivery/inbox.js.map +1 -1
- package/dist/delivery/reception-observation.d.ts +56 -0
- package/dist/delivery/reception-observation.d.ts.map +1 -0
- package/dist/delivery/reception-observation.js +67 -0
- package/dist/delivery/reception-observation.js.map +1 -0
- package/dist/repository/repository.d.ts +3 -4
- package/dist/repository/repository.d.ts.map +1 -1
- package/dist/repository/repository.js +155 -166
- package/dist/repository/repository.js.map +1 -1
- package/dist/runtime/runtime.d.ts +11 -0
- package/dist/runtime/runtime.d.ts.map +1 -1
- package/dist/runtime/runtime.js +13 -0
- package/dist/runtime/runtime.js.map +1 -1
- package/dist/runtime/signal-metadata.d.ts.map +1 -1
- package/dist/runtime/signal-metadata.js +3 -10
- package/dist/runtime/signal-metadata.js.map +1 -1
- package/dist/runtime/signal-publisher.d.ts +11 -33
- package/dist/runtime/signal-publisher.d.ts.map +1 -1
- package/dist/runtime/signal-publisher.js +70 -55
- package/dist/runtime/signal-publisher.js.map +1 -1
- package/dist/runtime/standalone-handler-runtime.d.ts.map +1 -1
- package/dist/runtime/standalone-handler-runtime.js +1 -31
- package/dist/runtime/standalone-handler-runtime.js.map +1 -1
- package/dist/server/environment-delivery-worker.d.ts.map +1 -1
- package/dist/server/environment-delivery-worker.js +305 -5
- package/dist/server/environment-delivery-worker.js.map +1 -1
- package/dist/server/managed-server-application.d.ts +2 -2
- package/dist/server/managed-server-application.d.ts.map +1 -1
- package/dist/server/managed-server-application.js +467 -177
- package/dist/server/managed-server-application.js.map +1 -1
- package/dist/server/node-coordinator.d.ts +14 -0
- package/dist/server/node-coordinator.d.ts.map +1 -1
- package/dist/server/node-coordinator.js +266 -45
- package/dist/server/node-coordinator.js.map +1 -1
- package/dist/server/server-log.d.ts.map +1 -1
- package/dist/server/server-log.js +4 -0
- package/dist/server/server-log.js.map +1 -1
- package/dist/server/server.js +20 -7
- package/dist/server/server.js.map +1 -1
- package/dist/services/spine-services.d.ts.map +1 -1
- package/dist/services/spine-services.js +200 -72
- package/dist/services/spine-services.js.map +1 -1
- package/dist/stand/event-origin-filter.d.ts +16 -0
- package/dist/stand/event-origin-filter.d.ts.map +1 -0
- package/dist/stand/event-origin-filter.js +124 -0
- package/dist/stand/event-origin-filter.js.map +1 -0
- package/dist/stand/subscription-observer.d.ts.map +1 -1
- package/dist/stand/subscription-observer.js +7 -0
- package/dist/stand/subscription-observer.js.map +1 -1
- package/dist/stand/subscription-runtime.d.ts +18 -1
- package/dist/stand/subscription-runtime.d.ts.map +1 -1
- package/dist/stand/subscription-runtime.js +32 -4
- package/dist/stand/subscription-runtime.js.map +1 -1
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +2 -2
- package/dist/testing/index.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +15 -15
|
@@ -19,13 +19,13 @@ import { CommandContextSchema, ActorContextSchema, CommandIdSchema, CommandSchem
|
|
|
19
19
|
import * as EntityLog from "@spine-event-engine/proto/generated/spine/system/server/entity_log_events_pb.js";
|
|
20
20
|
import { EntityTypeNameSchema } from "@spine-event-engine/proto/generated/spine/system/server/entity_type_pb.js";
|
|
21
21
|
import { EntityRecordSchema, } from "@spine-event-engine/proto/generated/spine/server/entity/entity_pb.js";
|
|
22
|
-
import { StorageQueryPolicy, } from "@spine-event-engine/storage";
|
|
22
|
+
import { EventStore, StorageQueryPolicy, } from "@spine-event-engine/storage";
|
|
23
23
|
import { TenantBoundary } from "@spine-event-engine/storage/provider";
|
|
24
24
|
import { EntityCommitStorageFactories } from "@spine-event-engine/storage/provider";
|
|
25
25
|
import { AgentHistoryStorageFactories, } from "@spine-event-engine/storage/provider";
|
|
26
26
|
import { AgentExecutionStorageFactories, } from "@spine-event-engine/storage/provider";
|
|
27
27
|
import { AgentHistoryEntrySchema, AgentInvocationTerminatedSchema, AgentModelSelectionChangedSchema as SelectionChangedSchema, AiModelKind, AiDiagnosticIdSchema, ModelRefSchema, ToolEffect, ConversationIdSchema, } from "@spine-event-engine/proto/agent";
|
|
28
|
-
import { AgentInvocationKeySchema, AgentExecutionStartSchema, AgentExecutionCompletionSchema, AgentInvocationBoundsSchema, AgentInvocationStatus,
|
|
28
|
+
import { AgentInvocationKeySchema, AgentExecutionStartSchema, AgentExecutionCompletionSchema, AgentInvocationBoundsSchema, AgentInvocationStatus, AgentOutgoingCommandSchema, AgentSignalKeySchema, AgentSavedDispatchTargetSchema as SavedTargetSchema, AgentSavedRepositoryFamily, AgentSavedTargetKind, } from "@spine-event-engine/proto/generated/spine/server/agent/execution_record_pb.js";
|
|
29
29
|
import { registryOptions } from "@spine-event-engine/ai/spi/runtime";
|
|
30
30
|
import { CommandValidationError } from "../bus/command-errors.js";
|
|
31
31
|
import { SignalPublisher } from "../runtime/signal-publisher.js";
|
|
@@ -38,6 +38,7 @@ import { RoutingDeclarations } from "./routing-declarations.js";
|
|
|
38
38
|
import { EventDispatcherOriginSchemas } from "../bus/event-dispatcher-origin-schemas.js";
|
|
39
39
|
import { SavedDispatcherBindings, } from "../bus/saved-dispatcher-binding.js";
|
|
40
40
|
import { Delivery } from "../delivery/delivery.js";
|
|
41
|
+
import { receptionObservation } from "../delivery/reception-observation.js";
|
|
41
42
|
import { commitFenced } from "./commit-fence.js";
|
|
42
43
|
import { AgentHistoryReads } from "../agent/agent-history.js";
|
|
43
44
|
import { AgentReadRuntime } from "../agent/agent-read-runtime.js";
|
|
@@ -438,8 +439,8 @@ const RepositoryAgentReads = {
|
|
|
438
439
|
return "accepted";
|
|
439
440
|
case AgentInvocationStatus.AGENT_INVOCATION_ACTIVE:
|
|
440
441
|
return "active";
|
|
441
|
-
case AgentInvocationStatus.
|
|
442
|
-
return "completed-pending-
|
|
442
|
+
case AgentInvocationStatus.AGENT_INVOCATION_COMPLETED_PENDING_COMMANDS:
|
|
443
|
+
return "completed-pending-commands";
|
|
443
444
|
case AgentInvocationStatus.AGENT_INVOCATION_COMPLETED:
|
|
444
445
|
return "completed";
|
|
445
446
|
case AgentInvocationStatus.AGENT_INVOCATION_TERMINATED:
|
|
@@ -2024,25 +2025,32 @@ class ProcessManagerExecutionSupport {
|
|
|
2024
2025
|
*
|
|
2025
2026
|
* @param loaded Process Manager and commit storage.
|
|
2026
2027
|
* @param options Stand tenant selection.
|
|
2027
|
-
* @param
|
|
2028
|
-
* @param
|
|
2028
|
+
* @param diagnostics Input and produced Events to retain when configured.
|
|
2029
|
+
* @param producedEvents Delivery Events to save before current state.
|
|
2029
2030
|
* @returns `true` after a successful commit or unchanged no-op.
|
|
2030
2031
|
*/
|
|
2031
|
-
async commit(loaded, options,
|
|
2032
|
+
async commit(loaded, options, diagnostics, producedEvents) {
|
|
2032
2033
|
const version = RepositoryEntities.repositoryVersion(loaded.entity);
|
|
2033
2034
|
const priorNumber = loaded.current?.version?.number ?? 0;
|
|
2034
2035
|
if (version.number === priorNumber) {
|
|
2035
|
-
await this.#appendUnchangedDiagnostics(loaded,
|
|
2036
|
-
|
|
2036
|
+
await this.#appendUnchangedDiagnostics(loaded, diagnostics);
|
|
2037
|
+
const store = new EventStore(this.#runtime.context, this.#runtime.storageFactory);
|
|
2038
|
+
try {
|
|
2039
|
+
await store.appendAll(producedEvents);
|
|
2040
|
+
}
|
|
2041
|
+
finally {
|
|
2042
|
+
store.close();
|
|
2043
|
+
}
|
|
2044
|
+
await this.#appendAgentEvents(loaded, producedEvents);
|
|
2037
2045
|
return true;
|
|
2038
2046
|
}
|
|
2039
2047
|
const entityId = loaded.entity.id;
|
|
2040
2048
|
const state = RepositoryEntities.repositoryState(loaded.entity);
|
|
2041
2049
|
const lifecycle = RepositoryEntities.repositoryLifecycle(loaded.entity);
|
|
2042
2050
|
const deferred = await standAccess.deferUpdate(this.#runtime.stand, this.#repository.stateSchema, state, RepositoryStand.standUpdateOptions(options.tenantId, version, lifecycle), this.#repository.metadata);
|
|
2043
|
-
await this.#storeProcessManagerRecord(loaded, entityId,
|
|
2044
|
-
|
|
2045
|
-
this.#
|
|
2051
|
+
await this.#storeProcessManagerRecord(loaded, entityId, diagnostics, producedEvents, deferred);
|
|
2052
|
+
this.#notifyProcessManager(deferred, diagnostics);
|
|
2053
|
+
await this.#appendAgentEvents(loaded, producedEvents);
|
|
2046
2054
|
return true;
|
|
2047
2055
|
}
|
|
2048
2056
|
/**
|
|
@@ -2086,13 +2094,14 @@ class ProcessManagerExecutionSupport {
|
|
|
2086
2094
|
*
|
|
2087
2095
|
* @param loaded Process Manager and commit storage.
|
|
2088
2096
|
* @param entityId Process Manager identifier.
|
|
2089
|
-
* @param
|
|
2097
|
+
* @param diagnostics Diagnostic Events to retain when configured.
|
|
2098
|
+
* @param producedEvents Delivery Events to save before current state.
|
|
2090
2099
|
* @param deferred Stand update to notify or cancel.
|
|
2091
2100
|
* @returns Completion after durable persistence.
|
|
2092
2101
|
*/
|
|
2093
|
-
async #storeProcessManagerRecord(loaded, entityId,
|
|
2102
|
+
async #storeProcessManagerRecord(loaded, entityId, diagnostics, producedEvents, deferred) {
|
|
2094
2103
|
try {
|
|
2095
|
-
await this.#commitProcessManagerRecord(loaded, entityId,
|
|
2104
|
+
await this.#commitProcessManagerRecord(loaded, entityId, diagnostics, producedEvents, deferred);
|
|
2096
2105
|
entityStateHistoryCaches.get(loaded.entity)?.clear();
|
|
2097
2106
|
}
|
|
2098
2107
|
catch (error) {
|
|
@@ -2105,11 +2114,12 @@ class ProcessManagerExecutionSupport {
|
|
|
2105
2114
|
*
|
|
2106
2115
|
* @param loaded Loaded Process Manager and commit storage.
|
|
2107
2116
|
* @param entityId Process Manager identifier.
|
|
2108
|
-
* @param
|
|
2117
|
+
* @param diagnostics Diagnostic Events to retain when configured.
|
|
2118
|
+
* @param producedEvents Delivery Events to save before current state.
|
|
2109
2119
|
* @param deferred Stand update containing the prepared record.
|
|
2110
2120
|
* @returns Completion after the storage commit.
|
|
2111
2121
|
*/
|
|
2112
|
-
#commitProcessManagerRecord(loaded, entityId,
|
|
2122
|
+
#commitProcessManagerRecord(loaded, entityId, diagnostics, producedEvents, deferred) {
|
|
2113
2123
|
const history = RepositoryStorage.historyConfiguration(this.#repository);
|
|
2114
2124
|
const record = RepositoryStand.preparedRecord(this.#repository, deferred, entityId);
|
|
2115
2125
|
return loaded.commits.commit({
|
|
@@ -2119,8 +2129,9 @@ class ProcessManagerExecutionSupport {
|
|
|
2119
2129
|
next: record,
|
|
2120
2130
|
...(history.stateHistory ? { states: [record] } : {}),
|
|
2121
2131
|
...(history.processManagerEventHistory
|
|
2122
|
-
? { diagnostics:
|
|
2132
|
+
? { diagnostics: diagnostics.map((event) => clone(EventSchema, event)) }
|
|
2123
2133
|
: {}),
|
|
2134
|
+
events: producedEvents.map((event) => clone(EventSchema, event)),
|
|
2124
2135
|
});
|
|
2125
2136
|
}
|
|
2126
2137
|
/**
|
|
@@ -2217,7 +2228,9 @@ const AgentExecutionRunner = {
|
|
|
2217
2228
|
* @returns When the fenced repository operation completes.
|
|
2218
2229
|
*/
|
|
2219
2230
|
async handleRunFailure(repository, runtime, tenantId, session, error) {
|
|
2220
|
-
if (session.record().status ===
|
|
2231
|
+
if (session.record().status ===
|
|
2232
|
+
AgentInvocationStatus.AGENT_INVOCATION_COMPLETED_PENDING_COMMANDS ||
|
|
2233
|
+
session.record().status === AgentInvocationStatus.AGENT_INVOCATION_COMPLETED)
|
|
2221
2234
|
throw error;
|
|
2222
2235
|
if (error instanceof AgentUncertainAttemptError) {
|
|
2223
2236
|
const reason = this.hasUnresolvedToolWrite(session.record())
|
|
@@ -2248,8 +2261,8 @@ const AgentExecutionRunner = {
|
|
|
2248
2261
|
return this.terminate(repository, runtime, tenantId, session, this.hasUnresolvedToolWrite(session.record())
|
|
2249
2262
|
? "TOOL_OUTCOME_UNKNOWN"
|
|
2250
2263
|
: "MODEL_OUTCOME_UNKNOWN");
|
|
2251
|
-
if (session.record().status === AgentInvocationStatus.
|
|
2252
|
-
return this.
|
|
2264
|
+
if (session.record().status === AgentInvocationStatus.AGENT_INVOCATION_COMPLETED_PENDING_COMMANDS)
|
|
2265
|
+
return this.deliverCommands(runtime, session);
|
|
2253
2266
|
if (this.deadlineExpired(session.record()))
|
|
2254
2267
|
return this.terminate(repository, runtime, tenantId, session, "DEADLINE_EXCEEDED");
|
|
2255
2268
|
return this.execute(repository, runtime, tenantId, session);
|
|
@@ -2431,9 +2444,8 @@ const AgentExecutionRunner = {
|
|
|
2431
2444
|
: await this.selectMissingModels(repository, runtime, session, accepted, tenantId);
|
|
2432
2445
|
if (session.signal.aborted)
|
|
2433
2446
|
return;
|
|
2434
|
-
const
|
|
2435
|
-
|
|
2436
|
-
await this.deliver(runtime, session);
|
|
2447
|
+
const outputs = await this.completeExecution(repository, runtime, tenantId, session, loaded, accepted, handlers, entityId, record.started?.initialVersion ?? create(VersionSchema));
|
|
2448
|
+
await this.deliverInitial(runtime, session, outputs);
|
|
2437
2449
|
},
|
|
2438
2450
|
/**
|
|
2439
2451
|
* Creates or rejects the draft before one conditional Entity completion.
|
|
@@ -2451,7 +2463,8 @@ const AgentExecutionRunner = {
|
|
|
2451
2463
|
*/
|
|
2452
2464
|
async completeExecution(repository, runtime, tenantId, session, loaded, accepted, handlers, entityId, initialVersion) {
|
|
2453
2465
|
const outputs = await this.outputsOrRejection(repository, runtime, tenantId, session, loaded.entity, accepted, handlers, entityId, initialVersion);
|
|
2454
|
-
|
|
2466
|
+
await this.complete(repository, runtime, tenantId, session, loaded, entityId, outputs);
|
|
2467
|
+
return outputs;
|
|
2455
2468
|
},
|
|
2456
2469
|
/**
|
|
2457
2470
|
* Rejects a Command draft and persists only its declared rejection.
|
|
@@ -2483,22 +2496,20 @@ const AgentExecutionRunner = {
|
|
|
2483
2496
|
}
|
|
2484
2497
|
},
|
|
2485
2498
|
/**
|
|
2486
|
-
* Wraps the original rejection Event
|
|
2499
|
+
* Wraps the original rejection Event for one normal EventBus handoff.
|
|
2487
2500
|
*
|
|
2488
2501
|
* @param runtime Bounded Context storage and publication services.
|
|
2489
2502
|
* @param repository Registered Entity repository for this operation.
|
|
2490
2503
|
* @param command Original typed Command envelope.
|
|
2491
2504
|
* @param entityId Typed recipient Entity identifier.
|
|
2492
2505
|
* @param error Failure raised while processing this accepted signal.
|
|
2493
|
-
* @returns Prepared original rejection Event for
|
|
2506
|
+
* @returns Prepared original rejection Event for one normal EventBus handoff.
|
|
2494
2507
|
*/
|
|
2495
2508
|
rejectionOutput(runtime, repository, command, entityId, error) {
|
|
2496
|
-
return
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
},
|
|
2501
|
-
});
|
|
2509
|
+
return {
|
|
2510
|
+
case: "event",
|
|
2511
|
+
value: RepositorySignals.rejectionEvent(runtime, repository, command, entityId, error),
|
|
2512
|
+
};
|
|
2502
2513
|
},
|
|
2503
2514
|
/**
|
|
2504
2515
|
* Restores handler results and binds their declared original output envelopes.
|
|
@@ -2700,15 +2711,18 @@ const AgentExecutionRunner = {
|
|
|
2700
2711
|
const initialVersion = record.started?.initialVersion;
|
|
2701
2712
|
if (initialVersion === undefined)
|
|
2702
2713
|
throw new Error("Agent completion requires its started Version.");
|
|
2714
|
+
const commands = outputs
|
|
2715
|
+
.filter((output) => output.case === "command")
|
|
2716
|
+
.map((output) => create(AgentOutgoingCommandSchema, { command: output.value }));
|
|
2703
2717
|
record.status =
|
|
2704
|
-
|
|
2718
|
+
commands.length === 0
|
|
2705
2719
|
? AgentInvocationStatus.AGENT_INVOCATION_COMPLETED
|
|
2706
|
-
: AgentInvocationStatus.
|
|
2720
|
+
: AgentInvocationStatus.AGENT_INVOCATION_COMPLETED_PENDING_COMMANDS;
|
|
2707
2721
|
record.completion = create(AgentExecutionCompletionSchema, {
|
|
2708
2722
|
initialVersion,
|
|
2709
2723
|
resultingVersion: version,
|
|
2710
2724
|
preferences: [...preferences],
|
|
2711
|
-
|
|
2725
|
+
commands,
|
|
2712
2726
|
});
|
|
2713
2727
|
return record;
|
|
2714
2728
|
},
|
|
@@ -2720,9 +2734,9 @@ const AgentExecutionRunner = {
|
|
|
2720
2734
|
*/
|
|
2721
2735
|
emittedHistory(outputs) {
|
|
2722
2736
|
return outputs.flatMap((output) => {
|
|
2723
|
-
if (output.
|
|
2737
|
+
if (output.case !== "event" || output.value.context?.rejection !== undefined)
|
|
2724
2738
|
return [];
|
|
2725
|
-
const event = output.
|
|
2739
|
+
const event = output.value;
|
|
2726
2740
|
const occurredAt = event.context?.timestamp;
|
|
2727
2741
|
if (occurredAt === undefined)
|
|
2728
2742
|
throw new Error("Agent emitted Event requires its original timestamp.");
|
|
@@ -2839,7 +2853,7 @@ const AgentExecutionRunner = {
|
|
|
2839
2853
|
* @param version Entity version associated with the signal.
|
|
2840
2854
|
* @param signal Original domain signal or execution cancellation signal.
|
|
2841
2855
|
* @param schema Generated message descriptor for the signal.
|
|
2842
|
-
* @returns Typed original Event envelope for
|
|
2856
|
+
* @returns Typed original Event envelope for one normal EventBus handoff.
|
|
2843
2857
|
*/
|
|
2844
2858
|
bindEventOutput(repository, runtime, source, entityId, version, signal, schema) {
|
|
2845
2859
|
if (source.case !== "command" && source.case !== "event")
|
|
@@ -2852,7 +2866,7 @@ const AgentExecutionRunner = {
|
|
|
2852
2866
|
message: AnyMessages.pack(schema, signal),
|
|
2853
2867
|
context: RepositorySignals.eventContextWithProducer(metadata.context, repository, entityId, version),
|
|
2854
2868
|
});
|
|
2855
|
-
return
|
|
2869
|
+
return { case: "event", value: event };
|
|
2856
2870
|
},
|
|
2857
2871
|
/**
|
|
2858
2872
|
* Creates the original Command envelope from its accepted origin.
|
|
@@ -2874,66 +2888,97 @@ const AgentExecutionRunner = {
|
|
|
2874
2888
|
message: AnyMessages.pack(schema, signal),
|
|
2875
2889
|
context: metadata.context,
|
|
2876
2890
|
});
|
|
2877
|
-
return
|
|
2891
|
+
return { case: "command", value: command };
|
|
2878
2892
|
},
|
|
2879
2893
|
/**
|
|
2880
|
-
*
|
|
2894
|
+
* Dispatches every emitted Event to the normal EventBus and advances saved Commands.
|
|
2881
2895
|
*
|
|
2882
2896
|
* @param runtime Bound normal bus acceptance callbacks.
|
|
2883
2897
|
* @param session Fenced record containing pending saved envelopes.
|
|
2898
|
+
* @param outputs Locally produced outputs in original handler order.
|
|
2884
2899
|
* @returns When the fenced repository operation completes.
|
|
2885
2900
|
*/
|
|
2886
|
-
async
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2901
|
+
async deliverInitial(runtime, session, outputs) {
|
|
2902
|
+
let commandIndex = 0;
|
|
2903
|
+
let failed = false;
|
|
2904
|
+
let firstFailure;
|
|
2905
|
+
for (const output of outputs) {
|
|
2906
|
+
try {
|
|
2907
|
+
if (output.case === "event") {
|
|
2908
|
+
await runtime.publishAgentEvent(output.value);
|
|
2909
|
+
}
|
|
2910
|
+
else {
|
|
2911
|
+
await this.deliverCommand(runtime, session, commandIndex);
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
catch (error) {
|
|
2915
|
+
if (!failed) {
|
|
2916
|
+
firstFailure = error;
|
|
2917
|
+
failed = true;
|
|
2918
|
+
}
|
|
2919
|
+
}
|
|
2920
|
+
if (output.case === "command")
|
|
2921
|
+
commandIndex += 1;
|
|
2922
|
+
}
|
|
2923
|
+
if (failed)
|
|
2924
|
+
throw firstFailure;
|
|
2925
|
+
},
|
|
2926
|
+
/**
|
|
2927
|
+
* Retries pending saved Commands without rerunning the Agent handler.
|
|
2928
|
+
*
|
|
2929
|
+
* @param runtime Bound normal Command bus callbacks.
|
|
2930
|
+
* @param session Fenced record containing saved Commands.
|
|
2931
|
+
* @returns Completion after pending Command attempts.
|
|
2932
|
+
*/
|
|
2933
|
+
async deliverCommands(runtime, session) {
|
|
2934
|
+
for (const [index] of (session.record().completion?.commands ?? []).entries()) {
|
|
2892
2935
|
if (session.signal.aborted)
|
|
2893
2936
|
return;
|
|
2894
|
-
|
|
2895
|
-
continue;
|
|
2896
|
-
const signal = output.signal;
|
|
2897
|
-
if (signal.case !== "event" && signal.case !== "command")
|
|
2898
|
-
throw new Error("Agent outgoing signal has no original envelope.");
|
|
2899
|
-
const key = this.outputKey(output);
|
|
2900
|
-
const plan = output.plan ??
|
|
2901
|
-
(await (signal.case === "event"
|
|
2902
|
-
? runtime.prepareSavedEvent(signal.value)
|
|
2903
|
-
: runtime.prepareSavedCommand(signal.value)));
|
|
2904
|
-
if (output.plan === undefined) {
|
|
2905
|
-
await session.update((current) => {
|
|
2906
|
-
const pending = current.completion?.outgoing[index];
|
|
2907
|
-
if (pending?.plan !== undefined || pending?.signal.case !== signal.case)
|
|
2908
|
-
throw new Error("Saved Agent output changed before plan installation.");
|
|
2909
|
-
pending.plan = plan;
|
|
2910
|
-
return current;
|
|
2911
|
-
});
|
|
2912
|
-
}
|
|
2913
|
-
if (signal.case === "event")
|
|
2914
|
-
await runtime.publishSavedEvent(signal.value, plan);
|
|
2915
|
-
else
|
|
2916
|
-
await runtime.publishSavedCommand(signal.value, plan);
|
|
2917
|
-
await session.markDelivered([key]);
|
|
2918
|
-
runtime.recordAcceptedSaved(signal.value);
|
|
2937
|
+
await this.deliverCommand(runtime, session, index);
|
|
2919
2938
|
}
|
|
2920
2939
|
},
|
|
2921
2940
|
/**
|
|
2922
|
-
*
|
|
2941
|
+
* Sends one saved Command under the current claim and records its acknowledgement.
|
|
2923
2942
|
*
|
|
2924
|
-
* @param
|
|
2925
|
-
* @
|
|
2943
|
+
* @param runtime Bound normal Command bus callbacks.
|
|
2944
|
+
* @param session Fenced record containing saved Commands.
|
|
2945
|
+
* @param index Command position in the saved completion.
|
|
2946
|
+
* @returns Completion after the Command is acknowledged or already delivered.
|
|
2926
2947
|
*/
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
if (
|
|
2933
|
-
|
|
2934
|
-
|
|
2948
|
+
async deliverCommand(runtime, session, index) {
|
|
2949
|
+
const output = session.record().completion?.commands[index];
|
|
2950
|
+
if (output === undefined || output.delivered)
|
|
2951
|
+
return;
|
|
2952
|
+
const command = output.command;
|
|
2953
|
+
if (command === undefined)
|
|
2954
|
+
throw new Error("Agent outgoing Command has no original envelope.");
|
|
2955
|
+
const key = this.outputKey(output);
|
|
2956
|
+
const plan = output.plan ?? (await runtime.prepareSavedCommand(command));
|
|
2957
|
+
if (output.plan === undefined) {
|
|
2958
|
+
await session.update((current) => {
|
|
2959
|
+
const pending = current.completion?.commands[index];
|
|
2960
|
+
if (pending === undefined ||
|
|
2961
|
+
pending.plan !== undefined ||
|
|
2962
|
+
pending.command?.id?.uuid !== command.id?.uuid)
|
|
2963
|
+
throw new Error("Saved Agent Command changed before plan installation.");
|
|
2964
|
+
pending.plan = plan;
|
|
2965
|
+
return current;
|
|
2935
2966
|
});
|
|
2936
|
-
|
|
2967
|
+
}
|
|
2968
|
+
await runtime.publishSavedCommand(command, plan);
|
|
2969
|
+
await session.markDelivered([key]);
|
|
2970
|
+
runtime.recordAcceptedSaved(command);
|
|
2971
|
+
},
|
|
2972
|
+
/**
|
|
2973
|
+
* Returns the typed original ID of one completed outgoing Command.
|
|
2974
|
+
*
|
|
2975
|
+
* @param output Prepared outgoing Command.
|
|
2976
|
+
* @returns Original durable Command ID.
|
|
2977
|
+
*/
|
|
2978
|
+
outputKey(output) {
|
|
2979
|
+
if (output.command?.id !== undefined)
|
|
2980
|
+
return output.command.id;
|
|
2981
|
+
throw new Error("Agent outgoing Command requires its original typed ID.");
|
|
2937
2982
|
},
|
|
2938
2983
|
/**
|
|
2939
2984
|
* Validates every stored binding against the current generated selectors.
|
|
@@ -3468,7 +3513,7 @@ class ProcessManagerCommandExecution {
|
|
|
3468
3513
|
async #commitAndPublish(loaded, tenantOptions, intake, producedSignals) {
|
|
3469
3514
|
const commands = this.#commandOutputs(intake.assignee, producedSignals);
|
|
3470
3515
|
const events = this.#eventOutputs(intake.assignee, producedSignals, intake.route.entityId, RepositoryEntities.priorVersion(loaded.current));
|
|
3471
|
-
const committed = await this.#support.commit(loaded, tenantOptions, events);
|
|
3516
|
+
const committed = await this.#support.commit(loaded, tenantOptions, events, events);
|
|
3472
3517
|
if (!committed)
|
|
3473
3518
|
return undefined;
|
|
3474
3519
|
this.#publishChangedState(loaded, intake.route.entityId);
|
|
@@ -3648,7 +3693,7 @@ class ProcessManagerCommandExecution {
|
|
|
3648
3693
|
#postEvents(events) {
|
|
3649
3694
|
for (const event of events) {
|
|
3650
3695
|
// spine-log-boundary: server.repository_event_follow_up
|
|
3651
|
-
void this.#runtime.publisher.
|
|
3696
|
+
void this.#runtime.publisher.publishReactorEvent(event);
|
|
3652
3697
|
}
|
|
3653
3698
|
}
|
|
3654
3699
|
}
|
|
@@ -3744,9 +3789,10 @@ class ProcessManagerEventExecution {
|
|
|
3744
3789
|
const produced = await this.#invokeHandlers(entityId, loaded.entity, intake, tenantOptions.tenantId);
|
|
3745
3790
|
const events = this.#bindProducedEvents(produced.events, entityId, RepositoryEntities.priorVersion(loaded.current));
|
|
3746
3791
|
const commands = this.#bindProducedCommands(produced.commands);
|
|
3747
|
-
const diagnostics =
|
|
3748
|
-
|
|
3749
|
-
|
|
3792
|
+
const diagnostics = [
|
|
3793
|
+
DispatchGuards.guardedJournalEvent(this.#repository, this.#event, entityId),
|
|
3794
|
+
...events,
|
|
3795
|
+
];
|
|
3750
3796
|
const committed = await this.#support.commit(loaded, tenantOptions, diagnostics, events);
|
|
3751
3797
|
if (!committed)
|
|
3752
3798
|
return;
|
|
@@ -3944,7 +3990,7 @@ class ProcessManagerEventExecution {
|
|
|
3944
3990
|
#postEvents(events) {
|
|
3945
3991
|
for (const event of events) {
|
|
3946
3992
|
// spine-log-boundary: server.process_manager_event_follow_up
|
|
3947
|
-
void this.#runtime.publisher.
|
|
3993
|
+
void this.#runtime.publisher.publishReactorEvent(event);
|
|
3948
3994
|
}
|
|
3949
3995
|
}
|
|
3950
3996
|
}
|
|
@@ -4266,7 +4312,23 @@ const EntityInvocation = {
|
|
|
4266
4312
|
if (typeof method !== "function") {
|
|
4267
4313
|
throw new TypeError(`Repository entity execution requires method "${methodName}".`);
|
|
4268
4314
|
}
|
|
4269
|
-
|
|
4315
|
+
let result;
|
|
4316
|
+
try {
|
|
4317
|
+
result = Reflect.apply(method, entity, parameterCount === 2 ? [message, context] : [message]);
|
|
4318
|
+
}
|
|
4319
|
+
catch (error) {
|
|
4320
|
+
receptionObservation.recordHandlerFailure(error);
|
|
4321
|
+
throw error;
|
|
4322
|
+
}
|
|
4323
|
+
if (result !== null &&
|
|
4324
|
+
(typeof result === "object" || typeof result === "function") &&
|
|
4325
|
+
typeof result.then === "function") {
|
|
4326
|
+
return Promise.resolve(result).catch((error) => {
|
|
4327
|
+
receptionObservation.recordHandlerFailure(error);
|
|
4328
|
+
throw error;
|
|
4329
|
+
});
|
|
4330
|
+
}
|
|
4331
|
+
return result;
|
|
4270
4332
|
},
|
|
4271
4333
|
/**
|
|
4272
4334
|
* Copies a Command context or creates an empty context when absent.
|
|
@@ -8007,65 +8069,6 @@ const SavedRepositoryDispatch = {
|
|
|
8007
8069
|
throw new Error("Saved Agent Command repository binding changed before delivery.");
|
|
8008
8070
|
return { runtime, signalType: schema.typeName, recipient };
|
|
8009
8071
|
},
|
|
8010
|
-
/**
|
|
8011
|
-
* Prepares the exact ordered Event recipients and selected generated handlers.
|
|
8012
|
-
*
|
|
8013
|
-
* @param repository Registered Entity repository for this operation.
|
|
8014
|
-
* @param routing Registered generated handler routing metadata.
|
|
8015
|
-
* @param event Original typed Event envelope.
|
|
8016
|
-
* @returns Validated frozen Event recipient target.
|
|
8017
|
-
*/
|
|
8018
|
-
async prepareEvent(repository, routing, event) {
|
|
8019
|
-
const route = await repository.routeEvent(event);
|
|
8020
|
-
return create(SavedTargetSchema, {
|
|
8021
|
-
kind: AgentSavedTargetKind.AGENT_SAVED_REPOSITORY_EVENT,
|
|
8022
|
-
receiverStateType: repository.stateSchema.typeName,
|
|
8023
|
-
repositoryFamily: SavedRepositoryDispatch.family(repository),
|
|
8024
|
-
signalType: route.messageFullTypeName,
|
|
8025
|
-
bindingFingerprint: SavedRepositoryDispatch.fingerprint(repository, SavedRepositoryDispatch.eventHandlers(routing, event)),
|
|
8026
|
-
recipients: route.entityIds.map((id) => InboxMessages.inboxTargetId(id, repository.idField)),
|
|
8027
|
-
});
|
|
8028
|
-
},
|
|
8029
|
-
/**
|
|
8030
|
-
* Restores the saved Event route and current generated handler metadata.
|
|
8031
|
-
*
|
|
8032
|
-
* @param repository Registered Entity repository for this operation.
|
|
8033
|
-
* @param routing Registered generated handler routing metadata.
|
|
8034
|
-
* @param event Original typed Event envelope.
|
|
8035
|
-
* @param target Frozen recipient binding.
|
|
8036
|
-
* @returns When the fenced repository operation completes.
|
|
8037
|
-
*/
|
|
8038
|
-
bindEvent(repository, routing, event, target) {
|
|
8039
|
-
const { signalType } = SavedRepositoryDispatch.requireEventBinding(repository, routing, event, target);
|
|
8040
|
-
const entityIds = target.recipients.map((id) => SavedRepositoryDispatch.recipient(repository, id));
|
|
8041
|
-
const route = {
|
|
8042
|
-
entityIds,
|
|
8043
|
-
messageFullTypeName: signalType,
|
|
8044
|
-
invocation: "deferred",
|
|
8045
|
-
};
|
|
8046
|
-
return Promise.resolve(() => RepositoryDispatch.dispatchRepositoryEvent(repository, routing, event, route));
|
|
8047
|
-
},
|
|
8048
|
-
/**
|
|
8049
|
-
* Checks saved Event metadata and active repository registration.
|
|
8050
|
-
*
|
|
8051
|
-
* @param repository Registered Entity repository for this operation.
|
|
8052
|
-
* @param routing Registered generated handler routing metadata.
|
|
8053
|
-
* @param event Original typed Event envelope.
|
|
8054
|
-
* @param target Frozen recipient binding.
|
|
8055
|
-
* @returns Registered Event route for the frozen target.
|
|
8056
|
-
*/
|
|
8057
|
-
requireEventBinding(repository, routing, event, target) {
|
|
8058
|
-
const packed = EntityInvocation.requireSignalMessage(event.message, "event");
|
|
8059
|
-
const schema = RepositoryRoutes.schemaForTypeUrl(routing.eventSchemas, packed.typeUrl, "event");
|
|
8060
|
-
const fingerprint = SavedRepositoryDispatch.fingerprint(repository, SavedRepositoryDispatch.eventHandlers(routing, event));
|
|
8061
|
-
const runtime = repositoryRuntimes.get(repository);
|
|
8062
|
-
if (!SavedRepositoryDispatch.matches(repository, target, AgentSavedTargetKind.AGENT_SAVED_REPOSITORY_EVENT) ||
|
|
8063
|
-
target.signalType !== schema.typeName ||
|
|
8064
|
-
target.bindingFingerprint !== fingerprint ||
|
|
8065
|
-
runtime === undefined)
|
|
8066
|
-
throw new Error("Saved Agent Event repository binding changed before delivery.");
|
|
8067
|
-
return { runtime, signalType: schema.typeName };
|
|
8068
|
-
},
|
|
8069
8072
|
/**
|
|
8070
8073
|
* Creates one internal Command binding from the repository registration.
|
|
8071
8074
|
*
|
|
@@ -8080,20 +8083,6 @@ const SavedRepositoryDispatch = {
|
|
|
8080
8083
|
bind: (command, target) => SavedRepositoryDispatch.bindCommand(repository, routing, command, target),
|
|
8081
8084
|
};
|
|
8082
8085
|
},
|
|
8083
|
-
/**
|
|
8084
|
-
* Creates one internal Event binding from the repository registration.
|
|
8085
|
-
*
|
|
8086
|
-
* @param repository Registered Entity repository for this operation.
|
|
8087
|
-
* @param routing Registered generated handler routing metadata.
|
|
8088
|
-
* @returns Saved Event binding for this registration.
|
|
8089
|
-
*/
|
|
8090
|
-
eventBinding(repository, routing) {
|
|
8091
|
-
return {
|
|
8092
|
-
prepare: (event) => SavedRepositoryDispatch.prepareEvent(repository, routing, event),
|
|
8093
|
-
matches: (target) => SavedRepositoryDispatch.matches(repository, target, AgentSavedTargetKind.AGENT_SAVED_REPOSITORY_EVENT),
|
|
8094
|
-
bind: (event, target) => SavedRepositoryDispatch.bindEvent(repository, routing, event, target),
|
|
8095
|
-
};
|
|
8096
|
-
},
|
|
8097
8086
|
};
|
|
8098
8087
|
Object.freeze(SavedRepositoryDispatch);
|
|
8099
8088
|
/**
|
|
@@ -8156,7 +8145,7 @@ const RepositoryDispatch = {
|
|
|
8156
8145
|
},
|
|
8157
8146
|
});
|
|
8158
8147
|
const originAware = EventDispatcherOriginSchemas.define(dispatcher, routing.domesticEventSchemas, routing.externalEventSchemas);
|
|
8159
|
-
return
|
|
8148
|
+
return originAware;
|
|
8160
8149
|
},
|
|
8161
8150
|
/**
|
|
8162
8151
|
* Creates a system-Event dispatcher for registered Entity-state subscriptions.
|