@effect-agent/testing 0.1.0-beta.83 → 0.1.0-beta.85
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/Certification.d.mts +3 -3
- package/dist/Certification.mjs +8 -4
- package/dist/Certification.mjs.map +1 -1
- package/dist/Chaos.d.mts +1 -1
- package/dist/DocsResearcher.d.mts +11 -5
- package/dist/ScriptedModel.mjs +1 -1
- package/dist/ScriptedModel.mjs.map +1 -1
- package/dist/TravelPlanner.d.mts +27 -11
- package/dist/TravelPlanner.mjs +3 -3
- package/dist/TravelPlanner.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Certification.ts +12 -3
- package/src/ScriptedModel.ts +3 -4
- package/src/fixtures/travel-planner/phase6.ts +3 -3
package/dist/Certification.d.mts
CHANGED
|
@@ -71,9 +71,9 @@ interface CertifyDurableAdaptersOptions<LedgerE = never, StoreE = never> {
|
|
|
71
71
|
declare const CERTIFICATION_SCENARIOS: ReadonlyArray<CertificationScenario>;
|
|
72
72
|
/**
|
|
73
73
|
* Coordinator failpoint locations that none of the six scenario shapes can reach, recorded
|
|
74
|
-
* honestly instead of silently claimed. These require operator, compaction, reservation,
|
|
75
|
-
* background-worker paths the shapes do not take. They are pinned in-process
|
|
76
|
-
* (`packages/testing/test/durable-tools.test.ts` "resolveUnknown is idempotent across the
|
|
74
|
+
* honestly instead of silently claimed. These require operator, compaction, reservation,
|
|
75
|
+
* background-worker, or Agent-update paths the shapes do not take. They are pinned in-process
|
|
76
|
+
* by the P5/S2 suites (`packages/testing/test/durable-tools.test.ts` "resolveUnknown is idempotent across the
|
|
77
77
|
* intent failpoint", `durable-runtime.test.ts` abort rows,
|
|
78
78
|
* `durable-subagents.test.ts` abort propagation) and by the process-kill/eviction crash
|
|
79
79
|
* matrices. Runner tests assert the observed never-fired set equals EXACTLY this list, so a
|
package/dist/Certification.mjs
CHANGED
|
@@ -34,9 +34,9 @@ const CERTIFICATION_SCENARIOS = [
|
|
|
34
34
|
];
|
|
35
35
|
/**
|
|
36
36
|
* Coordinator failpoint locations that none of the six scenario shapes can reach, recorded
|
|
37
|
-
* honestly instead of silently claimed. These require operator, compaction, reservation,
|
|
38
|
-
* background-worker paths the shapes do not take. They are pinned in-process
|
|
39
|
-
* (`packages/testing/test/durable-tools.test.ts` "resolveUnknown is idempotent across the
|
|
37
|
+
* honestly instead of silently claimed. These require operator, compaction, reservation,
|
|
38
|
+
* background-worker, or Agent-update paths the shapes do not take. They are pinned in-process
|
|
39
|
+
* by the P5/S2 suites (`packages/testing/test/durable-tools.test.ts` "resolveUnknown is idempotent across the
|
|
40
40
|
* intent failpoint", `durable-runtime.test.ts` abort rows,
|
|
41
41
|
* `durable-subagents.test.ts` abort propagation) and by the process-kill/eviction crash
|
|
42
42
|
* matrices. Runner tests assert the observed never-fired set equals EXACTLY this list, so a
|
|
@@ -63,7 +63,11 @@ const TIER2_UNREACHED_LOCATIONS = [
|
|
|
63
63
|
"worker:before-report-append",
|
|
64
64
|
"worker:after-report-append",
|
|
65
65
|
"worker:before-report-delivery",
|
|
66
|
-
"worker:after-report-delivery"
|
|
66
|
+
"worker:after-report-delivery",
|
|
67
|
+
"update:before-canonical-append",
|
|
68
|
+
"update:after-canonical-append",
|
|
69
|
+
"update:before-delivery-insert",
|
|
70
|
+
"update:after-delivery-insert"
|
|
67
71
|
];
|
|
68
72
|
/** Locations of `tier2` rows whose armed fault never fired in ANY scenario, sorted. */
|
|
69
73
|
const tier2NeverFiredLocations = (tier2) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Certification.mjs","names":[],"sources":["../src/Certification.ts"],"sourcesContent":["import * as Subagent from \"@effect-agent/capabilities/Subagent\";\nimport { SubagentPolicy, SubagentRuntime } from \"@effect-agent/capabilities/Subagent\";\nimport { SubagentReservationsMemoryLive } from \"@effect-agent/capabilities/SubagentReservations\";\nimport * as Agent from \"@effect-agent/core/Agent\";\nimport { AgentPolicy } from \"@effect-agent/core/AgentPolicy\";\nimport {\n ThreadId,\n RunId,\n ToolCallId,\n TurnId,\n type AgentId,\n type SubmissionId,\n} from \"@effect-agent/core/Identifiers\";\nimport { IdGenerator } from \"@effect-agent/core/IdGenerator\";\nimport { DurableStep, DurableStepError } from \"@effect-agent/engine/DurableStep\";\nimport { RunToolAuthorization } from \"@effect-agent/engine/RunOptions\";\nimport { DurableWorkerBinding, type ResolvedBinding } from \"@effect-agent/thread/AgentRegistration\";\nimport {\n DurableAgentRuntime,\n DurableRuntimeConfig,\n type DurableSubmitFailure,\n type DurableSubmitOptions,\n type Receipt,\n} from \"@effect-agent/thread/DurableAgentRuntime\";\nimport {\n DurableRuntimeFailpointError,\n DurableRuntimeFailpointLocation,\n} from \"@effect-agent/thread/DurableFailpoint\";\nimport {\n DefinitionDigests,\n DeploymentId,\n Digest,\n ProducerId,\n type BatchId,\n} from \"@effect-agent/thread/Records\";\nimport { childThreadIdFor } from \"@effect-agent/thread/RunJournal\";\nimport {\n ApprovalDecisionCommand,\n IdempotencyKey,\n Principal,\n ResolutionSafeToRetry,\n SubmissionLedger,\n SubmissionLookupById,\n UnknownResolutionCommand,\n DEFAULT_OWNERSHIP_LEASE_DURATION,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n type CertificationCaseResult,\n CertificationReport,\n CertificationSweepResult,\n CertificationTierThreeReport,\n CertifiedAdapterIdentity,\n certifyPorts,\n type CertificationScenario,\n} from \"@effect-agent/thread/testing/Certification\";\nimport { DurableRuntimeFailpointTestControl } from \"@effect-agent/thread/testing/DurableFailpointTestControl\";\nimport { verifyThreadInvariants } from \"@effect-agent/thread/ThreadInvariants\";\nimport {\n ThreadExportRequest,\n ThreadStore,\n LoadCheckpointRequest,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { ToolReconciler } from \"@effect-agent/thread/ToolReconciler\";\nimport { WakeScheduler } from \"@effect-agent/thread/WakeScheduler\";\nimport type { Crypto } from \"effect\";\nimport {\n Cause,\n Clock,\n DateTime,\n Duration,\n Effect,\n Exit,\n Layer,\n Option,\n Ref,\n Schema,\n Stream,\n} from \"effect\";\nimport { TestClock } from \"effect/testing\";\nimport { LanguageModel, Model, Tool, Toolkit, type Response } from \"effect/unstable/ai\";\n\n/**\n * P7 WP2 — `certifyDurableAdapters` (plan §1): the one certification entry point a durable\n * adapter pair runs to earn a Schema-encoded certificate.\n *\n * - **Tier 1 — port contract**: the two shared conformance case arrays, verbatim, through\n * `certifyPorts` (TEST-004/STORE-010).\n * - **Tier 2 — coordinator protocol + failpoint convergence**: the durable coordinator is\n * assembled over the CANDIDATE Layer pair with a scripted deterministic model; every\n * `DurableRuntimeFailpointLocation` is armed one-shot across the six scenario shapes\n * (plain / uncertain-tool / durable-steps / approval / join / delegation). After the injected\n * fault the runner asserts the state stays CLASSIFIABLE (recovery + the public unblocking\n * operations `resolveUnknown`/`resolveApproval` are the only levers used) and that the\n * re-drive CONVERGES to `verifyThreadInvariants` with `requireAllSettled` — including a\n * fully discharged digest-chain check, because the runner captures per-batch producer\n * identity at append time.\n * - **Tier 3 — real loss lever**: recorded honestly. A durable adapter either supplies a\n * `CertificationCrashLever` executed in this run, cites its committed real-loss evidence\n * (process-kill / eviction suites), or the certificate says `not-exercised`. A non-durable\n * reference adapter records `not-applicable`.\n *\n * The runner is adapter-neutral and platform-neutral: it imports nothing Node-only, so the\n * same entry point runs under `@effect/vitest` on Node and inside workerd (storage-cloudflare's\n * in-workerd runner). It must run under a TestClock (Tier 1 drives lease expiry through\n * virtual time), and requires only `Crypto.Crypto` from the environment.\n */\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * A real-loss lever supplied by an adapter that wants Tier 3 exercised IN this certification\n * run (kill/evict/reopen around a designated row subset). Rows report with\n * `suite: \"real-loss\"`. Failures must be captured per-row — the lever's error channel is\n * `never` so a certificate is always produced.\n */\nexport type CertificationCrashLever = Effect.Effect<ReadonlyArray<CertificationCaseResult>>;\n\nexport interface CertifyDurableAdaptersOptions<LedgerE = never, StoreE = never> {\n /** Adapter pair identity named by the certificate (durability is read from the ledger). */\n readonly adapter: {\n readonly name: string;\n readonly version?: string | undefined;\n };\n /**\n * The candidate Layer pair. When both ports must share one connection root (the ADR-0011\n * \"same file\" rule), pass the SAME combined Layer instance for both fields — Layer\n * memoization builds it once. A candidate may require `Crypto.Crypto` (the memory reference\n * does); the certification's own environment supplies nothing else.\n */\n readonly submissionLedger: Layer.Layer<SubmissionLedger, LedgerE, Crypto.Crypto>;\n readonly threadStore: Layer.Layer<ThreadStore, StoreE, Crypto.Crypto>;\n /** Defaults to `WakeScheduler.layerNoop`; the runner re-drives lanes explicitly. */\n readonly wakeScheduler?: Layer.Layer<WakeScheduler> | undefined;\n /** Executes Tier 3 in this run; takes precedence over `tierThreeEvidence`. */\n readonly crashLever?: CertificationCrashLever | undefined;\n /** Repository-relative citations of committed real-loss suites (Tier 3 `recorded-evidence`). */\n readonly tierThreeEvidence?: ReadonlyArray<string> | undefined;\n /**\n * The candidate ledger's configured ownership lease (defaults to the D5 default, 30s).\n * Every Tier-2 re-drive round advances the TestClock past this lease before reclaiming:\n * a live lease may block ALL new claims (the SQL adapters do; the memory reference also\n * allows same-producer reclaim), so the adapter-NEUTRAL recovery lever after a mid-Attempt\n * fault is lease expiry — exactly the documented D5 liveness mechanism, driven through\n * virtual time.\n */\n readonly ownershipLeaseDuration?: Duration.Duration | undefined;\n}\n\n/** The six Tier-2 scenario shapes in sweep order. */\nexport const CERTIFICATION_SCENARIOS: ReadonlyArray<CertificationScenario> = [\n \"plain\",\n \"uncertain-tool\",\n \"durable-steps\",\n \"approval\",\n \"join\",\n \"delegation\",\n];\n\n/**\n * Coordinator failpoint locations that none of the six scenario shapes can reach, recorded\n * honestly instead of silently claimed. These require operator, compaction, reservation, or\n * background-worker paths the shapes do not take. They are pinned in-process by the P5/S2 suites\n * (`packages/testing/test/durable-tools.test.ts` \"resolveUnknown is idempotent across the\n * intent failpoint\", `durable-runtime.test.ts` abort rows,\n * `durable-subagents.test.ts` abort propagation) and by the process-kill/eviction crash\n * matrices. Runner tests assert the observed never-fired set equals EXACTLY this list, so a\n * protocol change that silently stops exercising a location fails the certification.\n */\nexport const TIER2_UNREACHED_LOCATIONS: ReadonlyArray<DurableRuntimeFailpointLocation> = [\n // Tier 2 has no native compaction; dedicated checkpoint process-loss tests cover these.\n \"checkpoint:before-save\",\n \"checkpoint:after-save\",\n \"abort:after-intent\",\n // Compaction requires a `contextTokenLimit` policy plus prior-Run history\n // none of the six scenario shapes carries; pinned in-process by the\n // RUN-026 rows in `packages/testing/test/durable-runtime.test.ts`\n // (compaction failpoint idempotence across re-drive).\n \"compaction:before-canonical-append\",\n \"compaction:after-canonical-append\",\n // These shapes use neither programmatic Tools nor grace finalization. Their reservations\n // are exercised before/after append in the public durable-runtime regression suite.\n \"policy:before-reservation-append\",\n \"policy:after-reservation-append\",\n \"resolve:after-intent\",\n \"subagent:after-child-abort-intent\",\n // Background workers use retained delivery, source capacity, and child-origin paths absent\n // from these six attached/ordinary scenarios. The before/after creation and completion\n // boundaries are exercised by packages/thread/test/worker-host.test.ts.\n \"worker:before-source-append\",\n \"worker:after-source-append\",\n \"worker:before-origin-append\",\n \"worker:after-origin-append\",\n \"worker:before-completion-append\",\n \"worker:after-completion-append\",\n // Root attached declarations keep their independent pool; nested shared subtree mutations\n // are covered by the same focused worker-host failpoint suite.\n \"worker:before-subtree-append\",\n \"worker:after-subtree-append\",\n // Automatic report decisions and retained delivery insertion have dedicated worker crash tests.\n \"worker:before-report-append\",\n \"worker:after-report-append\",\n \"worker:before-report-delivery\",\n \"worker:after-report-delivery\",\n];\n\n/** Locations of `tier2` rows whose armed fault never fired in ANY scenario, sorted. */\nexport const tier2NeverFiredLocations = (\n tier2: ReadonlyArray<CertificationSweepResult>,\n): ReadonlyArray<DurableRuntimeFailpointLocation> => {\n const fired = new Set<DurableRuntimeFailpointLocation>();\n\n for (const row of tier2) {\n if (row.failpointFired) fired.add(row.location);\n }\n\n return DurableRuntimeFailpointLocation.literals.filter((location) => !fired.has(location)).sort();\n};\n\n// ---------------------------------------------------------------------------\n// Deterministic fixtures (scripted prompt-shape models, agents, delegation)\n// ---------------------------------------------------------------------------\n\nconst SHA_A = Schema.decodeSync(Digest)(\"a\".repeat(64));\nconst DIGESTS = DefinitionDigests.make({ agent: SHA_A, model: SHA_A, tools: SHA_A });\n\nconst CHILD_DIGEST_STRINGS = {\n agent: \"b\".repeat(64),\n model: \"c\".repeat(64),\n tools: \"d\".repeat(64),\n} as const;\n\nconst CHILD_DIGESTS = DefinitionDigests.make({\n agent: Schema.decodeSync(Digest)(CHILD_DIGEST_STRINGS.agent),\n model: Schema.decodeSync(Digest)(CHILD_DIGEST_STRINGS.model),\n tools: Schema.decodeSync(Digest)(CHILD_DIGEST_STRINGS.tools),\n});\n\nconst PRINCIPAL = Schema.decodeSync(Principal)(\"principal-certification\");\nconst decodeThreadId = Schema.decodeSync(ThreadId);\nconst decodeIdempotencyKey = Schema.decodeSync(IdempotencyKey);\nconst decodeToolCallId = Schema.decodeSync(ToolCallId);\n\nconst usage = { inputTokens: {}, outputTokens: {} };\n\nconst finalParts = (text: string): ReadonlyArray<Response.StreamPartEncoded> => [\n { type: \"text-start\", id: \"answer\" },\n { type: \"text-delta\", id: \"answer\", delta: text },\n { type: \"text-end\", id: \"answer\" },\n { type: \"finish\", reason: \"stop\", usage },\n];\n\nconst toolCallPart = (id: string, name: string, params: unknown): Response.StreamPartEncoded => ({\n type: \"tool-call\",\n id,\n name,\n params,\n providerExecuted: false,\n});\n\nconst toolTurn = (\n ...calls: ReadonlyArray<Response.StreamPartEncoded>\n): ReadonlyArray<Response.StreamPartEncoded> => [\n ...calls,\n { type: \"finish\", reason: \"tool-calls\", usage },\n];\n\n/**\n * Stateless scripted model that decides by PROMPT SHAPE instead of call count: while the\n * prompt carries no committed tool result the model declares `toolParts` (when given),\n * otherwise it answers with the final text. Deciding on the canonical prompt keeps every cell\n * deterministic regardless of where the injected fault fell — a re-invoked Turn re-declares\n * the same batch and a resumed batch flows into the final answer, so every scenario always\n * exercises its tool path and always converges.\n */\nconst promptShapeModel = (\n name: string,\n finalText: string,\n toolParts?: ReadonlyArray<Response.StreamPartEncoded>,\n) =>\n Model.make(\n \"scripted\",\n name,\n Layer.effect(\n LanguageModel.LanguageModel,\n LanguageModel.make({\n generateText: () => Effect.succeed([]),\n streamText: (request) => {\n const hasToolResult = request.prompt.content.some((message) => message.role === \"tool\");\n\n const parts =\n toolParts === undefined || hasToolResult ? finalParts(finalText) : toolParts;\n\n return Stream.fromIterable(parts);\n },\n }),\n ),\n );\n\n// Tier-2 intentionally advances virtual time past a 30-second ownership lease on every\n// re-drive round. Keep its business-policy duration above the full eight-round sweep so this\n// fixture certifies crash convergence rather than accidentally relying on a fresh duration\n// allowance per replacement Attempt. RUN-030 owns the dedicated duration-expiry coverage.\nconst CERTIFICATION_MAX_DURATION = \"10 minutes\" as const;\n\nconst policy = AgentPolicy.make({\n maxTurns: 4,\n maxToolCalls: 4,\n maxDuration: CERTIFICATION_MAX_DURATION,\n toolConcurrency: 2,\n});\n\nconst QuestionInput = Schema.Struct({ question: Schema.String });\nconst AnswerOutput = Schema.Struct({ answer: Schema.String });\n\n/** plain / join: no tools — the pure Turn/submission/join seams. */\nconst plainDefinition = Agent.make(\"certify-plain\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Answer as JSON.\",\n toolkit: Toolkit.empty,\n policy,\n});\n\n/** uncertain-tool: unannotated → fail-closed `uncertain`, enters the prepared/settled protocol. */\nconst Book = Tool.make(\"book\", {\n parameters: Schema.Struct({ ref: Schema.String }),\n success: Schema.Struct({ confirmation: Schema.String }),\n});\n\nconst bookToolkit = Toolkit.make(Book);\n\nconst uncertainDefinition = Agent.make(\"certify-uncertain\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Book it.\",\n toolkit: bookToolkit,\n policy,\n});\n\n/** durable-steps: declaring `DurableStep` as a dependency is what makes the Tool durable. */\nconst Itinerary = Tool.make(\"itinerary\", {\n parameters: Schema.Struct({ ref: Schema.String }),\n success: Schema.Struct({ state: Schema.String }),\n failure: DurableStepError,\n dependencies: [DurableStep],\n});\n\nconst itineraryToolkit = Toolkit.make(Itinerary);\n\nconst stepsDefinition = Agent.make(\"certify-steps\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Reserve the itinerary.\",\n toolkit: itineraryToolkit,\n policy,\n});\n\n/** approval: fail-closed — no `DurableApprovalResolver` Layer, so undecided approvals suspend. */\nconst BookApproval = Tool.make(\"book\", {\n parameters: Schema.Struct({ ref: Schema.String }),\n success: Schema.Struct({ confirmation: Schema.String }),\n needsApproval: true,\n});\n\nconst approvalToolkit = Toolkit.make(BookApproval);\n\nconst approvalDefinition = Agent.make(\"certify-approval\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Book after approval.\",\n toolkit: approvalToolkit,\n policy,\n});\n\n/** delegation: durable attached child plus an ordinary uncertain sibling in ONE batch. */\nconst childDefinition = Agent.make(\"certify-child\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Answer as JSON.\",\n toolkit: Toolkit.empty,\n policy: AgentPolicy.make({\n maxTurns: 2,\n maxToolCalls: 1,\n maxDuration: CERTIFICATION_MAX_DURATION,\n toolConcurrency: 1,\n }),\n});\n\nclass CertifyDelegationFailed extends Schema.TaggedError<CertifyDelegationFailed>()(\n \"CertifyDelegationFailed\",\n { childErrorTag: Schema.String },\n) {}\n\nconst researchDelegation = Subagent.define(\"delegate_research\", {\n description: \"Research one bounded question and return findings.\",\n target: childDefinition,\n parameters: Schema.Struct({ topic: Schema.String }),\n success: Schema.Struct({ summary: Schema.String }),\n failure: CertifyDelegationFailed,\n prepareInput: ({ topic }) => Effect.succeed({ question: `research:${topic}` }),\n projectResult: (output) => Effect.succeed({ summary: `finding:${output.answer}` }),\n policy: SubagentPolicy.make({\n maxChildren: 2,\n maxConcurrency: 2,\n maxTurns: 4,\n maxToolCalls: 4,\n maxDuration: CERTIFICATION_MAX_DURATION,\n }),\n});\n\nconst Lookup = Tool.make(\"lookup\", {\n parameters: Schema.Struct({ key: Schema.String }),\n success: Schema.Struct({ value: Schema.String }),\n});\n\nconst coordinatorDefinition = Agent.make(\"certify-coordinator\", {\n input: Schema.Struct({ mission: Schema.String }),\n output: Schema.Struct({ report: Schema.String }),\n instructions: \"Delegate and look up, then answer as JSON.\",\n toolkit: Toolkit.make(researchDelegation.tool, Lookup),\n policy: AgentPolicy.make({\n maxTurns: 4,\n maxToolCalls: 3,\n maxDuration: CERTIFICATION_MAX_DURATION,\n toolConcurrency: 2,\n }),\n});\n\nconst mapChildFailure = (failure: { readonly _tag: string }) =>\n CertifyDelegationFailed.make({ childErrorTag: failure._tag });\n\nconst DELEGATE_CALL = decodeToolCallId(\"delegate-1\");\n\n/** Fixture-only identity source consumed by the delegation Layer's ephemeral capture. */\nconst identifiers = Layer.effect(\n IdGenerator,\n Effect.gen(function* () {\n const counter = yield* Ref.make(0);\n\n const next = <A>(decode: (value: string) => A, prefix: string) =>\n Ref.getAndUpdate(counter, (value) => value + 1).pipe(\n Effect.map((value) => decode(`${prefix}-${value}`)),\n );\n\n return {\n nextThreadId: next(decodeThreadId, \"certify-fixture-thread\"),\n nextRunId: next(Schema.decodeSync(RunId), \"certify-fixture-run\"),\n nextTurnId: next(Schema.decodeSync(TurnId), \"certify-fixture-turn\"),\n };\n }),\n);\n\nconst delegationSupport = Layer.mergeAll(SubagentReservationsMemoryLive, identifiers);\n\n// ---------------------------------------------------------------------------\n// Tier 2 — scenario cells\n// ---------------------------------------------------------------------------\n\ninterface CertificationCell {\n readonly bindings: ReadonlyArray<ResolvedBinding>;\n /** Idempotent submission batch — safe to replay verbatim after a submit-boundary fault. */\n readonly submit: Effect.Effect<ReadonlyArray<Receipt>, DurableSubmitFailure, DurableAgentRuntime>;\n /** All lanes of the cell in drive order, computed from the (possibly replayed) receipts. */\n readonly lanes: (receipts: ReadonlyArray<Receipt>) => ReadonlyArray<ThreadId>;\n}\n\nconst submitOptionsFor = (slug: string, threadId: ThreadId): DurableSubmitOptions => ({\n threadId,\n principal: PRINCIPAL,\n idempotencyKey: decodeIdempotencyKey(`certify-key-${slug}`),\n definitions: DIGESTS,\n});\n\n/** One single-agent cell: one lane, one Submission, one registered exact-digest binding. */\nconst makeSingleAgentCell = (\n definition: { readonly id: AgentId; readonly input: typeof QuestionInput },\n resolved: ResolvedBinding,\n slug: string,\n): CertificationCell => {\n const threadId = decodeThreadId(`certify-${slug}`);\n\n const submit = Effect.gen(function* () {\n const runtime = yield* DurableAgentRuntime;\n\n const receipt = yield* runtime.submit(\n { definition: { id: definition.id, input: definition.input } },\n { question: `certify ${slug}` },\n submitOptionsFor(slug, threadId),\n );\n\n return [receipt];\n });\n\n return {\n bindings: [resolved],\n submit,\n lanes: () => [threadId],\n };\n};\n\nconst makeCell = Effect.fn(\"Certification.makeCell\")(function* (\n scenario: CertificationScenario,\n slug: string,\n) {\n switch (scenario) {\n case \"plain\": {\n const binding = Agent.withModel(\n plainDefinition,\n promptShapeModel(\"certify-plain\", '{\"answer\":\"done\"}'),\n );\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS);\n\n return makeSingleAgentCell(plainDefinition, resolved, slug);\n }\n case \"uncertain-tool\": {\n const binding = Agent.withModel(\n uncertainDefinition,\n promptShapeModel(\n \"certify-uncertain\",\n '{\"answer\":\"booked\"}',\n toolTurn(toolCallPart(\"book-1\", \"book\", { ref: `r-${slug}` })),\n ),\n );\n\n const toolLayer = bookToolkit.toLayer({\n book: ({ ref }) => Effect.succeed({ confirmation: `confirmed-${ref}` }),\n });\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS).pipe(\n Effect.provide(toolLayer),\n );\n\n return makeSingleAgentCell(uncertainDefinition, resolved, slug);\n }\n case \"durable-steps\": {\n const binding = Agent.withModel(\n stepsDefinition,\n promptShapeModel(\n \"certify-steps\",\n '{\"answer\":\"reserved\"}',\n toolTurn(toolCallPart(\"itinerary-1\", \"itinerary\", { ref: `trip-${slug}` })),\n ),\n );\n\n const toolLayer = itineraryToolkit.toLayer({\n itinerary: ({ ref }) =>\n Effect.gen(function* () {\n const step = yield* DurableStep;\n\n const flight = yield* step.do(\n \"reserve-flight\",\n Schema.String,\n Effect.succeed(`flight-${ref}`),\n );\n\n const lodging = yield* step.do(\n \"reserve-lodging\",\n Schema.String,\n Effect.succeed(`lodging-${ref}`),\n );\n\n return { state: `${flight}+${lodging}` };\n }),\n });\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS).pipe(\n Effect.provide(toolLayer),\n );\n\n return makeSingleAgentCell(stepsDefinition, resolved, slug);\n }\n case \"approval\": {\n const binding = Agent.withModel(\n approvalDefinition,\n promptShapeModel(\n \"certify-approval\",\n '{\"answer\":\"approved\"}',\n toolTurn(toolCallPart(\"book-1\", \"book\", { ref: `r-${slug}` })),\n ),\n );\n\n const toolLayer = approvalToolkit.toLayer({\n book: ({ ref }) => Effect.succeed({ confirmation: `confirmed-${ref}` }),\n });\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS).pipe(\n Effect.provide(toolLayer),\n );\n\n return makeSingleAgentCell(approvalDefinition, resolved, slug);\n }\n case \"join\": {\n const binding = Agent.withModel(\n plainDefinition,\n promptShapeModel(\"certify-join\", '{\"answer\":\"host answer\"}'),\n );\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS);\n const threadId = decodeThreadId(`certify-${slug}`);\n\n const submitOne = Effect.fn(\"Certification.submitOne\")(function* (\n key: string,\n question: string,\n ) {\n const runtime = yield* DurableAgentRuntime;\n\n return yield* runtime.submit(\n { definition: { id: plainDefinition.id, input: plainDefinition.input } },\n { question },\n {\n threadId,\n principal: PRINCIPAL,\n idempotencyKey: decodeIdempotencyKey(key),\n definitions: DIGESTS,\n },\n );\n });\n\n const cell: CertificationCell = {\n bindings: [resolved],\n submit: Effect.gen(function* () {\n const host = yield* submitOne(`certify-key-${slug}-host`, \"host question\");\n const queued = yield* submitOne(`certify-key-${slug}-queued`, \"queued question\");\n\n return [host, queued];\n }),\n lanes: () => [threadId],\n };\n\n return cell;\n }\n case \"delegation\": {\n const childBinding = Agent.withModel(\n childDefinition,\n promptShapeModel(\"certify-child\", '{\"answer\":\"child-answer\"}'),\n );\n\n const parentBinding = Agent.withModel(\n coordinatorDefinition,\n promptShapeModel(\n \"certify-parent\",\n '{\"report\":\"done\"}',\n toolTurn(\n toolCallPart(\"delegate-1\", \"delegate_research\", { topic: \"paris\" }),\n toolCallPart(\"lookup-1\", \"lookup\", { key: \"hotels\" }),\n ),\n ),\n );\n\n const delegationLayer = SubagentRuntime.layer(researchDelegation, childBinding, {\n mapChildFailure,\n durable: { targetDigests: CHILD_DIGEST_STRINGS },\n }).pipe(Layer.provide(delegationSupport));\n\n const lookupLayer = Toolkit.make(Lookup).toLayer({\n lookup: ({ key }) => Effect.succeed({ value: `found-${key}` }),\n });\n\n const parentResolved = yield* DurableWorkerBinding.make(parentBinding, DIGESTS).pipe(\n Effect.provide(Layer.mergeAll(delegationLayer, lookupLayer)),\n );\n\n const childResolved = yield* DurableWorkerBinding.make(childBinding, CHILD_DIGESTS);\n const threadId = decodeThreadId(`certify-${slug}`);\n\n const cell: CertificationCell = {\n bindings: [parentResolved, childResolved],\n submit: Effect.gen(function* () {\n const runtime = yield* DurableAgentRuntime;\n\n const receipt = yield* runtime.submit(\n { definition: { id: coordinatorDefinition.id, input: coordinatorDefinition.input } },\n { mission: \"plan\" },\n submitOptionsFor(slug, threadId),\n );\n\n return [receipt];\n }),\n lanes: (receipts) => {\n const parent = receipts.at(0);\n\n return parent === undefined\n ? [threadId]\n : [threadId, childThreadIdFor(parent.submissionId, DELEGATE_CALL)];\n },\n };\n\n return cell;\n }\n }\n});\n\n/** Maximum recovery/drive/unblock rounds before a cell is reported non-convergent. */\nconst MAX_REDRIVE_ROUNDS = 8;\n\n/**\n * Verify one lane after convergence: canonical export + every lane Submission the ledger or\n * the log names (the same collection rule as the admin `verify` member), fed to the shared\n * invariant checker in convergence mode WITH the captured per-batch producer directory, so\n * the digest chain is fully recomputed instead of skipped.\n */\nconst verifyLane = Effect.fn(\"Certification.verifyLane\")(function* (\n lane: ThreadId,\n batchProducers: ReadonlyMap<BatchId, ProducerId>,\n) {\n const store = yield* ThreadStore;\n const ledger = yield* SubmissionLedger;\n const exported = yield* store.export(ThreadExportRequest.make({ threadId: lane }));\n const rows = new Map<SubmissionId, SubmissionSnapshot>();\n const nonterminal = yield* Stream.runCollect(ledger.scanNonterminal);\n\n for (const submission of nonterminal) {\n if (submission.threadId === lane) rows.set(submission.submissionId, submission);\n }\n const named = new Set<SubmissionId>();\n\n for (const envelope of exported.records) {\n const payload = envelope.record.payload;\n\n if (\n payload._tag === \"UserInputRecorded\" ||\n payload._tag === \"SubmissionSettled\" ||\n payload._tag === \"AbortRequested\"\n ) {\n if (payload.submissionId !== undefined) named.add(payload.submissionId);\n }\n }\n for (const submissionId of named) {\n if (rows.has(submissionId)) continue;\n const found = yield* ledger.lookup(SubmissionLookupById.make({ submissionId }));\n\n if (Option.isSome(found) && found.value.threadId === lane) {\n rows.set(submissionId, found.value);\n }\n }\n\n const checkpoint =\n store.checkpoints === undefined\n ? Option.none()\n : yield* store.checkpoints.load(LoadCheckpointRequest.make({ threadId: lane }));\n\n return yield* verifyThreadInvariants({\n export: exported,\n submissions: [...rows.values()],\n batchProducers,\n checkpoint: Option.getOrUndefined(checkpoint),\n checkpointsSupported: store.checkpoints !== undefined,\n requireAllSettled: true,\n });\n});\n\nconst failureTagOf = <E>(cause: Cause.Cause<E>): string => {\n const failure = Cause.findErrorOption(cause);\n\n if (Option.isSome(failure)) {\n const error: unknown = failure.value;\n\n if (typeof error === \"object\" && error !== null && \"_tag\" in error) {\n return String(error._tag);\n }\n\n return String(error).slice(0, 256);\n }\n\n return \"defect\";\n};\n\n/** One Tier-2 sweep cell: arm `location` one-shot, drive `scenario`, converge, verify. */\nconst runSweepCell = Effect.fn(\"Certification.runSweepCell\")(function* (\n scenario: CertificationScenario,\n location: DurableRuntimeFailpointLocation,\n batchProducers: ReadonlyMap<BatchId, ProducerId>,\n leaseAdvance: Duration.Duration,\n) {\n const ledger = yield* SubmissionLedger;\n const control = yield* DurableRuntimeFailpointTestControl;\n const slug = `${scenario}-${location.replaceAll(\":\", \"-\")}`;\n\n const failed = (detail: string, fired: boolean): CertificationSweepResult =>\n CertificationSweepResult.make({\n scenario,\n location,\n failpointFired: fired,\n status: \"failed\",\n digestChainVerified: false,\n detail: detail.slice(0, 4_096),\n });\n\n const cell = yield* makeCell(scenario, slug);\n\n const runtime = yield* DurableAgentRuntime.pipe(\n Effect.provide(\n DurableAgentRuntime.layerWithBindings(cell.bindings).pipe(\n Layer.provide(RunToolAuthorization.allowAll),\n ),\n ),\n );\n\n const submit = cell.submit.pipe(Effect.provideService(DurableAgentRuntime, runtime));\n\n // One-shot arm: the fault fires at most once anywhere in the cell (initial drive OR a\n // re-drive round's public unblocking operation), modelling one crash at this boundary.\n const fired = yield* Ref.make(false);\n\n yield* control.setHandler((hit) =>\n hit !== location\n ? Effect.void\n : Ref.getAndSet(fired, true).pipe(\n Effect.flatMap((already) =>\n already\n ? Effect.void\n : Effect.fail(DurableRuntimeFailpointError.make({ location: hit })),\n ),\n ),\n );\n\n // Submissions are idempotent (DUR-001): one replay recovers a submit-boundary fault.\n let receipts: ReadonlyArray<Receipt>;\n const firstSubmit = yield* Effect.exit(submit);\n\n if (Exit.isSuccess(firstSubmit)) {\n receipts = firstSubmit.value;\n } else {\n const secondSubmit = yield* Effect.exit(submit);\n\n if (Exit.isFailure(secondSubmit)) {\n yield* control.clear;\n\n return failed(\n `submission replay did not recover: ${failureTagOf(secondSubmit.cause)}`,\n yield* Ref.get(fired),\n );\n }\n receipts = secondSubmit.value;\n }\n const lanes = cell.lanes(receipts);\n\n const driveLane = (lane: ThreadId) => runtime.processThreadResolved(lane);\n\n const allSettled = Effect.gen(function* () {\n for (const receipt of receipts) {\n const snapshot = yield* ledger.lookup(\n SubmissionLookupById.make({ submissionId: receipt.submissionId }),\n );\n\n if (Option.isNone(snapshot) || snapshot.value.state !== \"settled\") return false;\n }\n\n return true;\n });\n\n // Re-drive to convergence using ONLY public operations: worker drives, recovery passes,\n // and the authorized DUR-017/approval unblocking paths chosen from `explainThread`.\n let converged = false;\n\n for (let round = 0; round < MAX_REDRIVE_ROUNDS && !converged; round++) {\n // Expire any lease a faulted Attempt left behind (D5): virtual time is the\n // adapter-neutral reclaim lever — a live lease may block every new claim.\n yield* TestClock.adjust(leaseAdvance);\n yield* Effect.exit(runtime.runRecovery);\n for (const lane of lanes) {\n yield* Effect.exit(driveLane(lane));\n }\n for (const lane of lanes) {\n const explains = yield* Effect.exit(runtime.explainThread(lane));\n\n if (Exit.isFailure(explains)) continue;\n for (const explanation of explains.value) {\n for (const unknown of explanation.evidence.unknownCalls) {\n if (unknown.resolved) continue;\n yield* Effect.exit(\n runtime.resolveUnknown(\n UnknownResolutionCommand.make({\n submissionId: explanation.submission.submissionId,\n toolCallId: unknown.toolCallId,\n author: \"certification-runner\",\n reason: `re-drive after injected fault at ${location}`,\n resolution: ResolutionSafeToRetry.make(),\n }),\n ),\n );\n }\n for (const pending of explanation.evidence.approvalsPending) {\n const decided = explanation.evidence.approvalDecisions.some(\n (decision) => decision.toolCallId === pending.toolCallId,\n );\n\n if (decided) continue;\n yield* Effect.exit(\n runtime.resolveApproval(\n ApprovalDecisionCommand.make({\n submissionId: explanation.submission.submissionId,\n toolCallId: pending.toolCallId,\n decision: \"approved\",\n resolver: \"certification-runner\",\n reason: `re-drive after injected fault at ${location}`,\n }),\n ),\n );\n }\n }\n }\n const settled = yield* Effect.exit(allSettled);\n\n converged = Exit.isSuccess(settled) && settled.value;\n }\n yield* control.clear;\n const wasFired = yield* Ref.get(fired);\n\n if (!converged) {\n return failed(`did not converge within ${MAX_REDRIVE_ROUNDS} re-drive rounds`, wasFired);\n }\n\n // Every lane of the cell must verify in convergence mode with a recomputed digest chain.\n let digestChainVerified = true;\n const failedChecks: Array<string> = [];\n\n for (const lane of lanes) {\n const verdict = yield* Effect.exit(verifyLane(lane, batchProducers));\n\n if (Exit.isFailure(verdict)) {\n return failed(`lane ${lane} could not be verified: ${failureTagOf(verdict.cause)}`, wasFired);\n }\n for (const check of verdict.value.checks) {\n if (check.status === \"failed\") {\n failedChecks.push(\n `${lane}:${check.name}${check.detail === undefined ? \"\" : ` (${check.detail})`}`,\n );\n }\n if (check.name === \"digest-chain\" && check.status !== \"passed\") {\n digestChainVerified = false;\n }\n }\n }\n if (failedChecks.length > 0 || !digestChainVerified) {\n return failed(\n failedChecks.length > 0\n ? `invariant checks failed: ${failedChecks.join(\"; \")}`\n : \"the digest chain was not fully recomputed\",\n wasFired,\n );\n }\n\n return CertificationSweepResult.make({\n scenario,\n location,\n failpointFired: wasFired,\n status: wasFired ? \"converged\" : \"not-triggered\",\n digestChainVerified,\n });\n});\n\n// ---------------------------------------------------------------------------\n// Tier 3 — real loss lever record\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the Tier-3 record honestly (plan §1): a non-durable reference adapter has no real\n * loss to exercise (`not-applicable`); a supplied lever runs NOW (`exercised`); committed\n * real-loss citations are recorded (`recorded-evidence`); otherwise the certificate says\n * `not-exercised` — a scoped statement, never a silent claim.\n */\nexport const resolveTierThree = Effect.fn(\"Certification.resolveTierThree\")(function* (\n durability: CertifiedAdapterIdentity[\"durability\"],\n options: {\n readonly crashLever?: CertificationCrashLever | undefined;\n readonly tierThreeEvidence?: ReadonlyArray<string> | undefined;\n },\n): Effect.fn.Return<CertificationTierThreeReport, never> {\n if (durability === \"non-durable\") {\n return CertificationTierThreeReport.make({\n status: \"not-applicable\",\n evidence: [],\n cases: [],\n detail:\n \"the adapter declares non-durable state (reference/conformance adapter); there is no real loss to exercise\",\n });\n }\n if (options.crashLever !== undefined) {\n const cases = yield* options.crashLever;\n\n return CertificationTierThreeReport.make({\n status: cases.length === 0 ? \"not-exercised\" : \"exercised\",\n evidence: options.tierThreeEvidence ?? [],\n cases,\n ...(cases.length === 0\n ? { detail: \"the supplied crash lever executed no real-loss cases\" }\n : {}),\n });\n }\n if (options.tierThreeEvidence !== undefined && options.tierThreeEvidence.length > 0) {\n return CertificationTierThreeReport.make({\n status: \"recorded-evidence\",\n evidence: options.tierThreeEvidence,\n cases: [],\n });\n }\n\n return CertificationTierThreeReport.make({\n status: \"not-exercised\",\n evidence: [],\n cases: [],\n detail:\n \"no crash lever was supplied and no committed real-loss evidence was cited; Tier 3 is NOT discharged for this adapter\",\n });\n});\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nconst nowUtc: Effect.Effect<DateTime.Utc> = Effect.map(Clock.currentTimeMillis, (millis) =>\n DateTime.toUtc(DateTime.makeUnsafe(millis)),\n);\n\n/**\n * Certify one durable adapter pair (plan §1, §8 WP2). Runs Tier 2 FIRST over pristine\n * storage (each cell converges to all-settled before the next starts, so the recovery scan\n * never sees foreign leftovers), then Tier 1's port contract cases (whose lanes deliberately\n * end in every nonterminal shape), then records Tier 3. Requires `Crypto.Crypto` and a\n * TestClock-backed environment; the candidate Layers are built exactly once.\n */\nexport const certifyDurableAdapters = <LedgerE = never, StoreE = never>(\n options: CertifyDurableAdaptersOptions<LedgerE, StoreE>,\n): Effect.Effect<CertificationReport, LedgerE | StoreE, Crypto.Crypto> => {\n const batchProducers = new Map<BatchId, ProducerId>();\n\n // Interpose the candidate store with an append-time capture of each batch's producer\n // identity — the one value the ThreadStore port deliberately does not export — so\n // Tier 2's invariant verification recomputes the FULL digest chain instead of skipping it.\n const capturingStore = Layer.effect(ThreadStore)(\n Effect.gen(function* () {\n const inner = yield* ThreadStore;\n\n return ThreadStore.of({\n ...inner,\n append: (request) =>\n Effect.sync(() => {\n batchProducers.set(request.batch.batchId, request.batch.producerId);\n }).pipe(Effect.andThen(inner.append(request))),\n });\n }),\n ).pipe(Layer.provide(options.threadStore));\n\n // RUN-036: certification uses the default-none Tool failure observer. Trusted application\n // reporting adds no durable transition and is verified separately from adapter certification.\n const environment = Layer.mergeAll(\n options.submissionLedger,\n capturingStore,\n options.wakeScheduler ?? WakeScheduler.layerNoop,\n DurableRuntimeFailpointTestControl.layer,\n ToolReconciler.uncertain,\n DurableRuntimeConfig.layer({\n deploymentId: Schema.decodeSync(DeploymentId)(\"deployment-certification\"),\n producerId: Schema.decodeSync(ProducerId)(\"producer-certification\"),\n settlementPollInterval: Duration.millis(50),\n leaseRenewalInterval: Duration.seconds(5),\n abortPollInterval: Duration.millis(50),\n }),\n );\n\n const leaseAdvance = Duration.millis(\n Duration.toMillis(options.ownershipLeaseDuration ?? DEFAULT_OWNERSHIP_LEASE_DURATION) + 1_000,\n );\n\n const program = Effect.gen(function* () {\n const ledger = yield* SubmissionLedger;\n\n // Tier 2 — coordinator failpoint convergence sweep.\n const tier2: Array<CertificationSweepResult> = [];\n\n for (const scenario of CERTIFICATION_SCENARIOS) {\n for (const location of DurableRuntimeFailpointLocation.literals) {\n tier2.push(yield* runSweepCell(scenario, location, batchProducers, leaseAdvance));\n }\n }\n\n // Tier 1 — the shared port contract suites, verbatim.\n const tier1 = yield* certifyPorts();\n\n // Tier 3 — the real loss lever record.\n const capabilities = yield* ledger.capabilities;\n const tier3 = yield* resolveTierThree(capabilities.durability, options);\n\n const generatedAt = yield* nowUtc;\n\n const ok =\n tier1.every((result) => result.status === \"passed\") &&\n tier2.every((result) => result.status !== \"failed\") &&\n tier3.cases.every((result) => result.status === \"passed\");\n\n return CertificationReport.make({\n format: \"effect-agent/certification@2\",\n adapter: CertifiedAdapterIdentity.make({\n name: options.adapter.name,\n ...(options.adapter.version === undefined ? {} : { version: options.adapter.version }),\n durability: capabilities.durability,\n }),\n generatedAt,\n tier1,\n tier2,\n tier3,\n ok,\n fullyCertified:\n ok &&\n capabilities.durability !== \"non-durable\" &&\n tier3.status === \"exercised\" &&\n tier3.cases.length > 0 &&\n tier3.cases.every((result) => result.suite === \"real-loss\"),\n });\n });\n\n return program.pipe(Effect.provide(environment));\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Certification.mjs","names":[],"sources":["../src/Certification.ts"],"sourcesContent":["import * as Subagent from \"@effect-agent/capabilities/Subagent\";\nimport { SubagentPolicy, SubagentRuntime } from \"@effect-agent/capabilities/Subagent\";\nimport { SubagentReservationsMemoryLive } from \"@effect-agent/capabilities/SubagentReservations\";\nimport * as Agent from \"@effect-agent/core/Agent\";\nimport { AgentPolicy } from \"@effect-agent/core/AgentPolicy\";\nimport {\n ThreadId,\n RunId,\n ToolCallId,\n TurnId,\n type AgentId,\n type SubmissionId,\n} from \"@effect-agent/core/Identifiers\";\nimport { IdGenerator } from \"@effect-agent/core/IdGenerator\";\nimport { DurableStep, DurableStepError } from \"@effect-agent/engine/DurableStep\";\nimport { RunToolAuthorization } from \"@effect-agent/engine/RunOptions\";\nimport { DurableWorkerBinding, type ResolvedBinding } from \"@effect-agent/thread/AgentRegistration\";\nimport {\n DurableAgentRuntime,\n DurableRuntimeConfig,\n type DurableSubmitFailure,\n type DurableSubmitOptions,\n type Receipt,\n} from \"@effect-agent/thread/DurableAgentRuntime\";\nimport {\n DurableRuntimeFailpointError,\n DurableRuntimeFailpointLocation,\n} from \"@effect-agent/thread/DurableFailpoint\";\nimport {\n DefinitionDigests,\n DeploymentId,\n Digest,\n ProducerId,\n type BatchId,\n} from \"@effect-agent/thread/Records\";\nimport { childThreadIdFor } from \"@effect-agent/thread/RunJournal\";\nimport {\n ApprovalDecisionCommand,\n IdempotencyKey,\n Principal,\n ResolutionSafeToRetry,\n SubmissionLedger,\n SubmissionLookupById,\n UnknownResolutionCommand,\n DEFAULT_OWNERSHIP_LEASE_DURATION,\n type SubmissionSnapshot,\n} from \"@effect-agent/thread/SubmissionLedger\";\nimport {\n type CertificationCaseResult,\n CertificationReport,\n CertificationSweepResult,\n CertificationTierThreeReport,\n CertifiedAdapterIdentity,\n certifyPorts,\n type CertificationScenario,\n} from \"@effect-agent/thread/testing/Certification\";\nimport { DurableRuntimeFailpointTestControl } from \"@effect-agent/thread/testing/DurableFailpointTestControl\";\nimport { verifyThreadInvariants } from \"@effect-agent/thread/ThreadInvariants\";\nimport {\n ThreadExportRequest,\n ThreadStore,\n LoadCheckpointRequest,\n} from \"@effect-agent/thread/ThreadStore\";\nimport { ToolReconciler } from \"@effect-agent/thread/ToolReconciler\";\nimport { WakeScheduler } from \"@effect-agent/thread/WakeScheduler\";\nimport type { Crypto } from \"effect\";\nimport {\n Cause,\n Clock,\n DateTime,\n Duration,\n Effect,\n Exit,\n Layer,\n Option,\n Ref,\n Schema,\n Stream,\n} from \"effect\";\nimport { TestClock } from \"effect/testing\";\nimport { LanguageModel, Model, Tool, Toolkit, type Response } from \"effect/unstable/ai\";\n\n/**\n * P7 WP2 — `certifyDurableAdapters` (plan §1): the one certification entry point a durable\n * adapter pair runs to earn a Schema-encoded certificate.\n *\n * - **Tier 1 — port contract**: the two shared conformance case arrays, verbatim, through\n * `certifyPorts` (TEST-004/STORE-010).\n * - **Tier 2 — coordinator protocol + failpoint convergence**: the durable coordinator is\n * assembled over the CANDIDATE Layer pair with a scripted deterministic model; every\n * `DurableRuntimeFailpointLocation` is armed one-shot across the six scenario shapes\n * (plain / uncertain-tool / durable-steps / approval / join / delegation). After the injected\n * fault the runner asserts the state stays CLASSIFIABLE (recovery + the public unblocking\n * operations `resolveUnknown`/`resolveApproval` are the only levers used) and that the\n * re-drive CONVERGES to `verifyThreadInvariants` with `requireAllSettled` — including a\n * fully discharged digest-chain check, because the runner captures per-batch producer\n * identity at append time.\n * - **Tier 3 — real loss lever**: recorded honestly. A durable adapter either supplies a\n * `CertificationCrashLever` executed in this run, cites its committed real-loss evidence\n * (process-kill / eviction suites), or the certificate says `not-exercised`. A non-durable\n * reference adapter records `not-applicable`.\n *\n * The runner is adapter-neutral and platform-neutral: it imports nothing Node-only, so the\n * same entry point runs under `@effect/vitest` on Node and inside workerd (storage-cloudflare's\n * in-workerd runner). It must run under a TestClock (Tier 1 drives lease expiry through\n * virtual time), and requires only `Crypto.Crypto` from the environment.\n */\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\n/**\n * A real-loss lever supplied by an adapter that wants Tier 3 exercised IN this certification\n * run (kill/evict/reopen around a designated row subset). Rows report with\n * `suite: \"real-loss\"`. Failures must be captured per-row — the lever's error channel is\n * `never` so a certificate is always produced.\n */\nexport type CertificationCrashLever = Effect.Effect<ReadonlyArray<CertificationCaseResult>>;\n\nexport interface CertifyDurableAdaptersOptions<LedgerE = never, StoreE = never> {\n /** Adapter pair identity named by the certificate (durability is read from the ledger). */\n readonly adapter: {\n readonly name: string;\n readonly version?: string | undefined;\n };\n /**\n * The candidate Layer pair. When both ports must share one connection root (the ADR-0011\n * \"same file\" rule), pass the SAME combined Layer instance for both fields — Layer\n * memoization builds it once. A candidate may require `Crypto.Crypto` (the memory reference\n * does); the certification's own environment supplies nothing else.\n */\n readonly submissionLedger: Layer.Layer<SubmissionLedger, LedgerE, Crypto.Crypto>;\n readonly threadStore: Layer.Layer<ThreadStore, StoreE, Crypto.Crypto>;\n /** Defaults to `WakeScheduler.layerNoop`; the runner re-drives lanes explicitly. */\n readonly wakeScheduler?: Layer.Layer<WakeScheduler> | undefined;\n /** Executes Tier 3 in this run; takes precedence over `tierThreeEvidence`. */\n readonly crashLever?: CertificationCrashLever | undefined;\n /** Repository-relative citations of committed real-loss suites (Tier 3 `recorded-evidence`). */\n readonly tierThreeEvidence?: ReadonlyArray<string> | undefined;\n /**\n * The candidate ledger's configured ownership lease (defaults to the D5 default, 30s).\n * Every Tier-2 re-drive round advances the TestClock past this lease before reclaiming:\n * a live lease may block ALL new claims (the SQL adapters do; the memory reference also\n * allows same-producer reclaim), so the adapter-NEUTRAL recovery lever after a mid-Attempt\n * fault is lease expiry — exactly the documented D5 liveness mechanism, driven through\n * virtual time.\n */\n readonly ownershipLeaseDuration?: Duration.Duration | undefined;\n}\n\n/** The six Tier-2 scenario shapes in sweep order. */\nexport const CERTIFICATION_SCENARIOS: ReadonlyArray<CertificationScenario> = [\n \"plain\",\n \"uncertain-tool\",\n \"durable-steps\",\n \"approval\",\n \"join\",\n \"delegation\",\n];\n\n/**\n * Coordinator failpoint locations that none of the six scenario shapes can reach, recorded\n * honestly instead of silently claimed. These require operator, compaction, reservation,\n * background-worker, or Agent-update paths the shapes do not take. They are pinned in-process\n * by the P5/S2 suites (`packages/testing/test/durable-tools.test.ts` \"resolveUnknown is idempotent across the\n * intent failpoint\", `durable-runtime.test.ts` abort rows,\n * `durable-subagents.test.ts` abort propagation) and by the process-kill/eviction crash\n * matrices. Runner tests assert the observed never-fired set equals EXACTLY this list, so a\n * protocol change that silently stops exercising a location fails the certification.\n */\nexport const TIER2_UNREACHED_LOCATIONS: ReadonlyArray<DurableRuntimeFailpointLocation> = [\n // Tier 2 has no native compaction; dedicated checkpoint process-loss tests cover these.\n \"checkpoint:before-save\",\n \"checkpoint:after-save\",\n \"abort:after-intent\",\n // Compaction requires a `contextTokenLimit` policy plus prior-Run history\n // none of the six scenario shapes carries; pinned in-process by the\n // RUN-026 rows in `packages/testing/test/durable-runtime.test.ts`\n // (compaction failpoint idempotence across re-drive).\n \"compaction:before-canonical-append\",\n \"compaction:after-canonical-append\",\n // These shapes use neither programmatic Tools nor grace finalization. Their reservations\n // are exercised before/after append in the public durable-runtime regression suite.\n \"policy:before-reservation-append\",\n \"policy:after-reservation-append\",\n \"resolve:after-intent\",\n \"subagent:after-child-abort-intent\",\n // Background workers use retained delivery, source capacity, and child-origin paths absent\n // from these six attached/ordinary scenarios. The before/after creation and completion\n // boundaries are exercised by packages/thread/test/worker-host.test.ts.\n \"worker:before-source-append\",\n \"worker:after-source-append\",\n \"worker:before-origin-append\",\n \"worker:after-origin-append\",\n \"worker:before-completion-append\",\n \"worker:after-completion-append\",\n // Root attached declarations keep their independent pool; nested shared subtree mutations\n // are covered by the same focused worker-host failpoint suite.\n \"worker:before-subtree-append\",\n \"worker:after-subtree-append\",\n // Automatic report decisions and retained delivery insertion have dedicated worker crash tests.\n \"worker:before-report-append\",\n \"worker:after-report-append\",\n \"worker:before-report-delivery\",\n \"worker:after-report-delivery\",\n // None of the six shapes emits Agent updates. All four boundaries are exercised separately\n // by packages/thread/test/worker-host.test.ts (\"repairs an accepted parent update after ...\").\n // Node restart/lost-ack coverage is in packages/platform-node/test/worker-updates.test.ts;\n // Cloudflare eviction/alarm recovery is in packages/platform-cloudflare/test/background-workers.test.ts.\n // These suites are not executed by this certification runner; its update rows remain not-triggered.\n \"update:before-canonical-append\",\n \"update:after-canonical-append\",\n \"update:before-delivery-insert\",\n \"update:after-delivery-insert\",\n];\n\n/** Locations of `tier2` rows whose armed fault never fired in ANY scenario, sorted. */\nexport const tier2NeverFiredLocations = (\n tier2: ReadonlyArray<CertificationSweepResult>,\n): ReadonlyArray<DurableRuntimeFailpointLocation> => {\n const fired = new Set<DurableRuntimeFailpointLocation>();\n\n for (const row of tier2) {\n if (row.failpointFired) fired.add(row.location);\n }\n\n return DurableRuntimeFailpointLocation.literals.filter((location) => !fired.has(location)).sort();\n};\n\n// ---------------------------------------------------------------------------\n// Deterministic fixtures (scripted prompt-shape models, agents, delegation)\n// ---------------------------------------------------------------------------\n\nconst SHA_A = Schema.decodeSync(Digest)(\"a\".repeat(64));\nconst DIGESTS = DefinitionDigests.make({ agent: SHA_A, model: SHA_A, tools: SHA_A });\n\nconst CHILD_DIGEST_STRINGS = {\n agent: \"b\".repeat(64),\n model: \"c\".repeat(64),\n tools: \"d\".repeat(64),\n} as const;\n\nconst CHILD_DIGESTS = DefinitionDigests.make({\n agent: Schema.decodeSync(Digest)(CHILD_DIGEST_STRINGS.agent),\n model: Schema.decodeSync(Digest)(CHILD_DIGEST_STRINGS.model),\n tools: Schema.decodeSync(Digest)(CHILD_DIGEST_STRINGS.tools),\n});\n\nconst PRINCIPAL = Schema.decodeSync(Principal)(\"principal-certification\");\nconst decodeThreadId = Schema.decodeSync(ThreadId);\nconst decodeIdempotencyKey = Schema.decodeSync(IdempotencyKey);\nconst decodeToolCallId = Schema.decodeSync(ToolCallId);\n\nconst usage = { inputTokens: {}, outputTokens: {} };\n\nconst finalParts = (text: string): ReadonlyArray<Response.StreamPartEncoded> => [\n { type: \"text-start\", id: \"answer\" },\n { type: \"text-delta\", id: \"answer\", delta: text },\n { type: \"text-end\", id: \"answer\" },\n { type: \"finish\", reason: \"stop\", usage },\n];\n\nconst toolCallPart = (id: string, name: string, params: unknown): Response.StreamPartEncoded => ({\n type: \"tool-call\",\n id,\n name,\n params,\n providerExecuted: false,\n});\n\nconst toolTurn = (\n ...calls: ReadonlyArray<Response.StreamPartEncoded>\n): ReadonlyArray<Response.StreamPartEncoded> => [\n ...calls,\n { type: \"finish\", reason: \"tool-calls\", usage },\n];\n\n/**\n * Stateless scripted model that decides by PROMPT SHAPE instead of call count: while the\n * prompt carries no committed tool result the model declares `toolParts` (when given),\n * otherwise it answers with the final text. Deciding on the canonical prompt keeps every cell\n * deterministic regardless of where the injected fault fell — a re-invoked Turn re-declares\n * the same batch and a resumed batch flows into the final answer, so every scenario always\n * exercises its tool path and always converges.\n */\nconst promptShapeModel = (\n name: string,\n finalText: string,\n toolParts?: ReadonlyArray<Response.StreamPartEncoded>,\n) =>\n Model.make(\n \"scripted\",\n name,\n Layer.effect(\n LanguageModel.LanguageModel,\n LanguageModel.make({\n generateText: () => Effect.succeed([]),\n streamText: (request) => {\n const hasToolResult = request.prompt.content.some((message) => message.role === \"tool\");\n\n const parts =\n toolParts === undefined || hasToolResult ? finalParts(finalText) : toolParts;\n\n return Stream.fromIterable(parts);\n },\n }),\n ),\n );\n\n// Tier-2 intentionally advances virtual time past a 30-second ownership lease on every\n// re-drive round. Keep its business-policy duration above the full eight-round sweep so this\n// fixture certifies crash convergence rather than accidentally relying on a fresh duration\n// allowance per replacement Attempt. RUN-030 owns the dedicated duration-expiry coverage.\nconst CERTIFICATION_MAX_DURATION = \"10 minutes\" as const;\n\nconst policy = AgentPolicy.make({\n maxTurns: 4,\n maxToolCalls: 4,\n maxDuration: CERTIFICATION_MAX_DURATION,\n toolConcurrency: 2,\n});\n\nconst QuestionInput = Schema.Struct({ question: Schema.String });\nconst AnswerOutput = Schema.Struct({ answer: Schema.String });\n\n/** plain / join: no tools — the pure Turn/submission/join seams. */\nconst plainDefinition = Agent.make(\"certify-plain\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Answer as JSON.\",\n toolkit: Toolkit.empty,\n policy,\n});\n\n/** uncertain-tool: unannotated → fail-closed `uncertain`, enters the prepared/settled protocol. */\nconst Book = Tool.make(\"book\", {\n parameters: Schema.Struct({ ref: Schema.String }),\n success: Schema.Struct({ confirmation: Schema.String }),\n});\n\nconst bookToolkit = Toolkit.make(Book);\n\nconst uncertainDefinition = Agent.make(\"certify-uncertain\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Book it.\",\n toolkit: bookToolkit,\n policy,\n});\n\n/** durable-steps: declaring `DurableStep` as a dependency is what makes the Tool durable. */\nconst Itinerary = Tool.make(\"itinerary\", {\n parameters: Schema.Struct({ ref: Schema.String }),\n success: Schema.Struct({ state: Schema.String }),\n failure: DurableStepError,\n dependencies: [DurableStep],\n});\n\nconst itineraryToolkit = Toolkit.make(Itinerary);\n\nconst stepsDefinition = Agent.make(\"certify-steps\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Reserve the itinerary.\",\n toolkit: itineraryToolkit,\n policy,\n});\n\n/** approval: fail-closed — no `DurableApprovalResolver` Layer, so undecided approvals suspend. */\nconst BookApproval = Tool.make(\"book\", {\n parameters: Schema.Struct({ ref: Schema.String }),\n success: Schema.Struct({ confirmation: Schema.String }),\n needsApproval: true,\n});\n\nconst approvalToolkit = Toolkit.make(BookApproval);\n\nconst approvalDefinition = Agent.make(\"certify-approval\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Book after approval.\",\n toolkit: approvalToolkit,\n policy,\n});\n\n/** delegation: durable attached child plus an ordinary uncertain sibling in ONE batch. */\nconst childDefinition = Agent.make(\"certify-child\", {\n input: QuestionInput,\n output: AnswerOutput,\n instructions: \"Answer as JSON.\",\n toolkit: Toolkit.empty,\n policy: AgentPolicy.make({\n maxTurns: 2,\n maxToolCalls: 1,\n maxDuration: CERTIFICATION_MAX_DURATION,\n toolConcurrency: 1,\n }),\n});\n\nclass CertifyDelegationFailed extends Schema.TaggedError<CertifyDelegationFailed>()(\n \"CertifyDelegationFailed\",\n { childErrorTag: Schema.String },\n) {}\n\nconst researchDelegation = Subagent.define(\"delegate_research\", {\n description: \"Research one bounded question and return findings.\",\n target: childDefinition,\n parameters: Schema.Struct({ topic: Schema.String }),\n success: Schema.Struct({ summary: Schema.String }),\n failure: CertifyDelegationFailed,\n prepareInput: ({ topic }) => Effect.succeed({ question: `research:${topic}` }),\n projectResult: (output) => Effect.succeed({ summary: `finding:${output.answer}` }),\n policy: SubagentPolicy.make({\n maxChildren: 2,\n maxConcurrency: 2,\n maxTurns: 4,\n maxToolCalls: 4,\n maxDuration: CERTIFICATION_MAX_DURATION,\n }),\n});\n\nconst Lookup = Tool.make(\"lookup\", {\n parameters: Schema.Struct({ key: Schema.String }),\n success: Schema.Struct({ value: Schema.String }),\n});\n\nconst coordinatorDefinition = Agent.make(\"certify-coordinator\", {\n input: Schema.Struct({ mission: Schema.String }),\n output: Schema.Struct({ report: Schema.String }),\n instructions: \"Delegate and look up, then answer as JSON.\",\n toolkit: Toolkit.make(researchDelegation.tool, Lookup),\n policy: AgentPolicy.make({\n maxTurns: 4,\n maxToolCalls: 3,\n maxDuration: CERTIFICATION_MAX_DURATION,\n toolConcurrency: 2,\n }),\n});\n\nconst mapChildFailure = (failure: { readonly _tag: string }) =>\n CertifyDelegationFailed.make({ childErrorTag: failure._tag });\n\nconst DELEGATE_CALL = decodeToolCallId(\"delegate-1\");\n\n/** Fixture-only identity source consumed by the delegation Layer's ephemeral capture. */\nconst identifiers = Layer.effect(\n IdGenerator,\n Effect.gen(function* () {\n const counter = yield* Ref.make(0);\n\n const next = <A>(decode: (value: string) => A, prefix: string) =>\n Ref.getAndUpdate(counter, (value) => value + 1).pipe(\n Effect.map((value) => decode(`${prefix}-${value}`)),\n );\n\n return {\n nextThreadId: next(decodeThreadId, \"certify-fixture-thread\"),\n nextRunId: next(Schema.decodeSync(RunId), \"certify-fixture-run\"),\n nextTurnId: next(Schema.decodeSync(TurnId), \"certify-fixture-turn\"),\n };\n }),\n);\n\nconst delegationSupport = Layer.mergeAll(SubagentReservationsMemoryLive, identifiers);\n\n// ---------------------------------------------------------------------------\n// Tier 2 — scenario cells\n// ---------------------------------------------------------------------------\n\ninterface CertificationCell {\n readonly bindings: ReadonlyArray<ResolvedBinding>;\n /** Idempotent submission batch — safe to replay verbatim after a submit-boundary fault. */\n readonly submit: Effect.Effect<ReadonlyArray<Receipt>, DurableSubmitFailure, DurableAgentRuntime>;\n /** All lanes of the cell in drive order, computed from the (possibly replayed) receipts. */\n readonly lanes: (receipts: ReadonlyArray<Receipt>) => ReadonlyArray<ThreadId>;\n}\n\nconst submitOptionsFor = (slug: string, threadId: ThreadId): DurableSubmitOptions => ({\n threadId,\n principal: PRINCIPAL,\n idempotencyKey: decodeIdempotencyKey(`certify-key-${slug}`),\n definitions: DIGESTS,\n});\n\n/** One single-agent cell: one lane, one Submission, one registered exact-digest binding. */\nconst makeSingleAgentCell = (\n definition: { readonly id: AgentId; readonly input: typeof QuestionInput },\n resolved: ResolvedBinding,\n slug: string,\n): CertificationCell => {\n const threadId = decodeThreadId(`certify-${slug}`);\n\n const submit = Effect.gen(function* () {\n const runtime = yield* DurableAgentRuntime;\n\n const receipt = yield* runtime.submit(\n { definition: { id: definition.id, input: definition.input } },\n { question: `certify ${slug}` },\n submitOptionsFor(slug, threadId),\n );\n\n return [receipt];\n });\n\n return {\n bindings: [resolved],\n submit,\n lanes: () => [threadId],\n };\n};\n\nconst makeCell = Effect.fn(\"Certification.makeCell\")(function* (\n scenario: CertificationScenario,\n slug: string,\n) {\n switch (scenario) {\n case \"plain\": {\n const binding = Agent.withModel(\n plainDefinition,\n promptShapeModel(\"certify-plain\", '{\"answer\":\"done\"}'),\n );\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS);\n\n return makeSingleAgentCell(plainDefinition, resolved, slug);\n }\n case \"uncertain-tool\": {\n const binding = Agent.withModel(\n uncertainDefinition,\n promptShapeModel(\n \"certify-uncertain\",\n '{\"answer\":\"booked\"}',\n toolTurn(toolCallPart(\"book-1\", \"book\", { ref: `r-${slug}` })),\n ),\n );\n\n const toolLayer = bookToolkit.toLayer({\n book: ({ ref }) => Effect.succeed({ confirmation: `confirmed-${ref}` }),\n });\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS).pipe(\n Effect.provide(toolLayer),\n );\n\n return makeSingleAgentCell(uncertainDefinition, resolved, slug);\n }\n case \"durable-steps\": {\n const binding = Agent.withModel(\n stepsDefinition,\n promptShapeModel(\n \"certify-steps\",\n '{\"answer\":\"reserved\"}',\n toolTurn(toolCallPart(\"itinerary-1\", \"itinerary\", { ref: `trip-${slug}` })),\n ),\n );\n\n const toolLayer = itineraryToolkit.toLayer({\n itinerary: ({ ref }) =>\n Effect.gen(function* () {\n const step = yield* DurableStep;\n\n const flight = yield* step.do(\n \"reserve-flight\",\n Schema.String,\n Effect.succeed(`flight-${ref}`),\n );\n\n const lodging = yield* step.do(\n \"reserve-lodging\",\n Schema.String,\n Effect.succeed(`lodging-${ref}`),\n );\n\n return { state: `${flight}+${lodging}` };\n }),\n });\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS).pipe(\n Effect.provide(toolLayer),\n );\n\n return makeSingleAgentCell(stepsDefinition, resolved, slug);\n }\n case \"approval\": {\n const binding = Agent.withModel(\n approvalDefinition,\n promptShapeModel(\n \"certify-approval\",\n '{\"answer\":\"approved\"}',\n toolTurn(toolCallPart(\"book-1\", \"book\", { ref: `r-${slug}` })),\n ),\n );\n\n const toolLayer = approvalToolkit.toLayer({\n book: ({ ref }) => Effect.succeed({ confirmation: `confirmed-${ref}` }),\n });\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS).pipe(\n Effect.provide(toolLayer),\n );\n\n return makeSingleAgentCell(approvalDefinition, resolved, slug);\n }\n case \"join\": {\n const binding = Agent.withModel(\n plainDefinition,\n promptShapeModel(\"certify-join\", '{\"answer\":\"host answer\"}'),\n );\n\n const resolved = yield* DurableWorkerBinding.make(binding, DIGESTS);\n const threadId = decodeThreadId(`certify-${slug}`);\n\n const submitOne = Effect.fn(\"Certification.submitOne\")(function* (\n key: string,\n question: string,\n ) {\n const runtime = yield* DurableAgentRuntime;\n\n return yield* runtime.submit(\n { definition: { id: plainDefinition.id, input: plainDefinition.input } },\n { question },\n {\n threadId,\n principal: PRINCIPAL,\n idempotencyKey: decodeIdempotencyKey(key),\n definitions: DIGESTS,\n },\n );\n });\n\n const cell: CertificationCell = {\n bindings: [resolved],\n submit: Effect.gen(function* () {\n const host = yield* submitOne(`certify-key-${slug}-host`, \"host question\");\n const queued = yield* submitOne(`certify-key-${slug}-queued`, \"queued question\");\n\n return [host, queued];\n }),\n lanes: () => [threadId],\n };\n\n return cell;\n }\n case \"delegation\": {\n const childBinding = Agent.withModel(\n childDefinition,\n promptShapeModel(\"certify-child\", '{\"answer\":\"child-answer\"}'),\n );\n\n const parentBinding = Agent.withModel(\n coordinatorDefinition,\n promptShapeModel(\n \"certify-parent\",\n '{\"report\":\"done\"}',\n toolTurn(\n toolCallPart(\"delegate-1\", \"delegate_research\", { topic: \"paris\" }),\n toolCallPart(\"lookup-1\", \"lookup\", { key: \"hotels\" }),\n ),\n ),\n );\n\n const delegationLayer = SubagentRuntime.layer(researchDelegation, childBinding, {\n mapChildFailure,\n durable: { targetDigests: CHILD_DIGEST_STRINGS },\n }).pipe(Layer.provide(delegationSupport));\n\n const lookupLayer = Toolkit.make(Lookup).toLayer({\n lookup: ({ key }) => Effect.succeed({ value: `found-${key}` }),\n });\n\n const parentResolved = yield* DurableWorkerBinding.make(parentBinding, DIGESTS).pipe(\n Effect.provide(Layer.mergeAll(delegationLayer, lookupLayer)),\n );\n\n const childResolved = yield* DurableWorkerBinding.make(childBinding, CHILD_DIGESTS);\n const threadId = decodeThreadId(`certify-${slug}`);\n\n const cell: CertificationCell = {\n bindings: [parentResolved, childResolved],\n submit: Effect.gen(function* () {\n const runtime = yield* DurableAgentRuntime;\n\n const receipt = yield* runtime.submit(\n { definition: { id: coordinatorDefinition.id, input: coordinatorDefinition.input } },\n { mission: \"plan\" },\n submitOptionsFor(slug, threadId),\n );\n\n return [receipt];\n }),\n lanes: (receipts) => {\n const parent = receipts.at(0);\n\n return parent === undefined\n ? [threadId]\n : [threadId, childThreadIdFor(parent.submissionId, DELEGATE_CALL)];\n },\n };\n\n return cell;\n }\n }\n});\n\n/** Maximum recovery/drive/unblock rounds before a cell is reported non-convergent. */\nconst MAX_REDRIVE_ROUNDS = 8;\n\n/**\n * Verify one lane after convergence: canonical export + every lane Submission the ledger or\n * the log names (the same collection rule as the admin `verify` member), fed to the shared\n * invariant checker in convergence mode WITH the captured per-batch producer directory, so\n * the digest chain is fully recomputed instead of skipped.\n */\nconst verifyLane = Effect.fn(\"Certification.verifyLane\")(function* (\n lane: ThreadId,\n batchProducers: ReadonlyMap<BatchId, ProducerId>,\n) {\n const store = yield* ThreadStore;\n const ledger = yield* SubmissionLedger;\n const exported = yield* store.export(ThreadExportRequest.make({ threadId: lane }));\n const rows = new Map<SubmissionId, SubmissionSnapshot>();\n const nonterminal = yield* Stream.runCollect(ledger.scanNonterminal);\n\n for (const submission of nonterminal) {\n if (submission.threadId === lane) rows.set(submission.submissionId, submission);\n }\n const named = new Set<SubmissionId>();\n\n for (const envelope of exported.records) {\n const payload = envelope.record.payload;\n\n if (\n payload._tag === \"UserInputRecorded\" ||\n payload._tag === \"SubmissionSettled\" ||\n payload._tag === \"AbortRequested\"\n ) {\n if (payload.submissionId !== undefined) named.add(payload.submissionId);\n }\n }\n for (const submissionId of named) {\n if (rows.has(submissionId)) continue;\n const found = yield* ledger.lookup(SubmissionLookupById.make({ submissionId }));\n\n if (Option.isSome(found) && found.value.threadId === lane) {\n rows.set(submissionId, found.value);\n }\n }\n\n const checkpoint =\n store.checkpoints === undefined\n ? Option.none()\n : yield* store.checkpoints.load(LoadCheckpointRequest.make({ threadId: lane }));\n\n return yield* verifyThreadInvariants({\n export: exported,\n submissions: [...rows.values()],\n batchProducers,\n checkpoint: Option.getOrUndefined(checkpoint),\n checkpointsSupported: store.checkpoints !== undefined,\n requireAllSettled: true,\n });\n});\n\nconst failureTagOf = <E>(cause: Cause.Cause<E>): string => {\n const failure = Cause.findErrorOption(cause);\n\n if (Option.isSome(failure)) {\n const error: unknown = failure.value;\n\n if (typeof error === \"object\" && error !== null && \"_tag\" in error) {\n return String(error._tag);\n }\n\n return String(error).slice(0, 256);\n }\n\n return \"defect\";\n};\n\n/** One Tier-2 sweep cell: arm `location` one-shot, drive `scenario`, converge, verify. */\nconst runSweepCell = Effect.fn(\"Certification.runSweepCell\")(function* (\n scenario: CertificationScenario,\n location: DurableRuntimeFailpointLocation,\n batchProducers: ReadonlyMap<BatchId, ProducerId>,\n leaseAdvance: Duration.Duration,\n) {\n const ledger = yield* SubmissionLedger;\n const control = yield* DurableRuntimeFailpointTestControl;\n const slug = `${scenario}-${location.replaceAll(\":\", \"-\")}`;\n\n const failed = (detail: string, fired: boolean): CertificationSweepResult =>\n CertificationSweepResult.make({\n scenario,\n location,\n failpointFired: fired,\n status: \"failed\",\n digestChainVerified: false,\n detail: detail.slice(0, 4_096),\n });\n\n const cell = yield* makeCell(scenario, slug);\n\n const runtime = yield* DurableAgentRuntime.pipe(\n Effect.provide(\n DurableAgentRuntime.layerWithBindings(cell.bindings).pipe(\n Layer.provide(RunToolAuthorization.allowAll),\n ),\n ),\n );\n\n const submit = cell.submit.pipe(Effect.provideService(DurableAgentRuntime, runtime));\n\n // One-shot arm: the fault fires at most once anywhere in the cell (initial drive OR a\n // re-drive round's public unblocking operation), modelling one crash at this boundary.\n const fired = yield* Ref.make(false);\n\n yield* control.setHandler((hit) =>\n hit !== location\n ? Effect.void\n : Ref.getAndSet(fired, true).pipe(\n Effect.flatMap((already) =>\n already\n ? Effect.void\n : Effect.fail(DurableRuntimeFailpointError.make({ location: hit })),\n ),\n ),\n );\n\n // Submissions are idempotent (DUR-001): one replay recovers a submit-boundary fault.\n let receipts: ReadonlyArray<Receipt>;\n const firstSubmit = yield* Effect.exit(submit);\n\n if (Exit.isSuccess(firstSubmit)) {\n receipts = firstSubmit.value;\n } else {\n const secondSubmit = yield* Effect.exit(submit);\n\n if (Exit.isFailure(secondSubmit)) {\n yield* control.clear;\n\n return failed(\n `submission replay did not recover: ${failureTagOf(secondSubmit.cause)}`,\n yield* Ref.get(fired),\n );\n }\n receipts = secondSubmit.value;\n }\n const lanes = cell.lanes(receipts);\n\n const driveLane = (lane: ThreadId) => runtime.processThreadResolved(lane);\n\n const allSettled = Effect.gen(function* () {\n for (const receipt of receipts) {\n const snapshot = yield* ledger.lookup(\n SubmissionLookupById.make({ submissionId: receipt.submissionId }),\n );\n\n if (Option.isNone(snapshot) || snapshot.value.state !== \"settled\") return false;\n }\n\n return true;\n });\n\n // Re-drive to convergence using ONLY public operations: worker drives, recovery passes,\n // and the authorized DUR-017/approval unblocking paths chosen from `explainThread`.\n let converged = false;\n\n for (let round = 0; round < MAX_REDRIVE_ROUNDS && !converged; round++) {\n // Expire any lease a faulted Attempt left behind (D5): virtual time is the\n // adapter-neutral reclaim lever — a live lease may block every new claim.\n yield* TestClock.adjust(leaseAdvance);\n yield* Effect.exit(runtime.runRecovery);\n for (const lane of lanes) {\n yield* Effect.exit(driveLane(lane));\n }\n for (const lane of lanes) {\n const explains = yield* Effect.exit(runtime.explainThread(lane));\n\n if (Exit.isFailure(explains)) continue;\n for (const explanation of explains.value) {\n for (const unknown of explanation.evidence.unknownCalls) {\n if (unknown.resolved) continue;\n yield* Effect.exit(\n runtime.resolveUnknown(\n UnknownResolutionCommand.make({\n submissionId: explanation.submission.submissionId,\n toolCallId: unknown.toolCallId,\n author: \"certification-runner\",\n reason: `re-drive after injected fault at ${location}`,\n resolution: ResolutionSafeToRetry.make(),\n }),\n ),\n );\n }\n for (const pending of explanation.evidence.approvalsPending) {\n const decided = explanation.evidence.approvalDecisions.some(\n (decision) => decision.toolCallId === pending.toolCallId,\n );\n\n if (decided) continue;\n yield* Effect.exit(\n runtime.resolveApproval(\n ApprovalDecisionCommand.make({\n submissionId: explanation.submission.submissionId,\n toolCallId: pending.toolCallId,\n decision: \"approved\",\n resolver: \"certification-runner\",\n reason: `re-drive after injected fault at ${location}`,\n }),\n ),\n );\n }\n }\n }\n const settled = yield* Effect.exit(allSettled);\n\n converged = Exit.isSuccess(settled) && settled.value;\n }\n yield* control.clear;\n const wasFired = yield* Ref.get(fired);\n\n if (!converged) {\n return failed(`did not converge within ${MAX_REDRIVE_ROUNDS} re-drive rounds`, wasFired);\n }\n\n // Every lane of the cell must verify in convergence mode with a recomputed digest chain.\n let digestChainVerified = true;\n const failedChecks: Array<string> = [];\n\n for (const lane of lanes) {\n const verdict = yield* Effect.exit(verifyLane(lane, batchProducers));\n\n if (Exit.isFailure(verdict)) {\n return failed(`lane ${lane} could not be verified: ${failureTagOf(verdict.cause)}`, wasFired);\n }\n for (const check of verdict.value.checks) {\n if (check.status === \"failed\") {\n failedChecks.push(\n `${lane}:${check.name}${check.detail === undefined ? \"\" : ` (${check.detail})`}`,\n );\n }\n if (check.name === \"digest-chain\" && check.status !== \"passed\") {\n digestChainVerified = false;\n }\n }\n }\n if (failedChecks.length > 0 || !digestChainVerified) {\n return failed(\n failedChecks.length > 0\n ? `invariant checks failed: ${failedChecks.join(\"; \")}`\n : \"the digest chain was not fully recomputed\",\n wasFired,\n );\n }\n\n return CertificationSweepResult.make({\n scenario,\n location,\n failpointFired: wasFired,\n status: wasFired ? \"converged\" : \"not-triggered\",\n digestChainVerified,\n });\n});\n\n// ---------------------------------------------------------------------------\n// Tier 3 — real loss lever record\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve the Tier-3 record honestly (plan §1): a non-durable reference adapter has no real\n * loss to exercise (`not-applicable`); a supplied lever runs NOW (`exercised`); committed\n * real-loss citations are recorded (`recorded-evidence`); otherwise the certificate says\n * `not-exercised` — a scoped statement, never a silent claim.\n */\nexport const resolveTierThree = Effect.fn(\"Certification.resolveTierThree\")(function* (\n durability: CertifiedAdapterIdentity[\"durability\"],\n options: {\n readonly crashLever?: CertificationCrashLever | undefined;\n readonly tierThreeEvidence?: ReadonlyArray<string> | undefined;\n },\n): Effect.fn.Return<CertificationTierThreeReport, never> {\n if (durability === \"non-durable\") {\n return CertificationTierThreeReport.make({\n status: \"not-applicable\",\n evidence: [],\n cases: [],\n detail:\n \"the adapter declares non-durable state (reference/conformance adapter); there is no real loss to exercise\",\n });\n }\n if (options.crashLever !== undefined) {\n const cases = yield* options.crashLever;\n\n return CertificationTierThreeReport.make({\n status: cases.length === 0 ? \"not-exercised\" : \"exercised\",\n evidence: options.tierThreeEvidence ?? [],\n cases,\n ...(cases.length === 0\n ? { detail: \"the supplied crash lever executed no real-loss cases\" }\n : {}),\n });\n }\n if (options.tierThreeEvidence !== undefined && options.tierThreeEvidence.length > 0) {\n return CertificationTierThreeReport.make({\n status: \"recorded-evidence\",\n evidence: options.tierThreeEvidence,\n cases: [],\n });\n }\n\n return CertificationTierThreeReport.make({\n status: \"not-exercised\",\n evidence: [],\n cases: [],\n detail:\n \"no crash lever was supplied and no committed real-loss evidence was cited; Tier 3 is NOT discharged for this adapter\",\n });\n});\n\n// ---------------------------------------------------------------------------\n// Entry point\n// ---------------------------------------------------------------------------\n\nconst nowUtc: Effect.Effect<DateTime.Utc> = Effect.map(Clock.currentTimeMillis, (millis) =>\n DateTime.toUtc(DateTime.makeUnsafe(millis)),\n);\n\n/**\n * Certify one durable adapter pair (plan §1, §8 WP2). Runs Tier 2 FIRST over pristine\n * storage (each cell converges to all-settled before the next starts, so the recovery scan\n * never sees foreign leftovers), then Tier 1's port contract cases (whose lanes deliberately\n * end in every nonterminal shape), then records Tier 3. Requires `Crypto.Crypto` and a\n * TestClock-backed environment; the candidate Layers are built exactly once.\n */\nexport const certifyDurableAdapters = <LedgerE = never, StoreE = never>(\n options: CertifyDurableAdaptersOptions<LedgerE, StoreE>,\n): Effect.Effect<CertificationReport, LedgerE | StoreE, Crypto.Crypto> => {\n const batchProducers = new Map<BatchId, ProducerId>();\n\n // Interpose the candidate store with an append-time capture of each batch's producer\n // identity — the one value the ThreadStore port deliberately does not export — so\n // Tier 2's invariant verification recomputes the FULL digest chain instead of skipping it.\n const capturingStore = Layer.effect(ThreadStore)(\n Effect.gen(function* () {\n const inner = yield* ThreadStore;\n\n return ThreadStore.of({\n ...inner,\n append: (request) =>\n Effect.sync(() => {\n batchProducers.set(request.batch.batchId, request.batch.producerId);\n }).pipe(Effect.andThen(inner.append(request))),\n });\n }),\n ).pipe(Layer.provide(options.threadStore));\n\n // RUN-036: certification uses the default-none Tool failure observer. Trusted application\n // reporting adds no durable transition and is verified separately from adapter certification.\n const environment = Layer.mergeAll(\n options.submissionLedger,\n capturingStore,\n options.wakeScheduler ?? WakeScheduler.layerNoop,\n DurableRuntimeFailpointTestControl.layer,\n ToolReconciler.uncertain,\n DurableRuntimeConfig.layer({\n deploymentId: Schema.decodeSync(DeploymentId)(\"deployment-certification\"),\n producerId: Schema.decodeSync(ProducerId)(\"producer-certification\"),\n settlementPollInterval: Duration.millis(50),\n leaseRenewalInterval: Duration.seconds(5),\n abortPollInterval: Duration.millis(50),\n }),\n );\n\n const leaseAdvance = Duration.millis(\n Duration.toMillis(options.ownershipLeaseDuration ?? DEFAULT_OWNERSHIP_LEASE_DURATION) + 1_000,\n );\n\n const program = Effect.gen(function* () {\n const ledger = yield* SubmissionLedger;\n\n // Tier 2 — coordinator failpoint convergence sweep.\n const tier2: Array<CertificationSweepResult> = [];\n\n for (const scenario of CERTIFICATION_SCENARIOS) {\n for (const location of DurableRuntimeFailpointLocation.literals) {\n tier2.push(yield* runSweepCell(scenario, location, batchProducers, leaseAdvance));\n }\n }\n\n // Tier 1 — the shared port contract suites, verbatim.\n const tier1 = yield* certifyPorts();\n\n // Tier 3 — the real loss lever record.\n const capabilities = yield* ledger.capabilities;\n const tier3 = yield* resolveTierThree(capabilities.durability, options);\n\n const generatedAt = yield* nowUtc;\n\n const ok =\n tier1.every((result) => result.status === \"passed\") &&\n tier2.every((result) => result.status !== \"failed\") &&\n tier3.cases.every((result) => result.status === \"passed\");\n\n return CertificationReport.make({\n format: \"effect-agent/certification@2\",\n adapter: CertifiedAdapterIdentity.make({\n name: options.adapter.name,\n ...(options.adapter.version === undefined ? {} : { version: options.adapter.version }),\n durability: capabilities.durability,\n }),\n generatedAt,\n tier1,\n tier2,\n tier3,\n ok,\n fullyCertified:\n ok &&\n capabilities.durability !== \"non-durable\" &&\n tier3.status === \"exercised\" &&\n tier3.cases.length > 0 &&\n tier3.cases.every((result) => result.suite === \"real-loss\"),\n });\n });\n\n return program.pipe(Effect.provide(environment));\n};\n"],"mappings":"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"}
|
package/dist/Chaos.d.mts
CHANGED
|
@@ -42,7 +42,7 @@ declare const ChaosPlan_base: Schema.Class<ChaosPlan, Schema.Struct<{
|
|
|
42
42
|
readonly lanes: Schema.Int;
|
|
43
43
|
readonly submissions: Schema.NonEmptyArray<typeof ChaosSubmissionSpec>;
|
|
44
44
|
/** Coordinator failpoint arms, consumed one per round (each fails every hit that round). */
|
|
45
|
-
readonly failpointArms: Schema.$Array<Schema.Literals<readonly ["submit:after-admit", "submit:after-materialize", "claim:after-claim", "input:after-canonical-append", "run:before-start-append", "run:after-start-append", "turn:after-canonical-append", "turn:after-response-append", "turn:after-results-append", "compaction:before-canonical-append", "compaction:after-canonical-append", "checkpoint:before-save", "checkpoint:after-save", "tools:after-prepared-append", "tools:before-prepared-append", "policy:before-reservation-append", "policy:after-reservation-append", "step:after-step-append", "approval:after-request-append", "approval:after-suspend", "join:after-claim", "join:after-canonical-append", "resolve:after-intent", "terminalize:after-reserve", "terminalize:after-canonical-append", "abort:after-intent", "subagent:after-reserve", "subagent:after-request-append", "subagent:after-admit", "subagent:after-child-ready", "subagent:after-start-append", "subagent:after-sibling-settle", "subagent:after-suspend", "subagent:after-child-abort-intent", "subagent:before-join-append", "subagent:after-join-append", "subagent:after-release-pending", "subagent:after-release", "worker:before-source-append", "worker:after-source-append", "worker:before-origin-append", "worker:after-origin-append", "worker:before-completion-append", "worker:after-completion-append", "worker:before-subtree-append", "worker:after-subtree-append", "worker:before-report-append", "worker:after-report-append", "worker:before-report-delivery", "worker:after-report-delivery"]>>;
|
|
45
|
+
readonly failpointArms: Schema.$Array<Schema.Literals<readonly ["submit:after-admit", "submit:after-materialize", "claim:after-claim", "input:after-canonical-append", "run:before-start-append", "run:after-start-append", "turn:after-canonical-append", "turn:after-response-append", "turn:after-results-append", "compaction:before-canonical-append", "compaction:after-canonical-append", "checkpoint:before-save", "checkpoint:after-save", "tools:after-prepared-append", "tools:before-prepared-append", "policy:before-reservation-append", "policy:after-reservation-append", "step:after-step-append", "approval:after-request-append", "approval:after-suspend", "join:after-claim", "join:after-canonical-append", "resolve:after-intent", "terminalize:after-reserve", "terminalize:after-canonical-append", "abort:after-intent", "subagent:after-reserve", "subagent:after-request-append", "subagent:after-admit", "subagent:after-child-ready", "subagent:after-start-append", "subagent:after-sibling-settle", "subagent:after-suspend", "subagent:after-child-abort-intent", "subagent:before-join-append", "subagent:after-join-append", "subagent:after-release-pending", "subagent:after-release", "worker:before-source-append", "worker:after-source-append", "worker:before-origin-append", "worker:after-origin-append", "worker:before-completion-append", "worker:after-completion-append", "worker:before-subtree-append", "worker:after-subtree-append", "worker:before-report-append", "worker:after-report-append", "worker:before-report-delivery", "worker:after-report-delivery", "update:before-canonical-append", "update:after-canonical-append", "update:before-delivery-insert", "update:after-delivery-insert"]>>;
|
|
46
46
|
/** Adapter-owned failpoint arms (e.g. SQLite `ledger:*`/`append:*` locations). */
|
|
47
47
|
readonly adapterArms: Schema.$Array<Schema.String>;
|
|
48
48
|
/** Flattened submission indices to abort mid-plan (modulo the submission count). */
|
|
@@ -88,7 +88,9 @@ declare const DocSummarizer: Agent.Definition<typeof SummaryBrief, typeof Docume
|
|
|
88
88
|
readonly failure: typeof DocumentUnavailable;
|
|
89
89
|
readonly failureMode: "error";
|
|
90
90
|
}, DocumentLibrary>;
|
|
91
|
-
}>, undefined, undefined
|
|
91
|
+
}>, undefined, undefined, undefined> & {
|
|
92
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "doc-summarizer";
|
|
93
|
+
};
|
|
92
94
|
declare const SummaryRequest_base: Schema.Class<SummaryRequest, Schema.Struct<{
|
|
93
95
|
readonly documentId: Schema.brand<Schema.NonEmptyString, "@effect-agent/testing/docs-researcher/ResearchDocumentId">;
|
|
94
96
|
}>, {}>;
|
|
@@ -119,7 +121,9 @@ declare const delegateDocumentSummary: Subagent.SubagentDelegation<"delegate_doc
|
|
|
119
121
|
readonly failure: typeof DocumentUnavailable;
|
|
120
122
|
readonly failureMode: "error";
|
|
121
123
|
}, DocumentLibrary>;
|
|
122
|
-
}>, undefined, undefined
|
|
124
|
+
}>, undefined, undefined, undefined> & {
|
|
125
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "doc-summarizer";
|
|
126
|
+
};
|
|
123
127
|
};
|
|
124
128
|
/** Total mapping from every expected child Run failure to the declared Tool failure (SUB-028). */
|
|
125
129
|
declare const mapSummaryChildFailure: (failure: {
|
|
@@ -141,7 +145,7 @@ declare const docsSummaryHandlersLayer: <Provider, ModelProvides, ModelRequires>
|
|
|
141
145
|
}, DocumentLibrary>;
|
|
142
146
|
}, Provider, ModelProvides, ModelRequires, never, never, never, {
|
|
143
147
|
readonly _tag: string;
|
|
144
|
-
}, never, undefined>>;
|
|
148
|
+
}, never, undefined, undefined, undefined>>;
|
|
145
149
|
declare const ResearchRequest_base: Schema.Class<ResearchRequest, Schema.Struct<{
|
|
146
150
|
readonly question: Schema.NonEmptyString;
|
|
147
151
|
readonly documentIds: Schema.$Array<Schema.brand<Schema.NonEmptyString, "@effect-agent/testing/docs-researcher/ResearchDocumentId">>;
|
|
@@ -170,7 +174,9 @@ declare const DocsResearcher: Agent.Definition<typeof ResearchRequest, typeof Re
|
|
|
170
174
|
readonly failure: Subagent.SubagentToolFailure<typeof DocumentSummaryFailed>;
|
|
171
175
|
readonly failureMode: "error";
|
|
172
176
|
}, import("@effect-agent/engine/AgentRuntime").AgentSpawner | import("@effect-agent/core/IdGenerator").IdGenerator | import("@effect-agent/engine/RunEventSink").RunEventSink | import("@effect-agent/engine/AgentRuntime").SubagentDurability>;
|
|
173
|
-
}>, undefined, undefined
|
|
177
|
+
}>, undefined, undefined, undefined> & {
|
|
178
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "docs-researcher";
|
|
179
|
+
};
|
|
174
180
|
/** The default two-document research mission. */
|
|
175
181
|
declare const researchMissionRequest: ResearchRequest;
|
|
176
182
|
/** The coordinator's expected final digest for the given documents. */
|
|
@@ -189,7 +195,7 @@ declare const docsResearcherSubmitOptions: (threadId: ThreadId, idempotencyKey:
|
|
|
189
195
|
/** The structural submit slice of the coordinator Binding (`DurableAgentRuntime.submit`). */
|
|
190
196
|
declare const docsResearcherSubmitAgent: {
|
|
191
197
|
readonly definition: {
|
|
192
|
-
readonly id:
|
|
198
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "docs-researcher";
|
|
193
199
|
readonly input: typeof ResearchRequest;
|
|
194
200
|
};
|
|
195
201
|
};
|
package/dist/ScriptedModel.mjs
CHANGED
|
@@ -97,7 +97,7 @@ const takeTurn = Effect.fn("ScriptedModel.takeTurn")((state, kind, options) => R
|
|
|
97
97
|
options
|
|
98
98
|
}]
|
|
99
99
|
}];
|
|
100
|
-
}).pipe(Effect.
|
|
100
|
+
}).pipe(Effect.filterOrFail((turn) => turn !== void 0, () => scriptedError(kind, `Script exhausted before the ${kind} request`))));
|
|
101
101
|
const requireGenerateTurn = (turn) => turn._tag === "Generate" ? Effect.succeed(turn) : Effect.fail(scriptedError("generate", `Expected a Generate turn but found ${turn._tag}`));
|
|
102
102
|
const requireStreamTurn = (turn) => turn._tag === "Stream" ? Effect.succeed(turn) : Effect.fail(scriptedError("stream", `Expected a Stream turn but found ${turn._tag}`));
|
|
103
103
|
const streamForTurn = (turn) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScriptedModel.mjs","names":[],"sources":["../src/ScriptedModel.ts"],"sourcesContent":["import { Context, Effect, Layer, Ref, Schema, Stream } from \"effect\";\nimport { AiError, LanguageModel, Response, Toolkit } from \"effect/unstable/ai\";\n\nconst ScriptedPartMetadata = Schema.Record(Schema.String, Schema.NullOr(Schema.Json));\n\nconst ScriptedPartBase = {\n metadata: Schema.optionalKey(ScriptedPartMetadata),\n};\n\nconst ScriptedToolCallPart = Schema.Struct({\n ...ScriptedPartBase,\n type: Schema.Literal(\"tool-call\"),\n id: Schema.String,\n name: Schema.String,\n params: Schema.Unknown,\n providerExecuted: Schema.optionalKey(Schema.Boolean),\n});\n\nconst ScriptedToolResultPart = Schema.Struct({\n ...ScriptedPartBase,\n type: Schema.Literal(\"tool-result\"),\n id: Schema.String,\n name: Schema.String,\n result: Schema.Unknown,\n isFailure: Schema.Boolean,\n providerExecuted: Schema.optionalKey(Schema.Boolean),\n preliminary: Schema.optionalKey(Schema.Boolean),\n});\n\n/**\n * Schema for encoded, non-streaming Effect AI response parts.\n *\n * Generic Tool payloads remain explicitly unknown here. `LanguageModel.make`\n * performs the toolkit-specific decode when the scripted response is consumed.\n */\nexport const ScriptedGeneratePart = Schema.Union([\n Schema.toEncoded(Response.Part(Toolkit.empty)),\n // PartEncoded also admits these reasoning markers, which the Part schema omits.\n Schema.toEncoded(Response.ReasoningDeltaPart),\n Schema.toEncoded(Response.ReasoningEndPart),\n ScriptedToolCallPart,\n ScriptedToolResultPart,\n]).annotate({ identifier: \"ScriptedGeneratePart\" });\n\nexport type ScriptedGeneratePart = typeof ScriptedGeneratePart.Type;\n\n/**\n * Schema for encoded Effect AI streaming response parts.\n */\nexport const ScriptedStreamPart = Schema.Union([\n Schema.toEncoded(Response.StreamPart(Toolkit.empty)),\n ScriptedToolCallPart,\n ScriptedToolResultPart,\n]).annotate({ identifier: \"ScriptedStreamPart\" });\n\nexport type ScriptedStreamPart = typeof ScriptedStreamPart.Type;\n\n/** Controls whether a scripted stream completes, fails, or waits for interruption. */\nexport const ScriptedStreamTermination = Schema.Union([\n Schema.TaggedStruct(\"Complete\", {}),\n Schema.TaggedStruct(\"Fail\", {\n description: Schema.String,\n }),\n Schema.TaggedStruct(\"Hang\", {}),\n]);\n\nexport type ScriptedStreamTermination = typeof ScriptedStreamTermination.Type;\n\n/** One non-streaming invocation and the encoded response parts it returns. */\nexport const ScriptedGenerateTurn = Schema.TaggedStruct(\"Generate\", {\n parts: Schema.Array(ScriptedGeneratePart),\n});\n\nexport type ScriptedGenerateTurn = typeof ScriptedGenerateTurn.Type;\n\n/** One streaming invocation with its encoded parts and terminal behavior. */\nexport const ScriptedStreamTurn = Schema.TaggedStruct(\"Stream\", {\n parts: Schema.Array(ScriptedStreamPart),\n termination: ScriptedStreamTermination,\n});\n\nexport type ScriptedStreamTurn = typeof ScriptedStreamTurn.Type;\n\n/**\n * Serializable grammar for one finite scripted provider invocation.\n */\nexport const ScriptedTurn = Schema.Union([ScriptedGenerateTurn, ScriptedStreamTurn]);\nexport type ScriptedTurn = typeof ScriptedTurn.Type;\n\nexport type ScriptedRequestKind = \"generate\" | \"stream\";\n\n/**\n * A request after Effect AI has normalized its prompt, tools, response format,\n * tool choice, span, and incremental-response fields.\n */\nexport interface ScriptedRequest {\n readonly kind: ScriptedRequestKind;\n readonly options: LanguageModel.ProviderOptions;\n}\n\n/** Optional request assertions and stream lifecycle effects for one scripted turn. */\nexport interface ScriptedTurnHooks {\n /** Runs against the normalized provider request before producing the response. */\n readonly assertRequest?: (\n request: LanguageModel.ProviderOptions,\n ) => Effect.Effect<void, AiError.AiError> | void;\n /** Runs immediately before the scripted stream begins emitting parts. */\n readonly onStreamStart?: Effect.Effect<void> | undefined;\n /** Runs when the scripted stream completes, fails, or is interrupted. */\n readonly onStreamFinalize?: Effect.Effect<void> | undefined;\n}\n\n/**\n * Runtime hooks are deliberately separate from the serializable turn grammar.\n */\nexport type ScriptedTurnInput = ScriptedTurn & ScriptedTurnHooks;\n\ninterface ScriptState {\n readonly remaining: ReadonlyArray<ScriptedTurnInput>;\n readonly requests: ReadonlyArray<ScriptedRequest>;\n}\n\nconst scriptedError = (method: string, description: string): AiError.AiError =>\n AiError.AiError.make({\n module: \"@effect-agent/testing/ScriptedModel\",\n method,\n reason: AiError.UnknownError.make({ description }),\n });\n\nconst runAssertion = Effect.fn(\"ScriptedModel.runAssertion\")((\n assertion: ScriptedTurnHooks[\"assertRequest\"],\n request: LanguageModel.ProviderOptions,\n): Effect.Effect<void, AiError.AiError> => {\n if (assertion === undefined) {\n return Effect.void;\n }\n\n return Effect.suspend(() => {\n const result = assertion(request);\n\n return Effect.isEffect(result) ? result : Effect.void;\n });\n});\n\nconst takeTurn = Effect.fn(\"ScriptedModel.takeTurn\")(\n (\n state: Ref.Ref<ScriptState>,\n kind: ScriptedRequestKind,\n options: LanguageModel.ProviderOptions,\n ): Effect.Effect<ScriptedTurnInput, AiError.AiError> =>\n Ref.modify(state, (current) => {\n const turn = current.remaining[0];\n\n if (turn === undefined) {\n return [\n undefined,\n {\n ...current,\n requests: [...current.requests, { kind, options }],\n },\n ] as const;\n }\n\n return [\n turn,\n {\n remaining: current.remaining.slice(1),\n requests: [...current.requests, { kind, options }],\n },\n ] as const;\n }).pipe(\n Effect.flatMap((turn) =>\n turn === undefined\n ? Effect.fail(scriptedError(kind, `Script exhausted before the ${kind} request`))\n : Effect.succeed(turn),\n ),\n ),\n);\n\nconst requireGenerateTurn = (\n turn: ScriptedTurnInput,\n): Effect.Effect<ScriptedGenerateTurn & ScriptedTurnHooks, AiError.AiError> =>\n turn._tag === \"Generate\"\n ? Effect.succeed(turn)\n : Effect.fail(scriptedError(\"generate\", `Expected a Generate turn but found ${turn._tag}`));\n\nconst requireStreamTurn = (\n turn: ScriptedTurnInput,\n): Effect.Effect<ScriptedStreamTurn & ScriptedTurnHooks, AiError.AiError> =>\n turn._tag === \"Stream\"\n ? Effect.succeed(turn)\n : Effect.fail(scriptedError(\"stream\", `Expected a Stream turn but found ${turn._tag}`));\n\nconst streamForTurn = (\n turn: ScriptedStreamTurn & ScriptedTurnHooks,\n): Stream.Stream<Response.StreamPartEncoded, AiError.AiError> => {\n let stream: Stream.Stream<Response.StreamPartEncoded, AiError.AiError> = Stream.fromIterable(\n turn.parts,\n );\n\n switch (turn.termination._tag) {\n case \"Complete\": {\n break;\n }\n case \"Fail\": {\n stream = stream.pipe(\n Stream.concat(Stream.fail(scriptedError(\"stream\", turn.termination.description))),\n );\n break;\n }\n case \"Hang\": {\n stream = stream.pipe(Stream.concat(Stream.never));\n break;\n }\n }\n if (turn.onStreamStart !== undefined) {\n stream = Stream.fromEffectDrain(turn.onStreamStart).pipe(Stream.concat(stream));\n }\n if (turn.onStreamFinalize !== undefined) {\n stream = stream.pipe(Stream.ensuring(turn.onStreamFinalize));\n }\n\n return stream;\n};\n\n/** Inspection service for a deterministic LanguageModel backed by finite scripted turns. */\nexport class ScriptedModel extends Context.Service<\n ScriptedModel,\n {\n /** Normalized provider requests captured in invocation order. */\n readonly requests: Effect.Effect<ReadonlyArray<ScriptedRequest>>;\n /** Number of scripted turns not yet consumed. */\n readonly remaining: Effect.Effect<number>;\n /** Fails with `AiError` when any scripted turns remain. */\n readonly assertExhausted: Effect.Effect<void, AiError.AiError>;\n }\n>()(\"@effect-agent/testing/ScriptedModel\") {\n /**\n * Provides the native Effect AI `LanguageModel` and this inspection service.\n * Supplying the extra inspection service does not add it to model-call\n * requirements. Each model invocation consumes one turn before assertion and\n * turn-kind validation.\n */\n static layer(\n turns: ReadonlyArray<ScriptedTurnInput>,\n ): Layer.Layer<LanguageModel.LanguageModel | ScriptedModel, never, never> {\n return Layer.effectContext(\n Effect.gen(function* () {\n const state = yield* Ref.make<ScriptState>({\n remaining: [...turns],\n requests: [],\n });\n\n const languageModel = yield* LanguageModel.make({\n generateText: (options) =>\n Effect.gen(function* () {\n const turn = yield* takeTurn(state, \"generate\", options);\n\n yield* runAssertion(turn.assertRequest, options);\n const generateTurn = yield* requireGenerateTurn(turn);\n\n return [...generateTurn.parts];\n }),\n streamText: (options) =>\n Stream.unwrap(\n Effect.gen(function* () {\n const turn = yield* takeTurn(state, \"stream\", options);\n\n yield* runAssertion(turn.assertRequest, options);\n const streamTurn = yield* requireStreamTurn(turn);\n\n return streamForTurn(streamTurn);\n }),\n ),\n });\n\n const inspection = ScriptedModel.of({\n requests: Ref.get(state).pipe(Effect.map((current) => current.requests)),\n remaining: Ref.get(state).pipe(Effect.map((current) => current.remaining.length)),\n assertExhausted: Ref.get(state).pipe(\n Effect.flatMap((current) =>\n current.remaining.length === 0\n ? Effect.void\n : Effect.fail(\n scriptedError(\n \"assertExhausted\",\n `${current.remaining.length} scripted turn(s) remain`,\n ),\n ),\n ),\n ),\n });\n\n return Context.make(LanguageModel.LanguageModel, languageModel).pipe(\n Context.add(ScriptedModel, inspection),\n );\n }),\n );\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ScriptedModel.mjs","names":[],"sources":["../src/ScriptedModel.ts"],"sourcesContent":["import { Context, Effect, Layer, Ref, Schema, Stream } from \"effect\";\nimport { AiError, LanguageModel, Response, Toolkit } from \"effect/unstable/ai\";\n\nconst ScriptedPartMetadata = Schema.Record(Schema.String, Schema.NullOr(Schema.Json));\n\nconst ScriptedPartBase = {\n metadata: Schema.optionalKey(ScriptedPartMetadata),\n};\n\nconst ScriptedToolCallPart = Schema.Struct({\n ...ScriptedPartBase,\n type: Schema.Literal(\"tool-call\"),\n id: Schema.String,\n name: Schema.String,\n params: Schema.Unknown,\n providerExecuted: Schema.optionalKey(Schema.Boolean),\n});\n\nconst ScriptedToolResultPart = Schema.Struct({\n ...ScriptedPartBase,\n type: Schema.Literal(\"tool-result\"),\n id: Schema.String,\n name: Schema.String,\n result: Schema.Unknown,\n isFailure: Schema.Boolean,\n providerExecuted: Schema.optionalKey(Schema.Boolean),\n preliminary: Schema.optionalKey(Schema.Boolean),\n});\n\n/**\n * Schema for encoded, non-streaming Effect AI response parts.\n *\n * Generic Tool payloads remain explicitly unknown here. `LanguageModel.make`\n * performs the toolkit-specific decode when the scripted response is consumed.\n */\nexport const ScriptedGeneratePart = Schema.Union([\n Schema.toEncoded(Response.Part(Toolkit.empty)),\n // PartEncoded also admits these reasoning markers, which the Part schema omits.\n Schema.toEncoded(Response.ReasoningDeltaPart),\n Schema.toEncoded(Response.ReasoningEndPart),\n ScriptedToolCallPart,\n ScriptedToolResultPart,\n]).annotate({ identifier: \"ScriptedGeneratePart\" });\n\nexport type ScriptedGeneratePart = typeof ScriptedGeneratePart.Type;\n\n/**\n * Schema for encoded Effect AI streaming response parts.\n */\nexport const ScriptedStreamPart = Schema.Union([\n Schema.toEncoded(Response.StreamPart(Toolkit.empty)),\n ScriptedToolCallPart,\n ScriptedToolResultPart,\n]).annotate({ identifier: \"ScriptedStreamPart\" });\n\nexport type ScriptedStreamPart = typeof ScriptedStreamPart.Type;\n\n/** Controls whether a scripted stream completes, fails, or waits for interruption. */\nexport const ScriptedStreamTermination = Schema.Union([\n Schema.TaggedStruct(\"Complete\", {}),\n Schema.TaggedStruct(\"Fail\", {\n description: Schema.String,\n }),\n Schema.TaggedStruct(\"Hang\", {}),\n]);\n\nexport type ScriptedStreamTermination = typeof ScriptedStreamTermination.Type;\n\n/** One non-streaming invocation and the encoded response parts it returns. */\nexport const ScriptedGenerateTurn = Schema.TaggedStruct(\"Generate\", {\n parts: Schema.Array(ScriptedGeneratePart),\n});\n\nexport type ScriptedGenerateTurn = typeof ScriptedGenerateTurn.Type;\n\n/** One streaming invocation with its encoded parts and terminal behavior. */\nexport const ScriptedStreamTurn = Schema.TaggedStruct(\"Stream\", {\n parts: Schema.Array(ScriptedStreamPart),\n termination: ScriptedStreamTermination,\n});\n\nexport type ScriptedStreamTurn = typeof ScriptedStreamTurn.Type;\n\n/**\n * Serializable grammar for one finite scripted provider invocation.\n */\nexport const ScriptedTurn = Schema.Union([ScriptedGenerateTurn, ScriptedStreamTurn]);\nexport type ScriptedTurn = typeof ScriptedTurn.Type;\n\nexport type ScriptedRequestKind = \"generate\" | \"stream\";\n\n/**\n * A request after Effect AI has normalized its prompt, tools, response format,\n * tool choice, span, and incremental-response fields.\n */\nexport interface ScriptedRequest {\n readonly kind: ScriptedRequestKind;\n readonly options: LanguageModel.ProviderOptions;\n}\n\n/** Optional request assertions and stream lifecycle effects for one scripted turn. */\nexport interface ScriptedTurnHooks {\n /** Runs against the normalized provider request before producing the response. */\n readonly assertRequest?: (\n request: LanguageModel.ProviderOptions,\n ) => Effect.Effect<void, AiError.AiError> | void;\n /** Runs immediately before the scripted stream begins emitting parts. */\n readonly onStreamStart?: Effect.Effect<void> | undefined;\n /** Runs when the scripted stream completes, fails, or is interrupted. */\n readonly onStreamFinalize?: Effect.Effect<void> | undefined;\n}\n\n/**\n * Runtime hooks are deliberately separate from the serializable turn grammar.\n */\nexport type ScriptedTurnInput = ScriptedTurn & ScriptedTurnHooks;\n\ninterface ScriptState {\n readonly remaining: ReadonlyArray<ScriptedTurnInput>;\n readonly requests: ReadonlyArray<ScriptedRequest>;\n}\n\nconst scriptedError = (method: string, description: string): AiError.AiError =>\n AiError.AiError.make({\n module: \"@effect-agent/testing/ScriptedModel\",\n method,\n reason: AiError.UnknownError.make({ description }),\n });\n\nconst runAssertion = Effect.fn(\"ScriptedModel.runAssertion\")((\n assertion: ScriptedTurnHooks[\"assertRequest\"],\n request: LanguageModel.ProviderOptions,\n): Effect.Effect<void, AiError.AiError> => {\n if (assertion === undefined) {\n return Effect.void;\n }\n\n return Effect.suspend(() => {\n const result = assertion(request);\n\n return Effect.isEffect(result) ? result : Effect.void;\n });\n});\n\nconst takeTurn = Effect.fn(\"ScriptedModel.takeTurn\")(\n (\n state: Ref.Ref<ScriptState>,\n kind: ScriptedRequestKind,\n options: LanguageModel.ProviderOptions,\n ): Effect.Effect<ScriptedTurnInput, AiError.AiError> =>\n Ref.modify(state, (current) => {\n const turn = current.remaining[0];\n\n if (turn === undefined) {\n return [\n undefined,\n {\n ...current,\n requests: [...current.requests, { kind, options }],\n },\n ] as const;\n }\n\n return [\n turn,\n {\n remaining: current.remaining.slice(1),\n requests: [...current.requests, { kind, options }],\n },\n ] as const;\n }).pipe(\n Effect.filterOrFail(\n (turn) => turn !== undefined,\n () => scriptedError(kind, `Script exhausted before the ${kind} request`),\n ),\n ),\n);\n\nconst requireGenerateTurn = (\n turn: ScriptedTurnInput,\n): Effect.Effect<ScriptedGenerateTurn & ScriptedTurnHooks, AiError.AiError> =>\n turn._tag === \"Generate\"\n ? Effect.succeed(turn)\n : Effect.fail(scriptedError(\"generate\", `Expected a Generate turn but found ${turn._tag}`));\n\nconst requireStreamTurn = (\n turn: ScriptedTurnInput,\n): Effect.Effect<ScriptedStreamTurn & ScriptedTurnHooks, AiError.AiError> =>\n turn._tag === \"Stream\"\n ? Effect.succeed(turn)\n : Effect.fail(scriptedError(\"stream\", `Expected a Stream turn but found ${turn._tag}`));\n\nconst streamForTurn = (\n turn: ScriptedStreamTurn & ScriptedTurnHooks,\n): Stream.Stream<Response.StreamPartEncoded, AiError.AiError> => {\n let stream: Stream.Stream<Response.StreamPartEncoded, AiError.AiError> = Stream.fromIterable(\n turn.parts,\n );\n\n switch (turn.termination._tag) {\n case \"Complete\": {\n break;\n }\n case \"Fail\": {\n stream = stream.pipe(\n Stream.concat(Stream.fail(scriptedError(\"stream\", turn.termination.description))),\n );\n break;\n }\n case \"Hang\": {\n stream = stream.pipe(Stream.concat(Stream.never));\n break;\n }\n }\n if (turn.onStreamStart !== undefined) {\n stream = Stream.fromEffectDrain(turn.onStreamStart).pipe(Stream.concat(stream));\n }\n if (turn.onStreamFinalize !== undefined) {\n stream = stream.pipe(Stream.ensuring(turn.onStreamFinalize));\n }\n\n return stream;\n};\n\n/** Inspection service for a deterministic LanguageModel backed by finite scripted turns. */\nexport class ScriptedModel extends Context.Service<\n ScriptedModel,\n {\n /** Normalized provider requests captured in invocation order. */\n readonly requests: Effect.Effect<ReadonlyArray<ScriptedRequest>>;\n /** Number of scripted turns not yet consumed. */\n readonly remaining: Effect.Effect<number>;\n /** Fails with `AiError` when any scripted turns remain. */\n readonly assertExhausted: Effect.Effect<void, AiError.AiError>;\n }\n>()(\"@effect-agent/testing/ScriptedModel\") {\n /**\n * Provides the native Effect AI `LanguageModel` and this inspection service.\n * Supplying the extra inspection service does not add it to model-call\n * requirements. Each model invocation consumes one turn before assertion and\n * turn-kind validation.\n */\n static layer(\n turns: ReadonlyArray<ScriptedTurnInput>,\n ): Layer.Layer<LanguageModel.LanguageModel | ScriptedModel, never, never> {\n return Layer.effectContext(\n Effect.gen(function* () {\n const state = yield* Ref.make<ScriptState>({\n remaining: [...turns],\n requests: [],\n });\n\n const languageModel = yield* LanguageModel.make({\n generateText: (options) =>\n Effect.gen(function* () {\n const turn = yield* takeTurn(state, \"generate\", options);\n\n yield* runAssertion(turn.assertRequest, options);\n const generateTurn = yield* requireGenerateTurn(turn);\n\n return [...generateTurn.parts];\n }),\n streamText: (options) =>\n Stream.unwrap(\n Effect.gen(function* () {\n const turn = yield* takeTurn(state, \"stream\", options);\n\n yield* runAssertion(turn.assertRequest, options);\n const streamTurn = yield* requireStreamTurn(turn);\n\n return streamForTurn(streamTurn);\n }),\n ),\n });\n\n const inspection = ScriptedModel.of({\n requests: Ref.get(state).pipe(Effect.map((current) => current.requests)),\n remaining: Ref.get(state).pipe(Effect.map((current) => current.remaining.length)),\n assertExhausted: Ref.get(state).pipe(\n Effect.flatMap((current) =>\n current.remaining.length === 0\n ? Effect.void\n : Effect.fail(\n scriptedError(\n \"assertExhausted\",\n `${current.remaining.length} scripted turn(s) remain`,\n ),\n ),\n ),\n ),\n });\n\n return Context.make(LanguageModel.LanguageModel, languageModel).pipe(\n Context.add(ScriptedModel, inspection),\n );\n }),\n );\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAGA,MAAM,uBAAuB,OAAO,OAAO,OAAO,QAAQ,OAAO,OAAO,OAAO,IAAI,CAAC;AAEpF,MAAM,mBAAmB,EACvB,UAAU,OAAO,YAAY,oBAAoB,EACnD;AAEA,MAAM,uBAAuB,OAAO,OAAO;CACzC,GAAG;CACH,MAAM,OAAO,QAAQ,WAAW;CAChC,IAAI,OAAO;CACX,MAAM,OAAO;CACb,QAAQ,OAAO;CACf,kBAAkB,OAAO,YAAY,OAAO,OAAO;AACrD,CAAC;AAED,MAAM,yBAAyB,OAAO,OAAO;CAC3C,GAAG;CACH,MAAM,OAAO,QAAQ,aAAa;CAClC,IAAI,OAAO;CACX,MAAM,OAAO;CACb,QAAQ,OAAO;CACf,WAAW,OAAO;CAClB,kBAAkB,OAAO,YAAY,OAAO,OAAO;CACnD,aAAa,OAAO,YAAY,OAAO,OAAO;AAChD,CAAC;;;;;;;AAQD,MAAa,uBAAuB,OAAO,MAAM;CAC/C,OAAO,UAAU,SAAS,KAAK,QAAQ,KAAK,CAAC;CAE7C,OAAO,UAAU,SAAS,kBAAkB;CAC5C,OAAO,UAAU,SAAS,gBAAgB;CAC1C;CACA;AACF,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,uBAAuB,CAAC;;;;AAOlD,MAAa,qBAAqB,OAAO,MAAM;CAC7C,OAAO,UAAU,SAAS,WAAW,QAAQ,KAAK,CAAC;CACnD;CACA;AACF,CAAC,CAAC,CAAC,SAAS,EAAE,YAAY,qBAAqB,CAAC;;AAKhD,MAAa,4BAA4B,OAAO,MAAM;CACpD,OAAO,aAAa,YAAY,CAAC,CAAC;CAClC,OAAO,aAAa,QAAQ,EAC1B,aAAa,OAAO,OACtB,CAAC;CACD,OAAO,aAAa,QAAQ,CAAC,CAAC;AAChC,CAAC;;AAKD,MAAa,uBAAuB,OAAO,aAAa,YAAY,EAClE,OAAO,OAAO,MAAM,oBAAoB,EAC1C,CAAC;;AAKD,MAAa,qBAAqB,OAAO,aAAa,UAAU;CAC9D,OAAO,OAAO,MAAM,kBAAkB;CACtC,aAAa;AACf,CAAC;;;;AAOD,MAAa,eAAe,OAAO,MAAM,CAAC,sBAAsB,kBAAkB,CAAC;AAoCnF,MAAM,iBAAiB,QAAgB,gBACrC,QAAQ,QAAQ,KAAK;CACnB,QAAQ;CACR;CACA,QAAQ,QAAQ,aAAa,KAAK,EAAE,YAAY,CAAC;AACnD,CAAC;AAEH,MAAM,eAAe,OAAO,GAAG,4BAA4B,CAAC,EAC1D,WACA,YACyC;CACzC,IAAI,cAAc,KAAA,GAChB,OAAO,OAAO;CAGhB,OAAO,OAAO,cAAc;EAC1B,MAAM,SAAS,UAAU,OAAO;EAEhC,OAAO,OAAO,SAAS,MAAM,IAAI,SAAS,OAAO;CACnD,CAAC;AACH,CAAC;AAED,MAAM,WAAW,OAAO,GAAG,wBAAwB,CAAC,EAEhD,OACA,MACA,YAEA,IAAI,OAAO,QAAQ,YAAY;CAC7B,MAAM,OAAO,QAAQ,UAAU;CAE/B,IAAI,SAAS,KAAA,GACX,OAAO,CACL,KAAA,GACA;EACE,GAAG;EACH,UAAU,CAAC,GAAG,QAAQ,UAAU;GAAE;GAAM;EAAQ,CAAC;CACnD,CACF;CAGF,OAAO,CACL,MACA;EACE,WAAW,QAAQ,UAAU,MAAM,CAAC;EACpC,UAAU,CAAC,GAAG,QAAQ,UAAU;GAAE;GAAM;EAAQ,CAAC;CACnD,CACF;AACF,CAAC,CAAC,CAAC,KACD,OAAO,cACJ,SAAS,SAAS,KAAA,SACb,cAAc,MAAM,+BAA+B,KAAK,SAAS,CACzE,CACF,CACJ;AAEA,MAAM,uBACJ,SAEA,KAAK,SAAS,aACV,OAAO,QAAQ,IAAI,IACnB,OAAO,KAAK,cAAc,YAAY,sCAAsC,KAAK,MAAM,CAAC;AAE9F,MAAM,qBACJ,SAEA,KAAK,SAAS,WACV,OAAO,QAAQ,IAAI,IACnB,OAAO,KAAK,cAAc,UAAU,oCAAoC,KAAK,MAAM,CAAC;AAE1F,MAAM,iBACJ,SAC+D;CAC/D,IAAI,SAAqE,OAAO,aAC9E,KAAK,KACP;CAEA,QAAQ,KAAK,YAAY,MAAzB;EACE,KAAK,YACH;EAEF,KAAK;GACH,SAAS,OAAO,KACd,OAAO,OAAO,OAAO,KAAK,cAAc,UAAU,KAAK,YAAY,WAAW,CAAC,CAAC,CAClF;GACA;EAEF,KAAK,QACH,SAAS,OAAO,KAAK,OAAO,OAAO,OAAO,KAAK,CAAC;CAGpD;CACA,IAAI,KAAK,kBAAkB,KAAA,GACzB,SAAS,OAAO,gBAAgB,KAAK,aAAa,CAAC,CAAC,KAAK,OAAO,OAAO,MAAM,CAAC;CAEhF,IAAI,KAAK,qBAAqB,KAAA,GAC5B,SAAS,OAAO,KAAK,OAAO,SAAS,KAAK,gBAAgB,CAAC;CAG7D,OAAO;AACT;;AAGA,IAAa,gBAAb,MAAa,sBAAsB,QAAQ,QAUzC,CAAC,CAAC,qCAAqC,CAAC,CAAC;;;;;;;CAOzC,OAAO,MACL,OACwE;EACxE,OAAO,MAAM,cACX,OAAO,IAAI,aAAa;GACtB,MAAM,QAAQ,OAAO,IAAI,KAAkB;IACzC,WAAW,CAAC,GAAG,KAAK;IACpB,UAAU,CAAC;GACb,CAAC;GAED,MAAM,gBAAgB,OAAO,cAAc,KAAK;IAC9C,eAAe,YACb,OAAO,IAAI,aAAa;KACtB,MAAM,OAAO,OAAO,SAAS,OAAO,YAAY,OAAO;KAEvD,OAAO,aAAa,KAAK,eAAe,OAAO;KAG/C,OAAO,CAAC,IAAG,OAFiB,oBAAoB,IAAI,EAAA,CAE5B,KAAK;IAC/B,CAAC;IACH,aAAa,YACX,OAAO,OACL,OAAO,IAAI,aAAa;KACtB,MAAM,OAAO,OAAO,SAAS,OAAO,UAAU,OAAO;KAErD,OAAO,aAAa,KAAK,eAAe,OAAO;KAC/C,MAAM,aAAa,OAAO,kBAAkB,IAAI;KAEhD,OAAO,cAAc,UAAU;IACjC,CAAC,CACH;GACJ,CAAC;GAED,MAAM,aAAa,cAAc,GAAG;IAClC,UAAU,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,YAAY,QAAQ,QAAQ,CAAC;IACvE,WAAW,IAAI,IAAI,KAAK,CAAC,CAAC,KAAK,OAAO,KAAK,YAAY,QAAQ,UAAU,MAAM,CAAC;IAChF,iBAAiB,IAAI,IAAI,KAAK,CAAC,CAAC,KAC9B,OAAO,SAAS,YACd,QAAQ,UAAU,WAAW,IACzB,OAAO,OACP,OAAO,KACL,cACE,mBACA,GAAG,QAAQ,UAAU,OAAO,yBAC9B,CACF,CACN,CACF;GACF,CAAC;GAED,OAAO,QAAQ,KAAK,cAAc,eAAe,aAAa,CAAC,CAAC,KAC9D,QAAQ,IAAI,eAAe,UAAU,CACvC;EACF,CAAC,CACH;CACF;AACF"}
|
package/dist/TravelPlanner.d.mts
CHANGED
|
@@ -202,7 +202,9 @@ declare const TravelPlanner: Agent.Definition<typeof TripRequest, typeof TravelP
|
|
|
202
202
|
readonly failure: typeof LodgingUnavailable;
|
|
203
203
|
readonly failureMode: "error";
|
|
204
204
|
}, LodgingCatalog>;
|
|
205
|
-
}>, undefined, undefined
|
|
205
|
+
}>, undefined, undefined, undefined> & {
|
|
206
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-planner";
|
|
207
|
+
};
|
|
206
208
|
//#endregion
|
|
207
209
|
//#region src/fixtures/travel-planner/deterministic-layers.d.ts
|
|
208
210
|
declare const CatalogLifecycleCounts_base: Schema.Class<CatalogLifecycleCounts, Schema.Struct<{
|
|
@@ -460,7 +462,9 @@ declare const TravelPlannerPhase2: Agent.Definition<typeof TripRequest, typeof T
|
|
|
460
462
|
readonly failure: typeof LodgingUnavailable;
|
|
461
463
|
readonly failureMode: "error";
|
|
462
464
|
}, LodgingCatalog>;
|
|
463
|
-
}>, undefined, undefined
|
|
465
|
+
}>, undefined, undefined, undefined> & {
|
|
466
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-planner-phase-2";
|
|
467
|
+
};
|
|
464
468
|
//#endregion
|
|
465
469
|
//#region src/fixtures/travel-planner/phase3.d.ts
|
|
466
470
|
declare const phase3TravelPlannerThreadId: string & import("effect/Brand").Brand<"@effect-agent/core/ThreadId">;
|
|
@@ -648,7 +652,9 @@ declare const TravelPlannerPhase4: Agent.Definition<typeof TripRequest, typeof T
|
|
|
648
652
|
readonly failure: typeof LodgingUnavailable;
|
|
649
653
|
readonly failureMode: "error";
|
|
650
654
|
}, LodgingCatalog>;
|
|
651
|
-
}>, undefined, undefined
|
|
655
|
+
}>, undefined, undefined, undefined> & {
|
|
656
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-planner-phase-4";
|
|
657
|
+
};
|
|
652
658
|
/**
|
|
653
659
|
* The P4 Agent Binding: the durable Travel Planner definition bound to a finite scripted model.
|
|
654
660
|
* The scripted Layer is rebuilt per Run, so every Run of one Binding replays the same
|
|
@@ -688,7 +694,9 @@ declare const makePhase4TravelPlannerAgent: (turns?: ReadonlyArray<ScriptedTurnI
|
|
|
688
694
|
readonly failure: typeof LodgingUnavailable;
|
|
689
695
|
readonly failureMode: "error";
|
|
690
696
|
}, LodgingCatalog>;
|
|
691
|
-
}>, undefined, undefined
|
|
697
|
+
}>, undefined, undefined, undefined> & {
|
|
698
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-planner-phase-4";
|
|
699
|
+
}, Model.Model<"scripted", import("effect/unstable/ai/LanguageModel").LanguageModel | ScriptedModel, never>>;
|
|
692
700
|
/**
|
|
693
701
|
* Everything a durable worker needs beyond the runtime stack, reusing the deterministic P1
|
|
694
702
|
* travel-service Layers. The durable coordinator supplies its own deterministic `IdGenerator`,
|
|
@@ -1030,7 +1038,9 @@ declare const TravelPlannerPhase5: Agent.Definition<typeof TripRequest, typeof T
|
|
|
1030
1038
|
readonly failure: typeof LodgingUnavailable;
|
|
1031
1039
|
readonly failureMode: "error";
|
|
1032
1040
|
}, LodgingCatalog>;
|
|
1033
|
-
}>, undefined, undefined
|
|
1041
|
+
}>, undefined, undefined, undefined> & {
|
|
1042
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-planner-phase-5";
|
|
1043
|
+
};
|
|
1034
1044
|
declare const TravelPlannerBookingEvidenceError_base: Schema.Class<TravelPlannerBookingEvidenceError, Schema.TaggedStruct<"TravelPlannerBookingEvidenceError", {
|
|
1035
1045
|
readonly message: Schema.String;
|
|
1036
1046
|
}>, import("effect/Cause").YieldableError>;
|
|
@@ -1155,7 +1165,9 @@ declare const DestinationResearcher: Agent.Definition<typeof DestinationBrief, t
|
|
|
1155
1165
|
readonly failure: typeof DestinationGuideUnavailable;
|
|
1156
1166
|
readonly failureMode: "error";
|
|
1157
1167
|
}, DestinationGuide>;
|
|
1158
|
-
}>, undefined, undefined
|
|
1168
|
+
}>, undefined, undefined, undefined> & {
|
|
1169
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "destination-researcher";
|
|
1170
|
+
};
|
|
1159
1171
|
/** Deterministic guide lookup shared by the default and test-local guide Layers. */
|
|
1160
1172
|
declare const destinationLookup: (query: DestinationQuery) => Effect.Effect<DestinationFacts, DestinationGuideUnavailable>;
|
|
1161
1173
|
/** The report the scripted researcher writes after consulting the guide. */
|
|
@@ -1212,7 +1224,9 @@ declare const destinationResearchDelegation: Subagent.SubagentDelegation<"delega
|
|
|
1212
1224
|
readonly failure: typeof DestinationGuideUnavailable;
|
|
1213
1225
|
readonly failureMode: "error";
|
|
1214
1226
|
}, DestinationGuide>;
|
|
1215
|
-
}>, undefined, undefined
|
|
1227
|
+
}>, undefined, undefined, undefined> & {
|
|
1228
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "destination-researcher";
|
|
1229
|
+
};
|
|
1216
1230
|
};
|
|
1217
1231
|
/** Total mapping from every expected child Run failure to the declared Tool failure (SUB-028). */
|
|
1218
1232
|
declare const mapResearchChildFailure: (failure: {
|
|
@@ -1228,7 +1242,7 @@ declare const destinationResearchHandlersLayer: <Provider, ModelProvides, ModelR
|
|
|
1228
1242
|
}, DestinationGuide>;
|
|
1229
1243
|
}, Provider, ModelProvides, ModelRequires, ResearchDispatchGate, never, never, {
|
|
1230
1244
|
readonly _tag: string;
|
|
1231
|
-
}, never, undefined>>;
|
|
1245
|
+
}, never, undefined, undefined, undefined>>;
|
|
1232
1246
|
declare const ResearchMission_base: Schema.Class<ResearchMission, Schema.Struct<{
|
|
1233
1247
|
readonly request: Schema.NonEmptyString;
|
|
1234
1248
|
readonly candidates: Schema.$Array<Schema.brand<Schema.NonEmptyString, "@effect-agent/testing/travel-planner/AirportCode">>;
|
|
@@ -1262,7 +1276,9 @@ declare const TravelCoordinator: Agent.Definition<typeof ResearchMission, typeof
|
|
|
1262
1276
|
readonly failure: Subagent.SubagentToolFailure<typeof DestinationResearchFailed>;
|
|
1263
1277
|
readonly failureMode: "error";
|
|
1264
1278
|
}, import("@effect-agent/engine/AgentRuntime").AgentSpawner | import("@effect-agent/core/IdGenerator").IdGenerator | import("@effect-agent/engine/RunEventSink").RunEventSink | import("@effect-agent/engine/AgentRuntime").SubagentDurability>;
|
|
1265
|
-
}>, undefined, undefined
|
|
1279
|
+
}>, undefined, undefined, undefined> & {
|
|
1280
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-coordinator";
|
|
1281
|
+
};
|
|
1266
1282
|
declare const researchMission: ResearchMission;
|
|
1267
1283
|
declare const expectedDestinationShortlist: DestinationShortlist;
|
|
1268
1284
|
interface DestinationResearchCall {
|
|
@@ -1575,7 +1591,7 @@ declare const s2TravelPlannerSubmitOptions: (threadId: ThreadId, idempotencyKey:
|
|
|
1575
1591
|
/** The structural submit slice of the coordinator Binding (`DurableAgentRuntime.submit`). */
|
|
1576
1592
|
declare const s2CoordinatorSubmitAgent: {
|
|
1577
1593
|
readonly definition: {
|
|
1578
|
-
readonly id:
|
|
1594
|
+
readonly id: import("effect/Brand").Brand<"@effect-agent/core/AgentId"> & "travel-coordinator";
|
|
1579
1595
|
readonly input: typeof ResearchMission;
|
|
1580
1596
|
};
|
|
1581
1597
|
};
|
|
@@ -1620,7 +1636,7 @@ declare const durableDestinationResearchHandlersLayer: <Provider, ModelProvides,
|
|
|
1620
1636
|
}, DestinationGuide>;
|
|
1621
1637
|
}, Provider, ModelProvides, ModelRequires, ResearchDispatchGate, never, never, {
|
|
1622
1638
|
readonly _tag: string;
|
|
1623
|
-
}, never, undefined>>;
|
|
1639
|
+
}, never, undefined, undefined, undefined>>;
|
|
1624
1640
|
/** Optional overrides for one durable research harness. */
|
|
1625
1641
|
interface DurableResearchHarnessOptions {
|
|
1626
1642
|
/** Researched destination; defaults to "LHR". */
|