effect-durable-agent-cloudflare 0.1.0-alpha.19 → 0.1.0-alpha.21

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,44 @@
1
+ import { AnthropicClient, AnthropicLanguageModel } from "@effect/ai-anthropic";
2
+ import * as Layer from "effect/Layer";
3
+ import * as Prompt from "effect/ai/Prompt";
4
+ //#region src/providers/anthropic.d.ts
5
+ /** Anthropic request defaults for one resolved model (everything but `model`). */
6
+ type EDAAnthropicModelConfig = Omit<typeof AnthropicLanguageModel.Config.Service, "model">;
7
+ /** Shared Anthropic transport and client options. */
8
+ interface EDAAnthropicClientOptions {
9
+ /** Cloudflare AI Gateway binding. With a gateway-stored key (BYOK) no `apiKey` is needed. */
10
+ readonly aiGateway?: AiGateway | undefined;
11
+ readonly apiKey?: string | undefined;
12
+ readonly apiUrl?: string | undefined;
13
+ /** Beta flags sent on every request, e.g. `thinking-binding-controls-2026-08-01`. */
14
+ readonly betas?: ReadonlyArray<string> | undefined;
15
+ }
16
+ /** Anthropic client layer over EDA's provider transport. */
17
+ declare const makeEDAAnthropicClientLayer: (options: EDAAnthropicClientOptions) => Layer.Layer<AnthropicClient.AnthropicClient>;
18
+ /** Beta that lets requests choose what happens to thinking bound to an edited conversation. */
19
+ declare const ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
20
+ /** Agent request policy for Claude 5.5-generation models. */
21
+ interface EDAAnthropicAgentSettings {
22
+ /** Thinking depth; Opus 5.5 cannot disable thinking, so effort is the only control. */
23
+ readonly effort: "low" | "medium" | "high";
24
+ /** Output budget including thinking. Defaults to 64,000. */
25
+ readonly maxTokens?: number | undefined;
26
+ /** `summarized` streams readable reasoning summaries. Defaults to `summarized`. */
27
+ readonly thinkingDisplay?: "summarized" | "omitted" | undefined;
28
+ /**
29
+ * Explicit preserved-thinking policy (requires {@link ANTHROPIC_THINKING_BINDING_BETA}).
30
+ * `drop_block` degrades instead of failing when replayed thinking no longer matches.
31
+ */
32
+ readonly prefixMismatchBehavior?: "error" | "drop_block" | undefined;
33
+ }
34
+ /** Model config for EDA agent sessions on Anthropic. */
35
+ declare const anthropicAgentModelConfig: (settings: EDAAnthropicAgentSettings) => EDAAnthropicModelConfig;
36
+ /**
37
+ * Anthropic prompt preparation: EDA cache hints become `cache_control` breakpoints (end of the
38
+ * instruction prefix and end of durable history), and Anthropic compaction summaries become the
39
+ * transport sentinel that is replayed as the signed `compaction` block.
40
+ */
41
+ declare const prepareEDAAnthropicPrompt: (prompt: Prompt.Prompt) => Prompt.Prompt;
42
+ //#endregion
43
+ export { ANTHROPIC_THINKING_BINDING_BETA, EDAAnthropicAgentSettings, EDAAnthropicClientOptions, EDAAnthropicModelConfig, anthropicAgentModelConfig, makeEDAAnthropicClientLayer, prepareEDAAnthropicPrompt };
44
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1,66 @@
1
+ import { i as prepareNativeCompaction, r as makeEDAProviderHttpClient } from "./transport-BzgK07l4.js";
2
+ import { AnthropicClient } from "@effect/ai-anthropic";
3
+ import { isEDACacheBreakpoint } from "effect-durable-agent/services/prompt-projector";
4
+ import * as Layer from "effect/Layer";
5
+ import * as Redacted from "effect/Redacted";
6
+ import * as Prompt from "effect/ai/Prompt";
7
+ import * as HttpClient from "effect/http/HttpClient";
8
+ //#region src/providers/anthropic.ts
9
+ /** Anthropic client layer over EDA's provider transport. */
10
+ const makeEDAAnthropicClientLayer = (options) => {
11
+ const apiKey = optionalNonEmptyString(options.apiKey);
12
+ if (apiKey === void 0 && options.aiGateway === void 0) throw new Error("ANTHROPIC_API_KEY is required unless Anthropic traffic goes through a Cloudflare AI Gateway binding with a stored key.");
13
+ return AnthropicClient.layer({
14
+ ...apiKey === void 0 ? {} : { apiKey: Redacted.make(apiKey) },
15
+ ...options.apiUrl === void 0 ? {} : { apiUrl: options.apiUrl }
16
+ }).pipe(Layer.provide(Layer.succeed(HttpClient.HttpClient, makeEDAProviderHttpClient({
17
+ provider: "anthropic",
18
+ aiGateway: options.aiGateway,
19
+ anthropicBetas: options.betas
20
+ }))));
21
+ };
22
+ /** Beta that lets requests choose what happens to thinking bound to an edited conversation. */
23
+ const ANTHROPIC_THINKING_BINDING_BETA = "thinking-binding-controls-2026-08-01";
24
+ /** Model config for EDA agent sessions on Anthropic. */
25
+ const anthropicAgentModelConfig = (settings) => {
26
+ const thinking = {
27
+ type: "adaptive",
28
+ display: settings.thinkingDisplay ?? "summarized",
29
+ ...settings.prefixMismatchBehavior === void 0 ? {} : { block_binding: { prefix_mismatch_behavior: settings.prefixMismatchBehavior } }
30
+ };
31
+ return {
32
+ max_tokens: settings.maxTokens ?? 64e3,
33
+ output_config: { effort: settings.effort },
34
+ thinking,
35
+ strictJsonSchema: false
36
+ };
37
+ };
38
+ /**
39
+ * Anthropic prompt preparation: EDA cache hints become `cache_control` breakpoints (end of the
40
+ * instruction prefix and end of durable history), and Anthropic compaction summaries become the
41
+ * transport sentinel that is replayed as the signed `compaction` block.
42
+ */
43
+ const prepareEDAAnthropicPrompt = (prompt) => prepareNativeCompaction("anthropic", Prompt.fromMessages(prompt.content.map((message) => isEDACacheBreakpoint(message) ? withMessageOptions(message, { anthropic: {
44
+ ...anthropicOptions(message.options),
45
+ cacheControl: { type: "ephemeral" }
46
+ } }) : message)));
47
+ const anthropicOptions = (options) => {
48
+ const current = options.anthropic;
49
+ return isJsonObject(current) ? current : {};
50
+ };
51
+ const isJsonObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
52
+ const withMessageOptions = (message, options) => ({
53
+ ...message,
54
+ options: {
55
+ ...message.options,
56
+ ...options
57
+ }
58
+ });
59
+ const optionalNonEmptyString = (value) => {
60
+ const trimmed = value?.trim();
61
+ return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
62
+ };
63
+ //#endregion
64
+ export { ANTHROPIC_THINKING_BINDING_BETA, anthropicAgentModelConfig, makeEDAAnthropicClientLayer, prepareEDAAnthropicPrompt };
65
+
66
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","names":[],"sources":["../src/providers/anthropic.ts"],"sourcesContent":["import { AnthropicClient, AnthropicLanguageModel } from \"@effect/ai-anthropic\";\nimport { isEDACacheBreakpoint } from \"effect-durable-agent/services/prompt-projector\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport type * as Schema from \"effect/Schema\";\nimport * as Prompt from \"effect/ai/Prompt\";\nimport * as HttpClient from \"effect/http/HttpClient\";\n\nimport { makeEDAProviderHttpClient, prepareNativeCompaction } from \"./transport\";\n\n/** Anthropic request defaults for one resolved model (everything but `model`). */\nexport type EDAAnthropicModelConfig = Omit<typeof AnthropicLanguageModel.Config.Service, \"model\">;\n\n/** Shared Anthropic transport and client options. */\nexport interface EDAAnthropicClientOptions {\n /** Cloudflare AI Gateway binding. With a gateway-stored key (BYOK) no `apiKey` is needed. */\n readonly aiGateway?: AiGateway | undefined;\n readonly apiKey?: string | undefined;\n readonly apiUrl?: string | undefined;\n /** Beta flags sent on every request, e.g. `thinking-binding-controls-2026-08-01`. */\n readonly betas?: ReadonlyArray<string> | undefined;\n}\n\n/** Anthropic client layer over EDA's provider transport. */\nexport const makeEDAAnthropicClientLayer = (\n options: EDAAnthropicClientOptions,\n): Layer.Layer<AnthropicClient.AnthropicClient> => {\n const apiKey = optionalNonEmptyString(options.apiKey);\n if (apiKey === undefined && options.aiGateway === undefined) {\n throw new Error(\n \"ANTHROPIC_API_KEY is required unless Anthropic traffic goes through a Cloudflare AI Gateway binding with a stored key.\",\n );\n }\n return AnthropicClient.layer({\n ...(apiKey === undefined ? {} : { apiKey: Redacted.make(apiKey) }),\n ...(options.apiUrl === undefined ? {} : { apiUrl: options.apiUrl }),\n }).pipe(\n Layer.provide(\n Layer.succeed(\n HttpClient.HttpClient,\n makeEDAProviderHttpClient({\n provider: \"anthropic\",\n aiGateway: options.aiGateway,\n anthropicBetas: options.betas,\n }),\n ),\n ),\n );\n};\n\n/** Beta that lets requests choose what happens to thinking bound to an edited conversation. */\nexport const ANTHROPIC_THINKING_BINDING_BETA = \"thinking-binding-controls-2026-08-01\";\n\n/** Agent request policy for Claude 5.5-generation models. */\nexport interface EDAAnthropicAgentSettings {\n /** Thinking depth; Opus 5.5 cannot disable thinking, so effort is the only control. */\n readonly effort: \"low\" | \"medium\" | \"high\";\n /** Output budget including thinking. Defaults to 64,000. */\n readonly maxTokens?: number | undefined;\n /** `summarized` streams readable reasoning summaries. Defaults to `summarized`. */\n readonly thinkingDisplay?: \"summarized\" | \"omitted\" | undefined;\n /**\n * Explicit preserved-thinking policy (requires {@link ANTHROPIC_THINKING_BINDING_BETA}).\n * `drop_block` degrades instead of failing when replayed thinking no longer matches.\n */\n readonly prefixMismatchBehavior?: \"error\" | \"drop_block\" | undefined;\n}\n\n/** Model config for EDA agent sessions on Anthropic. */\nexport const anthropicAgentModelConfig = (\n settings: EDAAnthropicAgentSettings,\n): EDAAnthropicModelConfig => {\n const thinking = {\n type: \"adaptive\" as const,\n display: settings.thinkingDisplay ?? \"summarized\",\n ...(settings.prefixMismatchBehavior === undefined\n ? {}\n : { block_binding: { prefix_mismatch_behavior: settings.prefixMismatchBehavior } }),\n };\n const config: EDAAnthropicModelConfig = {\n max_tokens: settings.maxTokens ?? 64_000,\n output_config: { effort: settings.effort },\n thinking,\n // EDA tool schemas are not written for strict mode's constraints.\n strictJsonSchema: false,\n };\n return config;\n};\n\n/**\n * Anthropic prompt preparation: EDA cache hints become `cache_control` breakpoints (end of the\n * instruction prefix and end of durable history), and Anthropic compaction summaries become the\n * transport sentinel that is replayed as the signed `compaction` block.\n */\nexport const prepareEDAAnthropicPrompt = (prompt: Prompt.Prompt): Prompt.Prompt =>\n prepareNativeCompaction(\n \"anthropic\",\n Prompt.fromMessages(\n prompt.content.map((message) =>\n isEDACacheBreakpoint(message)\n ? withMessageOptions(message, {\n anthropic: {\n ...anthropicOptions(message.options),\n cacheControl: { type: \"ephemeral\" },\n },\n })\n : message,\n ),\n ),\n );\n\nconst anthropicOptions = (\n options: Prompt.ProviderOptions,\n): Readonly<Record<string, Schema.Json>> => {\n const current = options.anthropic;\n return isJsonObject(current) ? current : {};\n};\n\nconst isJsonObject = (\n value: Schema.Json | null | undefined,\n): value is Readonly<Record<string, Schema.Json>> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst withMessageOptions = (\n message: Prompt.Message,\n options: Prompt.ProviderOptions,\n): Prompt.Message => ({ ...message, options: { ...message.options, ...options } });\n\nconst optionalNonEmptyString = (value: string | undefined): string | undefined => {\n const trimmed = value?.trim();\n return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed;\n};\n"],"mappings":";;;;;;;;;AAwBA,MAAa,+BACX,YACiD;CACjD,MAAM,SAAS,uBAAuB,QAAQ,MAAM;CACpD,IAAI,WAAW,KAAA,KAAa,QAAQ,cAAc,KAAA,GAChD,MAAM,IAAI,MACR,wHACF;CAEF,OAAO,gBAAgB,MAAM;EAC3B,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,SAAS,KAAK,MAAM,EAAE;EAChE,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;CACnE,CAAC,CAAC,CAAC,KACD,MAAM,QACJ,MAAM,QACJ,WAAW,YACX,0BAA0B;EACxB,UAAU;EACV,WAAW,QAAQ;EACnB,gBAAgB,QAAQ;CAC1B,CAAC,CACH,CACF,CACF;AACF;;AAGA,MAAa,kCAAkC;;AAkB/C,MAAa,6BACX,aAC4B;CAC5B,MAAM,WAAW;EACf,MAAM;EACN,SAAS,SAAS,mBAAmB;EACrC,GAAI,SAAS,2BAA2B,KAAA,IACpC,CAAC,IACD,EAAE,eAAe,EAAE,0BAA0B,SAAS,uBAAuB,EAAE;CACrF;CAQA,OAAO;EANL,YAAY,SAAS,aAAa;EAClC,eAAe,EAAE,QAAQ,SAAS,OAAO;EACzC;EAEA,kBAAkB;CAER;AACd;;;;;;AAOA,MAAa,6BAA6B,WACxC,wBACE,aACA,OAAO,aACL,OAAO,QAAQ,KAAK,YAClB,qBAAqB,OAAO,IACxB,mBAAmB,SAAS,EAC1B,WAAW;CACT,GAAG,iBAAiB,QAAQ,OAAO;CACnC,cAAc,EAAE,MAAM,YAAY;AACpC,EACF,CAAC,IACD,OACN,CACF,CACF;AAEF,MAAM,oBACJ,YAC0C;CAC1C,MAAM,UAAU,QAAQ;CACxB,OAAO,aAAa,OAAO,IAAI,UAAU,CAAC;AAC5C;AAEA,MAAM,gBACJ,UAEA,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAErE,MAAM,sBACJ,SACA,aACoB;CAAE,GAAG;CAAS,SAAS;EAAE,GAAG,QAAQ;EAAS,GAAG;CAAQ;AAAE;AAEhF,MAAM,0BAA0B,UAAkD;CAChF,MAAM,UAAU,OAAO,KAAK;CAC5B,OAAO,YAAY,KAAA,KAAa,QAAQ,WAAW,IAAI,KAAA,IAAY;AACrE"}
@@ -1,5 +1,5 @@
1
- import { a as SessionOutcomeInput, i as SessionGrantRunInput, n as SessionBlockInput, o as SessionScopedInput, r as SessionCommandInput, s as edaSessionRpc, t as SessionBatchInput } from "./rpc-spec-Cko7gaMg.js";
2
- import { i as EDASessionControllerOptions, l as EDAWebSocketProjection } from "./session-controller-BfA5NAuY.js";
1
+ import { a as SessionOutcomeInput, i as SessionGrantRunInput, n as SessionBlockInput, o as SessionScopedInput, r as SessionCommandInput, s as edaSessionRpc, t as SessionBatchInput } from "./rpc-spec-C8wknrbN.js";
2
+ import { i as EDASessionControllerOptions, l as EDAWebSocketProjection } from "./session-controller-DoeFP_Ej.js";
3
3
  import * as Schema from "effect/Schema";
4
4
  import { CommittedDurableEvent } from "effect-durable-agent/services/session-store";
5
5
  import { EDARuntimeConfig } from "effect-durable-agent/services/runtime";
@@ -286,6 +286,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
286
286
  readonly name: string;
287
287
  readonly isFailure: boolean;
288
288
  readonly result: unknown;
289
+ readonly providerExecuted: boolean;
289
290
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
290
291
  readonly options: {
291
292
  readonly [x: string]: Schema.Json;
@@ -307,6 +308,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
307
308
  readonly name: string;
308
309
  readonly isFailure: boolean;
309
310
  readonly result: unknown;
311
+ readonly providerExecuted: boolean;
310
312
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
311
313
  readonly options: {
312
314
  readonly [x: string]: Schema.Json;
@@ -327,6 +329,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
327
329
  readonly name: string;
328
330
  readonly isFailure: boolean;
329
331
  readonly result: unknown;
332
+ readonly providerExecuted: boolean;
330
333
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
331
334
  readonly options: {
332
335
  readonly [x: string]: Schema.Json;
@@ -517,6 +520,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
517
520
  readonly name: string;
518
521
  readonly isFailure: boolean;
519
522
  readonly result: unknown;
523
+ readonly providerExecuted: boolean;
520
524
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
521
525
  readonly options: {
522
526
  readonly [x: string]: Schema.Json;
@@ -581,6 +585,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
581
585
  readonly name: string;
582
586
  readonly isFailure: boolean;
583
587
  readonly result: unknown;
588
+ readonly providerExecuted: boolean;
584
589
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
585
590
  readonly options: {
586
591
  readonly [x: string]: Schema.Json;
@@ -1065,6 +1070,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1065
1070
  readonly name: string;
1066
1071
  readonly isFailure: boolean;
1067
1072
  readonly result: unknown;
1073
+ readonly providerExecuted: boolean;
1068
1074
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1069
1075
  readonly options: {
1070
1076
  readonly [x: string]: Schema.Json;
@@ -1129,6 +1135,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1129
1135
  readonly name: string;
1130
1136
  readonly isFailure: boolean;
1131
1137
  readonly result: unknown;
1138
+ readonly providerExecuted: boolean;
1132
1139
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1133
1140
  readonly options: {
1134
1141
  readonly [x: string]: Schema.Json;
@@ -1480,6 +1487,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1480
1487
  readonly name: string;
1481
1488
  readonly isFailure: boolean;
1482
1489
  readonly result: unknown;
1490
+ readonly providerExecuted: boolean;
1483
1491
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1484
1492
  readonly options: {
1485
1493
  readonly [x: string]: Schema.Json;
@@ -1501,6 +1509,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1501
1509
  readonly name: string;
1502
1510
  readonly isFailure: boolean;
1503
1511
  readonly result: unknown;
1512
+ readonly providerExecuted: boolean;
1504
1513
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1505
1514
  readonly options: {
1506
1515
  readonly [x: string]: Schema.Json;
@@ -1521,6 +1530,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1521
1530
  readonly name: string;
1522
1531
  readonly isFailure: boolean;
1523
1532
  readonly result: unknown;
1533
+ readonly providerExecuted: boolean;
1524
1534
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1525
1535
  readonly options: {
1526
1536
  readonly [x: string]: Schema.Json;
@@ -1711,6 +1721,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1711
1721
  readonly name: string;
1712
1722
  readonly isFailure: boolean;
1713
1723
  readonly result: unknown;
1724
+ readonly providerExecuted: boolean;
1714
1725
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1715
1726
  readonly options: {
1716
1727
  readonly [x: string]: Schema.Json;
@@ -1775,6 +1786,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
1775
1786
  readonly name: string;
1776
1787
  readonly isFailure: boolean;
1777
1788
  readonly result: unknown;
1789
+ readonly providerExecuted: boolean;
1778
1790
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
1779
1791
  readonly options: {
1780
1792
  readonly [x: string]: Schema.Json;
@@ -2436,6 +2448,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
2436
2448
  readonly name: string;
2437
2449
  readonly isFailure: boolean;
2438
2450
  readonly result: unknown;
2451
+ readonly providerExecuted: boolean;
2439
2452
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
2440
2453
  readonly options: {
2441
2454
  readonly [x: string]: Schema.Json;
@@ -2500,6 +2513,7 @@ declare const encodeEdaRpcSessionSnapshot: (input: {
2500
2513
  readonly name: string;
2501
2514
  readonly isFailure: boolean;
2502
2515
  readonly result: unknown;
2516
+ readonly providerExecuted: boolean;
2503
2517
  readonly "~effect/ai/Prompt/Part": "~effect/ai/Prompt/Part";
2504
2518
  readonly options: {
2505
2519
  readonly [x: string]: Schema.Json;
@@ -1,7 +1,7 @@
1
1
  import { a as SessionOutcomeInput, f as encodeEdaRpcDurableEvent, i as SessionGrantRunInput, n as SessionBlockInput, o as SessionScopedInput, r as SessionCommandInput, s as edaSessionRpc, t as SessionBatchInput } from "./rpc-spec-CkWEeWJG.js";
2
- import { t as EDASessionController } from "./session-controller-IrTPwdRt.js";
3
- import { durableEventEnvelope } from "effect-durable-agent/types/events/durable";
2
+ import { t as EDASessionController } from "./session-controller-BGfz1DdS.js";
4
3
  import * as Effect from "effect/Effect";
4
+ import { durableEventEnvelope } from "effect-durable-agent/types/events/durable";
5
5
  import * as Schema from "effect/Schema";
6
6
  import { CommandId, RunRequestId, SequenceNumber, SessionId } from "effect-durable-agent/types/core";
7
7
  import { EDATraceMetadata, makeEDATraceMetadataFromParent, makeRootEDATraceMetadata, parseEDATraceparent } from "effect-durable-agent/types/tracing";
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { i as DurableObjectSqlStorage, n as DurableObjectSessionStoreOptions, r as DurableObjectSqlCursor, t as DurableObjectSessionStorage } from "./durable-object-storage-BZCOHz9p.js";
2
- import { a as SessionOutcomeInput, i as SessionGrantRunInput, n as SessionBlockInput, o as SessionScopedInput, r as SessionCommandInput, s as edaSessionRpc, t as SessionBatchInput } from "./rpc-spec-Cko7gaMg.js";
3
- import { a as EDASessionEventsInput, c as EDASessionSubmitInput, d as EDAWebSocketProjectionInitial, f as EDAWebSocketProjectionResult, h as makeEDADurableObjectRuntimeLayer, i as EDASessionControllerOptions, l as EDAWebSocketProjection, m as EDASessionDurableObjectStorage, n as EDASessionBlockOnCommandInput, o as EDASessionScopedInput, p as EDADurableObjectRuntimeLayerOptions, r as EDASessionController, s as EDASessionSubmitBatchInput, t as EDAPreparedEventWebSocket, u as EDAWebSocketProjectionId } from "./session-controller-BfA5NAuY.js";
2
+ import { a as SessionOutcomeInput, i as SessionGrantRunInput, n as SessionBlockInput, o as SessionScopedInput, r as SessionCommandInput, s as edaSessionRpc, t as SessionBatchInput } from "./rpc-spec-C8wknrbN.js";
3
+ import { a as EDASessionEventsInput, c as EDASessionSubmitInput, d as EDAWebSocketProjectionInitial, f as EDAWebSocketProjectionResult, h as makeEDADurableObjectRuntimeLayer, i as EDASessionControllerOptions, l as EDAWebSocketProjection, m as EDASessionDurableObjectStorage, n as EDASessionBlockOnCommandInput, o as EDASessionScopedInput, p as EDADurableObjectRuntimeLayerOptions, r as EDASessionController, s as EDASessionSubmitBatchInput, t as EDAPreparedEventWebSocket, u as EDAWebSocketProjectionId } from "./session-controller-DoeFP_Ej.js";
4
4
  import { EDASessionBlockOnCommandRpcInput, EDASessionCommandRpcInput, EDASessionDurableObject, EDASessionDurableObjectOptions, EDASessionEventsRpcInput, EDASessionGrantRunRpcInput, EDASessionRpcSurface, EDASessionRunRequestOutcomeRpcInput, EDASessionScopedRpcInput, EDASessionSubmitBatchRpcInput, EDA_WEB_SOCKET_PROJECTION_HEADER, edaRuntimeConfig, encodeEdaRpcCommittedDurableEvent, encodeEdaRpcSessionSnapshot, getEDASessionDurableObjectByName } from "./durable-object.js";
5
- import { EDAOpenAiModelConfig, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer } from "./openai.js";
5
+ import { EDAOpenAiModelConfig, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDAOpenAiClientLayer } from "./openai.js";
6
6
  import { a as encodeEdaRpcDurableEvent, i as encodeEdaRpcCommand, n as decodeEdaRpcCommand, o as encodeEdaRpcSubmittables, r as decodeEdaRpcSubmittables, t as EDARpcSubmittable } from "./rpc-codec-B2aLiNqt.js";
7
- export { DurableObjectSessionStorage, DurableObjectSessionStoreOptions, DurableObjectSqlCursor, DurableObjectSqlStorage, EDADurableObjectRuntimeLayerOptions, EDAOpenAiModelConfig, EDAPreparedEventWebSocket, EDARpcSubmittable, EDASessionBlockOnCommandInput, EDASessionBlockOnCommandRpcInput, EDASessionCommandRpcInput, EDASessionController, EDASessionControllerOptions, EDASessionDurableObject, EDASessionDurableObjectOptions, EDASessionDurableObjectStorage, EDASessionEventsInput, EDASessionEventsRpcInput, EDASessionGrantRunRpcInput, EDASessionRpcSurface, EDASessionRunRequestOutcomeRpcInput, EDASessionScopedInput, EDASessionScopedRpcInput, EDASessionSubmitBatchInput, EDASessionSubmitBatchRpcInput, EDASessionSubmitInput, EDAWebSocketProjection, EDAWebSocketProjectionId, EDAWebSocketProjectionInitial, EDAWebSocketProjectionResult, EDA_WEB_SOCKET_PROJECTION_HEADER, SessionBatchInput, SessionBlockInput, SessionCommandInput, SessionGrantRunInput, SessionOutcomeInput, SessionScopedInput, decodeEdaRpcCommand, decodeEdaRpcSubmittables, edaRuntimeConfig, edaSessionRpc, encodeEdaRpcCommand, encodeEdaRpcCommittedDurableEvent, encodeEdaRpcDurableEvent, encodeEdaRpcSessionSnapshot, encodeEdaRpcSubmittables, getEDASessionDurableObjectByName, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDADurableObjectRuntimeLayer };
7
+ export { DurableObjectSessionStorage, DurableObjectSessionStoreOptions, DurableObjectSqlCursor, DurableObjectSqlStorage, EDADurableObjectRuntimeLayerOptions, EDAOpenAiModelConfig, EDAPreparedEventWebSocket, EDARpcSubmittable, EDASessionBlockOnCommandInput, EDASessionBlockOnCommandRpcInput, EDASessionCommandRpcInput, EDASessionController, EDASessionControllerOptions, EDASessionDurableObject, EDASessionDurableObjectOptions, EDASessionDurableObjectStorage, EDASessionEventsInput, EDASessionEventsRpcInput, EDASessionGrantRunRpcInput, EDASessionRpcSurface, EDASessionRunRequestOutcomeRpcInput, EDASessionScopedInput, EDASessionScopedRpcInput, EDASessionSubmitBatchInput, EDASessionSubmitBatchRpcInput, EDASessionSubmitInput, EDAWebSocketProjection, EDAWebSocketProjectionId, EDAWebSocketProjectionInitial, EDAWebSocketProjectionResult, EDA_WEB_SOCKET_PROJECTION_HEADER, SessionBatchInput, SessionBlockInput, SessionCommandInput, SessionGrantRunInput, SessionOutcomeInput, SessionScopedInput, decodeEdaRpcCommand, decodeEdaRpcSubmittables, edaRuntimeConfig, edaSessionRpc, encodeEdaRpcCommand, encodeEdaRpcCommittedDurableEvent, encodeEdaRpcDurableEvent, encodeEdaRpcSessionSnapshot, encodeEdaRpcSubmittables, getEDASessionDurableObjectByName, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDADurableObjectRuntimeLayer, makeEDAOpenAiClientLayer };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as SessionOutcomeInput, c as EDARpcSubmittable, d as encodeEdaRpcCommand, f as encodeEdaRpcDurableEvent, i as SessionGrantRunInput, l as decodeEdaRpcCommand, n as SessionBlockInput, o as SessionScopedInput, p as encodeEdaRpcSubmittables, r as SessionCommandInput, s as edaSessionRpc, t as SessionBatchInput, u as decodeEdaRpcSubmittables } from "./rpc-spec-CkWEeWJG.js";
2
- import { n as EDAWebSocketProjectionId, r as makeEDADurableObjectRuntimeLayer, t as EDASessionController } from "./session-controller-IrTPwdRt.js";
2
+ import { n as EDAWebSocketProjectionId, r as makeEDADurableObjectRuntimeLayer, t as EDASessionController } from "./session-controller-BGfz1DdS.js";
3
3
  import { EDASessionDurableObject, EDA_WEB_SOCKET_PROJECTION_HEADER, edaRuntimeConfig, encodeEdaRpcCommittedDurableEvent, encodeEdaRpcSessionSnapshot, getEDASessionDurableObjectByName } from "./durable-object.js";
4
4
  import "./storage.js";
5
- import { makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer } from "./openai.js";
6
- export { EDARpcSubmittable, EDASessionController, EDASessionDurableObject, EDAWebSocketProjectionId, EDA_WEB_SOCKET_PROJECTION_HEADER, SessionBatchInput, SessionBlockInput, SessionCommandInput, SessionGrantRunInput, SessionOutcomeInput, SessionScopedInput, decodeEdaRpcCommand, decodeEdaRpcSubmittables, edaRuntimeConfig, edaSessionRpc, encodeEdaRpcCommand, encodeEdaRpcCommittedDurableEvent, encodeEdaRpcDurableEvent, encodeEdaRpcSessionSnapshot, encodeEdaRpcSubmittables, getEDASessionDurableObjectByName, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDADurableObjectRuntimeLayer };
5
+ import { makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDAOpenAiClientLayer } from "./openai.js";
6
+ export { EDARpcSubmittable, EDASessionController, EDASessionDurableObject, EDAWebSocketProjectionId, EDA_WEB_SOCKET_PROJECTION_HEADER, SessionBatchInput, SessionBlockInput, SessionCommandInput, SessionGrantRunInput, SessionOutcomeInput, SessionScopedInput, decodeEdaRpcCommand, decodeEdaRpcSubmittables, edaRuntimeConfig, edaSessionRpc, encodeEdaRpcCommand, encodeEdaRpcCommittedDurableEvent, encodeEdaRpcDurableEvent, encodeEdaRpcSessionSnapshot, encodeEdaRpcSubmittables, getEDASessionDurableObjectByName, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDADurableObjectRuntimeLayer, makeEDAOpenAiClientLayer };
package/dist/openai.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { ModelSelectionPayload } from "effect-durable-agent/types/events";
2
1
  import * as Layer from "effect/Layer";
3
- import { OpenAiLanguageModel } from "@effect/ai-openai";
2
+ import { ModelSelectionPayload } from "effect-durable-agent/types/events";
3
+ import { OpenAiClient, OpenAiLanguageModel } from "@effect/ai-openai";
4
4
  import { ModelResolver } from "effect-durable-agent/services/model-resolver";
5
- import * as LanguageModel from "effect/unstable/ai/LanguageModel";
5
+ import * as LanguageModel from "effect/ai/LanguageModel";
6
6
  //#region src/providers/openai.d.ts
7
7
  /** Provider request defaults accepted by EDA's OpenAI Responses model adapter. */
8
8
  type EDAOpenAiModelConfig = Omit<typeof OpenAiLanguageModel.Config.Service, "model">;
@@ -24,6 +24,12 @@ declare const makeEDADurableObjectOpenAiModelLayer: (options: {
24
24
  readonly config?: EDAOpenAiModelConfig;
25
25
  readonly modelId: string;
26
26
  }) => Layer.Layer<LanguageModel.LanguageModel>;
27
+ /** OpenAI client layer over EDA's provider transport (Cloudflare AI Gateway or `fetch`). */
28
+ declare const makeEDAOpenAiClientLayer: (options: {
29
+ readonly aiGateway?: AiGateway | undefined;
30
+ readonly apiKey?: string | undefined;
31
+ readonly apiUrl?: string | undefined;
32
+ }) => Layer.Layer<OpenAiClient.OpenAiClient>;
27
33
  //#endregion
28
- export { EDAOpenAiModelConfig, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer };
34
+ export { EDAOpenAiModelConfig, makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDAOpenAiClientLayer };
29
35
  //# sourceMappingURL=openai.d.ts.map
package/dist/openai.js CHANGED
@@ -1,23 +1,15 @@
1
- import * as Effect from "effect/Effect";
1
+ import { r as makeEDAProviderHttpClient } from "./transport-BzgK07l4.js";
2
2
  import * as Layer from "effect/Layer";
3
+ import * as Redacted from "effect/Redacted";
4
+ import * as HttpClient from "effect/http/HttpClient";
5
+ import * as Effect from "effect/Effect";
3
6
  import { OpenAiClient, OpenAiLanguageModel } from "@effect/ai-openai";
4
7
  import { ModelResolver } from "effect-durable-agent/services/model-resolver";
5
- import * as Redacted from "effect/Redacted";
6
- import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
7
- import "effect/unstable/http/HttpBody";
8
- import * as HttpClient from "effect/unstable/http/HttpClient";
9
- import * as HttpClientError from "effect/unstable/http/HttpClientError";
10
- import * as HttpClientResponse from "effect/unstable/http/HttpClientResponse";
11
8
  //#region src/providers/openai.ts
12
9
  /** Resolves each durable selection while sharing the provider transport for the runtime lifetime. */
13
10
  const makeEDADurableObjectOpenAiModelResolverLayer = (options) => {
14
- const apiKey = optionalNonEmptyString(options.apiKey);
15
- if (apiKey === void 0 && options.aiGateway === void 0) throw new Error("OPENAI_API_KEY is required unless the EDA OpenAI model resolver is backed by a Cloudflare AI Gateway binding.");
16
- const transport = options.aiGateway === void 0 ? FetchHttpClient.layer : Layer.succeed(HttpClient.HttpClient, makeAiGatewayHttpClient(options.aiGateway));
17
- const client = OpenAiClient.layer({
18
- ...apiKey === void 0 ? {} : { apiKey: Redacted.make(apiKey) },
19
- ...options.apiUrl === void 0 ? {} : { apiUrl: options.apiUrl }
20
- }).pipe(Layer.provide(transport));
11
+ if (optionalNonEmptyString(options.apiKey) === void 0 && options.aiGateway === void 0) throw new Error("OPENAI_API_KEY is required unless the EDA OpenAI model resolver is backed by a Cloudflare AI Gateway binding.");
12
+ const client = makeEDAOpenAiClientLayer(options);
21
13
  return Layer.effect(ModelResolver, Effect.gen(function* () {
22
14
  const provider = yield* OpenAiClient.OpenAiClient;
23
15
  return { resolve: Effect.fn("OpenAiModelResolver.resolve")(function* (selection) {
@@ -31,50 +23,30 @@ const makeEDADurableObjectOpenAiModelResolverLayer = (options) => {
31
23
  };
32
24
  /** OpenAI-backed Effect AI model layer for a Cloudflare Worker. */
33
25
  const makeEDADurableObjectOpenAiModelLayer = (options) => {
34
- const apiKey = optionalNonEmptyString(options.apiKey);
35
- if (apiKey === void 0 && options.aiGateway === void 0) throw new Error("OPENAI_API_KEY is required unless the EDA OpenAI model layer is backed by a Cloudflare AI Gateway binding.");
36
- const httpClient = options.aiGateway === void 0 ? FetchHttpClient.layer : Layer.succeed(HttpClient.HttpClient, makeAiGatewayHttpClient(options.aiGateway));
37
- const client = OpenAiClient.layer({
38
- ...apiKey === void 0 ? {} : { apiKey: Redacted.make(apiKey) },
39
- ...options.apiUrl === void 0 ? {} : { apiUrl: options.apiUrl }
40
- }).pipe(Layer.provide(httpClient));
26
+ if (optionalNonEmptyString(options.apiKey) === void 0 && options.aiGateway === void 0) throw new Error("OPENAI_API_KEY is required unless the EDA OpenAI model layer is backed by a Cloudflare AI Gateway binding.");
27
+ const client = makeEDAOpenAiClientLayer(options);
41
28
  return OpenAiLanguageModel.layer({
42
29
  model: options.modelId,
43
30
  ...options.config === void 0 ? {} : { config: options.config }
44
31
  }).pipe(Layer.provide(client));
45
32
  };
46
- const makeAiGatewayHttpClient = (gateway) => HttpClient.make((request, url, signal) => Effect.tryPromise({
47
- try: async () => {
48
- const response = await gateway.run({
49
- endpoint: endpointFromUrl(url),
50
- headers: Object.fromEntries(Object.entries(request.headers).filter((entry) => typeof entry[1] === "string" && entry[0].toLowerCase() !== "host")),
51
- provider: "openai",
52
- query: requestBody(request.body)
53
- }, { signal });
54
- return HttpClientResponse.fromWeb(request, response);
55
- },
56
- catch: (cause) => new HttpClientError.HttpClientError({ reason: new HttpClientError.TransportError({
57
- request,
58
- cause,
59
- description: "Cloudflare AI Gateway request failed"
60
- }) })
61
- }));
62
- const endpointFromUrl = (url) => {
63
- return `${url.pathname.startsWith("/v1/") ? url.pathname.slice(4) : url.pathname.replace(/^\/+/, "")}${url.search}`;
64
- };
65
- const requestBody = (body) => {
66
- switch (body._tag) {
67
- case "Empty": return;
68
- case "Raw": return body.body;
69
- case "Uint8Array": return JSON.parse(new TextDecoder().decode(body.body));
70
- default: throw new Error(`Unsupported OpenAI request body for Cloudflare AI Gateway: ${body._tag}`);
71
- }
33
+ /** OpenAI client layer over EDA's provider transport (Cloudflare AI Gateway or `fetch`). */
34
+ const makeEDAOpenAiClientLayer = (options) => {
35
+ const apiKey = optionalNonEmptyString(options.apiKey);
36
+ if (apiKey === void 0 && options.aiGateway === void 0) throw new Error("OPENAI_API_KEY is required unless the EDA OpenAI client is backed by a Cloudflare AI Gateway binding.");
37
+ return OpenAiClient.layer({
38
+ ...apiKey === void 0 ? {} : { apiKey: Redacted.make(apiKey) },
39
+ ...options.apiUrl === void 0 ? {} : { apiUrl: options.apiUrl }
40
+ }).pipe(Layer.provide(Layer.succeed(HttpClient.HttpClient, makeEDAProviderHttpClient({
41
+ provider: "openai",
42
+ aiGateway: options.aiGateway
43
+ }))));
72
44
  };
73
45
  const optionalNonEmptyString = (value) => {
74
46
  const trimmed = value?.trim();
75
47
  return trimmed === void 0 || trimmed.length === 0 ? void 0 : trimmed;
76
48
  };
77
49
  //#endregion
78
- export { makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer };
50
+ export { makeEDADurableObjectOpenAiModelLayer, makeEDADurableObjectOpenAiModelResolverLayer, makeEDAOpenAiClientLayer };
79
51
 
80
52
  //# sourceMappingURL=openai.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","names":[],"sources":["../src/providers/openai.ts"],"sourcesContent":["import { OpenAiClient, OpenAiLanguageModel } from \"@effect/ai-openai\";\nimport { ModelResolver } from \"effect-durable-agent/services/model-resolver\";\nimport type { ModelSelectionPayload } from \"effect-durable-agent/types/events\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport type * as LanguageModel from \"effect/unstable/ai/LanguageModel\";\nimport * as FetchHttpClient from \"effect/unstable/http/FetchHttpClient\";\nimport * as HttpBody from \"effect/unstable/http/HttpBody\";\nimport * as HttpClient from \"effect/unstable/http/HttpClient\";\nimport * as HttpClientError from \"effect/unstable/http/HttpClientError\";\nimport * as HttpClientResponse from \"effect/unstable/http/HttpClientResponse\";\n\n/** Provider request defaults accepted by EDA's OpenAI Responses model adapter. */\nexport type EDAOpenAiModelConfig = Omit<typeof OpenAiLanguageModel.Config.Service, \"model\">;\n\n/** Resolves each durable selection while sharing the provider transport for the runtime lifetime. */\nexport const makeEDADurableObjectOpenAiModelResolverLayer = (options: {\n readonly aiGateway?: AiGateway;\n readonly apiKey?: string;\n readonly apiUrl?: string;\n readonly resolve: (selection: ModelSelectionPayload | undefined) => {\n readonly modelId: string;\n readonly config: EDAOpenAiModelConfig;\n };\n}): Layer.Layer<ModelResolver> => {\n const apiKey = optionalNonEmptyString(options.apiKey);\n if (apiKey === undefined && options.aiGateway === undefined) {\n throw new Error(\n \"OPENAI_API_KEY is required unless the EDA OpenAI model resolver is backed by a Cloudflare AI Gateway binding.\",\n );\n }\n const transport =\n options.aiGateway === undefined\n ? FetchHttpClient.layer\n : Layer.succeed(HttpClient.HttpClient, makeAiGatewayHttpClient(options.aiGateway));\n const client = OpenAiClient.layer({\n ...(apiKey === undefined ? {} : { apiKey: Redacted.make(apiKey) }),\n ...(options.apiUrl === undefined ? {} : { apiUrl: options.apiUrl }),\n }).pipe(Layer.provide(transport));\n return Layer.effect(\n ModelResolver,\n Effect.gen(function* () {\n const provider = yield* OpenAiClient.OpenAiClient;\n return {\n resolve: Effect.fn(\"OpenAiModelResolver.resolve\")(function* (selection) {\n const resolved = options.resolve(selection);\n return yield* OpenAiLanguageModel.make({\n model: resolved.modelId,\n config: resolved.config,\n }).pipe(Effect.provideService(OpenAiClient.OpenAiClient, provider));\n }),\n };\n }),\n ).pipe(Layer.provide(client));\n};\n\n/** OpenAI-backed Effect AI model layer for a Cloudflare Worker. */\nexport const makeEDADurableObjectOpenAiModelLayer = (options: {\n readonly aiGateway?: AiGateway;\n readonly apiKey?: string;\n readonly apiUrl?: string;\n readonly config?: EDAOpenAiModelConfig;\n readonly modelId: string;\n}): Layer.Layer<LanguageModel.LanguageModel> => {\n const apiKey = optionalNonEmptyString(options.apiKey);\n if (apiKey === undefined && options.aiGateway === undefined) {\n throw new Error(\n \"OPENAI_API_KEY is required unless the EDA OpenAI model layer is backed by a Cloudflare AI Gateway binding.\",\n );\n }\n\n const httpClient =\n options.aiGateway === undefined\n ? FetchHttpClient.layer\n : Layer.succeed(HttpClient.HttpClient, makeAiGatewayHttpClient(options.aiGateway));\n const client = OpenAiClient.layer({\n ...(apiKey === undefined ? {} : { apiKey: Redacted.make(apiKey) }),\n ...(options.apiUrl === undefined ? {} : { apiUrl: options.apiUrl }),\n }).pipe(Layer.provide(httpClient));\n\n return OpenAiLanguageModel.layer({\n model: options.modelId,\n ...(options.config === undefined ? {} : { config: options.config }),\n }).pipe(Layer.provide(client));\n};\n\nconst makeAiGatewayHttpClient = (gateway: AiGateway): HttpClient.HttpClient =>\n HttpClient.make((request, url, signal) =>\n Effect.tryPromise({\n try: async () => {\n const response = await gateway.run(\n {\n endpoint: endpointFromUrl(url),\n headers: Object.fromEntries(\n Object.entries(request.headers).filter(\n (entry): entry is [string, string] =>\n typeof entry[1] === \"string\" && entry[0].toLowerCase() !== \"host\",\n ),\n ),\n provider: \"openai\",\n query: requestBody(request.body),\n },\n { signal },\n );\n return HttpClientResponse.fromWeb(request, response);\n },\n catch: (cause) =>\n new HttpClientError.HttpClientError({\n reason: new HttpClientError.TransportError({\n request,\n cause,\n description: \"Cloudflare AI Gateway request failed\",\n }),\n }),\n }),\n );\n\nconst endpointFromUrl = (url: URL): string => {\n const path = url.pathname.startsWith(\"/v1/\")\n ? url.pathname.slice(\"/v1/\".length)\n : url.pathname.replace(/^\\/+/, \"\");\n return `${path}${url.search}`;\n};\n\nconst requestBody = (body: HttpBody.HttpBody): unknown => {\n switch (body._tag) {\n case \"Empty\":\n return undefined;\n case \"Raw\":\n return body.body;\n case \"Uint8Array\":\n return JSON.parse(new TextDecoder().decode(body.body)) as unknown;\n default:\n throw new Error(`Unsupported OpenAI request body for Cloudflare AI Gateway: ${body._tag}`);\n }\n};\n\nconst optionalNonEmptyString = (value: string | undefined): string | undefined => {\n const trimmed = value?.trim();\n return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed;\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"openai.js","names":[],"sources":["../src/providers/openai.ts"],"sourcesContent":["import { OpenAiClient, OpenAiLanguageModel } from \"@effect/ai-openai\";\nimport { ModelResolver } from \"effect-durable-agent/services/model-resolver\";\nimport type { ModelSelectionPayload } from \"effect-durable-agent/types/events\";\nimport * as Effect from \"effect/Effect\";\nimport * as Layer from \"effect/Layer\";\nimport * as Redacted from \"effect/Redacted\";\nimport type * as LanguageModel from \"effect/ai/LanguageModel\";\nimport * as HttpClient from \"effect/http/HttpClient\";\n\nimport { makeEDAProviderHttpClient } from \"./transport\";\n\n/** Provider request defaults accepted by EDA's OpenAI Responses model adapter. */\nexport type EDAOpenAiModelConfig = Omit<typeof OpenAiLanguageModel.Config.Service, \"model\">;\n\n/** Resolves each durable selection while sharing the provider transport for the runtime lifetime. */\nexport const makeEDADurableObjectOpenAiModelResolverLayer = (options: {\n readonly aiGateway?: AiGateway;\n readonly apiKey?: string;\n readonly apiUrl?: string;\n readonly resolve: (selection: ModelSelectionPayload | undefined) => {\n readonly modelId: string;\n readonly config: EDAOpenAiModelConfig;\n };\n}): Layer.Layer<ModelResolver> => {\n const apiKey = optionalNonEmptyString(options.apiKey);\n if (apiKey === undefined && options.aiGateway === undefined) {\n throw new Error(\n \"OPENAI_API_KEY is required unless the EDA OpenAI model resolver is backed by a Cloudflare AI Gateway binding.\",\n );\n }\n const client = makeEDAOpenAiClientLayer(options);\n return Layer.effect(\n ModelResolver,\n Effect.gen(function* () {\n const provider = yield* OpenAiClient.OpenAiClient;\n return {\n resolve: Effect.fn(\"OpenAiModelResolver.resolve\")(function* (selection) {\n const resolved = options.resolve(selection);\n return yield* OpenAiLanguageModel.make({\n model: resolved.modelId,\n config: resolved.config,\n }).pipe(Effect.provideService(OpenAiClient.OpenAiClient, provider));\n }),\n };\n }),\n ).pipe(Layer.provide(client));\n};\n\n/** OpenAI-backed Effect AI model layer for a Cloudflare Worker. */\nexport const makeEDADurableObjectOpenAiModelLayer = (options: {\n readonly aiGateway?: AiGateway;\n readonly apiKey?: string;\n readonly apiUrl?: string;\n readonly config?: EDAOpenAiModelConfig;\n readonly modelId: string;\n}): Layer.Layer<LanguageModel.LanguageModel> => {\n const apiKey = optionalNonEmptyString(options.apiKey);\n if (apiKey === undefined && options.aiGateway === undefined) {\n throw new Error(\n \"OPENAI_API_KEY is required unless the EDA OpenAI model layer is backed by a Cloudflare AI Gateway binding.\",\n );\n }\n\n const client = makeEDAOpenAiClientLayer(options);\n\n return OpenAiLanguageModel.layer({\n model: options.modelId,\n ...(options.config === undefined ? {} : { config: options.config }),\n }).pipe(Layer.provide(client));\n};\n\n/** OpenAI client layer over EDA's provider transport (Cloudflare AI Gateway or `fetch`). */\nexport const makeEDAOpenAiClientLayer = (options: {\n readonly aiGateway?: AiGateway | undefined;\n readonly apiKey?: string | undefined;\n readonly apiUrl?: string | undefined;\n}): Layer.Layer<OpenAiClient.OpenAiClient> => {\n const apiKey = optionalNonEmptyString(options.apiKey);\n if (apiKey === undefined && options.aiGateway === undefined) {\n throw new Error(\n \"OPENAI_API_KEY is required unless the EDA OpenAI client is backed by a Cloudflare AI Gateway binding.\",\n );\n }\n return OpenAiClient.layer({\n ...(apiKey === undefined ? {} : { apiKey: Redacted.make(apiKey) }),\n ...(options.apiUrl === undefined ? {} : { apiUrl: options.apiUrl }),\n }).pipe(\n Layer.provide(\n Layer.succeed(\n HttpClient.HttpClient,\n makeEDAProviderHttpClient({ provider: \"openai\", aiGateway: options.aiGateway }),\n ),\n ),\n );\n};\n\nconst optionalNonEmptyString = (value: string | undefined): string | undefined => {\n const trimmed = value?.trim();\n return trimmed === undefined || trimmed.length === 0 ? undefined : trimmed;\n};\n"],"mappings":";;;;;;;;;AAeA,MAAa,gDAAgD,YAQ3B;CAEhC,IADe,uBAAuB,QAAQ,MACrC,MAAM,KAAA,KAAa,QAAQ,cAAc,KAAA,GAChD,MAAM,IAAI,MACR,+GACF;CAEF,MAAM,SAAS,yBAAyB,OAAO;CAC/C,OAAO,MAAM,OACX,eACA,OAAO,IAAI,aAAa;EACtB,MAAM,WAAW,OAAO,aAAa;EACrC,OAAO,EACL,SAAS,OAAO,GAAG,6BAA6B,CAAC,CAAC,WAAW,WAAW;GACtE,MAAM,WAAW,QAAQ,QAAQ,SAAS;GAC1C,OAAO,OAAO,oBAAoB,KAAK;IACrC,OAAO,SAAS;IAChB,QAAQ,SAAS;GACnB,CAAC,CAAC,CAAC,KAAK,OAAO,eAAe,aAAa,cAAc,QAAQ,CAAC;EACpE,CAAC,EACH;CACF,CAAC,CACH,CAAC,CAAC,KAAK,MAAM,QAAQ,MAAM,CAAC;AAC9B;;AAGA,MAAa,wCAAwC,YAML;CAE9C,IADe,uBAAuB,QAAQ,MACrC,MAAM,KAAA,KAAa,QAAQ,cAAc,KAAA,GAChD,MAAM,IAAI,MACR,4GACF;CAGF,MAAM,SAAS,yBAAyB,OAAO;CAE/C,OAAO,oBAAoB,MAAM;EAC/B,OAAO,QAAQ;EACf,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;CACnE,CAAC,CAAC,CAAC,KAAK,MAAM,QAAQ,MAAM,CAAC;AAC/B;;AAGA,MAAa,4BAA4B,YAIK;CAC5C,MAAM,SAAS,uBAAuB,QAAQ,MAAM;CACpD,IAAI,WAAW,KAAA,KAAa,QAAQ,cAAc,KAAA,GAChD,MAAM,IAAI,MACR,uGACF;CAEF,OAAO,aAAa,MAAM;EACxB,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,SAAS,KAAK,MAAM,EAAE;EAChE,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;CACnE,CAAC,CAAC,CAAC,KACD,MAAM,QACJ,MAAM,QACJ,WAAW,YACX,0BAA0B;EAAE,UAAU;EAAU,WAAW,QAAQ;CAAU,CAAC,CAChF,CACF,CACF;AACF;AAEA,MAAM,0BAA0B,UAAkD;CAChF,MAAM,UAAU,OAAO,KAAK;CAC5B,OAAO,YAAY,KAAA,KAAa,QAAQ,WAAW,IAAI,KAAA,IAAY;AACrE"}
@@ -0,0 +1,53 @@
1
+ import { EDAOpenAiModelConfig } from "./openai.js";
2
+ import { EDAAnthropicClientOptions, EDAAnthropicModelConfig, prepareEDAAnthropicPrompt } from "./anthropic.js";
3
+ import * as Layer from "effect/Layer";
4
+ import { ModelSelectionPayload } from "effect-durable-agent/types/events";
5
+ import { CompactionExecutor } from "effect-durable-agent/services/compaction";
6
+ import { ModelResolver } from "effect-durable-agent/services/model-resolver";
7
+ //#region src/providers/providers.d.ts
8
+ /** Model request settings the host derives from a durable selection. */
9
+ type EDAResolvedModel = {
10
+ readonly provider: "openai";
11
+ readonly modelId: string;
12
+ readonly config: EDAOpenAiModelConfig;
13
+ } | {
14
+ readonly provider: "anthropic";
15
+ readonly modelId: string;
16
+ readonly config: EDAAnthropicModelConfig;
17
+ };
18
+ /** Clients for every provider a host serves; a session runs on the one its selection names. */
19
+ interface EDAMultiProviderModelResolverOptions {
20
+ readonly openai?: {
21
+ readonly aiGateway?: AiGateway | undefined;
22
+ readonly apiKey?: string | undefined;
23
+ readonly apiUrl?: string | undefined;
24
+ };
25
+ readonly anthropic?: EDAAnthropicClientOptions;
26
+ /** Host policy: validate the recorded selection and choose request settings. Throw to reject. */
27
+ readonly resolve: (selection: ModelSelectionPayload | undefined) => EDAResolvedModel;
28
+ }
29
+ /**
30
+ * Resolves each durable selection to the provider it names, sharing one client per provider for
31
+ * the runtime lifetime, and prepares prompts in that provider's cache and compaction shape.
32
+ */
33
+ declare const makeEDAMultiProviderModelResolverLayer: (options: EDAMultiProviderModelResolverOptions) => Layer.Layer<ModelResolver>;
34
+ /** Options for provider-native compaction. */
35
+ interface EDANativeCompactionOptions {
36
+ /**
37
+ * Custom summarization prompt for Anthropic (`compaction.instructions`, up to 16,384 characters).
38
+ * OpenAI compaction takes no prompt.
39
+ */
40
+ readonly anthropicInstructions?: string | undefined;
41
+ /** Output budget for the Anthropic summary call, thinking included. Defaults to 16,000. */
42
+ readonly anthropicMaxTokens?: number | undefined;
43
+ }
44
+ /**
45
+ * Compacts with the session provider's own endpoint: OpenAI `/responses/compact`, Anthropic
46
+ * on-demand compaction (`compact-2026-09-04`). Each call carries the exact earlier request prompt,
47
+ * so it reads the conversation from the provider cache, and the returned native items replace the
48
+ * summarized history on later requests. Other providers fall back to a prompt-prefix summary.
49
+ */
50
+ declare const makeEDANativeCompactionExecutorLayer: (options?: EDANativeCompactionOptions) => Layer.Layer<CompactionExecutor>;
51
+ //#endregion
52
+ export { type EDAAnthropicModelConfig, EDAMultiProviderModelResolverOptions, EDANativeCompactionOptions, type EDAOpenAiModelConfig, EDAResolvedModel, makeEDAMultiProviderModelResolverLayer, makeEDANativeCompactionExecutorLayer, prepareEDAAnthropicPrompt };
53
+ //# sourceMappingURL=providers.d.ts.map