@effect-agent/testing 0.1.0-beta.45 → 0.1.0-beta.47

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.
Files changed (60) hide show
  1. package/dist/{certification.d.mts → Certification.d.mts} +7 -4
  2. package/dist/{certification.mjs → Certification.mjs} +23 -7
  3. package/dist/Certification.mjs.map +1 -0
  4. package/dist/{chaos.d.mts → Chaos.d.mts} +7 -5
  5. package/dist/{chaos.mjs → Chaos.mjs} +21 -7
  6. package/dist/Chaos.mjs.map +1 -0
  7. package/dist/{code-executor.d.mts → CodeExecutorConformance.d.mts} +6 -21
  8. package/dist/{code-executor.mjs → CodeExecutorConformance.mjs} +6 -340
  9. package/dist/CodeExecutorConformance.mjs.map +1 -0
  10. package/dist/CodeExecutorSubstitute.d.mts +21 -0
  11. package/dist/CodeExecutorSubstitute.mjs +341 -0
  12. package/dist/CodeExecutorSubstitute.mjs.map +1 -0
  13. package/dist/{docs-researcher.d.mts → DocsResearcher.d.mts} +23 -16
  14. package/dist/{docs-researcher.mjs → DocsResearcher.mjs} +15 -5
  15. package/dist/DocsResearcher.mjs.map +1 -0
  16. package/dist/{scripted-model-dOa_e0-n.d.mts → ScriptedModel-Dx8aW73W.d.mts} +5 -3
  17. package/dist/ScriptedModel.d.mts +2 -0
  18. package/dist/{scripted-model-C2y0ztuj.mjs → ScriptedModel.mjs} +13 -3
  19. package/dist/ScriptedModel.mjs.map +1 -0
  20. package/dist/{travel-planner.d.mts → TravelPlanner.d.mts} +35 -24
  21. package/dist/{travel-planner.mjs → TravelPlanner.mjs} +18 -7
  22. package/dist/TravelPlanner.mjs.map +1 -0
  23. package/dist/{deterministic-layers-CKyYxBhN.mjs → deterministic-layers-Eka0fMZq.mjs} +7 -3
  24. package/dist/deterministic-layers-Eka0fMZq.mjs.map +1 -0
  25. package/dist/index.d.mts +2 -2
  26. package/dist/index.mjs +2 -2
  27. package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
  28. package/package.json +1 -1
  29. package/src/{certification.ts → Certification.ts} +37 -32
  30. package/src/{chaos.ts → Chaos.ts} +36 -32
  31. package/src/{code-executor-conformance.ts → CodeExecutorConformance.ts} +5 -3
  32. package/src/{code-executor-substitute.ts → CodeExecutorSubstitute.ts} +2 -2
  33. package/src/{fixtures/docs-researcher/index.ts → DocsResearcher.ts} +67 -4
  34. package/src/TravelPlanner.ts +244 -0
  35. package/src/fixtures/docs-researcher/definition.ts +5 -3
  36. package/src/fixtures/docs-researcher/harness.ts +9 -16
  37. package/src/fixtures/docs-researcher/mcp.ts +1 -1
  38. package/src/fixtures/travel-planner/definition.ts +2 -1
  39. package/src/fixtures/travel-planner/deterministic-layers.ts +4 -2
  40. package/src/fixtures/travel-planner/phase2.ts +2 -1
  41. package/src/fixtures/travel-planner/phase3.ts +4 -4
  42. package/src/fixtures/travel-planner/phase4.ts +8 -8
  43. package/src/fixtures/travel-planner/phase5.ts +14 -7
  44. package/src/fixtures/travel-planner/phase6.ts +6 -7
  45. package/src/fixtures/travel-planner/scenarios.ts +1 -1
  46. package/src/fixtures/travel-planner/subagents-durable.ts +9 -15
  47. package/src/fixtures/travel-planner/subagents.ts +6 -4
  48. package/src/index.ts +1 -2
  49. package/dist/certification.mjs.map +0 -1
  50. package/dist/chaos.mjs.map +0 -1
  51. package/dist/code-executor.mjs.map +0 -1
  52. package/dist/deterministic-layers-CKyYxBhN.mjs.map +0 -1
  53. package/dist/docs-researcher.mjs.map +0 -1
  54. package/dist/scripted-model-C2y0ztuj.mjs.map +0 -1
  55. package/dist/travel-planner.mjs.map +0 -1
  56. package/src/code-executor.ts +0 -3
  57. package/src/docs-researcher.ts +0 -2
  58. package/src/fixtures/travel-planner/index.ts +0 -11
  59. package/src/travel-planner.ts +0 -2
  60. /package/src/{scripted-model.ts → ScriptedModel.ts} +0 -0
@@ -0,0 +1,341 @@
1
+ import { Clock, Duration, Effect, Fiber, Layer, Option, Queue, Schema } from "effect";
2
+ import { CodeExecutionHost, CodeExecutionProtocolError, CodeExecutionResourceUse, CodeExecutionResult, CodeExecutionTimeoutError, CodeExecutor, CodeExecutorUnsupportedError, CodeHostCall, CodeHostCallLimitError, CodeHostCallResult, CodeOutputLimitError, CodeProgramFailedError, CodeSourceError } from "@effect-agent/sandbox/CodeExecutor";
3
+ import { SandboxImplementation } from "@effect-agent/sandbox/Sandbox";
4
+ //#region src/CodeExecutorSubstitute.ts
5
+ /**
6
+ * The deterministic in-process executor substitute (C1 of ADR-0017). It runs
7
+ * the generated program on the host JavaScript engine with best-effort global
8
+ * shadowing only, so it self-identifies as `unisolated` and is never a
9
+ * security boundary (CAP-010, CAP-015). It exists to prove the public
10
+ * `CodeExecutor` contract and to drive deterministic capability tests.
11
+ */
12
+ const inProcessCodeExecutorImplementation = SandboxImplementation.make({
13
+ isolation: "unisolated",
14
+ identity: "in-process-javascript"
15
+ });
16
+ const MAX_LOG_LINES = 4096;
17
+ const MAX_LOG_LINE_CHARACTERS = 16e3;
18
+ const MAX_THROWN_CHARACTERS = 4e3;
19
+ const utf8ByteLength = (value) => new TextEncoder().encode(value).byteLength;
20
+ /**
21
+ * Ambient globals shadowed inside the harness. Shadowing blocks the obvious
22
+ * identifier paths only; a determined program can still escape, which is
23
+ * exactly why this executor reports `unisolated` and the isolated network and
24
+ * CPU enforcement conformance cases run only against isolated adapters.
25
+ */
26
+ const shadowedGlobals = [
27
+ "fetch",
28
+ "process",
29
+ "require",
30
+ "module",
31
+ "exports",
32
+ "global",
33
+ "globalThis",
34
+ "XMLHttpRequest",
35
+ "WebSocket",
36
+ "Deno",
37
+ "Bun"
38
+ ];
39
+ var LogLimitSignal = class {
40
+ observed;
41
+ constructor(observed) {
42
+ this.observed = observed;
43
+ }
44
+ };
45
+ var EvaluationThrew = class {
46
+ inner;
47
+ constructor(inner) {
48
+ this.inner = inner;
49
+ }
50
+ };
51
+ var NotAFunction = class {
52
+ actual;
53
+ constructor(actual) {
54
+ this.actual = actual;
55
+ }
56
+ };
57
+ /**
58
+ * Total, defect-free rendering of untrusted values: a hostile Proxy can throw
59
+ * from property access, `toString`, and `Symbol.toPrimitive`, and an expected
60
+ * program failure must never escape the typed channel as a defect while its
61
+ * diagnostics are being serialized.
62
+ */
63
+ const formatLogValue = (value) => {
64
+ try {
65
+ if (typeof value === "string") return value;
66
+ return JSON.stringify(value) ?? String(value);
67
+ } catch {
68
+ try {
69
+ return String(value);
70
+ } catch {
71
+ return "[unprintable value]";
72
+ }
73
+ }
74
+ };
75
+ const makeConsole = (capture, limits) => {
76
+ const write = (...values) => {
77
+ const joined = values.map(formatLogValue).join(" ");
78
+ const line = joined.length > MAX_LOG_LINE_CHARACTERS ? `${joined.slice(0, 15999)}…` : joined;
79
+ const bytes = utf8ByteLength(line);
80
+ if (capture.lines.length >= MAX_LOG_LINES || capture.bytes + bytes > limits.maxLogBytes) throw new LogLimitSignal(capture.bytes + bytes);
81
+ capture.lines.push(line);
82
+ capture.bytes += bytes;
83
+ };
84
+ return {
85
+ debug: write,
86
+ error: write,
87
+ info: write,
88
+ log: write,
89
+ warn: write
90
+ };
91
+ };
92
+ const buildNamespaceObject = (namespace, offer) => {
93
+ const methods = {};
94
+ for (const method of namespace.methods) methods[method] = (argument) => new Promise((resolve, reject) => {
95
+ offer({
96
+ namespace: namespace.name,
97
+ method,
98
+ argument,
99
+ resolve,
100
+ reject
101
+ });
102
+ });
103
+ return methods;
104
+ };
105
+ const boundedText = (value) => {
106
+ try {
107
+ return (value instanceof Error ? `${value.name}: ${value.message}` : formatLogValue(value)).slice(0, MAX_THROWN_CHARACTERS);
108
+ } catch {
109
+ return "[unserializable thrown value]";
110
+ }
111
+ };
112
+ /** Schema decoding of hostile values may itself throw through trap getters. */
113
+ const safeDecodeJson = (value) => {
114
+ try {
115
+ return Schema.decodeUnknownOption(Schema.Json)(value);
116
+ } catch {
117
+ return Option.none();
118
+ }
119
+ };
120
+ const boundedThrown = (value) => {
121
+ const decoded = safeDecodeJson(value);
122
+ if (Option.isSome(decoded)) try {
123
+ const encoded = JSON.stringify(decoded.value);
124
+ if (encoded !== void 0 && encoded.length <= MAX_THROWN_CHARACTERS) return decoded.value;
125
+ } catch {}
126
+ return boundedText(value);
127
+ };
128
+ const encodedJsonByteLength = (value) => {
129
+ try {
130
+ const encoded = JSON.stringify(value);
131
+ return encoded === void 0 ? void 0 : utf8ByteLength(encoded);
132
+ } catch {
133
+ return;
134
+ }
135
+ };
136
+ /** Host outcomes are protocol input; a hostile value must not defect mid-decode. */
137
+ const decodeHostOutcome = (value) => {
138
+ try {
139
+ return Schema.decodeUnknownOption(CodeHostCallResult)(value);
140
+ } catch {
141
+ return Option.none();
142
+ }
143
+ };
144
+ const validateRequest = (request) => Effect.gen(function* () {
145
+ if (request.network._tag !== "NetworkDisabled") return yield* CodeExecutorUnsupportedError.make({
146
+ implementation: inProcessCodeExecutorImplementation,
147
+ feature: "network",
148
+ message: "The unisolated in-process executor cannot enforce an egress allowlist; only NetworkDisabled is accepted, and even that is shadowed rather than enforced"
149
+ });
150
+ if (request.limits.cpuMillis !== void 0) return yield* CodeExecutorUnsupportedError.make({
151
+ implementation: inProcessCodeExecutorImplementation,
152
+ feature: "cpu-limit",
153
+ message: "The unisolated in-process executor shares the host engine and cannot enforce a CPU limit"
154
+ });
155
+ const reservedNames = /* @__PURE__ */ new Set([...shadowedGlobals, "console"]);
156
+ const seen = /* @__PURE__ */ new Set();
157
+ for (const namespace of request.namespaces) {
158
+ if (reservedNames.has(namespace.name) || seen.has(namespace.name)) return yield* CodeExecutorUnsupportedError.make({
159
+ implementation: inProcessCodeExecutorImplementation,
160
+ feature: "namespaces",
161
+ message: `Namespace ${namespace.name} collides with a harness binding or another namespace`
162
+ });
163
+ seen.add(namespace.name);
164
+ }
165
+ const sourceBytes = utf8ByteLength(request.source);
166
+ if (sourceBytes > request.limits.maxSourceBytes) return yield* CodeSourceError.make({
167
+ implementation: inProcessCodeExecutorImplementation,
168
+ reason: "oversized",
169
+ message: `Source is ${sourceBytes} bytes; the request allows ${request.limits.maxSourceBytes}`
170
+ });
171
+ });
172
+ const serveHostCalls = (host, queue, limits, capture, counter) => Effect.gen(function* () {
173
+ while (true) {
174
+ const pending = yield* Queue.take(queue);
175
+ counter.calls += 1;
176
+ if (counter.calls > limits.maxHostCalls) return yield* CodeHostCallLimitError.make({
177
+ implementation: inProcessCodeExecutorImplementation,
178
+ limit: limits.maxHostCalls,
179
+ logs: [...capture.lines]
180
+ });
181
+ const argument = safeDecodeJson(pending.argument);
182
+ if (Option.isNone(argument)) {
183
+ pending.reject(/* @__PURE__ */ new TypeError("host call arguments must be JSON values"));
184
+ continue;
185
+ }
186
+ const argumentBytes = encodedJsonByteLength(argument.value);
187
+ if (argumentBytes === void 0 || argumentBytes > limits.maxHostCallArgumentBytes) return yield* CodeOutputLimitError.make({
188
+ implementation: inProcessCodeExecutorImplementation,
189
+ surface: "host-call-argument",
190
+ limit: limits.maxHostCallArgumentBytes,
191
+ observed: argumentBytes ?? 0,
192
+ logs: [...capture.lines]
193
+ });
194
+ const rawOutcome = yield* host.call(CodeHostCall.make({
195
+ namespace: pending.namespace,
196
+ method: pending.method,
197
+ argument: argument.value
198
+ }));
199
+ const outcome = decodeHostOutcome(rawOutcome);
200
+ if (Option.isNone(outcome)) return yield* CodeExecutionProtocolError.make({
201
+ implementation: inProcessCodeExecutorImplementation,
202
+ message: "The execution host returned a value outside the CodeHostCallResult schema"
203
+ });
204
+ if (outcome.value._tag === "CodeHostCallFailure") {
205
+ pending.reject(outcome.value.error);
206
+ continue;
207
+ }
208
+ const resultBytes = encodedJsonByteLength(outcome.value.value);
209
+ if (resultBytes === void 0 || resultBytes > limits.maxHostCallResultBytes) return yield* CodeOutputLimitError.make({
210
+ implementation: inProcessCodeExecutorImplementation,
211
+ surface: "host-call-result",
212
+ limit: limits.maxHostCallResultBytes,
213
+ observed: resultBytes ?? 0,
214
+ logs: [...capture.lines]
215
+ });
216
+ pending.resolve(outcome.value.value);
217
+ }
218
+ });
219
+ const classifyProgramFailure = (thrown, limits, capture) => {
220
+ const inner = thrown instanceof EvaluationThrew ? thrown.inner : thrown;
221
+ if (inner instanceof LogLimitSignal) return CodeOutputLimitError.make({
222
+ implementation: inProcessCodeExecutorImplementation,
223
+ surface: "logs",
224
+ limit: limits.maxLogBytes,
225
+ observed: inner.observed,
226
+ logs: [...capture.lines]
227
+ });
228
+ if (inner instanceof NotAFunction) return CodeSourceError.make({
229
+ implementation: inProcessCodeExecutorImplementation,
230
+ reason: "not-a-function",
231
+ message: `The source expression evaluated to ${inner.actual}; it must evaluate to one async function`
232
+ });
233
+ const reason = thrown instanceof EvaluationThrew || inner instanceof Error ? "threw" : "rejected";
234
+ return CodeProgramFailedError.make({
235
+ implementation: inProcessCodeExecutorImplementation,
236
+ reason,
237
+ thrown: boundedThrown(inner),
238
+ message: boundedText(inner),
239
+ logs: [...capture.lines]
240
+ });
241
+ };
242
+ const executeInProcess = Effect.fn("InProcessCodeExecutor.execute")(function* (request) {
243
+ yield* validateRequest(request);
244
+ const host = yield* CodeExecutionHost;
245
+ const capture = {
246
+ lines: [],
247
+ bytes: 0
248
+ };
249
+ const counter = { calls: 0 };
250
+ const queue = yield* Queue.unbounded();
251
+ const factory = yield* Effect.try({
252
+ try: () => new Function(...shadowedGlobals, "console", ...request.namespaces.map((namespace) => namespace.name), `"use strict";\nreturn (\n${request.source}\n);`),
253
+ catch: (cause) => CodeSourceError.make({
254
+ implementation: inProcessCodeExecutorImplementation,
255
+ reason: "invalid",
256
+ message: boundedText(cause)
257
+ })
258
+ });
259
+ const harnessConsole = makeConsole(capture, request.limits);
260
+ let issuedHostCalls = 0;
261
+ const namespaceObjects = request.namespaces.map((namespace) => buildNamespaceObject(namespace, (pending) => {
262
+ issuedHostCalls += 1;
263
+ if (issuedHostCalls > request.limits.maxHostCalls + 1) {
264
+ pending.reject(/* @__PURE__ */ new Error(`host-call limit of ${request.limits.maxHostCalls} exceeded`));
265
+ return;
266
+ }
267
+ Queue.offerUnsafe(queue, pending);
268
+ }));
269
+ const server = yield* serveHostCalls(host, queue, request.limits, capture, counter).pipe(Effect.forkScoped);
270
+ const program = Effect.tryPromise({
271
+ try: async () => {
272
+ let candidate;
273
+ try {
274
+ candidate = factory(...shadowedGlobals.map(() => void 0), harnessConsole, ...namespaceObjects);
275
+ } catch (cause) {
276
+ throw new EvaluationThrew(cause);
277
+ }
278
+ if (typeof candidate !== "function") throw new EvaluationThrew(new NotAFunction(typeof candidate));
279
+ let outcome;
280
+ try {
281
+ outcome = candidate();
282
+ } catch (cause) {
283
+ throw new EvaluationThrew(cause);
284
+ }
285
+ return await Promise.resolve(outcome);
286
+ },
287
+ catch: (thrown) => classifyProgramFailure(thrown, request.limits, capture)
288
+ });
289
+ const startedAt = yield* Clock.currentTimeMillis;
290
+ const returned = yield* Effect.raceFirst(program, Fiber.join(server)).pipe(Effect.timeoutOrElse({
291
+ duration: request.limits.maxWallTime,
292
+ orElse: () => CodeExecutionTimeoutError.make({
293
+ implementation: inProcessCodeExecutorImplementation,
294
+ kind: "wall-clock",
295
+ maxWallTime: request.limits.maxWallTime,
296
+ logs: [...capture.lines]
297
+ })
298
+ }), Effect.ensuring(Fiber.interrupt(server)));
299
+ const finishedAt = yield* Clock.currentTimeMillis;
300
+ if (issuedHostCalls > request.limits.maxHostCalls) return yield* CodeHostCallLimitError.make({
301
+ implementation: inProcessCodeExecutorImplementation,
302
+ limit: request.limits.maxHostCalls,
303
+ logs: [...capture.lines]
304
+ });
305
+ const value = yield* Schema.decodeUnknownEffect(Schema.Json)(returned).pipe(Effect.mapError(() => CodeProgramFailedError.make({
306
+ implementation: inProcessCodeExecutorImplementation,
307
+ reason: "non-json-result",
308
+ thrown: null,
309
+ message: "The program must return a JSON value",
310
+ logs: [...capture.lines]
311
+ })));
312
+ const resultBytes = encodedJsonByteLength(value);
313
+ if (resultBytes === void 0 || resultBytes > request.limits.maxResultBytes) return yield* CodeOutputLimitError.make({
314
+ implementation: inProcessCodeExecutorImplementation,
315
+ surface: "result",
316
+ limit: request.limits.maxResultBytes,
317
+ observed: resultBytes ?? 0,
318
+ logs: [...capture.lines]
319
+ });
320
+ return CodeExecutionResult.make({
321
+ implementation: inProcessCodeExecutorImplementation,
322
+ value,
323
+ logs: [...capture.lines],
324
+ resourceUse: CodeExecutionResourceUse.make({
325
+ wallTime: Duration.millis(Math.max(0, finishedAt - startedAt)),
326
+ hostCalls: counter.calls,
327
+ logBytes: capture.bytes,
328
+ resultBytes
329
+ })
330
+ });
331
+ });
332
+ /**
333
+ * Layer providing the unisolated in-process `CodeExecutor` substitute. The
334
+ * per-pass `CodeExecutionHost` stays in the caller's requirement channel, the
335
+ * same as every real adapter.
336
+ */
337
+ const inProcessCodeExecutorLayer = Layer.succeed(CodeExecutor)(CodeExecutor.of({ execute: executeInProcess }));
338
+ //#endregion
339
+ export { inProcessCodeExecutorImplementation, inProcessCodeExecutorLayer };
340
+
341
+ //# sourceMappingURL=CodeExecutorSubstitute.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CodeExecutorSubstitute.mjs","names":[],"sources":["../src/CodeExecutorSubstitute.ts"],"sourcesContent":["import {\n CodeExecutionHost,\n CodeExecutionProtocolError,\n CodeExecutionResourceUse,\n CodeExecutionResult,\n CodeExecutionTimeoutError,\n CodeExecutor,\n type CodeExecutorExecute,\n CodeExecutorUnsupportedError,\n CodeHostCall,\n CodeHostCallLimitError,\n CodeHostCallResult,\n CodeOutputLimitError,\n CodeProgramFailedError,\n CodeSourceError,\n type CodeExecutionLimits,\n type CodeExecutionNamespace,\n type CodeExecutionRequest,\n} from \"@effect-agent/sandbox/CodeExecutor\";\nimport { SandboxImplementation } from \"@effect-agent/sandbox/Sandbox\";\nimport { Clock, Duration, Effect, Fiber, Layer, Option, Queue, Schema } from \"effect\";\n\n/**\n * The deterministic in-process executor substitute (C1 of ADR-0017). It runs\n * the generated program on the host JavaScript engine with best-effort global\n * shadowing only, so it self-identifies as `unisolated` and is never a\n * security boundary (CAP-010, CAP-015). It exists to prove the public\n * `CodeExecutor` contract and to drive deterministic capability tests.\n */\nexport const inProcessCodeExecutorImplementation = SandboxImplementation.make({\n isolation: \"unisolated\",\n identity: \"in-process-javascript\",\n});\n\n// These two caps mirror the wire schema bounds (`BoundedLogs` is at most\n// 4096 lines of at most 16 KiB each): capture must stay inside what\n// `CodeExecutionResult` can carry. A line over the per-line cap is truncated\n// with an explicit `…` marker; exceeding either the byte budget or the line\n// cap fails the pass typed.\nconst MAX_LOG_LINES = 4_096;\nconst MAX_LOG_LINE_CHARACTERS = 16_000;\nconst MAX_THROWN_CHARACTERS = 4_000;\n\nconst utf8ByteLength = (value: string): number => new TextEncoder().encode(value).byteLength;\n\n/**\n * Ambient globals shadowed inside the harness. Shadowing blocks the obvious\n * identifier paths only; a determined program can still escape, which is\n * exactly why this executor reports `unisolated` and the isolated network and\n * CPU enforcement conformance cases run only against isolated adapters.\n */\nconst shadowedGlobals = [\n \"fetch\",\n \"process\",\n \"require\",\n \"module\",\n \"exports\",\n \"global\",\n \"globalThis\",\n \"XMLHttpRequest\",\n \"WebSocket\",\n \"Deno\",\n \"Bun\",\n] as const;\n\nclass LogLimitSignal {\n constructor(readonly observed: number) {}\n}\n\nclass EvaluationThrew {\n constructor(readonly inner: unknown) {}\n}\n\nclass NotAFunction {\n constructor(readonly actual: string) {}\n}\n\ninterface LogCapture {\n readonly lines: Array<string>;\n bytes: number;\n}\n\n/**\n * Total, defect-free rendering of untrusted values: a hostile Proxy can throw\n * from property access, `toString`, and `Symbol.toPrimitive`, and an expected\n * program failure must never escape the typed channel as a defect while its\n * diagnostics are being serialized.\n */\nconst formatLogValue = (value: unknown): string => {\n try {\n if (typeof value === \"string\") {\n return value;\n }\n\n return JSON.stringify(value) ?? String(value);\n } catch {\n try {\n return String(value);\n } catch {\n return \"[unprintable value]\";\n }\n }\n};\n\nconst makeConsole = (capture: LogCapture, limits: CodeExecutionLimits) => {\n const write = (...values: ReadonlyArray<unknown>): void => {\n const joined = values.map(formatLogValue).join(\" \");\n\n const line =\n joined.length > MAX_LOG_LINE_CHARACTERS\n ? `${joined.slice(0, MAX_LOG_LINE_CHARACTERS - 1)}…`\n : joined;\n\n const bytes = utf8ByteLength(line);\n\n if (capture.lines.length >= MAX_LOG_LINES || capture.bytes + bytes > limits.maxLogBytes) {\n throw new LogLimitSignal(capture.bytes + bytes);\n }\n capture.lines.push(line);\n capture.bytes += bytes;\n };\n\n return { debug: write, error: write, info: write, log: write, warn: write };\n};\n\ninterface PendingHostCall {\n readonly namespace: string;\n readonly method: string;\n readonly argument: unknown;\n readonly resolve: (value: unknown) => void;\n readonly reject: (reason: unknown) => void;\n}\n\nconst buildNamespaceObject = (\n namespace: CodeExecutionNamespace,\n offer: (pending: PendingHostCall) => void,\n): Record<string, unknown> => {\n const methods: Record<string, unknown> = {};\n\n for (const method of namespace.methods) {\n methods[method] = (argument: unknown) =>\n new Promise((resolve, reject) => {\n offer({ namespace: namespace.name, method, argument, resolve, reject });\n });\n }\n\n return methods;\n};\n\nconst boundedText = (value: unknown): string => {\n try {\n const text = value instanceof Error ? `${value.name}: ${value.message}` : formatLogValue(value);\n\n return text.slice(0, MAX_THROWN_CHARACTERS);\n } catch {\n return \"[unserializable thrown value]\";\n }\n};\n\n/** Schema decoding of hostile values may itself throw through trap getters. */\nconst safeDecodeJson = (value: unknown): Option.Option<Schema.Json> => {\n try {\n return Schema.decodeUnknownOption(Schema.Json)(value);\n } catch {\n return Option.none();\n }\n};\n\nconst boundedThrown = (value: unknown): Schema.Json => {\n const decoded = safeDecodeJson(value);\n\n if (Option.isSome(decoded)) {\n try {\n const encoded = JSON.stringify(decoded.value);\n\n if (encoded !== undefined && encoded.length <= MAX_THROWN_CHARACTERS) {\n return decoded.value;\n }\n } catch {\n // fall through to the bounded string form\n }\n }\n\n return boundedText(value);\n};\n\nconst encodedJsonByteLength = (value: Schema.Json): number | undefined => {\n try {\n const encoded = JSON.stringify(value);\n\n return encoded === undefined ? undefined : utf8ByteLength(encoded);\n } catch {\n return undefined;\n }\n};\n\n/** Host outcomes are protocol input; a hostile value must not defect mid-decode. */\nconst decodeHostOutcome = (value: unknown): Option.Option<CodeHostCallResult> => {\n try {\n return Schema.decodeUnknownOption(CodeHostCallResult)(value);\n } catch {\n return Option.none();\n }\n};\n\nconst validateRequest = (\n request: CodeExecutionRequest,\n): Effect.Effect<void, CodeExecutorUnsupportedError | CodeSourceError> =>\n Effect.gen(function* () {\n if (request.network._tag !== \"NetworkDisabled\") {\n return yield* CodeExecutorUnsupportedError.make({\n implementation: inProcessCodeExecutorImplementation,\n feature: \"network\",\n message:\n \"The unisolated in-process executor cannot enforce an egress allowlist; only NetworkDisabled is accepted, and even that is shadowed rather than enforced\",\n });\n }\n if (request.limits.cpuMillis !== undefined) {\n return yield* CodeExecutorUnsupportedError.make({\n implementation: inProcessCodeExecutorImplementation,\n feature: \"cpu-limit\",\n message:\n \"The unisolated in-process executor shares the host engine and cannot enforce a CPU limit\",\n });\n }\n const reservedNames = new Set<string>([...shadowedGlobals, \"console\"]);\n const seen = new Set<string>();\n\n for (const namespace of request.namespaces) {\n if (reservedNames.has(namespace.name) || seen.has(namespace.name)) {\n return yield* CodeExecutorUnsupportedError.make({\n implementation: inProcessCodeExecutorImplementation,\n feature: \"namespaces\",\n message: `Namespace ${namespace.name} collides with a harness binding or another namespace`,\n });\n }\n seen.add(namespace.name);\n }\n const sourceBytes = utf8ByteLength(request.source);\n\n if (sourceBytes > request.limits.maxSourceBytes) {\n return yield* CodeSourceError.make({\n implementation: inProcessCodeExecutorImplementation,\n reason: \"oversized\",\n message: `Source is ${sourceBytes} bytes; the request allows ${request.limits.maxSourceBytes}`,\n });\n }\n });\n\nconst serveHostCalls = (\n host: CodeExecutionHost[\"Service\"],\n queue: Queue.Queue<PendingHostCall>,\n limits: CodeExecutionLimits,\n capture: LogCapture,\n counter: { calls: number },\n): Effect.Effect<\n never,\n CodeHostCallLimitError | CodeOutputLimitError | CodeExecutionProtocolError\n> =>\n Effect.gen(function* () {\n while (true) {\n const pending = yield* Queue.take(queue);\n\n counter.calls += 1;\n if (counter.calls > limits.maxHostCalls) {\n return yield* CodeHostCallLimitError.make({\n implementation: inProcessCodeExecutorImplementation,\n limit: limits.maxHostCalls,\n logs: [...capture.lines],\n });\n }\n const argument = safeDecodeJson(pending.argument);\n\n if (Option.isNone(argument)) {\n pending.reject(new TypeError(\"host call arguments must be JSON values\"));\n continue;\n }\n const argumentBytes = encodedJsonByteLength(argument.value);\n\n if (argumentBytes === undefined || argumentBytes > limits.maxHostCallArgumentBytes) {\n return yield* CodeOutputLimitError.make({\n implementation: inProcessCodeExecutorImplementation,\n surface: \"host-call-argument\",\n limit: limits.maxHostCallArgumentBytes,\n observed: argumentBytes ?? 0,\n logs: [...capture.lines],\n });\n }\n\n const rawOutcome = yield* host.call(\n CodeHostCall.make({\n namespace: pending.namespace,\n method: pending.method,\n argument: argument.value,\n }),\n );\n\n const outcome = decodeHostOutcome(rawOutcome);\n\n if (Option.isNone(outcome)) {\n return yield* CodeExecutionProtocolError.make({\n implementation: inProcessCodeExecutorImplementation,\n message: \"The execution host returned a value outside the CodeHostCallResult schema\",\n });\n }\n if (outcome.value._tag === \"CodeHostCallFailure\") {\n pending.reject(outcome.value.error);\n continue;\n }\n const resultBytes = encodedJsonByteLength(outcome.value.value);\n\n if (resultBytes === undefined || resultBytes > limits.maxHostCallResultBytes) {\n return yield* CodeOutputLimitError.make({\n implementation: inProcessCodeExecutorImplementation,\n surface: \"host-call-result\",\n limit: limits.maxHostCallResultBytes,\n observed: resultBytes ?? 0,\n logs: [...capture.lines],\n });\n }\n pending.resolve(outcome.value.value);\n }\n });\n\nconst classifyProgramFailure = (\n thrown: unknown,\n limits: CodeExecutionLimits,\n capture: LogCapture,\n): CodeOutputLimitError | CodeSourceError | CodeProgramFailedError => {\n const inner = thrown instanceof EvaluationThrew ? thrown.inner : thrown;\n\n if (inner instanceof LogLimitSignal) {\n return CodeOutputLimitError.make({\n implementation: inProcessCodeExecutorImplementation,\n surface: \"logs\",\n limit: limits.maxLogBytes,\n observed: inner.observed,\n logs: [...capture.lines],\n });\n }\n if (inner instanceof NotAFunction) {\n return CodeSourceError.make({\n implementation: inProcessCodeExecutorImplementation,\n reason: \"not-a-function\",\n message: `The source expression evaluated to ${inner.actual}; it must evaluate to one async function`,\n });\n }\n // An async function converts a body-level `throw` into a rejection, so the\n // split is by value shape: exception-like values read as `threw`, plain\n // rejection values (an uncaught host failure envelope) read as `rejected`.\n const reason = thrown instanceof EvaluationThrew || inner instanceof Error ? \"threw\" : \"rejected\";\n\n return CodeProgramFailedError.make({\n implementation: inProcessCodeExecutorImplementation,\n reason,\n thrown: boundedThrown(inner),\n message: boundedText(inner),\n logs: [...capture.lines],\n });\n};\n\nconst executeInProcess: CodeExecutorExecute = Effect.fn(\"InProcessCodeExecutor.execute\")(\n function* (request) {\n yield* validateRequest(request);\n const host = yield* CodeExecutionHost;\n const capture: LogCapture = { lines: [], bytes: 0 };\n const counter = { calls: 0 };\n const queue = yield* Queue.unbounded<PendingHostCall>();\n\n const factory = yield* Effect.try({\n try: () =>\n // This substitute intentionally evaluates authored test programs in-process and reports\n // an `unisolated` posture. Real adapters own the security boundary and never use this path.\n // oxlint-disable-next-line typescript/no-implied-eval\n new Function(\n ...shadowedGlobals,\n \"console\",\n ...request.namespaces.map((namespace) => namespace.name),\n `\"use strict\";\\nreturn (\\n${request.source}\\n);`,\n ),\n catch: (cause) =>\n CodeSourceError.make({\n implementation: inProcessCodeExecutorImplementation,\n reason: \"invalid\",\n message: boundedText(cause),\n }),\n });\n\n const harnessConsole = makeConsole(capture, request.limits);\n // Admission is enforced at call creation, not only at the single-consumer\n // dequeue: a burst of unawaited calls can enqueue at most one entry past\n // the cap (the entry the server fails the pass on); everything beyond is\n // rejected synchronously, so the queue stays bounded against hostile\n // programs.\n let issuedHostCalls = 0;\n\n const namespaceObjects = request.namespaces.map((namespace) =>\n buildNamespaceObject(namespace, (pending) => {\n issuedHostCalls += 1;\n if (issuedHostCalls > request.limits.maxHostCalls + 1) {\n pending.reject(new Error(`host-call limit of ${request.limits.maxHostCalls} exceeded`));\n\n return;\n }\n Queue.offerUnsafe(queue, pending);\n }),\n );\n\n const server = yield* serveHostCalls(host, queue, request.limits, capture, counter).pipe(\n Effect.forkScoped,\n );\n\n const program = Effect.tryPromise({\n try: async () => {\n let candidate: unknown;\n\n try {\n candidate = factory(\n ...shadowedGlobals.map(() => undefined),\n harnessConsole,\n ...namespaceObjects,\n );\n } catch (cause) {\n throw new EvaluationThrew(cause);\n }\n if (typeof candidate !== \"function\") {\n throw new EvaluationThrew(new NotAFunction(typeof candidate));\n }\n let outcome: unknown;\n\n try {\n outcome = candidate();\n } catch (cause) {\n throw new EvaluationThrew(cause);\n }\n\n return await Promise.resolve(outcome);\n },\n catch: (thrown) => classifyProgramFailure(thrown, request.limits, capture),\n });\n\n const startedAt = yield* Clock.currentTimeMillis;\n\n // The wall-clock deadline interrupts only at asynchronous suspension\n // points: a synchronous runaway shares the host thread and cannot be\n // stopped in-process — exactly why the platform CPU enforcement cases\n // belong to isolated adapters only (testing spec §8.1). The server fiber\n // is interrupted when the pass settles so no host call outlives the\n // program that issued it.\n const returned = yield* Effect.raceFirst(program, Fiber.join(server)).pipe(\n Effect.timeoutOrElse({\n duration: request.limits.maxWallTime,\n orElse: () =>\n CodeExecutionTimeoutError.make({\n implementation: inProcessCodeExecutorImplementation,\n kind: \"wall-clock\",\n maxWallTime: request.limits.maxWallTime,\n logs: [...capture.lines],\n }),\n }),\n Effect.ensuring(Fiber.interrupt(server)),\n );\n\n const finishedAt = yield* Clock.currentTimeMillis;\n\n // An unawaited burst can outrun the server: the program may return before\n // the over-limit entry is dequeued, so the admission counter is the\n // authority — a pass that ISSUED more calls than the cap fails even when\n // its promise settled first.\n if (issuedHostCalls > request.limits.maxHostCalls) {\n return yield* CodeHostCallLimitError.make({\n implementation: inProcessCodeExecutorImplementation,\n limit: request.limits.maxHostCalls,\n logs: [...capture.lines],\n });\n }\n\n const value = yield* Schema.decodeUnknownEffect(Schema.Json)(returned).pipe(\n Effect.mapError(() =>\n CodeProgramFailedError.make({\n implementation: inProcessCodeExecutorImplementation,\n reason: \"non-json-result\",\n thrown: null,\n message: \"The program must return a JSON value\",\n logs: [...capture.lines],\n }),\n ),\n );\n\n const resultBytes = encodedJsonByteLength(value);\n\n if (resultBytes === undefined || resultBytes > request.limits.maxResultBytes) {\n return yield* CodeOutputLimitError.make({\n implementation: inProcessCodeExecutorImplementation,\n surface: \"result\",\n limit: request.limits.maxResultBytes,\n observed: resultBytes ?? 0,\n logs: [...capture.lines],\n });\n }\n\n return CodeExecutionResult.make({\n implementation: inProcessCodeExecutorImplementation,\n value,\n logs: [...capture.lines],\n resourceUse: CodeExecutionResourceUse.make({\n wallTime: Duration.millis(Math.max(0, finishedAt - startedAt)),\n hostCalls: counter.calls,\n logBytes: capture.bytes,\n resultBytes,\n }),\n });\n },\n);\n\n/**\n * Layer providing the unisolated in-process `CodeExecutor` substitute. The\n * per-pass `CodeExecutionHost` stays in the caller's requirement channel, the\n * same as every real adapter.\n */\nexport const inProcessCodeExecutorLayer: Layer.Layer<CodeExecutor> = Layer.succeed(CodeExecutor)(\n CodeExecutor.of({ execute: executeInProcess }),\n);\n"],"mappings":"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"}
@@ -1,9 +1,16 @@
1
1
  import { Context, Crypto, Effect, Layer, Schema } from "effect";
2
2
  import { Tool, Toolkit } from "effect/unstable/ai";
3
- import { McpConnection, McpConnectionRequest, McpConnector, McpDiscovery, McpServerIdentity, McpToolkitMismatch, RedactionError, Redactor, SubagentPolicy } from "@effect-agent/capabilities";
4
- import { ThreadId } from "@effect-agent/core";
5
- import { RuntimeBinding } from "@effect-agent/engine";
6
- import { DefinitionDigests, DurableSubmitOptions, IdempotencyKey, ResolvedBinding } from "@effect-agent/thread";
3
+ import * as Subagent from "@effect-agent/capabilities/Subagent";
4
+ import { SubagentPolicy } from "@effect-agent/capabilities/Subagent";
5
+ import * as Agent from "@effect-agent/core/Agent";
6
+ import { ThreadId } from "@effect-agent/core/Identifiers";
7
+ import { ResolvedBinding } from "@effect-agent/thread/AgentRegistration";
8
+ import { DurableSubmitOptions } from "@effect-agent/thread/DurableAgentRuntime";
9
+ import { DefinitionDigests } from "@effect-agent/thread/Records";
10
+ import { IdempotencyKey } from "@effect-agent/thread/SubmissionLedger";
11
+ import { RuntimeBinding } from "@effect-agent/engine/AgentRuntime";
12
+ import { McpConnection, McpConnectionRequest, McpConnector, McpDiscovery, McpServerIdentity, McpToolkitMismatch } from "@effect-agent/capabilities/Mcp";
13
+ import { RedactionError, Redactor } from "@effect-agent/capabilities/Redaction";
7
14
  //#region src/fixtures/docs-researcher/definition.d.ts
8
15
  declare const ResearchDocumentId: Schema.brand<Schema.NonEmptyString, "@effect-agent/testing/docs-researcher/ResearchDocumentId">;
9
16
  type ResearchDocumentId = typeof ResearchDocumentId.Type;
@@ -74,7 +81,7 @@ declare class DocumentSummary extends DocumentSummary_base {}
74
81
  /** The summary the scripted child writes after fetching the document. */
75
82
  declare const documentSummaryFor: (documentId: string) => DocumentSummary;
76
83
  declare const encodedDocumentSummary: (documentId: string) => string;
77
- declare const DocSummarizer: import("@effect-agent/core").Definition<typeof SummaryBrief, typeof DocumentSummary, "Fetch the briefed document with fetch_document exactly once, then return only a JSON document summary. Never copy raw notes or secrets into the summary.", Toolkit.Toolkit<{
84
+ declare const DocSummarizer: Agent.Definition<typeof SummaryBrief, typeof DocumentSummary, "Fetch the briefed document with fetch_document exactly once, then return only a JSON document summary. Never copy raw notes or secrets into the summary.", Toolkit.Toolkit<{
78
85
  readonly fetch_document: Tool.Tool<"fetch_document", {
79
86
  readonly parameters: typeof DocumentQuery;
80
87
  readonly success: typeof ResearchDocument;
@@ -97,7 +104,7 @@ declare const DocumentSummaryFailed_base: Schema.Class<DocumentSummaryFailed, Sc
97
104
  declare class DocumentSummaryFailed extends DocumentSummaryFailed_base {}
98
105
  /** Finite per-invocation bounds (SUB-009): one fetch per child, two children per Run. */
99
106
  declare const documentSummaryPolicy: SubagentPolicy;
100
- declare const delegateDocumentSummary: import("@effect-agent/capabilities").SubagentDelegation<"delegate_document_summary", typeof SummaryBrief, typeof DocumentSummary, "Fetch the briefed document with fetch_document exactly once, then return only a JSON document summary. Never copy raw notes or secrets into the summary.", {
107
+ declare const delegateDocumentSummary: Subagent.SubagentDelegation<"delegate_document_summary", typeof SummaryBrief, typeof DocumentSummary, "Fetch the briefed document with fetch_document exactly once, then return only a JSON document summary. Never copy raw notes or secrets into the summary.", {
101
108
  readonly fetch_document: Tool.Tool<"fetch_document", {
102
109
  readonly parameters: typeof DocumentQuery;
103
110
  readonly success: typeof ResearchDocument;
@@ -105,7 +112,7 @@ declare const delegateDocumentSummary: import("@effect-agent/capabilities").Suba
105
112
  readonly failureMode: "error";
106
113
  }, DocumentLibrary>;
107
114
  }, typeof SummaryRequest, typeof SummaryFinding, typeof DocumentSummaryFailed, never, never, "error"> & {
108
- readonly target: import("@effect-agent/core").Definition<typeof SummaryBrief, typeof DocumentSummary, "Fetch the briefed document with fetch_document exactly once, then return only a JSON document summary. Never copy raw notes or secrets into the summary.", Toolkit.Toolkit<{
115
+ readonly target: Agent.Definition<typeof SummaryBrief, typeof DocumentSummary, "Fetch the briefed document with fetch_document exactly once, then return only a JSON document summary. Never copy raw notes or secrets into the summary.", Toolkit.Toolkit<{
109
116
  readonly fetch_document: Tool.Tool<"fetch_document", {
110
117
  readonly parameters: typeof DocumentQuery;
111
118
  readonly success: typeof ResearchDocument;
@@ -125,7 +132,7 @@ declare const docsSummarizerDigestStrings: {
125
132
  readonly tools: string;
126
133
  };
127
134
  /** Runtime wiring: the immutable delegation plus one explicit child Binding (S2 declaration). */
128
- declare const docsSummaryHandlersLayer: <Provider, ModelProvides, ModelRequires>(childBinding: RuntimeBinding<typeof SummaryBrief, typeof DocumentSummary, string, Toolkit.Tools<typeof DocContentToolkit>, Provider, ModelProvides, ModelRequires>) => import("effect/Layer").Layer<Tool.Handler<"delegate_document_summary">, never, import("@effect-agent/capabilities").SubagentLayerRequirements<typeof SummaryBrief, typeof DocumentSummary, string, {
135
+ declare const docsSummaryHandlersLayer: <Provider, ModelProvides, ModelRequires>(childBinding: RuntimeBinding<typeof SummaryBrief, typeof DocumentSummary, string, Toolkit.Tools<typeof DocContentToolkit>, Provider, ModelProvides, ModelRequires>) => import("effect/Layer").Layer<Tool.Handler<"delegate_document_summary">, never, Subagent.SubagentLayerRequirements<typeof SummaryBrief, typeof DocumentSummary, string, {
129
136
  readonly fetch_document: Tool.Tool<"fetch_document", {
130
137
  readonly parameters: typeof DocumentQuery;
131
138
  readonly success: typeof ResearchDocument;
@@ -152,17 +159,17 @@ declare const DocsResearcherToolkit: Toolkit.Toolkit<{
152
159
  readonly delegate_document_summary: Tool.Tool<"delegate_document_summary", {
153
160
  readonly parameters: typeof SummaryRequest;
154
161
  readonly success: typeof SummaryFinding;
155
- readonly failure: import("@effect-agent/capabilities").SubagentToolFailure<typeof DocumentSummaryFailed>;
162
+ readonly failure: Subagent.SubagentToolFailure<typeof DocumentSummaryFailed>;
156
163
  readonly failureMode: "error";
157
- }, import("@effect-agent/engine").AgentSpawner | import("@effect-agent/core").IdGenerator | import("@effect-agent/engine").RunEventSink | import("@effect-agent/engine").SubagentDurability>;
164
+ }, import("@effect-agent/engine/AgentRuntime").AgentSpawner | import("@effect-agent/core/IdGenerator").IdGenerator | import("@effect-agent/engine/RunEventSink").RunEventSink | import("@effect-agent/engine/AgentRuntime").SubagentDurability>;
158
165
  }>;
159
- declare const DocsResearcher: import("@effect-agent/core").Definition<typeof ResearchRequest, typeof ResearchDigest, string, Toolkit.Toolkit<{
166
+ declare const DocsResearcher: Agent.Definition<typeof ResearchRequest, typeof ResearchDigest, string, Toolkit.Toolkit<{
160
167
  readonly delegate_document_summary: Tool.Tool<"delegate_document_summary", {
161
168
  readonly parameters: typeof SummaryRequest;
162
169
  readonly success: typeof SummaryFinding;
163
- readonly failure: import("@effect-agent/capabilities").SubagentToolFailure<typeof DocumentSummaryFailed>;
170
+ readonly failure: Subagent.SubagentToolFailure<typeof DocumentSummaryFailed>;
164
171
  readonly failureMode: "error";
165
- }, import("@effect-agent/engine").AgentSpawner | import("@effect-agent/core").IdGenerator | import("@effect-agent/engine").RunEventSink | import("@effect-agent/engine").SubagentDurability>;
172
+ }, import("@effect-agent/engine/AgentRuntime").AgentSpawner | import("@effect-agent/core/IdGenerator").IdGenerator | import("@effect-agent/engine/RunEventSink").RunEventSink | import("@effect-agent/engine/AgentRuntime").SubagentDurability>;
166
173
  }>, undefined, undefined>;
167
174
  /** The default two-document research mission. */
168
175
  declare const researchMissionRequest: ResearchRequest;
@@ -221,7 +228,7 @@ interface DocsResearcherHarness {
221
228
  * at assembly, not assumed. Content-tool execution then flows through the
222
229
  * counting `DocumentLibrary` — the scripted MCP server's content store.
223
230
  */
224
- declare const makeDocsResearcherHarness: (options?: DocsResearcherHarnessOptions) => Effect.Effect<DocsResearcherHarness, import("@effect-agent/capabilities").McpConnectionError | import("@effect-agent/capabilities").McpDiscoveryLimitExceeded | import("@effect-agent/capabilities").McpToolkitMismatch, Crypto.Crypto>;
231
+ declare const makeDocsResearcherHarness: (options?: DocsResearcherHarnessOptions) => Effect.Effect<DocsResearcherHarness, import("@effect-agent/capabilities/Mcp").McpConnectionError | import("@effect-agent/capabilities/Mcp").McpDiscoveryLimitExceeded | import("@effect-agent/capabilities/Mcp").McpToolkitMismatch, Crypto.Crypto>;
225
232
  /**
226
233
  * The audit-surface preview of one fetched document: the raw document —
227
234
  * secret marker and all — passes through the configured structural `Redactor`
@@ -259,5 +266,5 @@ declare const DocsMcpDiscoveryEvidence: Schema.Struct<{
259
266
  readonly toolkitSchemaDigest: Schema.String;
260
267
  }>;
261
268
  //#endregion
262
- export { BoundedSummary, DocContentToolkit, DocSummarizer, DocsMcpDiscoveryEvidence, DocsResearcher, DocsResearcherHarness, DocsResearcherHarnessOptions, DocsResearcherHarnessRequirements, DocsResearcherToolkit, DocumentLibrary, DocumentQuery, DocumentSummary, DocumentSummaryFailed, DocumentUnavailable, FetchDocument, ResearchDigest, ResearchDocument, ResearchDocumentId, ResearchRequest, SummaryBrief, SummaryFinding, SummaryRequest, assertDiscoveryMatchesAuthoredToolkit, delegateDocumentSummary, docContentToolkitLayer, docsCoordinatorConfidentialMarker, docsCoordinatorDigests, docsDocumentBodySecret, docsMcpConnectorLayer, docsMcpIdentity, docsMcpMismatchedConnectorLayer, docsMcpOversizedConnectorLayer, docsMcpRequest, docsMissionConfidentialMarker, docsResearcherDeploymentId, docsResearcherPrincipal, docsResearcherProducerId, docsResearcherSubmitAgent, docsResearcherSubmitOptions, docsSummarizerDigestStrings, docsSummarizerDigests, docsSummaryHandlersLayer, documentBodyPhrase, documentSummaryFor, documentSummaryPolicy, encodedDocumentSummary, expectedResearchDigest, fetchCallId, makeDocsResearcherHarness, mapSummaryChildFailure, redactedDocumentPreview, researchCorpusDocumentIds, researchDocumentFor, researchDocumentLookup, researchMissionRequest, summarizeCallId };
263
- //# sourceMappingURL=docs-researcher.d.mts.map
269
+ export { BoundedSummary, DocContentToolkit, DocSummarizer, DocsMcpDiscoveryEvidence, DocsResearcher, type DocsResearcherHarness, type DocsResearcherHarnessOptions, type DocsResearcherHarnessRequirements, DocsResearcherToolkit, DocumentLibrary, DocumentQuery, DocumentSummary, DocumentSummaryFailed, DocumentUnavailable, FetchDocument, ResearchDigest, ResearchDocument, ResearchDocumentId, ResearchRequest, SummaryBrief, SummaryFinding, SummaryRequest, assertDiscoveryMatchesAuthoredToolkit, delegateDocumentSummary, docContentToolkitLayer, docsCoordinatorConfidentialMarker, docsCoordinatorDigests, docsDocumentBodySecret, docsMcpConnectorLayer, docsMcpIdentity, docsMcpMismatchedConnectorLayer, docsMcpOversizedConnectorLayer, docsMcpRequest, docsMissionConfidentialMarker, docsResearcherDeploymentId, docsResearcherPrincipal, docsResearcherProducerId, docsResearcherSubmitAgent, docsResearcherSubmitOptions, docsSummarizerDigestStrings, docsSummarizerDigests, docsSummaryHandlersLayer, documentBodyPhrase, documentSummaryFor, documentSummaryPolicy, encodedDocumentSummary, expectedResearchDigest, fetchCallId, makeDocsResearcherHarness, mapSummaryChildFailure, redactedDocumentPreview, researchCorpusDocumentIds, researchDocumentFor, researchDocumentLookup, researchMissionRequest, summarizeCallId };
270
+ //# sourceMappingURL=DocsResearcher.d.mts.map
@@ -1,9 +1,19 @@
1
- import { a as DeterministicIdGeneratorLayer } from "./deterministic-layers-CKyYxBhN.mjs";
1
+ import { a as DeterministicIdGeneratorLayer } from "./deterministic-layers-Eka0fMZq.mjs";
2
2
  import { Context, Effect, JsonPointer, Layer, Ref, Schema, Stream } from "effect";
3
3
  import { LanguageModel, Model, Tool, Toolkit } from "effect/unstable/ai";
4
- import { McpConnectionRequest, McpConnector, McpServerIdentity, McpToolkitMismatch, Redactor, Subagent, SubagentPolicy, SubagentReservationsMemoryLive, SubagentRuntime, connectMcp } from "@effect-agent/capabilities";
5
- import { Agent, AgentPolicy } from "@effect-agent/core";
6
- import { DefinitionDigests, DeploymentId, Digest, DurableWorkerBinding, Principal, ProducerId } from "@effect-agent/thread";
4
+ import * as Subagent from "@effect-agent/capabilities/Subagent";
5
+ import { SubagentPolicy, SubagentRuntime } from "@effect-agent/capabilities/Subagent";
6
+ import { SubagentReservationsMemoryLive } from "@effect-agent/capabilities/SubagentReservations";
7
+ import * as Agent from "@effect-agent/core/Agent";
8
+ import { AgentPolicy } from "@effect-agent/core/AgentPolicy";
9
+ import "@effect-agent/core/Identifiers";
10
+ import { DurableWorkerBinding } from "@effect-agent/thread/AgentRegistration";
11
+ import "@effect-agent/thread/DurableAgentRuntime";
12
+ import { DefinitionDigests, DeploymentId, Digest, ProducerId } from "@effect-agent/thread/Records";
13
+ import { Principal } from "@effect-agent/thread/SubmissionLedger";
14
+ import "@effect-agent/engine/AgentRuntime";
15
+ import { McpConnectionRequest, McpConnector, McpServerIdentity, McpToolkitMismatch, connectMcp } from "@effect-agent/capabilities/Mcp";
16
+ import { Redactor } from "@effect-agent/capabilities/Redaction";
7
17
  import * as McpSchema from "effect/unstable/ai/McpSchema";
8
18
  //#region src/fixtures/docs-researcher/definition.ts
9
19
  const ResearchDocumentId = Schema.NonEmptyString.check(Schema.isMaxLength(64)).pipe(Schema.brand("@effect-agent/testing/docs-researcher/ResearchDocumentId"));
@@ -477,4 +487,4 @@ const redactedDocumentPreview = Effect.fn("DocsResearcher.redactedDocumentPrevie
477
487
  //#endregion
478
488
  export { BoundedSummary, DocContentToolkit, DocSummarizer, DocsMcpDiscoveryEvidence, DocsResearcher, DocsResearcherToolkit, DocumentLibrary, DocumentQuery, DocumentSummary, DocumentSummaryFailed, DocumentUnavailable, FetchDocument, ResearchDigest, ResearchDocument, ResearchDocumentId, ResearchRequest, SummaryBrief, SummaryFinding, SummaryRequest, assertDiscoveryMatchesAuthoredToolkit, delegateDocumentSummary, docContentToolkitLayer, docsCoordinatorConfidentialMarker, docsCoordinatorDigests, docsDocumentBodySecret, docsMcpConnectorLayer, docsMcpIdentity, docsMcpMismatchedConnectorLayer, docsMcpOversizedConnectorLayer, docsMcpRequest, docsMissionConfidentialMarker, docsResearcherDeploymentId, docsResearcherPrincipal, docsResearcherProducerId, docsResearcherSubmitAgent, docsResearcherSubmitOptions, docsSummarizerDigestStrings, docsSummarizerDigests, docsSummaryHandlersLayer, documentBodyPhrase, documentSummaryFor, documentSummaryPolicy, encodedDocumentSummary, expectedResearchDigest, fetchCallId, makeDocsResearcherHarness, mapSummaryChildFailure, redactedDocumentPreview, researchCorpusDocumentIds, researchDocumentFor, researchDocumentLookup, researchMissionRequest, summarizeCallId };
479
489
 
480
- //# sourceMappingURL=docs-researcher.mjs.map
490
+ //# sourceMappingURL=DocsResearcher.mjs.map