@effect-agent/platform-cloudflare 0.1.0-beta.33 → 0.1.0-beta.34

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/dist/index.d.mts CHANGED
@@ -6,10 +6,9 @@ import { Context, Crypto, Effect, Layer, Option, Schema, Scope } from "effect";
6
6
  import { AbortCommand, AbortIntent, AdmissionConflict, AgentBindingResolver, AppendConflict, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, CanonicalRecordEnvelope, CanonicalSequence, ConversationNotMaterialized, ConversationStore, ConversationStoreError, DefinitionDigests, DigestError, DurableAgentRuntime, DurableBindingFailure, DurableRuntimeConfig, DurableRuntimeFailpointError, DurableRuntimeFailpointHandler, DurableSubmitAgent, DurableSubmitOptions, DurableWorkerFailure, FenceRejected, IntegrityReport, JoinedToHost, LedgerError, ObligationReport, ObligationThresholds, OperationAuthorizerService, OperationDenied, OwnershipLost, ProducerId, Receipt, RecoveryExplanation, RecoveryReport, ResolvedBinding, RetryCommand, RetryRefused, RunJournalError, Settlement, SettlementConflict, SubmissionLedger, ToolReconciler, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, WakeScheduler } from "@effect-agent/session";
7
7
  import { ConversationPortTransport, DoStorageFailpointHandler, DoStorageInitializationError, PortRequest, PortResponse } from "@effect-agent/storage-cloudflare";
8
8
  import { AgentInputError, ConversationId } from "@effect-agent/core";
9
- import { RunContextPreparation, RunCostEstimator } from "@effect-agent/engine";
10
- import { DurableObjectState as DurableObjectState$1, WorkerEnvironment } from "effect-cf";
9
+ import { RunContextPreparation, RunCostEstimator, RunToolFailureObserver } from "@effect-agent/engine";
10
+ import { DurableObject, DurableObjectState as DurableObjectState$1, WorkerEnvironment } from "effect-cf";
11
11
  import { CodeExecutor, SandboxImplementation } from "@effect-agent/sandbox";
12
- import { DurableObject as DurableObject$1 } from "cloudflare:workers";
13
12
  //#region src/bindings.d.ts
14
13
  declare const CloudflareBindingError_base: Schema.Class<CloudflareBindingError, Schema.TaggedStruct<"CloudflareBindingError", {
15
14
  readonly binding: Schema.String;
@@ -29,25 +28,27 @@ declare class CloudflareBindingError extends CloudflareBindingError_base {}
29
28
  * and the cross-Object transport call it through `DurableObjectNamespace` stubs. Every
30
29
  * `encoded` value is a Schema-encoded envelope (`client.ts` wire schemas for host entry
31
30
  * points, `@effect-agent/storage-cloudflare` port envelopes for `portCall`), so the RPC
32
- * boundary carries only structured-cloneable JSON.
31
+ * boundary carries only structured-cloneable JSON. The optional trailing trace context is
32
+ * transient native RPC metadata, stripped by an opted-in effect-cf receiver before decoding
33
+ * the host envelope. It never enters durable state.
33
34
  */
34
35
  interface ConversationObjectRpc extends Rpc.DurableObjectBranded {
35
36
  /** Admission-limits gate + `DurableAgentRuntime.submit`; answers a `SubmitResponse`. */
36
- submitEncoded(encoded: unknown): Promise<unknown>;
37
+ submitEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
37
38
  /** Wake-hinted, poll-guaranteed settlement wait; answers an `AwaitSettlementResponse`. */
38
- awaitSettlementEncoded(encoded: unknown): Promise<unknown>;
39
+ awaitSettlementEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
39
40
  /** Event-driven durable progress wait; answers a `ProgressObserved` host response. */
40
- awaitProgressEncoded(encoded: unknown): Promise<unknown>;
41
+ awaitProgressEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
41
42
  /** Best-effort cancellation for one in-flight progress wait. */
42
- cancelProgressEncoded(encoded: unknown): Promise<unknown>;
43
+ cancelProgressEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
43
44
  /** One bounded page of canonical records; answers an `ObservePageResponse`. */
44
- observePage(encoded: unknown): Promise<unknown>;
45
+ observePage(encoded: unknown, traceContext?: unknown): Promise<unknown>;
45
46
  /** Durable abort intent; answers an `AbortResponse`. */
46
- abortEncoded(encoded: unknown): Promise<unknown>;
47
+ abortEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
47
48
  /** Durable approval decision (plan §2.6); answers a `ResolveApprovalResponse`. */
48
- resolveApprovalEncoded(encoded: unknown): Promise<unknown>;
49
+ resolveApprovalEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
49
50
  /** Authorized DUR-017 Unknown-Outcome resolution; answers a `ResolveUnknownResponse`. */
50
- resolveUnknownEncoded(encoded: unknown): Promise<unknown>;
51
+ resolveUnknownEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
51
52
  /** Owner-side cross-Object port endpoint (WP2 envelopes, executed on LOCAL facets). */
52
53
  portCall(encoded: unknown): Promise<unknown>;
53
54
  /** Droppable liveness hint from another Object: arms an immediate alarm. */
@@ -55,6 +56,8 @@ interface ConversationObjectRpc extends Rpc.DurableObjectBranded {
55
56
  }
56
57
  declare const ConversationObjectNamespace_base: Context.ServiceClass<ConversationObjectNamespace, "@effect-agent/platform-cloudflare/ConversationObjectNamespace", {
57
58
  readonly namespace: DurableObjectNamespace<ConversationObjectRpc>;
59
+ /** Stable binding name for opted-in native RPC tracing; absent by default. */
60
+ readonly rpcTracing?: string;
58
61
  }>;
59
62
  /**
60
63
  * The `DurableObjectNamespace` binding that addresses Conversation Objects. The Object
@@ -71,8 +74,13 @@ declare class ConversationObjectNamespace extends ConversationObjectNamespace_ba
71
74
  * a missing or misshaped binding fails typed before any Layer is built.
72
75
  */
73
76
  declare const conversationNamespaceFromEnv: (env: unknown, binding: string) => Effect.Effect<DurableObjectNamespace<ConversationObjectRpc>, CloudflareBindingError, never>;
74
- /** `ConversationObjectNamespace` built from the untyped Worker `env` (fails typed). */
75
- declare const conversationNamespaceLayer: (env: unknown, binding: string) => Layer.Layer<ConversationObjectNamespace, CloudflareBindingError>;
77
+ /**
78
+ * Build the namespace from Worker `env` (fails typed). Enable `rpcTracing` only when the
79
+ * receiver also opts into the effect-cf native RPC trace-context contract.
80
+ */
81
+ declare const conversationNamespaceLayer: (env: unknown, binding: string, options?: {
82
+ readonly rpcTracing?: boolean;
83
+ }) => Layer.Layer<ConversationObjectNamespace, CloudflareBindingError>;
76
84
  declare const DurableObjectContext_base: Context.ServiceClass<DurableObjectContext, "@effect-agent/platform-cloudflare/DurableObjectContext", {
77
85
  readonly ctx: DurableObjectState;
78
86
  readonly env: unknown;
@@ -375,6 +383,8 @@ interface CloudflareDurableRuntimeOptions {
375
383
  readonly abortPollInterval?: number | undefined;
376
384
  /** Deployment-owned pricing authority used by durable cost budgets and settlements. */
377
385
  readonly estimateCostMicrousd?: RunCostEstimator | undefined;
386
+ /** Closed trusted Tool failure reporting. Omission masks ambient observers at construction. */
387
+ readonly toolFailureObserver?: RunToolFailureObserver | undefined;
378
388
  /** Milliseconds; default 25. */
379
389
  readonly observationPollInterval?: number | undefined;
380
390
  /** Bytes; default just under the 2 MB platform value limit. */
@@ -717,6 +727,10 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
717
727
  readonly kind: "follow-up" | "steering" | "user";
718
728
  readonly runId?: string | undefined;
719
729
  readonly input: Schema.Json;
730
+ } | {
731
+ readonly _tag: "RunStarted";
732
+ readonly runId: string;
733
+ readonly maxDurationMillis: number;
720
734
  } | {
721
735
  readonly _tag: "ModelCompleted";
722
736
  readonly runId: string;
@@ -1052,7 +1066,7 @@ declare const encodeHostResponse: (input: AbortRecorded | ApprovalRecorded | Hos
1052
1066
  readonly attemptedEpoch: number;
1053
1067
  } | {
1054
1068
  readonly _tag: "DurableRuntimeFailpointError";
1055
- readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "claim:after-claim" | "compaction:after-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "resolve:after-intent" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append";
1069
+ readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "claim:after-claim" | "compaction:after-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "resolve:after-intent" | "run:after-start-append" | "run:before-start-append" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append";
1056
1070
  } | {
1057
1071
  readonly _tag: "AdmissionLimitExceeded";
1058
1072
  readonly limit: "database-bytes" | "input-bytes" | "queue-depth";
@@ -1141,6 +1155,8 @@ declare class CloudflareConversationClient extends CloudflareConversationClient_
1141
1155
  */
1142
1156
  /** Construction options for one deployed Conversation Object class. */
1143
1157
  interface ConversationObjectOptions extends CloudflareDurableRuntimeOptions {
1158
+ /** Accept transient native RPC tracing through effect-cf; disabled by default. */
1159
+ readonly rpcTracing?: boolean;
1144
1160
  /**
1145
1161
  * Name of the Worker `env` binding carrying THIS class's `DurableObjectNamespace` — the
1146
1162
  * Object's route back to sibling Conversation Objects for the WP2 cross-Object port calls
@@ -1148,6 +1164,8 @@ interface ConversationObjectOptions extends CloudflareDurableRuntimeOptions {
1148
1164
  */
1149
1165
  readonly namespaceBinding: string;
1150
1166
  }
1167
+ type EndpointServices = CloudflareDurableRuntimeServices | DurableObjectContext;
1168
+ type RuntimeServices = EndpointServices | ConversationObjectNamespace;
1151
1169
  declare const AdminExplainRequest_base: Schema.Class<AdminExplainRequest, Schema.Struct<{
1152
1170
  readonly submissionId: Schema.optionalKey<Schema.brand<Schema.NonEmptyString, "@effect-agent/core/SubmissionId">>;
1153
1171
  }>, {}>;
@@ -1597,20 +1615,43 @@ declare const encodeAdminResponse: (input: AdminFailed | ExplainedRecovery | Obl
1597
1615
  } | {
1598
1616
  readonly _tag: "AdminFailed";
1599
1617
  readonly failure: {
1618
+ readonly _tag: "DurableAlarmError";
1619
+ readonly operation: string;
1620
+ readonly message: string;
1621
+ readonly cause?: Schema.Json | undefined;
1622
+ } | {
1600
1623
  readonly _tag: "OperationDenied";
1601
1624
  readonly operation: "explain" | "observe" | "resolveApproval" | "resolveUnknown" | "retry" | "scanObligations" | "verify" | "wake";
1602
1625
  readonly reason: string;
1603
1626
  readonly conversationId?: string | undefined;
1604
1627
  readonly submissionId?: string | undefined;
1605
1628
  } | {
1606
- readonly _tag: "DigestError";
1629
+ readonly _tag: "RetryRefused";
1630
+ readonly submissionId: string;
1631
+ readonly refusal: "await-approval-decision" | "await-unknown-resolution" | "settled";
1632
+ readonly decisionTag: string;
1607
1633
  readonly message: string;
1608
- readonly cause?: Schema.Json | undefined;
1609
1634
  } | {
1610
1635
  readonly _tag: "LedgerError";
1611
1636
  readonly operation: string;
1612
1637
  readonly message: string;
1613
1638
  readonly cause?: Schema.Json | undefined;
1639
+ } | {
1640
+ readonly _tag: "RunJournalError";
1641
+ readonly message: string;
1642
+ readonly cause?: Schema.Json | undefined;
1643
+ } | {
1644
+ readonly _tag: "DigestError";
1645
+ readonly message: string;
1646
+ readonly cause?: Schema.Json | undefined;
1647
+ } | {
1648
+ readonly _tag: "OwnershipLost";
1649
+ readonly submissionId: string;
1650
+ readonly actualEpoch: number;
1651
+ } | {
1652
+ readonly _tag: "SettlementConflict";
1653
+ readonly submissionId: string;
1654
+ readonly existingOutcome: "aborted" | "completed" | "failed";
1614
1655
  } | {
1615
1656
  readonly _tag: "ConversationStoreError";
1616
1657
  readonly operation: string;
@@ -1633,46 +1674,23 @@ declare const encodeAdminResponse: (input: AdminFailed | ExplainedRecovery | Obl
1633
1674
  readonly attemptedEpoch: number;
1634
1675
  } | {
1635
1676
  readonly _tag: "DurableRuntimeFailpointError";
1636
- readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "claim:after-claim" | "compaction:after-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "resolve:after-intent" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append";
1637
- } | {
1638
- readonly _tag: "DurableAlarmError";
1639
- readonly operation: string;
1640
- readonly message: string;
1641
- readonly cause?: Schema.Json | undefined;
1677
+ readonly location: "abort:after-intent" | "approval:after-request-append" | "approval:after-suspend" | "claim:after-claim" | "compaction:after-canonical-append" | "input:after-canonical-append" | "join:after-canonical-append" | "join:after-claim" | "resolve:after-intent" | "run:after-start-append" | "run:before-start-append" | "step:after-step-append" | "subagent:after-admit" | "subagent:after-child-abort-intent" | "subagent:after-child-ready" | "subagent:after-join-append" | "subagent:after-release" | "subagent:after-release-pending" | "subagent:after-request-append" | "subagent:after-reserve" | "subagent:after-sibling-settle" | "subagent:after-start-append" | "subagent:after-suspend" | "submit:after-admit" | "submit:after-materialize" | "terminalize:after-canonical-append" | "terminalize:after-reserve" | "tools:after-prepared-append" | "turn:after-canonical-append" | "turn:after-response-append" | "turn:after-results-append";
1642
1678
  } | {
1643
1679
  readonly _tag: "HostProtocolError";
1644
1680
  readonly message: string;
1645
- } | {
1646
- readonly _tag: "SettlementConflict";
1647
- readonly submissionId: string;
1648
- readonly existingOutcome: "aborted" | "completed" | "failed";
1649
- } | {
1650
- readonly _tag: "RetryRefused";
1651
- readonly submissionId: string;
1652
- readonly refusal: "await-approval-decision" | "await-unknown-resolution" | "settled";
1653
- readonly decisionTag: string;
1654
- readonly message: string;
1655
- } | {
1656
- readonly _tag: "RunJournalError";
1657
- readonly message: string;
1658
- readonly cause?: Schema.Json | undefined;
1659
- } | {
1660
- readonly _tag: "OwnershipLost";
1661
- readonly submissionId: string;
1662
- readonly actualEpoch: number;
1663
1681
  };
1664
1682
  }, Schema.SchemaError, never>;
1665
1683
  declare const decodeAdminResponse: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Effect.Effect<AdminFailed | ExplainedRecovery | ObligationsScanned | RetryExecuted | VerifiedIntegrity, Schema.SchemaError, never>;
1666
- /** The public endpoint surface of one Conversation Object instance. */
1667
- interface ConversationObjectInstance extends DurableObject$1 {
1668
- submitEncoded(encoded: unknown): Promise<unknown>;
1669
- awaitSettlementEncoded(encoded: unknown): Promise<unknown>;
1670
- awaitProgressEncoded(encoded: unknown): Promise<unknown>;
1671
- cancelProgressEncoded(encoded: unknown): Promise<unknown>;
1672
- observePage(encoded: unknown): Promise<unknown>;
1673
- abortEncoded(encoded: unknown): Promise<unknown>;
1674
- resolveApprovalEncoded(encoded: unknown): Promise<unknown>;
1675
- resolveUnknownEncoded(encoded: unknown): Promise<unknown>;
1684
+ /** The public endpoints and effect-cf invocation hook of one Conversation Object instance. */
1685
+ interface ConversationObjectInstance<EventServices = never> extends InstanceType<DurableObject.DurableObjectClass<Record<never, never>, RuntimeServices | EventServices>> {
1686
+ submitEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1687
+ awaitSettlementEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1688
+ awaitProgressEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1689
+ cancelProgressEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1690
+ observePage(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1691
+ abortEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1692
+ resolveApprovalEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1693
+ resolveUnknownEncoded(encoded: unknown, traceContext?: unknown): Promise<unknown>;
1676
1694
  explainEncoded(encoded: unknown): Promise<unknown>;
1677
1695
  verifyEncoded(encoded: unknown): Promise<unknown>;
1678
1696
  retryEncoded(encoded: unknown): Promise<unknown>;
@@ -1682,8 +1700,8 @@ interface ConversationObjectInstance extends DurableObject$1 {
1682
1700
  alarm(alarmInfo?: AlarmInvocationInfo): Promise<void> | void;
1683
1701
  }
1684
1702
  /** The constructor shape workerd instantiates for each Conversation Object. */
1685
- interface ConversationObjectClass {
1686
- new (ctx: DurableObjectState, env: Cloudflare.Env): ConversationObjectInstance;
1703
+ interface ConversationObjectClass<EventServices = never> {
1704
+ new (ctx: DurableObjectState, env: Cloudflare.Env): ConversationObjectInstance<EventServices>;
1687
1705
  }
1688
1706
  /**
1689
1707
  * Build the application's Conversation Object class (export it from the Worker entry).
@@ -1692,7 +1710,7 @@ interface ConversationObjectClass {
1692
1710
  * event, so a host can install Tracer/Logger/Metric services and `OtlpExporter.Flusher` without
1693
1711
  * Effect Agent owning exporter lifecycle machinery.
1694
1712
  */
1695
- declare const makeConversationObjectClass: <EventLayerError = never, EventServices = never>(options: ConversationObjectOptions, observability?: Layer.Layer<EventServices, EventLayerError, DurableObjectContext | ConversationObjectNamespace | DurableObjectState$1.DurableObjectState | WorkerEnvironment>) => ConversationObjectClass;
1713
+ declare const makeConversationObjectClass: <EventLayerError = never, EventServices = never>(options: ConversationObjectOptions, observability?: Layer.Layer<EventServices, EventLayerError, DurableObjectContext | ConversationObjectNamespace | DurableObjectState$1.DurableObjectState | WorkerEnvironment>) => ConversationObjectClass<EventServices>;
1696
1714
  //#endregion
1697
1715
  //#region src/code-mode-executor.d.ts
1698
1716
  /**
package/dist/index.mjs CHANGED
@@ -6,10 +6,10 @@ import { Clock, Context, Crypto, Deferred, Duration, Effect, Exit, Fiber, Layer,
6
6
  import { AbortCommand, AbortIntent, AdmissionConflict, AgentBindingResolver, AppendConflict, ApprovalConflict, ApprovalDecisionCommand, ApprovalDecisionIntent, CanonicalRecordEnvelope, CanonicalSequence, ConversationNotMaterialized, ConversationRead, ConversationStore, ConversationStoreError, DEFAULT_OWNERSHIP_LEASE_DURATION, DefinitionDigests, DeploymentId, DigestError, DurableAgentRuntime, DurableRuntimeConfig, DurableRuntimeFailpoint, DurableRuntimeFailpointError, FenceRejected, IdempotencyKey, IntegrityReport, JoinedToHost, LedgerError, ObligationReport, ObligationThresholds, OperationAuthorizationRequest, OperationAuthorizer, OperationDenied, OwnershipLost, PersistedJson, Principal, ProducerId, Receipt, RecoveryExplanation, RecoveryReport, RetryCommand, RetryRefused, RunJournalError, Settlement, SettlementConflict, SubmissionLedger, SubmissionLookupByKey, ToolReconciler, UnknownResolutionCommand, UnknownResolutionConflict, UnknownResolutionIntent, WakeScheduler, makeWakeSubscriptionHub, operationAuthorizerLayer } from "@effect-agent/session";
7
7
  import { ConversationPortTransport, DEFAULT_MAX_STORED_VALUE_BYTES, conversationStoreLayer, decodePortRequest, encodePortResponse, executePortRequest, portTransportFailure, routedConversationStoreLayer, routedSubmissionLedgerLayer, storageConfigLayer, storageFailpointLayer, submissionLedgerLayer } from "@effect-agent/storage-cloudflare";
8
8
  import { AgentId, AgentInputError, ConversationId, SubmissionId } from "@effect-agent/core";
9
- import { RunContextPreparationPassthrough } from "@effect-agent/engine";
9
+ import { CurrentToolFailureObserver, RunContextPreparationPassthrough, toolFailureObserverLayer } from "@effect-agent/engine";
10
10
  import { BrowserCrypto } from "@effect/platform-browser";
11
11
  import { SqliteClient } from "@effect/sql-sqlite-do";
12
- import { DurableObject, DurableObjectState, WorkerEnvironment } from "effect-cf";
12
+ import { DurableObject, DurableObjectState, RpcTracing, WorkerEnvironment } from "effect-cf";
13
13
  import { CodeExecutionHost, CodeExecutionProtocolError, CodeExecutionResourceUse, CodeExecutionResult, CodeExecutionTimeoutError, CodeExecutor, CodeExecutorStartError, CodeExecutorTerminatedError, CodeExecutorUnsupportedError, CodeHostCall, CodeHostCallLimitError, CodeHostCallResult, CodeOutputLimitError, CodeProgramFailedError, CodeSourceError, SandboxImplementation } from "@effect-agent/sandbox";
14
14
  import { RpcTarget } from "cloudflare:workers";
15
15
  //#region src/bindings.ts
@@ -64,8 +64,14 @@ const conversationNamespaceFromEnv = Effect.fn("conversationNamespaceFromEnv")(f
64
64
  message: `env.${binding} is not a DurableObjectNamespace binding; declare the Conversation Object class under this binding in the Worker configuration.`
65
65
  });
66
66
  });
67
- /** `ConversationObjectNamespace` built from the untyped Worker `env` (fails typed). */
68
- const conversationNamespaceLayer = (env, binding) => Layer.effect(ConversationObjectNamespace)(Effect.map(conversationNamespaceFromEnv(env, binding), (namespace) => ({ namespace })));
67
+ /**
68
+ * Build the namespace from Worker `env` (fails typed). Enable `rpcTracing` only when the
69
+ * receiver also opts into the effect-cf native RPC trace-context contract.
70
+ */
71
+ const conversationNamespaceLayer = (env, binding, options = {}) => Layer.effect(ConversationObjectNamespace)(Effect.map(conversationNamespaceFromEnv(env, binding), (namespace) => ({
72
+ namespace,
73
+ ...options.rpcTracing === true ? { rpcTracing: binding } : {}
74
+ })));
69
75
  /**
70
76
  * The live Durable Object execution context of THIS incarnation. Only Layer construction and
71
77
  * the alarm service consume it; important state never lives on it (`ctx.storage` is truth,
@@ -765,6 +771,7 @@ var CloudflareDurableRuntime = class {
765
771
  const maintenanceFailpointLayer = options.maintenanceFailpoint === void 0 ? ConversationMaintenanceFailpoint.layer : Layer.succeed(ConversationMaintenanceFailpoint)({ hit: options.maintenanceFailpoint(ctx) });
766
772
  const reconcilerLayer = options.toolReconciler ?? ToolReconciler.uncertain;
767
773
  const authorizerLayer = options.operationAuthorizer === void 0 ? Layer.empty : operationAuthorizerLayer(options.operationAuthorizer);
774
+ const observerLayer = options.toolFailureObserver === void 0 ? Layer.succeed(CurrentToolFailureObserver)(void 0) : toolFailureObserverLayer(options.toolFailureObserver);
768
775
  const bindingResolverLayer = Layer.effect(AgentBindingResolver)(Effect.map(resolveBindings(options.bindings, {
769
776
  ctx,
770
777
  env,
@@ -778,7 +785,7 @@ var CloudflareDurableRuntime = class {
778
785
  producerId
779
786
  }).pipe(Layer.provide(BrowserCrypto.layer));
780
787
  const base = Layer.mergeAll(identityLayer, cloudflareConfigLayer, DurableAlarmService.layer, maintenanceFailpointLayer, ProgressWaitRegistry.layer);
781
- const runtimeStack = DurableAgentRuntime.layerWithContext.pipe(Layer.provideMerge(routedPorts), Layer.provideMerge(cloudflareWakeSchedulerLayer), Layer.provideMerge(runtimeConfigLayer), Layer.provideMerge(bindingResolverLayer), Layer.provide(Layer.mergeAll(runtimeFailpointLayer, reconcilerLayer, authorizerLayer, runContextLayer, BrowserCrypto.layer)), Layer.provideMerge(base));
788
+ const runtimeStack = DurableAgentRuntime.layerWithContext.pipe(Layer.provideMerge(routedPorts), Layer.provideMerge(cloudflareWakeSchedulerLayer), Layer.provideMerge(runtimeConfigLayer), Layer.provideMerge(bindingResolverLayer), Layer.provide(Layer.mergeAll(runtimeFailpointLayer, reconcilerLayer, authorizerLayer, observerLayer, runContextLayer, BrowserCrypto.layer)), Layer.provideMerge(base));
782
789
  return Layer.mergeAll(runtimeStack, ConversationMaintenance.layer.pipe(Layer.provide(runtimeStack)), portsEndpointLayer);
783
790
  }));
784
791
  }
@@ -960,23 +967,39 @@ const outOfContract = (conversationId, operation, observed) => ConversationClien
960
967
  conversationId,
961
968
  message: boundHostDiagnostic(`The Conversation Object answered ${operation} with the out-of-contract ${observed}.`)
962
969
  });
970
+ const hostRpcMethods = {
971
+ submit: "submitEncoded",
972
+ awaitSettlement: "awaitSettlementEncoded",
973
+ awaitProgress: "awaitProgressEncoded",
974
+ cancelProgress: "cancelProgressEncoded",
975
+ observePage: "observePage",
976
+ abort: "abortEncoded",
977
+ resolveApproval: "resolveApprovalEncoded",
978
+ resolveUnknown: "resolveUnknownEncoded"
979
+ };
963
980
  /** Worker-side client over the Conversation Object namespace (DEPLOY-010). */
964
981
  var CloudflareConversationClient = class CloudflareConversationClient extends Context.Service()("@effect-agent/platform-cloudflare/CloudflareConversationClient") {
965
982
  static layer = Layer.effect(CloudflareConversationClient)(Effect.gen(function* () {
966
- const { namespace } = yield* ConversationObjectNamespace;
983
+ const { namespace, rpcTracing } = yield* ConversationObjectNamespace;
967
984
  const crypto = yield* Crypto.Crypto;
968
- const call = (conversationId, operation, invoke) => Effect.tryPromise({
969
- try: () => invoke(namespace.get(namespace.idFromName(conversationId))),
970
- catch: (cause) => ConversationClientError.make({
971
- conversationId,
972
- message: boundHostDiagnostic(`${operation} did not reach the Conversation Object: ${safeCauseMessage(cause, "the RPC failed without a diagnostic")}`),
973
- cause,
974
- ...cloudflareFailureSignals(cause)
975
- })
976
- }).pipe(Effect.flatMap((raw) => decodeHostResponse(raw).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`The ${operation} answer could not be decoded: ${error.message}`) })))), Effect.withSpan("CloudflareConversationClient.call", { attributes: {
985
+ const call = Effect.fn(function* (conversationId, operation, encoded) {
986
+ const traceArgs = rpcTracing === void 0 ? [] : yield* RpcTracing.withRpcTraceContext([]);
987
+ const raw = yield* Effect.tryPromise({
988
+ try: () => {
989
+ return namespace.get(namespace.idFromName(conversationId))[hostRpcMethods[operation]](encoded, ...traceArgs);
990
+ },
991
+ catch: (cause) => ConversationClientError.make({
992
+ conversationId,
993
+ message: boundHostDiagnostic(`${operation} did not reach the Conversation Object: ${safeCauseMessage(cause, "the RPC failed without a diagnostic")}`),
994
+ cause,
995
+ ...cloudflareFailureSignals(cause)
996
+ })
997
+ });
998
+ return yield* decodeHostResponse(raw).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`The ${operation} answer could not be decoded: ${error.message}`) })));
999
+ }, (effect, conversationId, operation) => rpcTracing === void 0 ? Effect.withSpan(effect, "CloudflareConversationClient.call", { attributes: {
977
1000
  conversationId,
978
1001
  operation
979
- } }));
1002
+ } }) : RpcTracing.withRpcClientSpan(effect, rpcTracing, hostRpcMethods[operation]));
980
1003
  const expect = (conversationId, operation, resultSchema, failureSchema) => {
981
1004
  const isExpectedResult = Schema.is(resultSchema);
982
1005
  const isExpectedFailure = Schema.is(failureSchema);
@@ -995,10 +1018,10 @@ var CloudflareConversationClient = class CloudflareConversationClient extends Co
995
1018
  limit: options?.limit ?? 256
996
1019
  });
997
1020
  const encoded = yield* encodeObservePageRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`observePage request encode failed: ${error.message}`) })));
998
- const response = yield* call(conversationId, "observePage", (stub) => stub.observePage(encoded));
1021
+ const response = yield* call(conversationId, "observePage", encoded);
999
1022
  return (yield* expect(conversationId, "observePage", ObservedPage, ClientObserveHostFailure)(response)).records;
1000
1023
  });
1001
- const cancelProgress = (conversationId, waiterId) => encodeCancelProgressRequest(CancelProgressRequest.make({ waiterId })).pipe(Effect.mapError(() => void 0), Effect.flatMap((encoded) => call(conversationId, "cancelProgress", (stub) => stub.cancelProgressEncoded(encoded))), Effect.asVoid, Effect.ignore);
1024
+ const cancelProgress = (conversationId, waiterId) => encodeCancelProgressRequest(CancelProgressRequest.make({ waiterId })).pipe(Effect.mapError(() => void 0), Effect.flatMap((encoded) => call(conversationId, "cancelProgress", encoded)), Effect.asVoid, Effect.ignore);
1002
1025
  return CloudflareConversationClient.of({
1003
1026
  submit: (agent, input, options) => Effect.gen(function* () {
1004
1027
  const encodedInput = yield* Schema.encodeEffect(agent.definition.input)(input).pipe(Effect.mapError((cause) => AgentInputError.make({ message: `Unable to encode Agent input: ${cause.message}` })));
@@ -1011,12 +1034,12 @@ var CloudflareConversationClient = class CloudflareConversationClient extends Co
1011
1034
  inputPayload
1012
1035
  });
1013
1036
  const encoded = yield* encodeSubmitRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`submit request encode failed: ${error.message}`) })));
1014
- const response = yield* call(options.conversationId, "submit", (stub) => stub.submitEncoded(encoded));
1037
+ const response = yield* call(options.conversationId, "submit", encoded);
1015
1038
  return (yield* expect(options.conversationId, "submit", SubmitSucceeded, ClientSubmitHostFailure)(response)).receipt;
1016
1039
  }),
1017
1040
  awaitSettlement: (receipt) => Effect.gen(function* () {
1018
1041
  const encoded = yield* encodeReceipt(receipt).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`receipt encode failed: ${error.message}`) })));
1019
- const response = yield* call(receipt.conversationId, "awaitSettlement", (stub) => stub.awaitSettlementEncoded(encoded));
1042
+ const response = yield* call(receipt.conversationId, "awaitSettlement", encoded);
1020
1043
  return (yield* expect(receipt.conversationId, "awaitSettlement", SettlementReached, ClientAwaitHostFailure)(response)).settlement;
1021
1044
  }),
1022
1045
  awaitProgress: (conversationId, afterSequence) => Effect.gen(function* () {
@@ -1026,7 +1049,7 @@ var CloudflareConversationClient = class CloudflareConversationClient extends Co
1026
1049
  waiterId
1027
1050
  });
1028
1051
  const encoded = yield* encodeAwaitProgressRequest(request).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`awaitProgress request encode failed: ${error.message}`) })));
1029
- const attempt = (retry) => call(conversationId, "awaitProgress", (stub) => stub.awaitProgressEncoded(encoded)).pipe(Effect.flatMap(expect(conversationId, "awaitProgress", ProgressObserved, ClientObserveHostFailure)), Effect.asVoid, Effect.catchTag("ConversationClientError", (error) => error.retryable === true && error.overloaded !== true && retry < 5 ? Effect.sleep(Duration.millis(10 * 2 ** retry)).pipe(Effect.andThen(attempt(retry + 1))) : Effect.fail(error)));
1052
+ const attempt = (retry) => call(conversationId, "awaitProgress", encoded).pipe(Effect.flatMap(expect(conversationId, "awaitProgress", ProgressObserved, ClientObserveHostFailure)), Effect.asVoid, Effect.catchTag("ConversationClientError", (error) => error.retryable === true && error.overloaded !== true && retry < 5 ? Effect.sleep(Duration.millis(10 * 2 ** retry)).pipe(Effect.andThen(attempt(retry + 1))) : Effect.fail(error)));
1030
1053
  yield* attempt(0).pipe(Effect.onInterrupt(() => cancelProgress(conversationId, waiterId)));
1031
1054
  }),
1032
1055
  readPage,
@@ -1046,17 +1069,17 @@ var CloudflareConversationClient = class CloudflareConversationClient extends Co
1046
1069
  }),
1047
1070
  abort: (conversationId, command) => Effect.gen(function* () {
1048
1071
  const encoded = yield* encodeAbortCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`abort command encode failed: ${error.message}`) })));
1049
- const response = yield* call(conversationId, "abort", (stub) => stub.abortEncoded(encoded));
1072
+ const response = yield* call(conversationId, "abort", encoded);
1050
1073
  return (yield* expect(conversationId, "abort", AbortRecorded, ClientAbortHostFailure)(response)).intent;
1051
1074
  }),
1052
1075
  resolveApproval: (conversationId, command) => Effect.gen(function* () {
1053
1076
  const encoded = yield* encodeApprovalDecisionCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`approval command encode failed: ${error.message}`) })));
1054
- const response = yield* call(conversationId, "resolveApproval", (stub) => stub.resolveApprovalEncoded(encoded));
1077
+ const response = yield* call(conversationId, "resolveApproval", encoded);
1055
1078
  return (yield* expect(conversationId, "resolveApproval", ApprovalRecorded, ClientApprovalHostFailure)(response)).intent;
1056
1079
  }),
1057
1080
  resolveUnknown: (conversationId, command) => Effect.gen(function* () {
1058
1081
  const encoded = yield* encodeUnknownResolutionCommand(command).pipe(Effect.mapError((error) => HostProtocolError.make({ message: boundHostDiagnostic(`resolution command encode failed: ${error.message}`) })));
1059
- const response = yield* call(conversationId, "resolveUnknown", (stub) => stub.resolveUnknownEncoded(encoded));
1082
+ const response = yield* call(conversationId, "resolveUnknown", encoded);
1060
1083
  return (yield* expect(conversationId, "resolveUnknown", UnknownResolutionRecorded, ClientUnknownHostFailure)(response)).intent;
1061
1084
  })
1062
1085
  });
@@ -1323,7 +1346,7 @@ const gateEndpoint = Effect.gen(function* () {
1323
1346
  * ports. effect-cf owns the cached ManagedRuntime and supplies these values once per Object
1324
1347
  * incarnation; the durable runtime continues to depend only on the narrow services below.
1325
1348
  */
1326
- const effectCfPlatformLayer = (namespaceBinding) => {
1349
+ const effectCfPlatformLayer = (namespaceBinding, rpcTracing = false) => {
1327
1350
  const context = Layer.effect(DurableObjectContext)(Effect.gen(function* () {
1328
1351
  const state = yield* DurableObjectState.DurableObjectState;
1329
1352
  const env = yield* WorkerEnvironment;
@@ -1334,7 +1357,10 @@ const effectCfPlatformLayer = (namespaceBinding) => {
1334
1357
  }));
1335
1358
  const namespace = Layer.effect(ConversationObjectNamespace)(Effect.gen(function* () {
1336
1359
  const binding = yield* conversationNamespaceFromEnv(yield* WorkerEnvironment, namespaceBinding);
1337
- return ConversationObjectNamespace.of({ namespace: binding });
1360
+ return ConversationObjectNamespace.of({
1361
+ namespace: binding,
1362
+ ...rpcTracing === true ? { rpcTracing: namespaceBinding } : {}
1363
+ });
1338
1364
  }));
1339
1365
  return Layer.merge(context, namespace);
1340
1366
  };
@@ -1346,7 +1372,7 @@ const effectCfPlatformLayer = (namespaceBinding) => {
1346
1372
  * Effect Agent owning exporter lifecycle machinery.
1347
1373
  */
1348
1374
  const makeConversationObjectClass = (options, observability) => {
1349
- const application = CloudflareDurableRuntime.layer(options).pipe(Layer.provideMerge(effectCfPlatformLayer(options.namespaceBinding)));
1375
+ const application = CloudflareDurableRuntime.layer(options).pipe(Layer.provideMerge(effectCfPlatformLayer(options.namespaceBinding, options.rpcTracing)));
1350
1376
  const runtime = Layer.effectContext(Effect.gen(function* () {
1351
1377
  const state = yield* DurableObjectState.DurableObjectState;
1352
1378
  const scope = yield* Effect.scope;
@@ -1373,6 +1399,7 @@ const makeConversationObjectClass = (options, observability) => {
1373
1399
  wake: () => wakeEndpoint
1374
1400
  };
1375
1401
  const EffectCfConversationObject = DurableObject.make(runtime, {
1402
+ ...options.rpcTracing === true ? { rpcTracing: { service: options.namespaceBinding } } : {},
1376
1403
  ...observability === void 0 ? {} : { eventLayer: observability },
1377
1404
  initialize: Effect.void,
1378
1405
  rpc,