@kalphq/core 0.1.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.
@@ -0,0 +1,742 @@
1
+ import { IRNodeId, KalpAI, KalpActions, KalpAuth, KalpMemory, KalpVault, HandlerContext, IRGraph } from '@kalphq/sdk';
2
+
3
+ /**
4
+ * Core runtime types for the Kalp v2 Orchestration Reactor.
5
+ *
6
+ * These types define the execution event model, task primitives, and runtime
7
+ * event contracts. They are intentionally infrastructure-agnostic — no
8
+ * Cloudflare, Durable Object, or platform-specific types appear here.
9
+ *
10
+ * @module
11
+ */
12
+
13
+ /**
14
+ * Categories of untracked IO that Kalp can detect (best-effort).
15
+ *
16
+ * - `"network"` — bare `globalThis.fetch` or similar outside `actions.fetch`.
17
+ * - `"timer"` — `setTimeout` / `setInterval` outside `actions.wait`.
18
+ * - `"fs"` — Node `fs` access (not applicable in all runtimes; kept for portability).
19
+ * - `"unknown"` — anything else the heuristic can’t classify.
20
+ */
21
+ type UntrackedIOSource = "network" | "timer" | "fs" | "unknown";
22
+ /**
23
+ * Execution identity carried through every handler invocation.
24
+ *
25
+ * Hierarchy:
26
+ * ```
27
+ * thread = actor instance (identified by threadId)
28
+ * +-- trace = one handleEvent() call into the actor
29
+ * +-- execution = one handler invocation (step/tool/lifecycle run)
30
+ * ```
31
+ *
32
+ * `threadId` is opaque in Core. The adapter maps it to infrastructure
33
+ * (e.g. Durable Object id, in-memory key). Core never parses or assumes its format.
34
+ */
35
+ interface ExecutionContext {
36
+ /** Unique per handler invocation (UUID). Distinguishes retries, loop iterations. */
37
+ executionId: string;
38
+ /** Per `handleEvent()` call. Groups all executions from one external stimulus. */
39
+ traceId: string;
40
+ /** Opaque actor identifier. Adapter maps to infrastructure (CF: DO id, tests: in-memory). */
41
+ threadId: string;
42
+ /** Total count of detected untracked IO operations. */
43
+ untrackedIOCount: number;
44
+ /** Breakdown of untracked IO by source type. */
45
+ untrackedIOByType: Record<UntrackedIOSource, number>;
46
+ /** Whether any plugin has been loaded (observability may be incomplete). */
47
+ hasUntrustedPlugins: boolean;
48
+ }
49
+ /**
50
+ * Union of all structured events emitted during agent execution.
51
+ *
52
+ * Every runtime operation MUST emit an event. If it doesn't emit an event,
53
+ * it doesn't exist in the system. This is the fundamental invariant.
54
+ *
55
+ * These events enable: replay, debugging, billing, observability, and
56
+ * deterministic re-execution.
57
+ */
58
+ type ExecutionEvent = {
59
+ type: "node.started";
60
+ nodeId: IRNodeId;
61
+ executionId: string;
62
+ traceId: string;
63
+ threadId: string;
64
+ timestamp: number;
65
+ } | {
66
+ type: "node.completed";
67
+ nodeId: IRNodeId;
68
+ result: unknown;
69
+ executionId: string;
70
+ traceId: string;
71
+ threadId: string;
72
+ timestamp: number;
73
+ } | {
74
+ type: "primitive.invoked";
75
+ name: string;
76
+ params: unknown;
77
+ result: unknown;
78
+ executionId: string;
79
+ traceId: string;
80
+ threadId: string;
81
+ timestamp: number;
82
+ } | {
83
+ type: "action.run";
84
+ target: string;
85
+ input: unknown;
86
+ idempotencyKey?: string;
87
+ executionId: string;
88
+ traceId: string;
89
+ threadId: string;
90
+ timestamp: number;
91
+ } | {
92
+ type: "action.run.completed";
93
+ target: string;
94
+ result: unknown;
95
+ idempotencyKey?: string;
96
+ executionId: string;
97
+ traceId: string;
98
+ threadId: string;
99
+ timestamp: number;
100
+ } | {
101
+ type: "action.wait";
102
+ duration: string | number;
103
+ executionId: string;
104
+ traceId: string;
105
+ threadId: string;
106
+ timestamp: number;
107
+ } | {
108
+ type: "action.loop.start";
109
+ loopId: string;
110
+ executionId: string;
111
+ traceId: string;
112
+ threadId: string;
113
+ timestamp: number;
114
+ } | {
115
+ type: "action.loop.iteration";
116
+ loopId: string;
117
+ iteration: number;
118
+ executionId: string;
119
+ traceId: string;
120
+ threadId: string;
121
+ timestamp: number;
122
+ } | {
123
+ type: "action.loop.end";
124
+ loopId: string;
125
+ reason: string;
126
+ executionId: string;
127
+ traceId: string;
128
+ threadId: string;
129
+ timestamp: number;
130
+ } | {
131
+ type: "action.fetch";
132
+ url: string;
133
+ method: string;
134
+ status: number;
135
+ durationMs: number;
136
+ idempotencyKey?: string;
137
+ executionId: string;
138
+ traceId: string;
139
+ threadId: string;
140
+ timestamp: number;
141
+ } | {
142
+ type: "action.emit";
143
+ event: string;
144
+ payload: unknown;
145
+ executionId: string;
146
+ traceId: string;
147
+ threadId: string;
148
+ timestamp: number;
149
+ } | {
150
+ type: "action.schedule";
151
+ at: number;
152
+ payload: unknown;
153
+ executionId: string;
154
+ traceId: string;
155
+ threadId: string;
156
+ timestamp: number;
157
+ } | {
158
+ type: "state.write";
159
+ key: string;
160
+ value: unknown;
161
+ executionId: string;
162
+ traceId: string;
163
+ threadId: string;
164
+ timestamp: number;
165
+ } | {
166
+ type: "state.read";
167
+ key: string;
168
+ value: unknown;
169
+ executionId: string;
170
+ traceId: string;
171
+ threadId: string;
172
+ timestamp: number;
173
+ } | {
174
+ type: "action.ask";
175
+ executionId: string;
176
+ traceId: string;
177
+ threadId: string;
178
+ timestamp: number;
179
+ } | {
180
+ type: "action.approval";
181
+ executionId: string;
182
+ traceId: string;
183
+ threadId: string;
184
+ timestamp: number;
185
+ } | {
186
+ type: "action.call";
187
+ contract: string;
188
+ input: unknown;
189
+ executionId: string;
190
+ traceId: string;
191
+ threadId: string;
192
+ timestamp: number;
193
+ } | {
194
+ type: "execution.untracked";
195
+ source: UntrackedIOSource;
196
+ location?: string;
197
+ nodeId?: IRNodeId;
198
+ action?: string;
199
+ executionId: string;
200
+ traceId: string;
201
+ threadId: string;
202
+ timestamp: number;
203
+ } | {
204
+ type: "log";
205
+ level: "debug" | "info" | "warn" | "error";
206
+ msg: string;
207
+ data?: Record<string, unknown>;
208
+ executionId: string;
209
+ traceId: string;
210
+ threadId: string;
211
+ timestamp: number;
212
+ } | {
213
+ type: "error";
214
+ nodeId?: IRNodeId;
215
+ error: string;
216
+ executionId: string;
217
+ traceId: string;
218
+ threadId: string;
219
+ timestamp: number;
220
+ };
221
+ /**
222
+ * An external event that enters the reactor from the host adapter.
223
+ * Each event maps to an entry in the IR via `type` → `ir.entries[type]`.
224
+ */
225
+ interface RuntimeEvent {
226
+ /** Event name matching an IR entry key (e.g. "onMessage", "route:GET:/health"). */
227
+ type: string;
228
+ /** Arbitrary payload associated with the event. */
229
+ payload: unknown;
230
+ /** Opaque thread identifier. Adapter sets this from infrastructure (DO id, etc.). */
231
+ threadId?: string;
232
+ }
233
+ /**
234
+ * A task in the reactor's internal execution queue.
235
+ * Created when a node needs to be processed (entry traversal, handler execution, etc.).
236
+ */
237
+ interface ExecutionTask {
238
+ /** The IR node to process. */
239
+ nodeId: IRNodeId;
240
+ /** Context data passed to the handler. */
241
+ context: unknown;
242
+ /**
243
+ * Optional resolve callback for action.run intent pattern.
244
+ * When a handler calls `actions.run(step, input)`, the reactor creates a
245
+ * task with a resolve function. The handler's Promise awaits this resolve.
246
+ */
247
+ resolve?: (result: unknown) => void;
248
+ }
249
+ /**
250
+ * The runtime representation of a bundled handler module.
251
+ *
252
+ * Each handler is an isolated function that receives a {@link HandlerContext}
253
+ * (from `@kalphq/sdk`) and returns a result. The reactor executes these in a
254
+ * sandboxed context with intercepted primitives.
255
+ */
256
+ interface HandlerModule {
257
+ /** The handler's entry function. */
258
+ default: (context: unknown, input?: unknown) => Promise<unknown>;
259
+ }
260
+
261
+ /**
262
+ * Adapter interfaces for the Kalp v2 Orchestration Reactor.
263
+ *
264
+ * These contracts decouple the runtime core from any specific infrastructure.
265
+ * The reactor never touches storage, scheduling, or transport directly —
266
+ * it always goes through these interfaces.
267
+ *
268
+ * Implementations:
269
+ * - Cloudflare DO adapter (DurableObjectStorage, Alarms, fetch)
270
+ * - InMemory adapter (Maps, timeouts) — local dev / tests
271
+ *
272
+ * @module
273
+ */
274
+
275
+ /**
276
+ * KV-like state store for agent runtime data.
277
+ *
278
+ * Supports get/set/delete and atomic transactions. Co-located with the
279
+ * actor — adapters decide backing store (DO storage, Redis, in-memory).
280
+ */
281
+ interface StateStore {
282
+ /**
283
+ * Reads a value from state.
284
+ *
285
+ * @param key - The state key.
286
+ * @returns The stored value, or `null` if not found.
287
+ */
288
+ get(key: string): Promise<unknown>;
289
+ /**
290
+ * Writes a value to state.
291
+ *
292
+ * @param key - The state key.
293
+ * @param value - The value to store (must be JSON-serializable).
294
+ */
295
+ set(key: string, value: unknown): Promise<void>;
296
+ /**
297
+ * Deletes a key from state.
298
+ *
299
+ * @param key - The state key to delete.
300
+ */
301
+ delete(key: string): Promise<void>;
302
+ /**
303
+ * Atomically increments a numeric value.
304
+ *
305
+ * @param key - The key to increment.
306
+ * @param amount - The amount to add.
307
+ * @returns The new value.
308
+ */
309
+ increment(key: string, amount: number): Promise<number>;
310
+ /**
311
+ * Executes a function within an atomic transaction.
312
+ *
313
+ * @param fn - The transactional function receiving a scoped store.
314
+ * @returns The transaction's return value.
315
+ */
316
+ transaction<T>(fn: (tx: StateStore) => Promise<T>): Promise<T>;
317
+ }
318
+ /**
319
+ * Append-only execution event log.
320
+ *
321
+ * All structured events flow through this store. It is the system's source
322
+ * of truth for replay, debugging, and observability.
323
+ */
324
+ interface EventStore {
325
+ /**
326
+ * Appends a structured event to the execution log.
327
+ * Events are append-only and ordered by insertion time.
328
+ *
329
+ * @param event - The execution event to persist.
330
+ */
331
+ append(event: ExecutionEvent): Promise<void>;
332
+ /**
333
+ * Loads all events from the execution log, ordered by insertion.
334
+ * Used for replay, debugging, and rehydration.
335
+ *
336
+ * @returns An ordered array of all persisted execution events.
337
+ */
338
+ loadAll(): Promise<ExecutionEvent[]>;
339
+ /**
340
+ * Loads events filtered by thread ID.
341
+ *
342
+ * @param threadId - The thread to filter by.
343
+ * @returns Events belonging to the specified thread.
344
+ */
345
+ loadByThread(threadId: string): Promise<ExecutionEvent[]>;
346
+ /**
347
+ * Loads events filtered by trace ID.
348
+ *
349
+ * @param traceId - The trace to filter by.
350
+ * @returns Events belonging to the specified trace.
351
+ */
352
+ loadByTrace(traceId: string): Promise<ExecutionEvent[]>;
353
+ }
354
+ /**
355
+ * KV store with TTL for idempotency deduplication.
356
+ *
357
+ * Actor-scoped (not global). Stored via the adapter's backing store.
358
+ * Zero race conditions since the actor is single-threaded.
359
+ */
360
+ interface IdempotencyStore {
361
+ /**
362
+ * Retrieves a cached result by idempotency key.
363
+ *
364
+ * @param key - The composite idempotency key.
365
+ * @returns The cached result, or `null` if not found or expired.
366
+ */
367
+ get(key: string): Promise<unknown | null>;
368
+ /**
369
+ * Stores a result with an optional TTL.
370
+ *
371
+ * @param key - The composite idempotency key.
372
+ * @param result - The result to cache.
373
+ * @param opts - Optional settings (TTL in milliseconds).
374
+ */
375
+ set(key: string, result: unknown, opts?: {
376
+ ttlMs?: number;
377
+ }): Promise<void>;
378
+ }
379
+ /**
380
+ * Thread metadata store.
381
+ *
382
+ * Stores and retrieves metadata associated with a thread (actor instance).
383
+ */
384
+ interface ThreadStore {
385
+ /**
386
+ * Retrieves metadata for a thread.
387
+ *
388
+ * @param threadId - The thread identifier.
389
+ * @returns The thread metadata, or `null` if not set.
390
+ */
391
+ getMeta(threadId: string): Promise<Record<string, unknown> | null>;
392
+ /**
393
+ * Stores metadata for a thread.
394
+ *
395
+ * @param threadId - The thread identifier.
396
+ * @param meta - The metadata to store.
397
+ */
398
+ setMeta(threadId: string, meta: Record<string, unknown>): Promise<void>;
399
+ }
400
+ /**
401
+ * Composite persistence adapter decomposed into specialized sub-stores.
402
+ *
403
+ * This prevents a single monolithic adapter from hiding 4 different
404
+ * storage patterns behind one interface. Each sub-store has clear semantics.
405
+ */
406
+ interface PersistenceAdapter {
407
+ /** KV-like state store (get/set/delete/transaction). */
408
+ state: StateStore;
409
+ /** Append-only execution event log. */
410
+ events: EventStore;
411
+ /** KV with TTL for idempotency deduplication. */
412
+ idempotency: IdempotencyStore;
413
+ /** Thread metadata store. */
414
+ threads: ThreadStore;
415
+ }
416
+ /**
417
+ * Scheduler adapter for deferred execution (alarms, timers).
418
+ *
419
+ * Used by `actions.wait`, `actions.loop`, and `actions.schedule` for future
420
+ * wake-ups. The adapter is responsible for persisting the alarm and re-entering
421
+ * the reactor when it fires.
422
+ *
423
+ * Adapters may have limitations (e.g. CF: 1 alarm per DO). Core handles
424
+ * multi-schedule queuing in {@link StateStore}; adapter fires one at a time.
425
+ *
426
+ * **Best-effort timing** — scheduled events are approximate, not guaranteed
427
+ * to fire at the exact requested time.
428
+ */
429
+ interface SchedulerAdapter {
430
+ /**
431
+ * Schedules a wake-up at the given timestamp (ms since epoch).
432
+ * If an alarm already exists, it should be replaced.
433
+ *
434
+ * @param at - Unix timestamp in milliseconds for the wake-up.
435
+ */
436
+ schedule(at: number): Promise<void>;
437
+ /**
438
+ * Cancels any pending scheduled wake-up.
439
+ */
440
+ cancel(): Promise<void>;
441
+ }
442
+ /**
443
+ * Transport adapter for sending responses back to the caller.
444
+ *
445
+ * Used when the reactor needs to push data to a connected client
446
+ * (e.g. WebSocket message, streaming response).
447
+ */
448
+ interface TransportAdapter {
449
+ /**
450
+ * Sends a response payload to the connected client.
451
+ *
452
+ * @param response - The data to send (will be JSON-serialized).
453
+ */
454
+ send(response: unknown): Promise<void>;
455
+ }
456
+ /**
457
+ * Adapter for cross-thread (cross-actor) messaging.
458
+ *
459
+ * Core never uses HTTP semantics directly. The adapter maps to the
460
+ * appropriate transport (CF: fetch to DO, Node: IPC, tests: direct call).
461
+ */
462
+ interface CrossThreadAdapter {
463
+ /**
464
+ * Sends an event to another thread (actor).
465
+ *
466
+ * @param targetThreadId - The target thread's opaque identifier.
467
+ * @param event - The event name.
468
+ * @param payload - The event payload.
469
+ */
470
+ send(targetThreadId: string, event: string, payload: unknown): Promise<void>;
471
+ }
472
+
473
+ /**
474
+ * Structured execution log for the Kalp v2 Orchestration Reactor.
475
+ *
476
+ * The execution log is the system's source of truth. Every runtime operation
477
+ * emits a structured event that is persisted via the {@link PersistenceAdapter}.
478
+ * This enables replay, time-travel debugging, billing, and observability.
479
+ *
480
+ * Rule: **If it doesn't emit an event, it doesn't exist.**
481
+ *
482
+ * @module
483
+ */
484
+
485
+ /**
486
+ * Append-only structured event log backed by an {@link EventStore}.
487
+ *
488
+ * All reactor operations flow through this class. It provides a unified
489
+ * interface for emitting and loading events regardless of the underlying
490
+ * storage mechanism.
491
+ */
492
+ declare class ExecutionLog {
493
+ private eventStore;
494
+ /** In-memory buffer of events emitted during the current processing cycle. */
495
+ private buffer;
496
+ /**
497
+ * Creates a new execution log backed by the given event store.
498
+ *
499
+ * @param eventStore - The store used to persist and load events.
500
+ */
501
+ constructor(eventStore: EventStore);
502
+ /**
503
+ * Emits a structured execution event.
504
+ *
505
+ * The event is immediately persisted via the adapter and buffered in memory
506
+ * for the current processing cycle.
507
+ *
508
+ * @param event - The execution event to emit.
509
+ */
510
+ emit(event: ExecutionEvent): Promise<void>;
511
+ /**
512
+ * Loads all previously persisted events from the adapter.
513
+ *
514
+ * Used for replay, rehydration, and debugging.
515
+ *
516
+ * @returns An ordered array of all persisted execution events.
517
+ */
518
+ load(): Promise<ExecutionEvent[]>;
519
+ /**
520
+ * Returns events emitted during the current processing cycle (in-memory only).
521
+ *
522
+ * @returns The in-memory event buffer.
523
+ */
524
+ getBuffer(): ReadonlyArray<ExecutionEvent>;
525
+ /**
526
+ * Clears the in-memory buffer. Called between processing cycles.
527
+ */
528
+ clearBuffer(): void;
529
+ }
530
+
531
+ /**
532
+ * AI primitive — intercepted LLM calls with event emission.
533
+ *
534
+ * Every generate/stream/classify call is logged to the execution log.
535
+ * The actual LLM provider call is delegated to the injected implementation.
536
+ *
537
+ * @module
538
+ */
539
+
540
+ /**
541
+ * A concrete AI provider implementation that performs the actual LLM calls.
542
+ * This is injected by the host adapter (e.g. Cloudflare AI, OpenAI fetch, etc.).
543
+ */
544
+ type AIProvider = KalpAI;
545
+ /**
546
+ * Creates an intercepted AI primitive that wraps every call with event emission.
547
+ *
548
+ * The returned object matches the SDK's {@link KalpAI} interface exactly.
549
+ * Internally, each method:
550
+ * 1. Emits a `primitive.invoked` event before calling the provider.
551
+ * 2. Calls the actual provider implementation.
552
+ * 3. Emits a `primitive.invoked` event with the result.
553
+ *
554
+ * @param provider - The concrete AI provider implementation.
555
+ * @param log - The execution log for event emission.
556
+ * @param execCtx - Optional execution context for event identity.
557
+ * @returns An intercepted {@link KalpAI} matching the SDK interface.
558
+ */
559
+ declare function createAIPrimitive(provider: AIProvider, log: ExecutionLog, execCtx?: ExecutionContext): KalpAI;
560
+
561
+ /**
562
+ * Actions primitive — intercepted orchestration intents with event emission.
563
+ *
564
+ * This is the core of the event-sourced runtime model. Every action is an
565
+ * **intent**, not a direct execution. The handler emits the intent, and the
566
+ * reactor resolves it.
567
+ *
568
+ * - `actions.run(step, input)` → emits `action.run`, suspends, reactor enqueues handler, resolves with result
569
+ * - `actions.wait(duration)` → emits `action.wait`, schedules alarm, terminates execution
570
+ * - `actions.loop(body)` → emits `action.loop.start`, reactor drives iterations
571
+ * - `actions.fetch(url, init)` → emits `action.fetch`, delegates to http primitive
572
+ *
573
+ * @module
574
+ */
575
+
576
+ /** Callback to dispatch a handler task into the reactor queue. */
577
+ type DispatchAction = (moduleRef: string, input: unknown) => Promise<unknown>;
578
+ /**
579
+ * Creates the intercepted actions primitive for handler context.
580
+ *
581
+ * Each method emits structured events and interacts with the reactor
582
+ * via the `dispatch` callback (for run) and the `scheduler` adapter
583
+ * (for wait).
584
+ *
585
+ * @param log - The execution log for event emission.
586
+ * @param scheduler - The scheduler adapter for deferred execution.
587
+ * @param dispatch - Callback to enqueue a handler task in the reactor.
588
+ * @param execCtx - Optional execution context for event identity.
589
+ * @returns A {@link KalpActions} matching the SDK interface exactly.
590
+ */
591
+ declare function createActionsPrimitive(log: ExecutionLog, scheduler: SchedulerAdapter, dispatch: DispatchAction, execCtx?: ExecutionContext): KalpActions;
592
+
593
+ /**
594
+ * Handler context builder for the Kalp v2 Orchestration Reactor.
595
+ *
596
+ * Assembles the {@link HandlerContext} that is passed to every handler function.
597
+ * Each primitive in the context is intercepted — all operations emit structured
598
+ * events to the execution log.
599
+ *
600
+ * The context shape matches the SDK's `HandlerContext` interface exactly,
601
+ * preserving DX:
602
+ *
603
+ * ```ts
604
+ * const { fetch, loop, run, wait } = actions;
605
+ * const { delete: deleteKey, get, put } = storage;
606
+ * const { classify, generate, stream } = ai;
607
+ * ```
608
+ *
609
+ * @module
610
+ */
611
+
612
+ /**
613
+ * External provider implementations injected by the host adapter.
614
+ * These are NOT part of the reactor core — they come from infrastructure.
615
+ */
616
+ interface RuntimeProviders {
617
+ /** AI provider implementation (e.g. OpenAI, Anthropic, Cloudflare AI). */
618
+ ai: AIProvider;
619
+ /** Authentication context for the current request. */
620
+ auth: KalpAuth;
621
+ /** Memory (conversation history) provider. */
622
+ memory: KalpMemory;
623
+ /** Secrets vault provider. */
624
+ vault: KalpVault;
625
+ }
626
+ /**
627
+ * Builds a {@link HandlerContext} with fully intercepted primitives.
628
+ *
629
+ * Every operation on the returned context (ai.generate, storage.put,
630
+ * actions.run, etc.) is intercepted to emit structured events to the
631
+ * execution log. The handler never touches infrastructure directly.
632
+ *
633
+ * @param log - The execution log for event emission.
634
+ * @param stateStore - The state sub-store for KV operations.
635
+ * @param scheduler - The scheduler adapter for deferred execution.
636
+ * @param dispatch - Callback to enqueue handler tasks in the reactor.
637
+ * @param providers - External providers (ai, auth, memory, vault).
638
+ * @param execCtx - Optional execution context for event identity.
639
+ * @param agentConfig - Optional agent configuration for metadata.
640
+ * @returns A complete {@link HandlerContext} matching the SDK interface.
641
+ */
642
+ declare function buildHandlerContext(log: ExecutionLog, stateStore: StateStore, scheduler: SchedulerAdapter, dispatch: DispatchAction, providers: RuntimeProviders, execCtx?: ExecutionContext, agentConfig?: {
643
+ name: string;
644
+ systemPrompt: string;
645
+ metadata?: Record<string, unknown>;
646
+ }): HandlerContext;
647
+
648
+ /**
649
+ * Orchestration Reactor — the Kalp v2 event-sourced execution engine.
650
+ *
651
+ * The reactor is **infrastructure-agnostic**. It receives events, processes
652
+ * tasks from an internal queue, and delegates all IO to adapter interfaces.
653
+ * When the queue is empty, control returns to the host adapter (Durable Object,
654
+ * Node process, test harness, etc.) which waits for the next external event.
655
+ *
656
+ * Key invariants:
657
+ * - The reactor never imports Cloudflare, Node, or any platform API.
658
+ * - Every operation emits structured events to the {@link ExecutionLog}.
659
+ * - Handler execution is sandboxed via intercepted primitives.
660
+ * - `actions.run` is an intent + suspend, not a direct call.
661
+ *
662
+ * @module
663
+ */
664
+
665
+ /**
666
+ * The Kalp v2 Orchestration Reactor.
667
+ *
668
+ * Processes external events by looking up the corresponding IR entry,
669
+ * executing the handler chain, and emitting structured events for every
670
+ * operation. The reactor is portable — it works in Durable Objects, Node,
671
+ * or any environment that provides the adapter interfaces.
672
+ */
673
+ declare class OrchestrationReactor {
674
+ /** The execution log (single source of truth). */
675
+ readonly log: ExecutionLog;
676
+ /** The IR graph (structural index only). */
677
+ readonly ir: IRGraph;
678
+ /** Internal task queue. */
679
+ private queue;
680
+ /** Bundled handler modules keyed by moduleRef. */
681
+ private bundles;
682
+ /** Composite persistence adapter (state, events, idempotency, threads). */
683
+ private persistence;
684
+ /** Scheduler adapter (alarms). */
685
+ private scheduler;
686
+ /** External providers (ai, auth, memory, vault). */
687
+ private providers;
688
+ /** Result of the last completed handler. */
689
+ private lastResult;
690
+ /** Opaque thread identifier (set by adapter via RuntimeEvent.threadId). */
691
+ private threadId;
692
+ /**
693
+ * Creates a new reactor instance.
694
+ *
695
+ * @param ir - The compiled IR graph.
696
+ * @param bundles - Map from moduleRef to bundled handler module.
697
+ * @param persistence - Persistence adapter for state and event log.
698
+ * @param scheduler - Scheduler adapter for deferred wake-ups.
699
+ * @param providers - External providers for ai, auth, memory, vault.
700
+ */
701
+ constructor(ir: IRGraph, bundles: Map<string, HandlerModule>, persistence: PersistenceAdapter, scheduler: SchedulerAdapter, providers: RuntimeProviders);
702
+ /**
703
+ * Handles an external event by resolving the IR entry and processing
704
+ * the handler chain until the queue is empty.
705
+ *
706
+ * @param event - The external runtime event.
707
+ * @returns The result of the last completed handler.
708
+ * @throws If no entry exists for the event type.
709
+ */
710
+ handleEvent(event: RuntimeEvent): Promise<unknown>;
711
+ /**
712
+ * Drains the task queue. Called internally after handleEvent and recursively
713
+ * after actions.run dispatches. When the queue is empty, control returns to
714
+ * the host adapter.
715
+ */
716
+ processUntilIdle(): Promise<void>;
717
+ /**
718
+ * Processes a single task from the queue.
719
+ *
720
+ * - **Entry nodes**: traverse sequential edges to find the handler.
721
+ * - **Handler nodes**: build context, execute handler, emit events.
722
+ */
723
+ private processTask;
724
+ /**
725
+ * Enqueues all successor nodes connected by outgoing edges from the given node.
726
+ *
727
+ * @param nodeId - The source node ID.
728
+ * @param context - The context to pass to successor tasks.
729
+ */
730
+ private enqueueSuccessors;
731
+ /**
732
+ * Creates a dispatch function for actions.run.
733
+ *
734
+ * When a handler calls `actions.run(step, input)`, this function:
735
+ * 1. Looks up the handler node by moduleRef in the IR.
736
+ * 2. Creates a task with a resolve callback.
737
+ * 3. Returns a Promise that resolves when the task completes.
738
+ */
739
+ private createDispatch;
740
+ }
741
+
742
+ export { type AIProvider as A, type CrossThreadAdapter as C, type DispatchAction as D, ExecutionLog as E, type HandlerModule as H, type IdempotencyStore as I, OrchestrationReactor as O, type PersistenceAdapter as P, type RuntimeProviders as R, type SchedulerAdapter as S, type ThreadStore as T, type UntrackedIOSource as U, type StateStore as a, type ExecutionContext as b, type EventStore as c, type ExecutionEvent as d, type ExecutionTask as e, type RuntimeEvent as f, type TransportAdapter as g, buildHandlerContext as h, createAIPrimitive as i, createActionsPrimitive as j };