effect-durable-agent-cloudflare 0.1.0-alpha.4

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Advait Shinde
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # effect-durable-agent-cloudflare
2
+
3
+ Cloudflare Durable Objects host for [`effect-durable-agent`](../../README.md).
4
+
5
+ ```sh
6
+ pnpm add effect-durable-agent@alpha effect-durable-agent-cloudflare@alpha
7
+ ```
8
+
9
+ ```ts
10
+ import { EDASessionDurableObject } from "effect-durable-agent-cloudflare";
11
+
12
+ export class AgentSession extends EDASessionDurableObject<Env> {
13
+ constructor(ctx: DurableObjectState, env: Env) {
14
+ super(ctx, env, makeAgentOptions(env));
15
+ }
16
+ }
17
+ ```
18
+
19
+ The host maps one session to one SQLite-backed Durable Object and owns alarms,
20
+ hibernatable WebSockets, RPC decoding, recovery, and sink checkpoints. Register
21
+ only the concrete application subclass in `wrangler.jsonc`.
22
+
23
+ Durable Object RPC uses structured clone. Encode Schema class instances before
24
+ passing commands or batches across the Worker-to-object boundary with
25
+ `encodeEdaRpcCommand` or `encodeEdaRpcSubmittables`.
26
+
27
+ The core and host packages are published in lockstep and must use the same
28
+ version.
@@ -0,0 +1,27 @@
1
+ //#region \0rolldown/runtime.js
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __exportAll = (all, no_symbols) => {
7
+ let target = {};
8
+ for (var name in all) __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
13
+ return target;
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
17
+ key = keys[i];
18
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
19
+ get: ((k) => from[k]).bind(null, key),
20
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
21
+ });
22
+ }
23
+ return to;
24
+ };
25
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
26
+ //#endregion
27
+ export { __reExport as n, __exportAll as t };
@@ -0,0 +1,194 @@
1
+ import { i as decodeEdaRpcSubmittables, n as decodeEdaRpcCommand, t as EDASessionDurableObjectHost } from "./durable-object-runtime-LgOJbsVm.js";
2
+ import { DurableObject } from "cloudflare:workers";
3
+ import * as Effect from "effect/Effect";
4
+ import * as Schema from "effect/Schema";
5
+ import { DurableEventEnvelope, EDADurableEvent, effectDurableAgentNamespace } from "effect-durable-agent/types/events";
6
+ import { EDACommand } from "effect-durable-agent/types/commands";
7
+ import { CommandId, SequenceNumber, SessionId } from "effect-durable-agent/types/core";
8
+ import { EDATraceMetadata, makeEDATraceMetadataFromParent, makeRootEDATraceMetadata, parseEDATraceparent } from "effect-durable-agent/types/tracing";
9
+ //#region src/rpc-codec.ts
10
+ /** Encode one durable event into a structured-clone-safe Durable Object RPC value. */
11
+ const encodeEdaRpcDurableEvent = (event) => {
12
+ const encoded = event.namespace === effectDurableAgentNamespace ? Schema.encodeSync(EDADurableEvent)(Schema.decodeUnknownSync(EDADurableEvent)(event)) : Schema.encodeSync(DurableEventEnvelope)(event);
13
+ return Schema.decodeUnknownSync(DurableEventEnvelope)(encoded);
14
+ };
15
+ //#endregion
16
+ //#region src/durable-object.ts
17
+ /** Resolve a concrete EDA session Durable Object binding by domain session id. */
18
+ const getEDASessionDurableObjectByName = (namespace, sessionId) => namespace.getByName(sessionId);
19
+ /**
20
+ * Base class for raw Cloudflare Durable Object hosts of one EDA session.
21
+ *
22
+ * Concrete products should extend this class, pass provider/tool layers from
23
+ * their own constructor, and register only that subclass in Wrangler. The base
24
+ * class is deliberately not exported from `workers/app.ts` and owns no binding
25
+ * name or routing convention.
26
+ */
27
+ var EDASessionDurableObject = class extends DurableObject {
28
+ #host;
29
+ constructor(ctx, env, options) {
30
+ super(ctx, env);
31
+ const storage = toEDASessionStorage(this.ctx.storage);
32
+ this.#host = new EDASessionDurableObjectHost({
33
+ ...options,
34
+ background: this.ctx,
35
+ storage
36
+ });
37
+ this.ctx.blockConcurrencyWhile(async () => {
38
+ await Effect.runPromise(EDASessionDurableObjectHost.migrate(storage));
39
+ });
40
+ }
41
+ async fetch(request) {
42
+ if (request.headers.get("Upgrade")?.toLowerCase() !== "websocket") return new Response("Expected WebSocket upgrade.", { status: 426 });
43
+ const url = new URL(request.url);
44
+ const sessionIdRaw = url.searchParams.get("sessionId");
45
+ if (sessionIdRaw === null) return new Response("Missing sessionId.", { status: 400 });
46
+ const afterSeq = Number(url.searchParams.get("afterSeq") ?? "0");
47
+ if (!Number.isInteger(afterSeq) || afterSeq < 0) return new Response("Invalid afterSeq.", { status: 400 });
48
+ const pair = new WebSocketPair();
49
+ const client = pair[0];
50
+ const server = pair[1];
51
+ this.ctx.acceptWebSocket(server);
52
+ await this.#host.acceptEventWebSocket({
53
+ afterSeq: SequenceNumber.make(afterSeq),
54
+ sessionId: this.parseSessionId(sessionIdRaw),
55
+ trace: traceMetadataFromRequest(request),
56
+ webSocket: server
57
+ });
58
+ return new Response(null, {
59
+ status: 101,
60
+ webSocket: client
61
+ });
62
+ }
63
+ async submit(input) {
64
+ await this.restoreAcceptedEventWebSockets();
65
+ return encodeEdaRpcCommittedDurableEvent(await this.#host.submit({
66
+ command: await decodeCommand(input.command),
67
+ sessionId: this.parseSessionId(input.sessionId),
68
+ trace: decodeTraceMetadata(input.trace)
69
+ }));
70
+ }
71
+ async submitBatch(input) {
72
+ await this.restoreAcceptedEventWebSockets();
73
+ return (await this.#host.submitBatch({
74
+ items: await decodeSubmittables(input.items),
75
+ sessionId: this.parseSessionId(input.sessionId),
76
+ trace: decodeTraceMetadata(input.trace)
77
+ })).map(encodeEdaRpcCommittedDurableEvent);
78
+ }
79
+ async submitAndBlock(input) {
80
+ await this.restoreAcceptedEventWebSockets();
81
+ return encodeEdaRpcCommittedDurableEvent(await this.#host.submitAndBlock({
82
+ command: await decodeCommand(input.command),
83
+ sessionId: this.parseSessionId(input.sessionId),
84
+ trace: decodeTraceMetadata(input.trace)
85
+ }));
86
+ }
87
+ async blockOnCommand(input) {
88
+ await this.restoreAcceptedEventWebSockets();
89
+ return encodeEdaRpcCommittedDurableEvent(await this.#host.blockOnCommand({
90
+ ...input.afterSeq === void 0 ? {} : { afterSeq: SequenceNumber.make(input.afterSeq) },
91
+ commandId: CommandId.make(input.commandId),
92
+ sessionId: this.parseSessionId(input.sessionId),
93
+ trace: decodeTraceMetadata(input.trace)
94
+ }));
95
+ }
96
+ async snapshot(input) {
97
+ await this.restoreAcceptedEventWebSockets();
98
+ return encodeEdaRpcSessionSnapshot(await this.#host.snapshot({
99
+ sessionId: this.parseSessionId(input.sessionId),
100
+ trace: decodeTraceMetadata(input.trace)
101
+ }));
102
+ }
103
+ async messages(input) {
104
+ await this.restoreAcceptedEventWebSockets();
105
+ return await this.#host.messages({
106
+ sessionId: this.parseSessionId(input.sessionId),
107
+ trace: decodeTraceMetadata(input.trace)
108
+ });
109
+ }
110
+ async webSocketMessage(webSocket, message) {
111
+ await this.#host.webSocketMessage(webSocket, message);
112
+ }
113
+ async webSocketClose(webSocket, _code, _reason, _wasClean) {
114
+ await this.#host.webSocketClose(webSocket);
115
+ }
116
+ async webSocketError(webSocket, _error) {
117
+ await this.#host.webSocketError(webSocket);
118
+ }
119
+ async destroySession(input) {
120
+ await this.#host.destroy({
121
+ sessionId: this.parseSessionId(input.sessionId),
122
+ trace: decodeTraceMetadata(input.trace)
123
+ });
124
+ await this.ctx.storage.deleteAlarm();
125
+ await this.ctx.storage.deleteAll();
126
+ }
127
+ async alarm() {
128
+ await this.restoreAcceptedEventWebSockets();
129
+ const sessionId = this.sessionIdFromObjectName();
130
+ await this.#host.alarm(sessionId === void 0 ? void 0 : {
131
+ sessionId,
132
+ trace: makeRootEDATraceMetadata()
133
+ });
134
+ }
135
+ parseSessionId(input) {
136
+ const sessionId = SessionId.make(input);
137
+ const objectName = this.ctx.id.name;
138
+ if (objectName !== void 0 && objectName !== sessionId) throw new Error(`EDA Durable Object name ${objectName} cannot serve session ${sessionId}`);
139
+ return sessionId;
140
+ }
141
+ sessionIdFromObjectName() {
142
+ return this.ctx.id.name === void 0 ? void 0 : SessionId.make(this.ctx.id.name);
143
+ }
144
+ async restoreAcceptedEventWebSockets() {
145
+ await this.#host.restoreEventWebSockets(this.ctx.getWebSockets());
146
+ }
147
+ };
148
+ const toEDASessionStorage = (storage) => {
149
+ return storage;
150
+ };
151
+ const decodeTraceMetadata = (input) => Schema.decodeUnknownSync(EDATraceMetadata)(input);
152
+ const traceMetadataFromRequest = (request) => {
153
+ const parent = parseEDATraceparent(request.headers.get("traceparent"), request.headers.get("tracestate"));
154
+ return parent === null ? makeRootEDATraceMetadata() : makeEDATraceMetadataFromParent(parent);
155
+ };
156
+ /** Convenience config constructor for subclasses that need only provider/model ids. */
157
+ const edaRuntimeConfig = (input) => ({
158
+ modelSelection: {
159
+ modelId: input.modelId,
160
+ provider: input.provider
161
+ },
162
+ ...input.maxToolCallsPerRun === void 0 ? {} : { maxToolCallsPerRun: input.maxToolCallsPerRun },
163
+ ...input.systemPrompt === void 0 ? {} : { systemPrompt: input.systemPrompt }
164
+ });
165
+ /** Encode committed events into structured-clone-safe Durable Object RPC payloads. */
166
+ const encodeEdaRpcCommittedDurableEvent = (event) => ({
167
+ position: event.position,
168
+ event: encodeEdaRpcDurableEvent(event.event)
169
+ });
170
+ /** Encode runtime snapshots into structured-clone-safe Durable Object RPC payloads. */
171
+ const encodeEdaRpcSessionSnapshot = (snapshot) => ({
172
+ ...snapshot,
173
+ reducerStates: new Map(snapshot.reducerStates),
174
+ state: {
175
+ ...snapshot.state,
176
+ commands: new Map(Array.from(snapshot.state.commands, ([commandId, record]) => [commandId, encodeCommandCarrierForRpc(record)])),
177
+ commandQueues: {
178
+ ...snapshot.state.commandQueues,
179
+ activeControlCommands: snapshot.state.commandQueues.activeControlCommands.map(encodeCommandCarrierForRpc),
180
+ pendingCommands: snapshot.state.commandQueues.pendingCommands.map(encodeCommandCarrierForRpc),
181
+ queuedCommands: snapshot.state.commandQueues.queuedCommands.map(encodeCommandCarrierForRpc)
182
+ }
183
+ }
184
+ });
185
+ const encodeCommandCarrierForRpc = (value) => value.command === void 0 ? value : {
186
+ ...value,
187
+ command: Schema.encodeSync(EDACommand)(value.command)
188
+ };
189
+ const decodeCommand = (input) => Effect.runPromise(decodeEdaRpcCommand(input));
190
+ const decodeSubmittables = (input) => Effect.runPromise(decodeEdaRpcSubmittables(input));
191
+ //#endregion
192
+ export { getEDASessionDurableObjectByName as a, encodeEdaRpcSessionSnapshot as i, edaRuntimeConfig as n, encodeEdaRpcCommittedDurableEvent as r, EDASessionDurableObject as t };
193
+
194
+ //# sourceMappingURL=durable-object-CjWWNyek.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"durable-object-CjWWNyek.js","names":["#host"],"sources":["../src/rpc-codec.ts","../src/durable-object.ts"],"sourcesContent":["import * as Schema from \"effect/Schema\";\n\nimport {\n DurableEventEnvelope,\n EDADurableEvent,\n effectDurableAgentNamespace,\n} from \"effect-durable-agent/types/events\";\n\n/** Encode one durable event into a structured-clone-safe Durable Object RPC value. */\nexport const encodeEdaRpcDurableEvent = (event: DurableEventEnvelope): DurableEventEnvelope => {\n const encoded =\n event.namespace === effectDurableAgentNamespace\n ? Schema.encodeSync(EDADurableEvent)(Schema.decodeUnknownSync(EDADurableEvent)(event))\n : Schema.encodeSync(DurableEventEnvelope)(event);\n return Schema.decodeUnknownSync(DurableEventEnvelope)(encoded);\n};\n","import { DurableObject } from \"cloudflare:workers\";\nimport * as Effect from \"effect/Effect\";\nimport * as Schema from \"effect/Schema\";\n\nimport type { DurableTranscriptMessage } from \"effect-durable-agent/domain/message-transcript\";\nimport { encodeEdaRpcDurableEvent } from \"./rpc-codec\";\nimport type { EDASessionSnapshot } from \"effect-durable-agent/services/session-query\";\nimport type { CommittedDurableEvent as CommittedDurableEventValue } from \"effect-durable-agent/services/session-store\";\nimport type {\n CommittedCommandTerminalEvent,\n EDARuntimeConfig,\n} from \"effect-durable-agent/services/runtime\";\nimport {\n EDACommand,\n type EDACommand as EDACommandValue,\n} from \"effect-durable-agent/types/commands\";\nimport type { EDASubmittable } from \"effect-durable-agent/services/session-state\";\nimport { CommandId, SequenceNumber, SessionId } from \"effect-durable-agent/types/core\";\nimport {\n EDATraceMetadata,\n makeEDATraceMetadataFromParent,\n makeRootEDATraceMetadata,\n parseEDATraceparent,\n} from \"effect-durable-agent/types/tracing\";\nimport {\n decodeEdaRpcCommand,\n decodeEdaRpcSubmittables,\n EDASessionDurableObjectHost,\n type EDASessionDurableObjectHostOptions,\n type EDASessionDurableObjectStorage,\n} from \"./durable-object-runtime\";\n\n/** Raw RPC shape decoded before admitting one session command. */\nexport interface EDASessionCommandRpcInput {\n readonly command: unknown;\n readonly sessionId: string;\n readonly trace: unknown;\n}\n\n/** Raw RPC shape decoded before admitting a durable command/app-event batch. */\nexport interface EDASessionSubmitBatchRpcInput {\n readonly items: ReadonlyArray<unknown>;\n readonly sessionId: string;\n readonly trace: unknown;\n}\n\n/** Raw RPC shape for read/destroy operations that only need a session id. */\nexport interface EDASessionScopedRpcInput {\n readonly sessionId: string;\n readonly trace: unknown;\n}\n\n/** Raw RPC shape for WebSocket event-stream upgrades with a resume cursor. */\nexport interface EDASessionEventsRpcInput {\n readonly afterSeq?: number;\n readonly sessionId: string;\n readonly trace: unknown;\n}\n\n/** Raw RPC shape decoded before blocking on one command terminal event. */\nexport interface EDASessionBlockOnCommandRpcInput {\n readonly afterSeq?: number;\n readonly commandId: string;\n readonly sessionId: string;\n readonly trace: unknown;\n}\n\n/** Constructor options for concrete app subclasses of the EDA Durable Object base. */\nexport type EDASessionDurableObjectOptions = Omit<\n EDASessionDurableObjectHostOptions,\n \"background\" | \"storage\"\n>;\n\n/** Resolve a concrete EDA session Durable Object binding by domain session id. */\nexport const getEDASessionDurableObjectByName = <T extends EDASessionDurableObject<object>>(\n namespace: DurableObjectNamespace<T>,\n sessionId: string,\n): DurableObjectStub<T> => namespace.getByName(sessionId);\n\n/**\n * Base class for raw Cloudflare Durable Object hosts of one EDA session.\n *\n * Concrete products should extend this class, pass provider/tool layers from\n * their own constructor, and register only that subclass in Wrangler. The base\n * class is deliberately not exported from `workers/app.ts` and owns no binding\n * name or routing convention.\n */\nexport abstract class EDASessionDurableObject<\n EnvType extends object = object,\n> extends DurableObject<EnvType> {\n readonly #host: EDASessionDurableObjectHost;\n\n protected constructor(\n ctx: DurableObjectState,\n env: EnvType,\n options: EDASessionDurableObjectOptions,\n ) {\n super(ctx, env);\n const storage = toEDASessionStorage(this.ctx.storage);\n this.#host = new EDASessionDurableObjectHost({\n ...options,\n background: this.ctx,\n storage,\n });\n\n this.ctx.blockConcurrencyWhile(async () => {\n await Effect.runPromise(EDASessionDurableObjectHost.migrate(storage));\n });\n }\n\n async fetch(request: Request): Promise<Response> {\n const upgrade = request.headers.get(\"Upgrade\");\n if (upgrade?.toLowerCase() !== \"websocket\") {\n return new Response(\"Expected WebSocket upgrade.\", { status: 426 });\n }\n\n const url = new URL(request.url);\n const sessionIdRaw = url.searchParams.get(\"sessionId\");\n if (sessionIdRaw === null) {\n return new Response(\"Missing sessionId.\", { status: 400 });\n }\n const afterSeq = Number(url.searchParams.get(\"afterSeq\") ?? \"0\");\n if (!Number.isInteger(afterSeq) || afterSeq < 0) {\n return new Response(\"Invalid afterSeq.\", { status: 400 });\n }\n\n const pair = new WebSocketPair();\n const client = pair[0];\n const server = pair[1];\n this.ctx.acceptWebSocket(server);\n await this.#host.acceptEventWebSocket({\n afterSeq: SequenceNumber.make(afterSeq),\n sessionId: this.parseSessionId(sessionIdRaw),\n trace: traceMetadataFromRequest(request),\n webSocket: server,\n });\n return new Response(null, { status: 101, webSocket: client });\n }\n\n async submit(input: EDASessionCommandRpcInput): Promise<CommittedDurableEventValue> {\n await this.restoreAcceptedEventWebSockets();\n const committed = await this.#host.submit({\n command: await decodeCommand(input.command),\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n return encodeEdaRpcCommittedDurableEvent(committed);\n }\n\n async submitBatch(\n input: EDASessionSubmitBatchRpcInput,\n ): Promise<ReadonlyArray<CommittedDurableEventValue>> {\n await this.restoreAcceptedEventWebSockets();\n const committed = await this.#host.submitBatch({\n items: await decodeSubmittables(input.items),\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n return committed.map(encodeEdaRpcCommittedDurableEvent);\n }\n\n async submitAndBlock(input: EDASessionCommandRpcInput): Promise<CommittedCommandTerminalEvent> {\n await this.restoreAcceptedEventWebSockets();\n const committed = await this.#host.submitAndBlock({\n command: await decodeCommand(input.command),\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n return encodeEdaRpcCommittedDurableEvent(committed) as CommittedCommandTerminalEvent;\n }\n\n async blockOnCommand(\n input: EDASessionBlockOnCommandRpcInput,\n ): Promise<CommittedCommandTerminalEvent> {\n await this.restoreAcceptedEventWebSockets();\n const committed = await this.#host.blockOnCommand({\n ...(input.afterSeq === undefined ? {} : { afterSeq: SequenceNumber.make(input.afterSeq) }),\n commandId: CommandId.make(input.commandId),\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n return encodeEdaRpcCommittedDurableEvent(committed) as CommittedCommandTerminalEvent;\n }\n\n async snapshot(input: EDASessionScopedRpcInput): Promise<EDASessionSnapshot> {\n await this.restoreAcceptedEventWebSockets();\n const snapshot = await this.#host.snapshot({\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n return encodeEdaRpcSessionSnapshot(snapshot);\n }\n\n async messages(\n input: EDASessionScopedRpcInput,\n ): Promise<ReadonlyArray<DurableTranscriptMessage>> {\n await this.restoreAcceptedEventWebSockets();\n return await this.#host.messages({\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n }\n\n async webSocketMessage(webSocket: WebSocket, message: string | ArrayBuffer): Promise<void> {\n await this.#host.webSocketMessage(webSocket, message);\n }\n\n async webSocketClose(\n webSocket: WebSocket,\n _code: number,\n _reason: string,\n _wasClean: boolean,\n ): Promise<void> {\n await this.#host.webSocketClose(webSocket);\n }\n\n async webSocketError(webSocket: WebSocket, _error: unknown): Promise<void> {\n await this.#host.webSocketError(webSocket);\n }\n\n async destroySession(input: EDASessionScopedRpcInput): Promise<void> {\n await this.#host.destroy({\n sessionId: this.parseSessionId(input.sessionId),\n trace: decodeTraceMetadata(input.trace),\n });\n await this.ctx.storage.deleteAlarm();\n await this.ctx.storage.deleteAll();\n }\n\n async alarm(): Promise<void> {\n await this.restoreAcceptedEventWebSockets();\n const sessionId = this.sessionIdFromObjectName();\n await this.#host.alarm(\n sessionId === undefined ? undefined : { sessionId, trace: makeRootEDATraceMetadata() },\n );\n }\n\n private parseSessionId(input: string): SessionId {\n const sessionId = SessionId.make(input);\n const objectName = this.ctx.id.name;\n if (objectName !== undefined && objectName !== sessionId) {\n throw new Error(`EDA Durable Object name ${objectName} cannot serve session ${sessionId}`);\n }\n return sessionId;\n }\n\n private sessionIdFromObjectName(): SessionId | undefined {\n return this.ctx.id.name === undefined ? undefined : SessionId.make(this.ctx.id.name);\n }\n\n private async restoreAcceptedEventWebSockets(): Promise<void> {\n await this.#host.restoreEventWebSockets(this.ctx.getWebSockets());\n }\n}\n\nconst toEDASessionStorage = (storage: DurableObjectStorage): EDASessionDurableObjectStorage => {\n // SAFETY: the adapter interface is the exact SQL, transaction, and alarm subset\n // of DurableObjectStorage; its looser row generic also supports test implementations.\n return storage as EDASessionDurableObjectStorage;\n};\n\nconst decodeTraceMetadata = (input: unknown): EDATraceMetadata =>\n Schema.decodeUnknownSync(EDATraceMetadata)(input);\n\nconst traceMetadataFromRequest = (request: Request): EDATraceMetadata => {\n const parent = parseEDATraceparent(\n request.headers.get(\"traceparent\"),\n request.headers.get(\"tracestate\"),\n );\n return parent === null ? makeRootEDATraceMetadata() : makeEDATraceMetadataFromParent(parent);\n};\n\n/** Convenience config constructor for subclasses that need only provider/model ids. */\nexport const edaRuntimeConfig = (input: {\n readonly maxToolCallsPerRun?: number;\n readonly modelId: string;\n readonly provider: string;\n readonly systemPrompt?: string;\n}): EDARuntimeConfig => ({\n modelSelection: { modelId: input.modelId, provider: input.provider },\n ...(input.maxToolCallsPerRun === undefined\n ? {}\n : { maxToolCallsPerRun: input.maxToolCallsPerRun }),\n ...(input.systemPrompt === undefined ? {} : { systemPrompt: input.systemPrompt }),\n});\n\n/** Encode committed events into structured-clone-safe Durable Object RPC payloads. */\nexport const encodeEdaRpcCommittedDurableEvent = (\n event: CommittedDurableEventValue,\n): CommittedDurableEventValue => ({\n position: event.position,\n event: encodeEdaRpcDurableEvent(event.event),\n});\n\n/** Encode runtime snapshots into structured-clone-safe Durable Object RPC payloads. */\nexport const encodeEdaRpcSessionSnapshot = (snapshot: EDASessionSnapshot): EDASessionSnapshot => ({\n ...snapshot,\n reducerStates: new Map(snapshot.reducerStates),\n state: {\n ...snapshot.state,\n commands: new Map(\n Array.from(snapshot.state.commands, ([commandId, record]) => [\n commandId,\n encodeCommandCarrierForRpc(record),\n ]),\n ),\n commandQueues: {\n ...snapshot.state.commandQueues,\n activeControlCommands: snapshot.state.commandQueues.activeControlCommands.map(\n encodeCommandCarrierForRpc,\n ),\n pendingCommands: snapshot.state.commandQueues.pendingCommands.map(encodeCommandCarrierForRpc),\n queuedCommands: snapshot.state.commandQueues.queuedCommands.map(encodeCommandCarrierForRpc),\n },\n },\n});\n\nconst encodeCommandCarrierForRpc = <A extends { readonly command?: EDACommandValue }>(\n value: A,\n): A =>\n value.command === undefined\n ? value\n : {\n ...value,\n command: Schema.encodeSync(EDACommand)(value.command) as EDACommandValue,\n };\n\nconst decodeCommand = (input: unknown): Promise<EDACommandValue> =>\n Effect.runPromise(decodeEdaRpcCommand(input));\n\nconst decodeSubmittables = (\n input: ReadonlyArray<unknown>,\n): Promise<ReadonlyArray<EDASubmittable>> => Effect.runPromise(decodeEdaRpcSubmittables(input));\n"],"mappings":"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"}
@@ -0,0 +1,265 @@
1
+ import { t as DurableObjectSessionStorage } from "./durable-object-storage-DCL2IyUe.js";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Schema from "effect/Schema";
4
+ import { EDACommand } from "effect-durable-agent/types/commands";
5
+ import { CommandId, SequenceNumber, SessionId } from "effect-durable-agent/types/core";
6
+ import { EDATraceMetadata } from "effect-durable-agent/types/tracing";
7
+ import { OpenAiLanguageModel } from "@effect/ai-openai";
8
+ import * as Layer from "effect/Layer";
9
+ import * as Tracer from "effect/Tracer";
10
+ import { CompactionExecutor, CompactionPolicy } from "effect-durable-agent/services/compaction";
11
+ import { EDAPromptProjector } from "effect-durable-agent/services/prompt-projector";
12
+ import { EDAReducer } from "effect-durable-agent/services/reducer-registry";
13
+ import { CommittedCommandTerminalEvent, EDARuntime, EDARuntimeConfig } from "effect-durable-agent/services/runtime";
14
+ import { CommittedDurableEvent, EDASessionStoreError } from "effect-durable-agent/services/session-store";
15
+ import * as LanguageModel from "effect/unstable/ai/LanguageModel";
16
+ import { DurableTranscriptMessage } from "effect-durable-agent/domain/message-transcript";
17
+ import { EDASessionSnapshot } from "effect-durable-agent/services/session-query";
18
+ import { EDASubmittable, SessionCommandAdmissionError } from "effect-durable-agent/services/session-state";
19
+ import { EDASink } from "effect-durable-agent/services/sink-registry";
20
+ import { EDAModelToolkit, EDAToolRegistryShape } from "effect-durable-agent/services/tool-registry";
21
+ import * as Fiber from "effect/Fiber";
22
+ import { EDAWebSocketServerFrameEncoder } from "effect-durable-agent/host/websocket-wire";
23
+
24
+ //#region src/durable-object-keepalive.d.ts
25
+ /** Minimal Durable Object storage alarm surface needed by the EDA host keepalive. */
26
+ interface DurableObjectAlarmStorage {
27
+ readonly getAlarm: () => number | null | Promise<number | null>;
28
+ readonly setAlarm: (scheduledTimeMs: number) => void | Promise<void>;
29
+ readonly deleteAlarm: () => void | Promise<void>;
30
+ }
31
+ /** Optional host hook for background alarm writes started from synchronous observers. */
32
+ interface DurableObjectBackgroundWaiter {
33
+ readonly waitUntil: (promise: Promise<unknown>) => void;
34
+ }
35
+ /** Configuration for the in-memory active-work heartbeat. */
36
+ interface DurableObjectKeepAliveOptions {
37
+ /** Alarm interval while at least one host-tracked fiber is still unsettled. */
38
+ readonly intervalMs?: number;
39
+ /** Clock used for scheduling; tests can inject a deterministic clock. */
40
+ readonly now?: () => number;
41
+ /** Receives best-effort release/reschedule failures that cannot be awaited by the caller. */
42
+ readonly onBackgroundError?: (error: unknown) => void;
43
+ }
44
+ /** Idempotent lease for one host-tracked active Effect fiber/root. */
45
+ interface DurableObjectKeepAliveLease {
46
+ readonly release: () => Promise<void>;
47
+ }
48
+ /**
49
+ * Alarm-backed in-memory keepalive for a raw Durable Object host.
50
+ *
51
+ * The active lease count is intentionally not durable: if the object is evicted
52
+ * or crashes, the fibers the leases represented are gone too, and normal EDA
53
+ * durable recovery must explain any escaped lifecycle boundaries.
54
+ */
55
+ declare class DurableObjectKeepAlive {
56
+ private readonly storage;
57
+ private readonly background;
58
+ private readonly intervalMs;
59
+ private readonly now;
60
+ private readonly onBackgroundError;
61
+ private activeLeases;
62
+ private generation;
63
+ private scheduleTail;
64
+ private shutdownRequested;
65
+ constructor(storage: DurableObjectAlarmStorage, background?: DurableObjectBackgroundWaiter | undefined, options?: DurableObjectKeepAliveOptions);
66
+ /** Number of active unsettled host roots currently holding the heartbeat. */
67
+ get activeLeaseCount(): number;
68
+ /** Acquire one active-work lease and arm the heartbeat if this is the first lease. */
69
+ acquire(): Promise<DurableObjectKeepAliveLease>;
70
+ /** Run a promise while holding a lease. Intended for host adapters, not EDA internals. */
71
+ runWhileActive<A>(fn: () => Promise<A>): Promise<A>;
72
+ /**
73
+ * Track an already-forked Effect fiber as active host work until it settles.
74
+ *
75
+ * Use this with `ManagedRuntime.runFork(...)` when the fiber needs an already
76
+ * built runtime context. The returned lease can be released manually, but it
77
+ * is normally released by the fiber observer.
78
+ */
79
+ trackFiber<A, E>(fiber: Fiber.Fiber<A, E>): Promise<DurableObjectKeepAliveLease>;
80
+ /**
81
+ * Fork an Effect as host-tracked active work.
82
+ *
83
+ * This mirrors Effect's host-runner pattern: observe the root fiber and release
84
+ * the alarm lease when it settles. It deliberately does not patch Effect
85
+ * internals or try to classify runnable vs suspended fibers.
86
+ */
87
+ fork<A, E>(effect: Effect.Effect<A, E>): Promise<Fiber.Fiber<A, E>>;
88
+ /** Handle the Durable Object `alarm()` callback and re-arm while work remains. */
89
+ alarm(): Promise<void>;
90
+ /** Permanently stop the heartbeat and prevent later lease releases from re-arming it. */
91
+ shutdown(): Promise<void>;
92
+ /** Start a fresh lease generation after the host intentionally resets its durable state. */
93
+ restart(): void;
94
+ private waitUntil;
95
+ private reschedule;
96
+ private syncAlarm;
97
+ }
98
+ //#endregion
99
+ //#region src/durable-object-runtime.d.ts
100
+ /** Durable Object storage capabilities needed by the EDA session host. */
101
+ type EDASessionDurableObjectStorage = DurableObjectSessionStorage & DurableObjectAlarmStorage;
102
+ /** Options for composing one EDA runtime inside a raw Durable Object. */
103
+ interface EDADurableObjectRuntimeLayerOptions {
104
+ readonly config: EDARuntimeConfig;
105
+ readonly compactionExecutorLayer?: Layer.Layer<CompactionExecutor, never, LanguageModel.LanguageModel>;
106
+ readonly compactionPolicyLayer?: Layer.Layer<CompactionPolicy>;
107
+ readonly keepAlive?: DurableObjectKeepAlive;
108
+ readonly modelLayer: Layer.Layer<LanguageModel.LanguageModel>;
109
+ readonly promptProjectorLayer?: Layer.Layer<EDAPromptProjector>;
110
+ readonly reducers?: ReadonlyArray<EDAReducer<any>>;
111
+ readonly sessionId: SessionId;
112
+ readonly sinks?: ReadonlyArray<EDASink>;
113
+ readonly storage: EDASessionDurableObjectStorage;
114
+ readonly toolkit?: EDAModelToolkit;
115
+ readonly toolRegistry?: EDAToolRegistryShape;
116
+ readonly tracer?: Tracer.Tracer;
117
+ }
118
+ /** Options for one live raw Durable Object host instance. */
119
+ interface EDASessionDurableObjectHostOptions {
120
+ readonly background?: DurableObjectBackgroundWaiter;
121
+ readonly config: EDARuntimeConfig;
122
+ readonly compactionExecutorLayer?: Layer.Layer<CompactionExecutor, never, LanguageModel.LanguageModel>;
123
+ readonly compactionPolicyLayer?: Layer.Layer<CompactionPolicy>;
124
+ readonly keepAlive?: DurableObjectKeepAlive;
125
+ readonly modelLayer: Layer.Layer<LanguageModel.LanguageModel>;
126
+ readonly promptProjectorLayer?: Layer.Layer<EDAPromptProjector>;
127
+ readonly reducers?: ReadonlyArray<EDAReducer<any>>;
128
+ readonly sinks?: ReadonlyArray<EDASink>;
129
+ readonly storage: EDASessionDurableObjectStorage;
130
+ readonly toolkit?: EDAModelToolkit | EDAToolkitFactory;
131
+ readonly toolRegistry?: EDAToolRegistryShape | EDAToolRegistryFactory;
132
+ readonly tracer?: Tracer.Tracer | EDATracerFactory;
133
+ readonly webSocketProtocol?: EDAWebSocketServerFrameEncoder;
134
+ }
135
+ /** Per-session factory for provider-visible model toolkit definitions. */
136
+ type EDAToolkitFactory = (input: {
137
+ readonly sessionId: SessionId;
138
+ }) => EDAModelToolkit;
139
+ /** Per-session factory for custom tool registry implementations. */
140
+ type EDAToolRegistryFactory = (input: {
141
+ readonly sessionId: SessionId;
142
+ }) => EDAToolRegistryShape;
143
+ type EDATracerFactory = (input: {
144
+ readonly sessionId: SessionId;
145
+ }) => Tracer.Tracer;
146
+ /** Typed host input for admitting one command through RPC or route code. */
147
+ interface EDASessionSubmitInput {
148
+ readonly command: EDACommand;
149
+ readonly sessionId: SessionId;
150
+ readonly trace: EDATraceMetadata;
151
+ }
152
+ /** Typed host input for admitting commands and app events as one durable batch. */
153
+ interface EDASessionSubmitBatchInput {
154
+ readonly items: ReadonlyArray<EDASubmittable>;
155
+ readonly sessionId: SessionId;
156
+ readonly trace: EDATraceMetadata;
157
+ }
158
+ /** Typed host input for waiting on a command terminal boundary. */
159
+ interface EDASessionBlockOnCommandInput {
160
+ readonly afterSeq?: SequenceNumber;
161
+ readonly commandId: CommandId;
162
+ readonly sessionId: SessionId;
163
+ readonly trace: EDATraceMetadata;
164
+ }
165
+ /** Typed host input for operations scoped only by session identity. */
166
+ interface EDASessionScopedInput {
167
+ readonly sessionId: SessionId;
168
+ readonly trace: EDATraceMetadata;
169
+ }
170
+ /** Typed host input for opening a live event stream from a durable cursor. */
171
+ interface EDASessionEventsInput {
172
+ readonly afterSeq?: SequenceNumber;
173
+ readonly sessionId: SessionId;
174
+ readonly trace: EDATraceMetadata;
175
+ }
176
+ /**
177
+ * Compose the full EDA service graph for one raw Durable Object session.
178
+ *
179
+ * The layer is intentionally host-owned: tests can pass a fake model layer,
180
+ * while the Worker host can pass a provider-backed layer from Env.
181
+ */
182
+ declare const makeEDADurableObjectRuntimeLayer: ({
183
+ config,
184
+ compactionExecutorLayer,
185
+ compactionPolicyLayer,
186
+ keepAlive,
187
+ modelLayer,
188
+ promptProjectorLayer,
189
+ reducers,
190
+ sessionId,
191
+ sinks,
192
+ storage,
193
+ toolkit,
194
+ toolRegistry,
195
+ tracer
196
+ }: EDADurableObjectRuntimeLayerOptions) => Layer.Layer<EDARuntime, SessionCommandAdmissionError>;
197
+ /** Provider request defaults accepted by EDA's OpenAI Responses model adapter. */
198
+ type EDAOpenAiModelConfig = Omit<typeof OpenAiLanguageModel.Config.Service, "model">;
199
+ /** OpenAI-backed Effect AI model layer for the default Worker host. */
200
+ declare const makeEDADurableObjectOpenAiModelLayer: (options: {
201
+ readonly aiGateway?: AiGateway;
202
+ readonly apiKey?: string;
203
+ readonly apiUrl?: string;
204
+ readonly config?: EDAOpenAiModelConfig;
205
+ readonly modelId: string;
206
+ }) => Layer.Layer<LanguageModel.LanguageModel>;
207
+ /** Raw Durable Object host controller for one EDA session object. */
208
+ declare class EDASessionDurableObjectHost {
209
+ private readonly options;
210
+ private readonly keepAlive;
211
+ private readonly eventSockets;
212
+ private runtimeState;
213
+ private runtimePromise;
214
+ constructor(options: EDASessionDurableObjectHostOptions);
215
+ /** Run idempotent host and event-store migrations. Safe from `blockConcurrencyWhile`. */
216
+ static readonly migrate: (storage: EDASessionDurableObjectStorage) => Effect.Effect<void, EDASessionStoreError>;
217
+ /** Admit one command durably. Active runtime work holds EDA keep-alive leases internally. */
218
+ submit(input: EDASessionSubmitInput): Promise<CommittedDurableEvent>;
219
+ /** Submit an ordered durable batch of commands and app events. */
220
+ submitBatch(input: EDASessionSubmitBatchInput): Promise<ReadonlyArray<CommittedDurableEvent>>;
221
+ /** Admit one command and wait for its terminal command boundary. */
222
+ submitAndBlock(input: EDASessionSubmitInput): Promise<CommittedCommandTerminalEvent>;
223
+ /** Wait for an existing command to reach its terminal command boundary. */
224
+ blockOnCommand(input: EDASessionBlockOnCommandInput): Promise<CommittedCommandTerminalEvent>;
225
+ /** Read the authoritative live session snapshot. */
226
+ snapshot(input: EDASessionScopedInput): Promise<EDASessionSnapshot>;
227
+ /** Read durable transcript messages in committed order. */
228
+ messages(input: EDASessionScopedInput): Promise<ReadonlyArray<DurableTranscriptMessage>>;
229
+ /** Accept one WebSocket as the live event stream for this session. */
230
+ acceptEventWebSocket(input: EDASessionEventsInput & {
231
+ readonly webSocket: WebSocket;
232
+ }): Promise<void>;
233
+ /** Restore hibernated event WebSockets whose in-memory subscriber fibers disappeared. */
234
+ restoreEventWebSockets(webSockets: ReadonlyArray<WebSocket>): Promise<void>;
235
+ /** Route one inbound WebSocket message into the subscriber ACK queue. */
236
+ webSocketMessage(webSocket: WebSocket, message: string | ArrayBuffer): Promise<void>;
237
+ /** Interrupt subscriber work after the client closes the WebSocket. */
238
+ webSocketClose(webSocket: WebSocket): Promise<void>;
239
+ /** Interrupt subscriber work after a host WebSocket error. */
240
+ webSocketError(webSocket: WebSocket): Promise<void>;
241
+ /** Dispose any live runtime before the host deletes its Durable Object storage. */
242
+ destroy(_input: EDASessionScopedInput): Promise<void>;
243
+ /** Durable Object alarm hook: wake/recover the runtime and re-arm while EDA has active work. */
244
+ alarm(input?: EDASessionScopedInput): Promise<void>;
245
+ /** Dispose the Effect runtime if the host wrapper is torn down by tests. */
246
+ dispose(): Promise<void>;
247
+ private withRuntime;
248
+ private ensureEventWebSocket;
249
+ private startEventWebSocket;
250
+ private getRuntime;
251
+ private buildRuntime;
252
+ }
253
+ /** Decode a raw RPC command payload at the Durable Object boundary. */
254
+ declare const encodeEdaRpcCommand: (input: EDACommand) => unknown;
255
+ /** Encode a command/app-event batch into structured-clone-safe RPC values. */
256
+ declare const encodeEdaRpcSubmittables: (input: ReadonlyArray<EDASubmittable>) => ReadonlyArray<unknown>;
257
+ /** Decode a raw RPC command payload at the Durable Object boundary. */
258
+ declare const decodeEdaRpcCommand: (input: unknown) => Effect.Effect<EDACommand, Schema.SchemaError>;
259
+ /** Decode a raw RPC batch item at the Durable Object boundary. */
260
+ declare const decodeEdaRpcSubmittable: (input: unknown) => Effect.Effect<EDASubmittable, Schema.SchemaError>;
261
+ /** Decode raw RPC batch items at the Durable Object boundary. */
262
+ declare const decodeEdaRpcSubmittables: (input: ReadonlyArray<unknown>) => Effect.Effect<ReadonlyArray<EDASubmittable>, Schema.SchemaError>;
263
+ //#endregion
264
+ export { encodeEdaRpcCommand as _, EDASessionDurableObjectHostOptions as a, makeEDADurableObjectRuntimeLayer as b, EDASessionScopedInput as c, EDAToolRegistryFactory as d, EDAToolkitFactory as f, decodeEdaRpcSubmittables as g, decodeEdaRpcSubmittable as h, EDASessionDurableObjectHost as i, EDASessionSubmitBatchInput as l, decodeEdaRpcCommand as m, EDAOpenAiModelConfig as n, EDASessionDurableObjectStorage as o, EDATracerFactory as p, EDASessionBlockOnCommandInput as r, EDASessionEventsInput as s, EDADurableObjectRuntimeLayerOptions as t, EDASessionSubmitInput as u, encodeEdaRpcSubmittables as v, makeEDADurableObjectOpenAiModelLayer as y };
265
+ //# sourceMappingURL=durable-object-runtime-Dehm7PsO.d.ts.map