@effect-agent/testing 0.1.0-beta.38 → 0.1.0-beta.40
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 +102 -0
- package/dist/certification.mjs +561 -0
- package/dist/certification.mjs.map +1 -0
- package/dist/chaos.d.mts +124 -0
- package/dist/chaos.mjs +739 -0
- package/dist/chaos.mjs.map +1 -0
- package/dist/code-executor.d.mts +48 -0
- package/dist/code-executor.mjs +565 -0
- package/dist/code-executor.mjs.map +1 -0
- package/dist/deterministic-layers-CKyYxBhN.mjs +354 -0
- package/dist/deterministic-layers-CKyYxBhN.mjs.map +1 -0
- package/dist/docs-researcher.d.mts +254 -0
- package/dist/docs-researcher.mjs +479 -0
- package/dist/docs-researcher.mjs.map +1 -0
- package/dist/index.d.mts +2 -2947
- package/dist/index.mjs +2 -4913
- package/dist/scripted-model-C2y0ztuj.mjs +167 -0
- package/dist/scripted-model-C2y0ztuj.mjs.map +1 -0
- package/dist/scripted-model-dOa_e0-n.d.mts +677 -0
- package/dist/travel-planner.d.mts +1767 -0
- package/dist/travel-planner.mjs +2103 -0
- package/dist/travel-planner.mjs.map +1 -0
- package/package.json +34 -11
- package/src/certification.ts +71 -61
- package/src/chaos.ts +58 -71
- package/src/code-executor.ts +3 -0
- package/src/docs-researcher.ts +2 -0
- package/src/fixtures/docs-researcher/definition.ts +7 -7
- package/src/fixtures/docs-researcher/harness.ts +12 -14
- package/src/fixtures/docs-researcher/index.ts +1 -1
- package/src/fixtures/travel-planner/definition.ts +1 -1
- package/src/fixtures/travel-planner/deterministic-layers.ts +7 -4
- package/src/fixtures/travel-planner/phase2.ts +1 -1
- package/src/fixtures/travel-planner/phase3.ts +14 -18
- package/src/fixtures/travel-planner/phase4.ts +7 -7
- package/src/fixtures/travel-planner/phase5.ts +5 -5
- package/src/fixtures/travel-planner/phase6.ts +30 -29
- package/src/fixtures/travel-planner/subagents-durable.ts +6 -6
- package/src/fixtures/travel-planner/subagents.ts +4 -4
- package/src/index.ts +1 -10
- package/src/travel-planner.ts +2 -0
- package/dist/index.mjs.map +0 -1
- package/src/code-executor-conformance.d.ts +0 -30
- package/src/fixtures/warehouse/index.ts +0 -412
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import { AgentId,
|
|
1
|
+
import { AgentId, ThreadId, RunId, SubmissionId } from "@effect-agent/core";
|
|
2
2
|
import {
|
|
3
3
|
BatchId,
|
|
4
4
|
CanonicalBatch,
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
ThreadCheckpoint,
|
|
6
|
+
ThreadProjection,
|
|
7
7
|
DefinitionDigests,
|
|
8
8
|
DeploymentId,
|
|
9
9
|
Digest,
|
|
10
10
|
ProducerId,
|
|
11
11
|
RecordEnvelope,
|
|
12
12
|
RecordId,
|
|
13
|
-
} from "@effect-agent/
|
|
13
|
+
} from "@effect-agent/thread";
|
|
14
14
|
import { Effect, Schema } from "effect";
|
|
15
15
|
|
|
16
16
|
import { TravelPlan, TripRequest } from "./definition.ts";
|
|
17
17
|
import { expectedTravelPlan, phase1Trip } from "./scenarios.ts";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
* The Phase 3 profile persists
|
|
20
|
+
* The Phase 3 profile persists Thread history but deliberately does not
|
|
21
21
|
* claim durable admission or recovery of accepted work.
|
|
22
22
|
*/
|
|
23
23
|
export class TravelPlannerPersistenceProfile extends Schema.Class<TravelPlannerPersistenceProfile>(
|
|
@@ -34,9 +34,7 @@ export const phase3TravelPlannerProfile = TravelPlannerPersistenceProfile.make({
|
|
|
34
34
|
canonicalSchemaVersion: 1,
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
-
export const
|
|
38
|
-
"travel-planner-p3-conversation",
|
|
39
|
-
);
|
|
37
|
+
export const phase3TravelPlannerThreadId = Schema.decodeSync(ThreadId)("travel-planner-p3-thread");
|
|
40
38
|
export const phase3TravelPlannerProducerId = Schema.decodeSync(ProducerId)(
|
|
41
39
|
"travel-planner-p3-producer",
|
|
42
40
|
);
|
|
@@ -61,7 +59,7 @@ const travelPlanOutput = Schema.encodeSync(TravelPlan)(expectedTravelPlan);
|
|
|
61
59
|
const record = (recordId: string, createdAt: string, payload: unknown) =>
|
|
62
60
|
Schema.decodeUnknownSync(RecordEnvelope)({
|
|
63
61
|
recordId: Schema.decodeSync(RecordId)(recordId),
|
|
64
|
-
family: "
|
|
62
|
+
family: "thread",
|
|
65
63
|
schemaVersion: 1,
|
|
66
64
|
createdAt,
|
|
67
65
|
deploymentId,
|
|
@@ -69,7 +67,7 @@ const record = (recordId: string, createdAt: string, payload: unknown) =>
|
|
|
69
67
|
});
|
|
70
68
|
|
|
71
69
|
/**
|
|
72
|
-
* The first atomic append establishes the
|
|
70
|
+
* The first atomic append establishes the Thread and records its input.
|
|
73
71
|
* Its encoded value is the redacted current-version persistence fixture.
|
|
74
72
|
*/
|
|
75
73
|
export const phase3TravelPlannerInitialBatch = CanonicalBatch.make({
|
|
@@ -77,7 +75,7 @@ export const phase3TravelPlannerInitialBatch = CanonicalBatch.make({
|
|
|
77
75
|
producerId: phase3TravelPlannerProducerId,
|
|
78
76
|
records: [
|
|
79
77
|
record("travel-planner-p3-created", "2026-09-01T00:00:00.000Z", {
|
|
80
|
-
_tag: "
|
|
78
|
+
_tag: "ThreadCreated",
|
|
81
79
|
agentId,
|
|
82
80
|
definitions: phase3TravelPlannerDefinitionDigests,
|
|
83
81
|
}),
|
|
@@ -125,7 +123,7 @@ export class TravelPlannerProjectionError extends Schema.TaggedError<TravelPlann
|
|
|
125
123
|
|
|
126
124
|
/** Decode the itinerary projection rebuilt from canonical model-completion records. */
|
|
127
125
|
export const travelPlanFromProjection = (
|
|
128
|
-
projection:
|
|
126
|
+
projection: ThreadProjection,
|
|
129
127
|
): Effect.Effect<TravelPlan, TravelPlannerProjectionError> => {
|
|
130
128
|
const output = projection.modelOutputs.at(-1);
|
|
131
129
|
if (output === undefined) {
|
|
@@ -141,18 +139,16 @@ export const travelPlanFromProjection = (
|
|
|
141
139
|
};
|
|
142
140
|
|
|
143
141
|
/** Build a disposable checkpoint bound to a validated canonical prefix. */
|
|
144
|
-
export const makePhase3TravelPlannerCheckpoint = (
|
|
145
|
-
|
|
146
|
-
): ConversationCheckpoint =>
|
|
147
|
-
Schema.decodeSync(ConversationCheckpoint)({
|
|
142
|
+
export const makePhase3TravelPlannerCheckpoint = (projection: ThreadProjection): ThreadCheckpoint =>
|
|
143
|
+
Schema.decodeSync(ThreadCheckpoint)({
|
|
148
144
|
schemaVersion: 1,
|
|
149
|
-
|
|
145
|
+
threadId: projection.threadId,
|
|
150
146
|
throughSequence: projection.throughSequence,
|
|
151
147
|
tailDigest: projection.tailDigest,
|
|
152
148
|
engineVersion: "phase-3-test-runtime",
|
|
153
149
|
agentDefinitionDigest: phase3TravelPlannerDefinitionDigests.agent,
|
|
154
150
|
modelDigest: phase3TravelPlannerDefinitionDigests.model,
|
|
155
151
|
toolDigest: phase3TravelPlannerDefinitionDigests.tools,
|
|
156
|
-
state: Schema.encodeSync(
|
|
152
|
+
state: Schema.encodeSync(ThreadProjection)(projection),
|
|
157
153
|
createdAt: "2026-09-01T00:00:04.000Z",
|
|
158
154
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Agent, AgentPolicy, type
|
|
1
|
+
import { Agent, AgentPolicy, type ThreadId } from "@effect-agent/core";
|
|
2
2
|
import { ToolExecutionClass } from "@effect-agent/engine";
|
|
3
3
|
import {
|
|
4
4
|
CanonicalRecordEnvelope,
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
type DurableSubmitOptions,
|
|
11
11
|
type IdempotencyKey,
|
|
12
12
|
type Receipt,
|
|
13
|
-
} from "@effect-agent/
|
|
13
|
+
} from "@effect-agent/thread";
|
|
14
14
|
import { Effect, Layer, Schema } from "effect";
|
|
15
15
|
import { Model, Tool, Toolkit } from "effect/unstable/ai";
|
|
16
16
|
|
|
@@ -85,10 +85,10 @@ export const phase4TravelPlannerDefinitionDigests = DefinitionDigests.make({
|
|
|
85
85
|
|
|
86
86
|
/** Durable admission options for one Travel Planner Submission on one trip lane. */
|
|
87
87
|
export const phase4TravelPlannerSubmitOptions = (
|
|
88
|
-
|
|
88
|
+
threadId: ThreadId,
|
|
89
89
|
idempotencyKey: IdempotencyKey,
|
|
90
90
|
): DurableSubmitOptions => ({
|
|
91
|
-
|
|
91
|
+
threadId,
|
|
92
92
|
principal: phase4TravelPlannerPrincipal,
|
|
93
93
|
idempotencyKey,
|
|
94
94
|
definitions: phase4TravelPlannerDefinitionDigests,
|
|
@@ -147,7 +147,7 @@ export const TravelPlannerPhase4ToolkitLayer = TravelPlannerPhase4Toolkit.toLaye
|
|
|
147
147
|
* runtime. The searches are read-only and safe to repeat across Attempts (D6); supplier booking
|
|
148
148
|
* is deliberately absent because DN does NOT claim replay-safe external mutation (P5 scope).
|
|
149
149
|
*/
|
|
150
|
-
export const TravelPlannerPhase4 = Agent.
|
|
150
|
+
export const TravelPlannerPhase4 = Agent.make("travel-planner-phase-4", {
|
|
151
151
|
input: TripRequest,
|
|
152
152
|
output: TravelPlan,
|
|
153
153
|
instructions: (input) =>
|
|
@@ -211,7 +211,7 @@ export const travelPlanFromDurableSettlement = Effect.fn(
|
|
|
211
211
|
const settled = settlements.at(0);
|
|
212
212
|
if (settled === undefined) {
|
|
213
213
|
return yield* TravelPlannerDurableEvidenceError.make({
|
|
214
|
-
message: "The canonical
|
|
214
|
+
message: "The canonical Thread Log has no SubmissionSettled record.",
|
|
215
215
|
});
|
|
216
216
|
}
|
|
217
217
|
if (settled.outcome !== "completed" || settled.result === undefined) {
|
|
@@ -235,7 +235,7 @@ const decodeComparableJson = Schema.decodeUnknownEffect(Schema.Json);
|
|
|
235
235
|
* Project canonical evidence into a Submission-identity-independent comparable form: batch
|
|
236
236
|
* identity, canonical sequence, and the full encoded record, with the ledger-minted
|
|
237
237
|
* `submissionId`/`receiptId` (and every identity derived from them: run, turn, batch, record,
|
|
238
|
-
* and settlement ids) replaced by stable placeholders. Two
|
|
238
|
+
* and settlement ids) replaced by stable placeholders. Two Threads whose normalized
|
|
239
239
|
* evidence is equal took byte-equivalent canonical histories, so restart-equivalence can compare
|
|
240
240
|
* a recovered run against an uninterrupted control run on a separate database.
|
|
241
241
|
*/
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Agent, AgentPolicy, type
|
|
1
|
+
import { Agent, AgentPolicy, type ThreadId } from "@effect-agent/core";
|
|
2
2
|
import { DurableStep, DurableStepError, ToolExecutionClass } from "@effect-agent/engine";
|
|
3
3
|
import {
|
|
4
4
|
DefinitionDigests,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
type CanonicalRecordEnvelope,
|
|
16
16
|
type DurableSubmitOptions,
|
|
17
17
|
type IdempotencyKey,
|
|
18
|
-
} from "@effect-agent/
|
|
18
|
+
} from "@effect-agent/thread";
|
|
19
19
|
import { Effect, Layer, Option, Schema } from "effect";
|
|
20
20
|
import { Tool, Toolkit } from "effect/unstable/ai";
|
|
21
21
|
|
|
@@ -93,10 +93,10 @@ export const phase5TravelPlannerDefinitionDigests = DefinitionDigests.make({
|
|
|
93
93
|
|
|
94
94
|
/** Durable admission options for one Travel Planner Submission on one trip lane. */
|
|
95
95
|
export const phase5TravelPlannerSubmitOptions = (
|
|
96
|
-
|
|
96
|
+
threadId: ThreadId,
|
|
97
97
|
idempotencyKey: IdempotencyKey,
|
|
98
98
|
): DurableSubmitOptions => ({
|
|
99
|
-
|
|
99
|
+
threadId,
|
|
100
100
|
principal: phase5TravelPlannerPrincipal,
|
|
101
101
|
idempotencyKey,
|
|
102
102
|
definitions: phase5TravelPlannerDefinitionDigests,
|
|
@@ -384,7 +384,7 @@ export const TravelSupplierReconcilerLayer: Layer.Layer<
|
|
|
384
384
|
* idempotent-by-contract cancellation, and one Durable Tool whose Steps carry supplier
|
|
385
385
|
* idempotency keys.
|
|
386
386
|
*/
|
|
387
|
-
export const TravelPlannerPhase5 = Agent.
|
|
387
|
+
export const TravelPlannerPhase5 = Agent.make("travel-planner-phase-5", {
|
|
388
388
|
input: TripRequest,
|
|
389
389
|
output: TravelBookingReport,
|
|
390
390
|
instructions: [
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
type Receipt,
|
|
11
11
|
type ResolvedBinding,
|
|
12
12
|
type ToolReconciler,
|
|
13
|
-
} from "@effect-agent/
|
|
13
|
+
} from "@effect-agent/thread";
|
|
14
14
|
import { Duration, Effect, Layer, Schema, Stream } from "effect";
|
|
15
15
|
import { LanguageModel, Model, type Response } from "effect/unstable/ai";
|
|
16
16
|
|
|
@@ -58,7 +58,7 @@ import {
|
|
|
58
58
|
// Phase 6 (P6): the SAME cumulative Travel Planner on the Cloudflare Durable
|
|
59
59
|
// Object runtime, deployment class DC. This module is deliberately
|
|
60
60
|
// platform-neutral (it imports no Cloudflare types): the worker Bindings it
|
|
61
|
-
// builds are plain `ResolvedBinding` values a
|
|
61
|
+
// builds are plain `ResolvedBinding` values a Thread Object registers,
|
|
62
62
|
// and the cross-platform evidence normal form is shared by the DN and DC
|
|
63
63
|
// halves of the equivalence suite (plan §1.8, D-P6-6).
|
|
64
64
|
// ---------------------------------------------------------------------------
|
|
@@ -101,11 +101,11 @@ export const phase6TravelPlannerProfile = TravelPlannerCloudflareProfile.make({
|
|
|
101
101
|
export const phase6TravelPlannerDeploymentId = Schema.decodeSync(DeploymentId)(
|
|
102
102
|
"travel-planner-p6-deployment",
|
|
103
103
|
);
|
|
104
|
-
/** Producer prefix of the DC host; each Object mints `{prefix}:{
|
|
104
|
+
/** Producer prefix of the DC host; each Object mints `{prefix}:{threadId}`. */
|
|
105
105
|
export const phase6TravelPlannerProducerPrefix = "travel-planner-p6-producer";
|
|
106
|
-
/** The full producer identity one DC
|
|
107
|
-
export const phase6TravelPlannerProducerId = (
|
|
108
|
-
Schema.decodeSync(ProducerId)(`${phase6TravelPlannerProducerPrefix}:${
|
|
106
|
+
/** The full producer identity one DC Thread Object mints for itself. */
|
|
107
|
+
export const phase6TravelPlannerProducerId = (threadId: string): ProducerId =>
|
|
108
|
+
Schema.decodeSync(ProducerId)(`${phase6TravelPlannerProducerPrefix}:${threadId}`);
|
|
109
109
|
|
|
110
110
|
const digestOf = (character: string) => Schema.decodeSync(Digest)(character.repeat(64));
|
|
111
111
|
|
|
@@ -127,11 +127,11 @@ export const phase6GatedPlannerDefinitionDigests = DefinitionDigests.make({
|
|
|
127
127
|
|
|
128
128
|
/** The run-specific identities the cross-platform normal form scrubs. */
|
|
129
129
|
export interface CrossPlatformEvidenceIdentity {
|
|
130
|
-
/** The
|
|
131
|
-
readonly
|
|
130
|
+
/** The Thread lane the evidence came from. */
|
|
131
|
+
readonly threadId: string;
|
|
132
132
|
/** The host's deployment identity (`DeploymentId` on every record envelope). */
|
|
133
133
|
readonly deploymentId: string;
|
|
134
|
-
/** The full producer identity of the run (DN: configured; DC: `{prefix}:{
|
|
134
|
+
/** The full producer identity of the run (DN: configured; DC: `{prefix}:{threadId}`). */
|
|
135
135
|
readonly producerId: string;
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -148,7 +148,7 @@ const decodeComparableEnvelopes = Schema.decodeUnknownEffect(Schema.Array(Compar
|
|
|
148
148
|
/**
|
|
149
149
|
* The CROSS-PLATFORM extension of `normalizeDurableTravelPlannerEvidence` (D-P6-6): after the
|
|
150
150
|
* base normalization replaces the two ledger-minted identities (which also normalizes the
|
|
151
|
-
* DC-format routable `{uuidv7}:{
|
|
151
|
+
* DC-format routable `{uuidv7}:{threadId}` Submission identities and everything derived
|
|
152
152
|
* from them), this form additionally scrubs everything that legitimately differs between a DN
|
|
153
153
|
* process and a DC Durable Object over the same scenario:
|
|
154
154
|
*
|
|
@@ -158,7 +158,7 @@ const decodeComparableEnvelopes = Schema.decodeUnknownEffect(Schema.Array(Compar
|
|
|
158
158
|
* control (on DC even a CLEAN run carries one, because every pass reconciles before it
|
|
159
159
|
* claims, so the ready lane's input is applied through the recovery path). Canonical ORDER
|
|
160
160
|
* is the durability §5 claim; sequence contiguity is a platform artifact of who appended;
|
|
161
|
-
* - the
|
|
161
|
+
* - the Thread identity (DC lanes mint unique names per test run);
|
|
162
162
|
* - the deployment and producer identities (host configuration, not canonical semantics);
|
|
163
163
|
* - `createdAt` commit timestamps (wall clock);
|
|
164
164
|
* - 64-hex digests (they hash RAW content that legally embeds run-specific identity, so they
|
|
@@ -185,7 +185,7 @@ export const normalizeCrossPlatformTravelPlannerEvidence = Effect.fn(
|
|
|
185
185
|
JSON.stringify(base)
|
|
186
186
|
.replaceAll(identity.producerId, "{producerId}")
|
|
187
187
|
.replaceAll(identity.deploymentId, "{deploymentId}")
|
|
188
|
-
.replaceAll(identity.
|
|
188
|
+
.replaceAll(identity.threadId, "{threadId}")
|
|
189
189
|
.replaceAll(/\d{4}-\d{2}-\d{2}T[0-9:.]+Z/g, "{timestamp}")
|
|
190
190
|
.replaceAll(/"[0-9a-f]{64}"/g, '"{digest}"'),
|
|
191
191
|
);
|
|
@@ -291,7 +291,7 @@ export const phase6PlannerModel = promptAwareModel("travel-planner-phase-4", pla
|
|
|
291
291
|
// ---------------------------------------------------------------------------
|
|
292
292
|
// Deterministic test gate for the admission-limits rows. Module state is
|
|
293
293
|
// intentionally NOT durable: it plays the external world's role (a slow
|
|
294
|
-
// upstream model), never
|
|
294
|
+
// upstream model), never Thread state.
|
|
295
295
|
// ---------------------------------------------------------------------------
|
|
296
296
|
|
|
297
297
|
const releasedPlannerGates = new Set<string>();
|
|
@@ -381,7 +381,7 @@ export const phase6SupplierDeskLayer: Layer.Layer<SupplierBookingDesk> = Layer.s
|
|
|
381
381
|
|
|
382
382
|
/**
|
|
383
383
|
* The REAL P5 supplier reconciliation policy over the shared desk, closed to no requirements
|
|
384
|
-
* so a
|
|
384
|
+
* so a Thread Object can install it directly: `book_flight` recovers only from supplier
|
|
385
385
|
* truth (absence stays fail-closed `Uncertain` → durable Unknown Outcome), keyed Steps are
|
|
386
386
|
* provably re-enterable.
|
|
387
387
|
*/
|
|
@@ -576,14 +576,14 @@ export const phase6ResearcherModel = promptAwareModel("destination-researcher-p6
|
|
|
576
576
|
);
|
|
577
577
|
|
|
578
578
|
// ---------------------------------------------------------------------------
|
|
579
|
-
// Worker Binding registrations for the DC
|
|
579
|
+
// Worker Binding registrations for the DC Thread Object
|
|
580
580
|
// ---------------------------------------------------------------------------
|
|
581
581
|
|
|
582
582
|
/**
|
|
583
583
|
* Every phase-6 Travel Planner worker Binding, captured with its requirement Contexts:
|
|
584
584
|
* the P4 planner and its gated twin, the P5 booking agent over the
|
|
585
585
|
* shared supplier desk, and the S2 coordinator/researcher pair wired through the durable
|
|
586
|
-
* delegation Layer. A
|
|
586
|
+
* delegation Layer. A Thread Object registers these via its `bindings` option; the
|
|
587
587
|
* capture runs once per incarnation, and everything stateful the assertions rely on (desk,
|
|
588
588
|
* guide counter, gates) lives at module level so it survives incarnation loss.
|
|
589
589
|
*/
|
|
@@ -656,16 +656,16 @@ export const makePhase6TravelPlannerBindings: Effect.Effect<ReadonlyArray<Resolv
|
|
|
656
656
|
*/
|
|
657
657
|
export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
658
658
|
{
|
|
659
|
-
batchId: "
|
|
659
|
+
batchId: "thread-created:{threadId}",
|
|
660
660
|
sequence: 1,
|
|
661
661
|
record: {
|
|
662
|
-
recordId: "
|
|
663
|
-
family: "
|
|
662
|
+
recordId: "thread-created:{threadId}",
|
|
663
|
+
family: "thread",
|
|
664
664
|
schemaVersion: 1,
|
|
665
665
|
createdAt: "{timestamp}",
|
|
666
666
|
deploymentId: "{deploymentId}",
|
|
667
667
|
payload: {
|
|
668
|
-
_tag: "
|
|
668
|
+
_tag: "ThreadCreated",
|
|
669
669
|
agentId: "travel-planner-phase-4",
|
|
670
670
|
definitions: {
|
|
671
671
|
agent: "{digest}",
|
|
@@ -680,7 +680,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
680
680
|
sequence: 2,
|
|
681
681
|
record: {
|
|
682
682
|
recordId: "input:{submissionId}",
|
|
683
|
-
family: "
|
|
683
|
+
family: "thread",
|
|
684
684
|
schemaVersion: 1,
|
|
685
685
|
createdAt: "{timestamp}",
|
|
686
686
|
deploymentId: "{deploymentId}",
|
|
@@ -708,13 +708,14 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
708
708
|
sequence: 3,
|
|
709
709
|
record: {
|
|
710
710
|
recordId: "run-start:run:{submissionId}",
|
|
711
|
-
family: "
|
|
711
|
+
family: "thread",
|
|
712
712
|
schemaVersion: 1,
|
|
713
713
|
createdAt: "{timestamp}",
|
|
714
714
|
deploymentId: "{deploymentId}",
|
|
715
715
|
payload: {
|
|
716
716
|
_tag: "RunStarted",
|
|
717
717
|
runId: "run:{submissionId}",
|
|
718
|
+
policyAccountingVersion: 1,
|
|
718
719
|
maxDurationMillis: 30_000,
|
|
719
720
|
},
|
|
720
721
|
},
|
|
@@ -724,7 +725,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
724
725
|
sequence: 4,
|
|
725
726
|
record: {
|
|
726
727
|
recordId: "model-response:run:{submissionId}:1",
|
|
727
|
-
family: "
|
|
728
|
+
family: "thread",
|
|
728
729
|
schemaVersion: 1,
|
|
729
730
|
createdAt: "{timestamp}",
|
|
730
731
|
deploymentId: "{deploymentId}",
|
|
@@ -824,7 +825,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
824
825
|
sequence: 5,
|
|
825
826
|
record: {
|
|
826
827
|
recordId: "tool-settled:run:{submissionId}:1:flight-call-1",
|
|
827
|
-
family: "
|
|
828
|
+
family: "thread",
|
|
828
829
|
schemaVersion: 1,
|
|
829
830
|
createdAt: "{timestamp}",
|
|
830
831
|
deploymentId: "{deploymentId}",
|
|
@@ -848,7 +849,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
848
849
|
sequence: 6,
|
|
849
850
|
record: {
|
|
850
851
|
recordId: "tool-settled:run:{submissionId}:1:lodging-call-1",
|
|
851
|
-
family: "
|
|
852
|
+
family: "thread",
|
|
852
853
|
schemaVersion: 1,
|
|
853
854
|
createdAt: "{timestamp}",
|
|
854
855
|
deploymentId: "{deploymentId}",
|
|
@@ -871,7 +872,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
871
872
|
sequence: 7,
|
|
872
873
|
record: {
|
|
873
874
|
recordId: "tool-settled:run:{submissionId}:1:activity-call-1",
|
|
874
|
-
family: "
|
|
875
|
+
family: "thread",
|
|
875
876
|
schemaVersion: 1,
|
|
876
877
|
createdAt: "{timestamp}",
|
|
877
878
|
deploymentId: "{deploymentId}",
|
|
@@ -892,7 +893,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
892
893
|
sequence: 8,
|
|
893
894
|
record: {
|
|
894
895
|
recordId: "model-response:run:{submissionId}:2",
|
|
895
|
-
family: "
|
|
896
|
+
family: "thread",
|
|
896
897
|
schemaVersion: 1,
|
|
897
898
|
createdAt: "{timestamp}",
|
|
898
899
|
deploymentId: "{deploymentId}",
|
|
@@ -940,7 +941,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
940
941
|
sequence: 9,
|
|
941
942
|
record: {
|
|
942
943
|
recordId: "run-completed:run:{submissionId}",
|
|
943
|
-
family: "
|
|
944
|
+
family: "thread",
|
|
944
945
|
schemaVersion: 1,
|
|
945
946
|
createdAt: "{timestamp}",
|
|
946
947
|
deploymentId: "{deploymentId}",
|
|
@@ -978,7 +979,7 @@ export const phase6TravelPlannerGoldenEvidence: Schema.Json = [
|
|
|
978
979
|
sequence: 10,
|
|
979
980
|
record: {
|
|
980
981
|
recordId: "settlement:{submissionId}",
|
|
981
|
-
family: "
|
|
982
|
+
family: "thread",
|
|
982
983
|
schemaVersion: 1,
|
|
983
984
|
createdAt: "{timestamp}",
|
|
984
985
|
deploymentId: "{deploymentId}",
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
SubagentReservationsMemoryLive,
|
|
4
4
|
SubagentRuntime,
|
|
5
5
|
} from "@effect-agent/capabilities";
|
|
6
|
-
import { Agent, type
|
|
6
|
+
import { Agent, type ThreadId } from "@effect-agent/core";
|
|
7
7
|
import type { RuntimeBinding } from "@effect-agent/engine";
|
|
8
8
|
import {
|
|
9
9
|
DefinitionDigests,
|
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
type DurableSubmitOptions,
|
|
16
16
|
type IdempotencyKey,
|
|
17
17
|
type ResolvedBinding,
|
|
18
|
-
} from "@effect-agent/
|
|
18
|
+
} from "@effect-agent/thread";
|
|
19
19
|
import { Effect, Layer, Ref, Schema, Stream } from "effect";
|
|
20
20
|
import { LanguageModel, Model, type Response, type Toolkit } from "effect/unstable/ai";
|
|
21
21
|
|
|
@@ -59,7 +59,7 @@ export class TravelPlannerSubagentDurabilityProfile extends Schema.Class<TravelP
|
|
|
59
59
|
deploymentClass: Schema.Literal("DN"),
|
|
60
60
|
durableAttachedSubagents: Schema.Literal(true),
|
|
61
61
|
canonicalSchemaVersion: Schema.Literal(1),
|
|
62
|
-
/** Establishment/join replay converges on one child Receipt,
|
|
62
|
+
/** Establishment/join replay converges on one child Receipt, Thread, and join batch. */
|
|
63
63
|
subagentReplaySafe: Schema.Literal(true),
|
|
64
64
|
/** Never claimed (rule 8): child ordinary Tools stop at Unknown Outcomes, they do not replay. */
|
|
65
65
|
childExternalEffectsExactlyOnce: Schema.Literal(false),
|
|
@@ -96,7 +96,7 @@ export const s2CoordinatorDigests = DefinitionDigests.make({
|
|
|
96
96
|
/**
|
|
97
97
|
* The exact child Binding digest strings the application declares on
|
|
98
98
|
* `SubagentRuntimeOptions.durable.targetDigests` AND the host registers with
|
|
99
|
-
* the
|
|
99
|
+
* the host's binding array for the researcher Binding. The coordinator
|
|
100
100
|
* stores and verifies them byte-for-byte (SUB-023); a host registration under
|
|
101
101
|
* different strings is a `ChildCompatibilityFailure`, never a substitution.
|
|
102
102
|
*/
|
|
@@ -114,10 +114,10 @@ export const s2ResearcherDigests = DefinitionDigests.make({
|
|
|
114
114
|
|
|
115
115
|
/** Durable admission options for one coordinator Submission on one mission lane. */
|
|
116
116
|
export const s2TravelPlannerSubmitOptions = (
|
|
117
|
-
|
|
117
|
+
threadId: ThreadId,
|
|
118
118
|
idempotencyKey: IdempotencyKey,
|
|
119
119
|
): DurableSubmitOptions => ({
|
|
120
|
-
|
|
120
|
+
threadId,
|
|
121
121
|
principal: s2TravelPlannerPrincipal,
|
|
122
122
|
idempotencyKey,
|
|
123
123
|
definitions: s2CoordinatorDigests,
|
|
@@ -65,7 +65,7 @@ export class DestinationReport extends Schema.Class<DestinationReport>("Destinat
|
|
|
65
65
|
advisory: Schema.NonEmptyString,
|
|
66
66
|
}) {}
|
|
67
67
|
|
|
68
|
-
export const DestinationResearcher = Agent.
|
|
68
|
+
export const DestinationResearcher = Agent.make("destination-researcher", {
|
|
69
69
|
input: DestinationBrief,
|
|
70
70
|
output: DestinationReport,
|
|
71
71
|
instructions:
|
|
@@ -230,7 +230,7 @@ export const destinationResearchDelegation = Subagent.define("delegate_destinati
|
|
|
230
230
|
});
|
|
231
231
|
}),
|
|
232
232
|
// The explicit declassification boundary (SUB-015): only the advisory
|
|
233
|
-
// crosses to the parent; guide highlights stay in the child
|
|
233
|
+
// crosses to the parent; guide highlights stay in the child Thread.
|
|
234
234
|
projectResult: (report) =>
|
|
235
235
|
Effect.succeed(
|
|
236
236
|
DestinationResearchFindings.make({
|
|
@@ -291,7 +291,7 @@ export const missionConfidentialMarker = "traveler-dossier-19f";
|
|
|
291
291
|
|
|
292
292
|
export const TravelCoordinatorToolkit = Toolkit.make(destinationResearchDelegation.tool);
|
|
293
293
|
|
|
294
|
-
export const TravelCoordinator = Agent.
|
|
294
|
+
export const TravelCoordinator = Agent.make("travel-coordinator", {
|
|
295
295
|
input: ResearchMission,
|
|
296
296
|
output: DestinationShortlist,
|
|
297
297
|
instructions: [
|
|
@@ -313,7 +313,7 @@ export const TravelCoordinator = Agent.define("travel-coordinator", {
|
|
|
313
313
|
});
|
|
314
314
|
|
|
315
315
|
export const researchMission = Schema.decodeSync(ResearchMission)({
|
|
316
|
-
request: `Shortlist one September culture city; keep ${missionConfidentialMarker} inside the coordinator
|
|
316
|
+
request: `Shortlist one September culture city; keep ${missionConfidentialMarker} inside the coordinator thread.`,
|
|
317
317
|
candidates: ["LHR", "CDG"],
|
|
318
318
|
});
|
|
319
319
|
|
package/src/index.ts
CHANGED
|
@@ -1,11 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
export * from "./chaos.ts";
|
|
3
|
-
export * from "./code-executor-conformance.ts";
|
|
4
|
-
export * from "./code-executor-substitute.ts";
|
|
5
|
-
export * from "./fixtures/docs-researcher/index.ts";
|
|
6
|
-
export * from "./fixtures/travel-planner/index.ts";
|
|
7
|
-
// The warehouse fixture is NOT re-exported here: it depends on
|
|
8
|
-
// `@effect/sql-sqlite-node` (`node:sqlite`), which workerd consumers of this
|
|
9
|
-
// barrel (the Cloudflare certification suites) cannot load. Import it
|
|
10
|
-
// directly from `@effect-agent/testing/src/fixtures/warehouse/index.ts`.
|
|
1
|
+
/** Scripted model support. Fixtures and specialized harnesses have dedicated subpaths. */
|
|
11
2
|
export * from "./scripted-model.ts";
|