| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260 |
- import { describe, expect, test } from "bun:test"
- import { Cause, Effect, Schema } from "effect"
- import { CodeMode, Tool, toolError } from "../src/index.js"
- const run = (tool: Tool.Definition<never>) =>
- Effect.runPromise(CodeMode.make({ tools: { host: { call: tool } } }).execute("return await tools.host.call({})"))
- class UnsafeHostError extends Schema.TaggedErrorClass<UnsafeHostError>()("UnsafeHostError", {
- reason: Schema.String,
- }) {}
- describe("CodeMode host failure boundary", () => {
- test("preserves explicit safe tool failures", async () => {
- const result = await run(
- Tool.make({
- description: "Fail safely",
- input: Schema.Struct({}),
- output: Schema.String,
- run: () => Effect.fail(toolError("Authorized request was refused")),
- }),
- )
- expect(result.ok ? undefined : result.error).toStrictEqual({
- kind: "ToolFailure",
- message: "Authorized request was refused",
- })
- })
- test("does not rewrite explicit safe tool failures", async () => {
- const result = await run(
- Tool.make({
- description: "Fail safely",
- input: Schema.Struct({}),
- output: Schema.String,
- run: () => Effect.fail(toolError("File not found: /tmp/report.json")),
- }),
- )
- expect(result.ok ? undefined : result.error).toStrictEqual({
- kind: "ToolFailure",
- message: "File not found: /tmp/report.json",
- })
- })
- test("sanitizes unknown host failures and defects", async () => {
- for (const failure of [
- Effect.fail(new UnsafeHostError({ reason: "Authorization: Bearer typed-secret" })),
- Effect.die(new Error("postgres://user:defect-secret@example.invalid")),
- ]) {
- const result = await run(
- Tool.make({
- description: "Fail internally",
- input: Schema.Struct({}),
- output: Schema.String,
- run: () => failure,
- }),
- )
- expect(result.ok ? undefined : result.error).toStrictEqual({
- kind: "ToolFailure",
- message: "Tool execution failed",
- })
- expect(JSON.stringify(result)).not.toMatch(/typed-secret|defect-secret|Authorization: Bearer/)
- }
- })
- test("sanitizes invalid host output", async () => {
- const secret = "invalid-output-secret"
- const result = await run(
- Tool.make({
- description: "Return invalid output",
- input: Schema.Struct({}),
- output: Schema.Struct({ safe: Schema.String }),
- run: () => Effect.succeed({ safe: 1, secret } as unknown as { readonly safe: string }),
- }),
- )
- expect(result.ok ? undefined : result.error).toStrictEqual({
- kind: "InvalidToolOutput",
- message: "Invalid output from tool 'host.call'.",
- })
- expect(JSON.stringify(result)).not.toMatch(/invalid-output-secret/)
- })
- test("sanitizes host output that throws while being copied", async () => {
- const result = await run(
- Tool.make({
- description: "Return hostile output",
- input: Schema.Struct({}),
- output: Schema.Unknown,
- run: () =>
- Effect.succeed(
- new Proxy(
- {},
- {
- ownKeys: () => {
- throw new Error("host-output-secret")
- },
- },
- ),
- ),
- }),
- )
- expect(result.ok ? undefined : result.error).toStrictEqual({
- kind: "InvalidToolOutput",
- message: "Invalid output from tool 'host.call'.",
- })
- expect(JSON.stringify(result)).not.toMatch(/host-output-secret/)
- })
- test("caught tool failures are Error values in-program", async () => {
- const result = await Effect.runPromise(
- CodeMode.make({
- tools: {
- host: {
- call: Tool.make({
- description: "Refuse",
- input: Schema.Struct({}),
- output: Schema.String,
- run: () => Effect.fail(toolError("Refused")),
- }),
- },
- },
- }).execute(`
- try {
- await tools.host.call({})
- return "no"
- } catch (e) {
- return { isError: e instanceof Error, message: e.message }
- }
- `),
- )
- expect(result.ok).toBe(true)
- if (result.ok) expect(result.value).toStrictEqual({ isError: true, message: "Refused" })
- })
- test("propagates host interruption instead of returning a diagnostic", async () => {
- const exit = await Effect.runPromiseExit(
- CodeMode.make({
- tools: {
- host: {
- call: Tool.make({
- description: "Interrupt",
- input: Schema.Struct({}),
- output: Schema.String,
- run: () => Effect.interrupt,
- }),
- },
- },
- }).execute("return await tools.host.call({})"),
- )
- expect(exit._tag).toBe("Failure")
- if (exit._tag === "Failure") {
- expect(Cause.hasInterruptsOnly(exit.cause)).toBe(true)
- }
- })
- })
- describe("CodeMode tool-call observation", () => {
- test("reports the tools actually invoked with decoded input", async () => {
- const calls: Array<unknown> = []
- const lookup = Tool.make({
- description: "Look up a value",
- input: Schema.Struct({ query: Schema.String }),
- output: Schema.String,
- run: ({ query }) => Effect.succeed(query),
- })
- const result = await Effect.runPromise(
- CodeMode.make({
- tools: { context: { lookup } },
- onToolCallStart: (call) => Effect.sync(() => calls.push(call)),
- }).execute(`
- if (false) await tools.context.lookup({ query: "not called" })
- return await tools.context.lookup({ query: "deployment failure" })
- `),
- )
- expect(result.ok).toBe(true)
- expect(calls).toStrictEqual([{ index: 0, name: "context.lookup", input: { query: "deployment failure" } }])
- })
- test("observes settled calls with outcome and duration", async () => {
- const events: Array<{ phase: string; index: number; name: string; outcome?: string; message?: string }> = []
- const lookup = Tool.make({
- description: "Look up a value",
- input: Schema.Struct({ query: Schema.String }),
- output: Schema.String,
- run: ({ query }) => (query === "boom" ? Effect.fail(toolError("Lookup refused")) : Effect.succeed(query)),
- })
- const runtime = CodeMode.make({
- tools: { context: { lookup } },
- onToolCallStart: (call) =>
- Effect.sync(() => {
- events.push({ phase: "start", index: call.index, name: call.name })
- }),
- onToolCallEnd: (call) =>
- Effect.sync(() => {
- expect(call.durationMs).toBeGreaterThanOrEqual(0)
- events.push({
- phase: "end",
- index: call.index,
- name: call.name,
- outcome: call.outcome,
- ...(call.message === undefined ? {} : { message: call.message }),
- })
- }),
- })
- const success = await Effect.runPromise(runtime.execute(`return await tools.context.lookup({ query: "ok" })`))
- expect(success.ok).toBe(true)
- const failure = await Effect.runPromise(runtime.execute(`return await tools.context.lookup({ query: "boom" })`))
- expect(failure.ok).toBe(false)
- expect(events).toStrictEqual([
- { phase: "start", index: 0, name: "context.lookup" },
- { phase: "end", index: 0, name: "context.lookup", outcome: "success" },
- { phase: "start", index: 0, name: "context.lookup" },
- { phase: "end", index: 0, name: "context.lookup", outcome: "failure", message: "Lookup refused" },
- ])
- })
- })
- describe("CodeMode console capture", () => {
- test("captures console output as bounded result logs", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- const returned = console.log("Thread info:", { name: "Demo", count: 2 })
- console.warn("careful")
- return returned
- `,
- }),
- )
- expect(result).toStrictEqual({
- ok: true,
- value: null,
- logs: ['Thread info: {"name":"Demo","count":2}', "[warn] careful"],
- toolCalls: [],
- })
- expect(Schema.decodeUnknownSync(CodeMode.Result)(JSON.parse(JSON.stringify(result)))).toStrictEqual(result)
- })
- test("keeps logs captured before failures", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.log("before failure")
- throw new Error("boom")
- `,
- }),
- )
- expect(result.ok ? undefined : result.logs).toStrictEqual(["before failure"])
- expect(result.ok ? undefined : result.error.message).toBe("Uncaught: boom")
- })
- test("prints NaN and Infinity literally instead of the JSON null", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.log(NaN)
- console.log(Infinity, -Infinity)
- console.log({ ratio: NaN, bounds: [Infinity] })
- return null
- `,
- }),
- )
- expect(result.ok).toBe(true)
- expect(result.logs).toStrictEqual(["NaN", "Infinity -Infinity", '{"ratio":NaN,"bounds":[Infinity]}'])
- })
- test("renders CodeMode values nested inside logged containers", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.log({ m: new Map([["a", 1]]), when: new Date(0), r: /ab/g, s: new Set([1, 2]) })
- console.log([new Date(0)])
- return null
- `,
- }),
- )
- expect(result.ok).toBe(true)
- expect(result.logs).toStrictEqual([
- '{"m":Map(1) [["a",1]],"when":1970-01-01T00:00:00.000Z,"r":/ab/g,"s":Set(2) [1,2]}',
- "[1970-01-01T00:00:00.000Z]",
- ])
- })
- test("console formatting is total: cycles and opaque references render as markers", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- const m = new Map()
- m.set("self", m)
- console.log({ box: m })
- console.log({ fn: (x) => x, ok: 1 })
- return null
- `,
- }),
- )
- expect(result.ok).toBe(true)
- expect(result.logs).toStrictEqual(['{"box":Map(1) [["self",[Circular]]]}', '{"fn":[opaque reference],"ok":1}'])
- })
- test("console.table renders CodeMode value cells", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.table([{ when: new Date(0), n: NaN }])
- return null
- `,
- }),
- )
- expect(result.ok).toBe(true)
- expect(result.logs).toStrictEqual(["(index)\twhen\tn\n0\t1970-01-01T00:00:00.000Z\tNaN"])
- })
- test("captures console.dir and console.table output", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.dir({ nested: { ok: true } })
- console.table([
- { name: "Kit", count: 1, hidden: "x" },
- { name: "Olive", count: 2, hidden: "y" }
- ], ["name", "count"])
- return "done"
- `,
- }),
- )
- expect(result).toStrictEqual({
- ok: true,
- value: "done",
- logs: ['{"nested":{"ok":true}}', "(index)\tname\tcount\n0\tKit\t1\n1\tOlive\t2"],
- toolCalls: [],
- })
- })
- })
- describe("CodeMode output budget", () => {
- test("absent maxOutputBytes means no truncation at all", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `console.log("z".repeat(50_000)); return "x".repeat(100_000)`,
- }),
- )
- expect(result.ok).toBe(true)
- if (!result.ok) return
- expect(result.truncated).toBeUndefined()
- expect(result.value).toBe("x".repeat(100_000))
- expect(result.logs).toStrictEqual(["z".repeat(50_000)])
- })
- test("truncates an oversized result value with a marker instead of failing", async () => {
- const limits: CodeMode.ExecutionLimits = { maxOutputBytes: 40 }
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `return { data: "${"x".repeat(200)}" }`,
- limits,
- }),
- )
- expect(result.ok).toBe(true)
- if (!result.ok) return
- expect(result.truncated).toBe(true)
- expect(typeof result.value).toBe("string")
- expect(result.value).toMatch(
- /^\{"data":"x+ \[result truncated: \d+ bytes exceeds the 40-byte output limit; return a smaller value\]$/,
- )
- expect(Schema.decodeUnknownSync(CodeMode.Result)(JSON.parse(JSON.stringify(result)))).toStrictEqual(result)
- })
- test("keeps leading logs within the remaining budget and marks the cut", async () => {
- const limits: CodeMode.ExecutionLimits = { maxOutputBytes: 40 }
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.log("first line")
- console.log("${"y".repeat(200)}")
- return "ok"
- `,
- limits,
- }),
- )
- expect(result.ok).toBe(true)
- if (!result.ok) return
- expect(result.value).toBe("ok")
- expect(result.truncated).toBe(true)
- expect(result.logs).toStrictEqual(["first line", "[logs truncated: showing 1 of 2 lines]"])
- })
- test("does not mark results within the budget", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `
- console.log("fits")
- return { fits: true }
- `,
- }),
- )
- expect(result).toStrictEqual({
- ok: true,
- value: { fits: true },
- logs: ["fits"],
- toolCalls: [],
- })
- })
- })
- describe("CodeMode schema flexibility", () => {
- test("accepts render-only JSON Schema input and omitted output", async () => {
- const observed: Array<unknown> = []
- const call = Tool.make({
- description: "Call an adapter-described tool",
- input: {
- type: "object",
- properties: { id: { type: "string" }, count: { type: "number" } },
- required: ["id"],
- },
- run: (input) =>
- Effect.sync(() => {
- observed.push(input)
- return { echoed: input }
- }),
- })
- const runtime = CodeMode.make({ tools: { adapter: { call } } })
- expect(runtime.catalog()).toStrictEqual([
- {
- path: "adapter.call",
- description: "Call an adapter-described tool",
- signature: "tools.adapter.call(input: {\n id: string,\n count?: number,\n}): Promise<unknown>",
- },
- ])
- // JSON Schema is render-only: mistyped input passes through unvalidated.
- const result = await Effect.runPromise(runtime.execute(`return await tools.adapter.call({ id: 42 })`))
- expect(result.ok).toBe(true)
- if (result.ok) expect(result.value).toStrictEqual({ echoed: { id: 42 } })
- expect(observed).toStrictEqual([{ id: 42 }])
- })
- test("outbound tool arguments follow JSON serialization semantics", async () => {
- const observed: Array<unknown> = []
- const call = Tool.make({
- description: "Observe raw input",
- input: { type: "object" },
- run: (input) =>
- Effect.sync(() => {
- observed.push(input)
- return "ok"
- }),
- })
- const runtime = CodeMode.make({ tools: { adapter: { call } } })
- const result = await Effect.runPromise(
- runtime.execute(
- `return await tools.adapter.call({ q: undefined, limit: 0 / 0, rate: 1 / 0, items: [1, undefined, 2], holes: [1, , 3] })`,
- ),
- )
- expect(result.ok).toBe(true)
- const received = observed[0] as Record<string, unknown>
- expect(received).toStrictEqual({ limit: null, rate: null, items: [1, null, 2], holes: [1, null, 3] })
- // The undefined-valued property is dropped like JSON.stringify, not delivered as undefined.
- expect(Object.hasOwn(received, "q")).toBe(false)
- })
- test("dropping undefined values lets optionalKey schemas accept conditional arguments", async () => {
- const observed: Array<unknown> = []
- const find = Tool.make({
- description: "Find things",
- input: Schema.Struct({ query: Schema.optionalKey(Schema.String), limit: Schema.optionalKey(Schema.Number) }),
- run: (input) =>
- Effect.sync(() => {
- observed.push(input)
- return "ok"
- }),
- })
- const runtime = CodeMode.make({ tools: { things: { find } } })
- // The `cond ? value : undefined` idiom: optionalKey rejects a present undefined, so the
- // JSON boundary must drop the key before the schema decodes.
- const result = await Effect.runPromise(
- runtime.execute(`return await tools.things.find({ query: undefined, limit: 5 })`),
- )
- expect(result.ok).toBe(true)
- expect(observed).toStrictEqual([{ limit: 5 }])
- const search = await Effect.runPromise(runtime.execute(`return (await search({ query: undefined })).items.length`))
- expect(search.ok).toBe(true)
- })
- test("renders JSON Schema outputs and $defs references", async () => {
- const lookup = Tool.make({
- description: "Look up a user",
- input: { type: "object", properties: { login: { type: "string" } }, required: ["login"] },
- output: {
- $ref: "#/$defs/User",
- $defs: {
- User: {
- type: "object",
- properties: { login: { type: "string" }, id: { type: "number" } },
- required: ["login", "id"],
- },
- },
- },
- run: () => Effect.succeed({ login: "kit", id: 7 }),
- })
- const runtime = CodeMode.make({ tools: { users: { lookup } } })
- expect(runtime.catalog()).toStrictEqual([
- {
- path: "users.lookup",
- description: "Look up a user",
- signature: "tools.users.lookup(input: {\n login: string,\n}): Promise<{\n login: string,\n id: number,\n}>",
- },
- ])
- const result = await Effect.runPromise(runtime.execute(`return await tools.users.lookup({ login: "kit" })`))
- expect(result.ok).toBe(true)
- if (result.ok) expect(result.value).toStrictEqual({ login: "kit", id: 7 })
- })
- test("Effect Schema output without an input transform still renders unknown when omitted", async () => {
- const ping = Tool.make({
- description: "Ping",
- input: Schema.Struct({ host: Schema.String }),
- run: () => Effect.succeed("pong"),
- })
- const runtime = CodeMode.make({ tools: { net: { ping } } })
- expect(runtime.catalog()[0]?.signature).toBe("tools.net.ping(input: {\n host: string,\n}): Promise<unknown>")
- const result = await Effect.runPromise(runtime.execute(`return await tools.net.ping({ host: "example.test" })`))
- expect(result.ok).toBe(true)
- if (result.ok) expect(result.value).toBe("pong")
- })
- })
- describe("CodeMode public contract", () => {
- const lookup = Tool.make({
- description: "Look up an order by ID",
- input: Schema.Struct({ id: Schema.String }),
- output: Schema.Struct({ id: Schema.String, status: Schema.String }),
- run: ({ id }) => Effect.succeed({ id, status: "open" }),
- })
- const tools = { orders: { lookup } }
- const source = `return await tools.orders.lookup({ id: "order_42" })`
- test("keeps one-shot and reusable execution equivalent", async () => {
- const runtime = CodeMode.make({ tools })
- const [oneShot, reusable] = await Promise.all([
- Effect.runPromise(CodeMode.execute({ tools, code: source })),
- Effect.runPromise(runtime.execute(source)),
- ])
- expect(reusable).toStrictEqual(oneShot)
- const input: CodeMode.Input = { code: source }
- expect(Schema.decodeUnknownSync(CodeMode.Input)(input)).toStrictEqual(input)
- expect(Schema.decodeUnknownSync(CodeMode.Result)(JSON.parse(JSON.stringify(reusable)))).toStrictEqual(reusable)
- })
- test("a reused execution Effect starts from a clean slate", async () => {
- const echo = Tool.make({
- description: "echo",
- input: Schema.Struct({}),
- output: Schema.Number,
- run: () => Effect.succeed(1),
- })
- const effect = CodeMode.execute({
- tools: { host: { echo } },
- code: `console.log("hi"); return await tools.host.echo({})`,
- limits: { maxToolCalls: 1 },
- })
- const first = await Effect.runPromise(effect)
- const second = await Effect.runPromise(effect)
- // Per-execution state (tool-call budget and audit list, logs, timeout bookkeeping) must
- // bind at run time, so the second run neither exhausts the budget nor leaks run 1's logs.
- expect(first).toStrictEqual(second)
- expect(second).toStrictEqual({ ok: true, value: 1, logs: ["hi"], toolCalls: [{ name: "host.echo" }] })
- })
- test("inlines a COMPLETE small catalog and keeps search registered but unadvertised", async () => {
- const runtime = CodeMode.make({ tools })
- expect(runtime.catalog()).toStrictEqual([
- {
- path: "orders.lookup",
- description: "Look up an order by ID",
- signature: "tools.orders.lookup(input: {\n id: string,\n}): Promise<{\n id: string,\n status: string,\n}>",
- },
- ])
- expect(runtime.instructions()).toContain("Available tools (COMPLETE list")
- expect(runtime.instructions()).toContain("- orders (1 tool)")
- expect(runtime.instructions()).toContain(
- " - tools.orders.lookup(input: {\n id: string,\n}): Promise<{\n id: string,\n status: string,\n}> // Look up an order by ID",
- )
- // A fully inlined catalog does not advertise search in the instructions...
- expect(runtime.instructions()).not.toContain("search(")
- // ...but the search built-in stays available, so a speculative call still works with the
- // same signature as the inline catalog.
- const result = await Effect.runPromise(runtime.execute(`return search({ query: "order" })`))
- expect(result.ok).toBe(true)
- if (result.ok) {
- expect(result.value).toStrictEqual({
- items: [
- {
- path: "tools.orders.lookup",
- description: "Look up an order by ID",
- signature:
- "tools.orders.lookup(input: {\n id: string,\n}): Promise<{\n id: string,\n status: string,\n}>",
- },
- ],
- remaining: 0,
- next: null,
- })
- }
- })
- test("renders bracket notation for tool names that are not JavaScript identifiers", async () => {
- const resolveLibrary = Tool.make({
- description: "Resolve a library ID",
- input: Schema.Struct({ libraryName: Schema.String }),
- output: Schema.String,
- run: ({ libraryName }) => Effect.succeed(`/resolved/${libraryName}`),
- })
- const runtime = CodeMode.make({ tools: { context7: { "resolve-library-id": resolveLibrary } } })
- expect(runtime.catalog()).toStrictEqual([
- {
- path: "context7.resolve-library-id",
- description: "Resolve a library ID",
- signature: 'tools.context7["resolve-library-id"](input: {\n libraryName: string,\n}): Promise<string>',
- },
- ])
- expect(runtime.instructions()).toContain(
- 'tools.context7["resolve-library-id"](input: {\n libraryName: string,\n}): Promise<string>',
- )
- const search = await Effect.runPromise(runtime.execute(`return search({ query: "resolve library id" })`))
- expect(search.ok).toBe(true)
- if (search.ok) {
- expect(search.value).toStrictEqual({
- items: [
- {
- path: 'tools.context7["resolve-library-id"]',
- description: "Resolve a library ID",
- signature: 'tools.context7["resolve-library-id"](input: {\n libraryName: string,\n}): Promise<string>',
- },
- ],
- remaining: 0,
- next: null,
- })
- }
- const call = await Effect.runPromise(
- runtime.execute(`return await tools.context7["resolve-library-id"]({ libraryName: "TypeScript" })`),
- )
- expect(call.ok).toBe(true)
- if (call.ok) expect(call.value).toBe("/resolved/TypeScript")
- const exact = await Effect.runPromise(
- runtime.execute(`return search({ query: 'tools.context7["resolve-library-id"]' })`),
- )
- expect(exact.ok).toBe(true)
- if (exact.ok) expect(exact.value).toMatchObject({ remaining: 0, next: null })
- })
- test("instructions use markdown sections with placeholder-only call forms", () => {
- const runtime = CodeMode.make({ tools })
- const instructions = runtime.instructions()
- // Sections in order: workflow at the top, catalog at the bottom.
- expect(instructions).toContain("## Workflow")
- expect(instructions).toContain("## Rules")
- expect(instructions).toContain("## Language")
- expect(instructions.indexOf("## Workflow")).toBeLessThan(instructions.indexOf("## Rules"))
- expect(instructions.indexOf("## Rules")).toBeLessThan(instructions.indexOf("## Language"))
- expect(instructions.indexOf("## Language")).toBeLessThan(
- instructions.indexOf("\n## Available tools (COMPLETE list"),
- )
- expect(instructions).not.toContain("JSON.parse(res)")
- expect(instructions).toContain("Return only the fields you need")
- expect(instructions).toContain("avoid returning large raw payloads")
- expect(instructions).toContain("Do not infer or normalize tool names")
- expect(instructions).toContain("bracket notation and quotes are part of the path")
- expect(instructions).toContain("surrounding agent tools are not available")
- expect(instructions).toContain("Only tools listed here are available")
- // Placeholders use generic namespace/tool/field names only - no fabricated real tools
- // and no real catalog tools cherry-picked into example lines.
- expect(instructions).toContain("`const result = await tools.<namespace>.<tool>(input)`")
- expect(instructions).toContain("Return only the fields you need from structured results")
- expect(instructions).toContain("check that it is a non-null object and not an array")
- expect(instructions).not.toContain("result.<field>")
- expect(instructions).not.toContain("data.<field>")
- expect(instructions).not.toContain("total_count")
- expect(instructions).not.toContain("list_issues")
- expect(instructions).not.toContain("tools.orders.lookup({")
- // COMPLETE: step 1 picks from the inlined list; search is not advertised.
- expect(instructions).toContain("1. Pick a tool from the list under `## Available tools`")
- expect(instructions).not.toContain("Browse one namespace")
- const partial = CodeMode.make({ tools, discovery: { catalogBudget: 0 } }).instructions()
- // PARTIAL: the workflow starts with search (with query-style guidance that is clearly
- // a query string, never a tool name) and the browse-namespace rule appears.
- expect(partial).toContain(
- '1. If needed, discover tools with the built-in search function: `return search({ query: "<intent + key nouns>" })`.',
- )
- expect(partial).toContain("In the next execution, copy a returned path exactly")
- expect(partial).toContain("Only tools listed here or returned by the built-in `search` function")
- expect(partial).toContain('- Browse one namespace: `search({ query: "", namespace: "<name>" })`.')
- expect(partial).toContain("repeat the same search with `offset: next.offset`")
- expect(partial).toContain(" limit?: number,\n offset?: number,")
- expect(partial).not.toContain("total_count")
- expect(partial).not.toContain("tools.orders.lookup({")
- })
- test("the language section describes the restricted runtime without overclaiming", () => {
- const instructions = CodeMode.make({ tools }).instructions()
- expect(instructions).toContain("restricted JavaScript language for calling tools")
- expect(instructions).toContain("not a general-purpose runtime")
- expect(instructions).not.toContain("Standard modern JavaScript works")
- expect(instructions).not.toContain("TypeScript type annotations")
- for (const missing of ["Modules/imports", "classes", "fetch"]) {
- expect(instructions).toContain(missing)
- }
- expect(instructions).not.toContain("generators")
- expect(instructions).not.toContain("new Promise(...) are unavailable")
- expect(instructions).not.toContain("promise chaining")
- expect(instructions).toContain("URL, URLSearchParams, and URI encoding helpers")
- expect(instructions).not.toContain("host globals")
- expect(instructions).toContain("Use tools for external operations")
- expect(instructions).toContain(
- "Prefer explicit `return`; otherwise only the final top-level expression becomes the result.",
- )
- expect(instructions).toContain(
- "Dates and URLs serialize to strings at data boundaries; Map/Set/RegExp/URLSearchParams serialize to `{}`.",
- )
- })
- test("zero tools keep minimal sections and the no-tools notice", () => {
- const runtime = CodeMode.make({})
- const instructions = runtime.instructions()
- expect(instructions).toContain("No tools are currently available.")
- expect(instructions).toContain("## Language")
- expect(instructions).toContain("## Available tools")
- expect(instructions).not.toContain("## Workflow")
- expect(instructions).not.toContain("## Rules")
- expect(instructions).not.toContain("search(")
- })
- test("uses one ranked search returning complete definitions for large catalogs", async () => {
- const upload = Tool.make({
- description: "Upload one readable local file to the current Discord thread",
- input: Schema.Struct({ path: Schema.String }),
- output: Schema.Struct({ sent: Schema.Boolean }),
- run: () => Effect.succeed({ sent: true }),
- })
- const generate = Tool.make({
- description: "Generate an image and upload it to the current Discord thread",
- input: Schema.Struct({ prompt: Schema.String }),
- output: Schema.Struct({ sent: Schema.Boolean }),
- run: () => Effect.succeed({ sent: true }),
- })
- const runtime = CodeMode.make({
- tools: { thread: { uploadFile: upload, generateImage: generate }, orders: { lookup } },
- discovery: { catalogBudget: 0 },
- })
- expect(runtime.instructions()).toContain("Available tools (PARTIAL - 0 of 3 shown; find the rest with search(...))")
- expect(runtime.instructions()).toContain("- thread (2 tools, none shown)")
- expect(runtime.instructions()).toContain("- orders (1 tool, none shown)")
- expect(runtime.instructions()).toContain("Search returns complete callable signatures:\n- search(input: {")
- expect(runtime.instructions()).not.toMatch(/tools\.thread\.uploadFile\(input/)
- const result = await Effect.runPromise(
- runtime.execute(`
- return search({
- query: "send message attachment upload file to current Discord thread",
- limit: 2
- })
- `),
- )
- expect(result.ok).toBe(true)
- if (!result.ok) return
- expect(result.value).toStrictEqual({
- items: [
- {
- path: "tools.thread.uploadFile",
- description: "Upload one readable local file to the current Discord thread",
- signature: "tools.thread.uploadFile(input: {\n path: string,\n}): Promise<{\n sent: boolean,\n}>",
- },
- {
- path: "tools.thread.generateImage",
- description: "Generate an image and upload it to the current Discord thread",
- signature: "tools.thread.generateImage(input: {\n prompt: string,\n}): Promise<{\n sent: boolean,\n}>",
- },
- ],
- remaining: 0,
- next: null,
- })
- expect(result.toolCalls).toStrictEqual([{ name: "search" }])
- const variants = await Effect.runPromise(
- runtime.execute(`
- return [
- search({ query: "file" }),
- search({ query: "image" })
- ]
- `),
- )
- expect(variants.ok).toBe(true)
- if (variants.ok) {
- expect((variants.value as Array<{ items: Array<{ path: string }> }>)[0]?.items[0]?.path).toBe(
- "tools.thread.uploadFile",
- )
- expect((variants.value as Array<{ items: Array<{ path: string }> }>)[1]?.items[0]?.path).toBe(
- "tools.thread.generateImage",
- )
- }
- })
- test("search is a counted tool call: it burns maxToolCalls and fires the hooks", async () => {
- const started: Array<string> = []
- const ended: Array<string> = []
- const limited = CodeMode.make({
- tools,
- limits: { maxToolCalls: 1 },
- onToolCallStart: (call) => Effect.sync(() => void started.push(call.name)),
- onToolCallEnd: (call) => Effect.sync(() => void ended.push(`${call.name}:${call.outcome}`)),
- })
- const result = await Effect.runPromise(limited.execute(`search({}); return search({})`))
- expect(result.ok).toBe(false)
- if (!result.ok) expect(result.error.kind).toBe("ToolCallLimitExceeded")
- expect(started).toEqual(["search"])
- expect(ended).toEqual(["search:success"])
- })
- test("search is an opaque, shadowable global like other built-ins", async () => {
- const runtime = CodeMode.make({ tools })
- expect(await Effect.runPromise(runtime.execute(`return typeof search`))).toMatchObject({ value: "function" })
- // A program-level declaration shadows the global, as JS module scope does.
- const shadowed = await Effect.runPromise(runtime.execute(`const search = () => "local"; return search()`))
- expect(shadowed.ok).toBe(true)
- if (shadowed.ok) expect(shadowed.value).toBe("local")
- // The reference itself cannot cross the data boundary.
- const escaped = await Effect.runPromise(runtime.execute(`return { search }`))
- expect(escaped.ok).toBe(false)
- if (!escaped.ok) expect(escaped.error.kind).toBe("InvalidDataValue")
- })
- test("search defaults to 10 results and resolves exact tool paths", async () => {
- const tool = (index: number) =>
- Tool.make({
- description: `Numbered tool ${index}`,
- input: Schema.Struct({ id: Schema.String }),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- const runtime = CodeMode.make({
- tools: {
- many: Object.fromEntries(Array.from({ length: 14 }, (_, index) => [`tool${index}`, tool(index)])),
- },
- })
- const browse = await Effect.runPromise(runtime.execute(`return search({})`))
- expect(browse.ok).toBe(true)
- if (browse.ok) {
- const value = browse.value as {
- items: Array<{ path: string }>
- remaining: number
- next: { offset: number } | null
- }
- expect(value.items).toHaveLength(10)
- expect(value.remaining).toBe(4)
- expect(value.next).toStrictEqual({ offset: 10 })
- }
- for (const query of ["many.tool13", "tools.many.tool13"]) {
- const exact = await Effect.runPromise(runtime.execute(`return search({ query: ${JSON.stringify(query)} })`))
- expect(exact.ok).toBe(true)
- if (exact.ok) {
- expect(exact.value).toStrictEqual({
- items: [
- {
- path: "tools.many.tool13",
- description: "Numbered tool 13",
- signature: "tools.many.tool13(input: {\n id: string,\n}): Promise<string>",
- },
- ],
- remaining: 0,
- next: null,
- })
- }
- }
- })
- test("scopes search to one namespace and browses it alphabetically", async () => {
- const simple = (description: string) =>
- Tool.make({
- description,
- input: Schema.Struct({ id: Schema.String }),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- const runtime = CodeMode.make({
- tools: {
- github: { list_issues: simple("List issues"), create_issue: simple("Create an issue") },
- linear: { list_issues: simple("List Linear issues") },
- },
- })
- // Empty query + namespace browses just that namespace, alphabetical by path.
- const browse = await Effect.runPromise(runtime.execute(`return search({ query: "", namespace: "github" })`))
- expect(browse.ok).toBe(true)
- if (browse.ok) {
- const value = browse.value as { items: Array<{ path: string }>; remaining: number }
- expect(value.remaining).toBe(0)
- expect(value.items.map((item) => item.path)).toStrictEqual([
- "tools.github.create_issue",
- "tools.github.list_issues",
- ])
- }
- // A query + namespace ranks within that namespace only.
- const scoped = await Effect.runPromise(runtime.execute(`return search({ query: "issues", namespace: "linear" })`))
- expect(scoped.ok).toBe(true)
- if (scoped.ok) {
- const value = scoped.value as { items: Array<{ path: string }>; remaining: number }
- expect(value.remaining).toBe(0)
- expect(value.items[0]?.path).toBe("tools.linear.list_issues")
- }
- const invalid = await Effect.runPromise(runtime.execute(`return search({ query: "issues", namespace: 7 })`))
- expect(invalid.ok).toBe(false)
- if (!invalid.ok) expect(invalid.error.kind).toBe("InvalidToolInput")
- })
- test("matches input parameter names and partial-word substrings", async () => {
- const upload = Tool.make({
- description: "Send a document to the workspace",
- input: {
- type: "object",
- properties: { attachment: { type: "string", description: "Local path of the payload to send" } },
- required: ["attachment"],
- },
- run: () => Effect.succeed("ok"),
- })
- const other = Tool.make({
- description: "Rename the workspace",
- input: Schema.Struct({ name: Schema.String }),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- const runtime = CodeMode.make({ tools: { files: { upload, other } } })
- // "attachment" appears in neither path nor description - only in the input schema's
- // property names, which the searchable text includes.
- const byParameter = await Effect.runPromise(runtime.execute(`return search({ query: "attachment" })`))
- expect(byParameter.ok).toBe(true)
- if (byParameter.ok) {
- const value = byParameter.value as { items: Array<{ path: string }>; remaining: number }
- expect(value.remaining).toBe(0)
- expect(value.items[0]?.path).toBe("tools.files.upload")
- }
- // Substring matching: a partial word ("docum") still hits the description.
- const bySubstring = await Effect.runPromise(runtime.execute(`return search({ query: "docum" })`))
- expect(bySubstring.ok).toBe(true)
- if (bySubstring.ok) {
- const value = bySubstring.value as { items: Array<{ path: string }>; remaining: number }
- expect(value.remaining).toBe(0)
- expect(value.items[0]?.path).toBe("tools.files.upload")
- }
- })
- test("a plural query term matches singular-only tool text", async () => {
- const simple = (description: string) =>
- Tool.make({
- description,
- input: Schema.Struct({ id: Schema.String }),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- const runtime = CodeMode.make({
- tools: {
- // Neither path nor description contains "issues" - only the singular "issue".
- tracker: { fetch_all: simple("Fetch every open issue in the project") },
- github: { list_issues: simple("List issues") },
- misc: { rename: simple("Rename the workspace") },
- },
- })
- // "issues" still finds the singular-only tool (term OR singular(term) per field)...
- const plural = await Effect.runPromise(runtime.execute(`return search({ query: "issues", namespace: "tracker" })`))
- expect(plural.ok).toBe(true)
- if (plural.ok) {
- const value = plural.value as { items: Array<{ path: string }>; remaining: number }
- expect(value.remaining).toBe(0)
- expect(value.items[0]?.path).toBe("tools.tracker.fetch_all")
- }
- // ...while a true "issues" path match still outranks the singular-only description match.
- const ranked = await Effect.runPromise(runtime.execute(`return search({ query: "issues" })`))
- expect(ranked.ok).toBe(true)
- if (ranked.ok) {
- const value = ranked.value as { items: Array<{ path: string }>; remaining: number }
- expect(value.remaining).toBe(0)
- expect(value.items.map((item) => item.path)).toStrictEqual([
- "tools.github.list_issues",
- "tools.tracker.fetch_all",
- ])
- }
- })
- test("empty query lists everything alphabetically by path", async () => {
- const simple = (description: string) =>
- Tool.make({
- description,
- input: Schema.Struct({}),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- // Deliberately declared out of alphabetical order.
- const runtime = CodeMode.make({
- tools: {
- zeta: { last: simple("Last") },
- alpha: { beta: simple("Middle"), aardvark: simple("First") },
- },
- })
- const browse = await Effect.runPromise(runtime.execute(`return search({})`))
- expect(browse.ok).toBe(true)
- if (browse.ok) {
- const value = browse.value as { items: Array<{ path: string }>; remaining: number; next: unknown }
- expect(value.items.map((item) => item.path)).toStrictEqual([
- "tools.alpha.aardvark",
- "tools.alpha.beta",
- "tools.zeta.last",
- ])
- expect(value.remaining).toBe(0)
- expect(value.next).toBeNull()
- }
- const middle = await Effect.runPromise(runtime.execute(`return search({ limit: 1, offset: 1 })`))
- expect(middle.ok).toBe(true)
- if (middle.ok) {
- expect(middle.value).toMatchObject({
- items: [{ path: "tools.alpha.beta" }],
- remaining: 1,
- next: { offset: 2 },
- })
- }
- const exhausted = await Effect.runPromise(runtime.execute(`return search({ limit: 1, offset: 3 })`))
- expect(exhausted.ok).toBe(true)
- if (exhausted.ok) expect(exhausted.value).toStrictEqual({ items: [], remaining: 0, next: null })
- })
- test("inlines round-robin across namespaces so one expensive namespace cannot starve the rest", () => {
- const cheap = Tool.make({
- description: "Cheap",
- input: Schema.Struct({ q: Schema.String }),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- const expensive = Tool.make({
- description:
- "An expensive tool whose description alone consumes far more than the remaining inline catalog byte budget for this runtime",
- input: Schema.Struct({
- someRatherLongParameterName: Schema.String,
- anotherEvenLongerParameterName: Schema.Number,
- }),
- output: Schema.String,
- run: () => Effect.succeed("ok"),
- })
- // Round 1 places alpha.cheap (~17 estimated tokens) and beta.cheap (~17); in round 2
- // alpha.expensive does not fit, which marks only alpha done - it must NOT prevent
- // other namespaces from inlining (beta already got its line in the same round).
- const runtime = CodeMode.make({
- tools: { alpha: { cheap, expensive }, beta: { cheap } },
- discovery: { catalogBudget: 40 },
- })
- const instructions = runtime.instructions()
- expect(instructions).toContain("Available tools (PARTIAL - 2 of 3 shown; find the rest with search(...))")
- expect(instructions).toContain("- alpha (2 tools, 1 shown)")
- expect(instructions).toContain(" - tools.alpha.cheap(input: {\n q: string,\n}): Promise<string> // Cheap")
- expect(instructions).not.toContain("tools.alpha.expensive(")
- // Fully shown namespaces read cleanly (no "shown" annotation).
- expect(instructions).toContain("- beta (1 tool)")
- expect(instructions).toContain(" - tools.beta.cheap(input: {\n q: string,\n}): Promise<string> // Cheap")
- expect(instructions).toContain("Search returns complete callable signatures:\n- search(input: {")
- })
- test("charges inline JSDoc against the catalog token budget", () => {
- const documented = Tool.make({
- description: "Look up a record",
- input: {
- type: "object",
- properties: {
- id: { type: "string", description: "A detailed identifier description. ".repeat(20) },
- },
- required: ["id"],
- } as const,
- run: () => Effect.succeed("ok"),
- })
- const runtime = CodeMode.make({
- tools: { records: { lookup: documented } },
- discovery: { catalogBudget: 40 },
- })
- expect(runtime.catalog()[0]?.signature).toContain("/** A detailed identifier description.")
- expect(runtime.instructions()).toContain("Available tools (PARTIAL - 0 of 1 shown; find the rest with search(...))")
- expect(runtime.instructions()).not.toContain("tools.records.lookup(input:")
- })
- test("decodes tool input and output before exposing either side", async () => {
- const observed: Array<unknown> = []
- const transformed = Tool.make({
- description: "Double a number",
- input: Schema.Struct({ value: Schema.NumberFromString }),
- output: Schema.NumberFromString,
- run: ({ value }) =>
- Effect.sync(() => {
- observed.push(value)
- return String(value * 2)
- }),
- })
- const runtime = CodeMode.make({
- tools: { math: { double: transformed } },
- onToolCallStart: (call) => Effect.sync(() => observed.push(call.input)),
- })
- const success = await Effect.runPromise(runtime.execute(`return await tools.math.double({ value: "21" })`))
- expect(success).toStrictEqual({ ok: true, value: 42, toolCalls: [{ name: "math.double" }] })
- expect(observed).toStrictEqual([{ value: 21 }, 21])
- const invalid = await Effect.runPromise(runtime.execute(`return await tools.math.double({ value: 21 })`))
- expect(invalid.ok).toBe(false)
- if (invalid.ok) return
- expect(invalid.error.kind).toBe("InvalidToolInput")
- expect(observed).toStrictEqual([{ value: 21 }, 21])
- })
- test("returns JSON-safe data and normalizes undefined to null", async () => {
- const result = await Effect.runPromise(
- CodeMode.execute({
- code: `return { top: undefined, nested: [1, undefined] }`,
- }),
- )
- expect(result).toStrictEqual({
- ok: true,
- value: { top: null, nested: [1, null] },
- toolCalls: [],
- })
- expect(Schema.decodeUnknownSync(CodeMode.Result)(JSON.parse(JSON.stringify(result)))).toStrictEqual(result)
- })
- test("returns the final top-level expression when return is omitted", async () => {
- const result = await Effect.runPromise(CodeMode.execute({ code: `1; 2` }))
- expect(result).toStrictEqual({ ok: true, value: 2, toolCalls: [] })
- })
- test("does not implicitly return expressions nested in control flow", async () => {
- const result = await Effect.runPromise(CodeMode.execute({ code: `if (true) { 2 }` }))
- expect(result).toStrictEqual({ ok: true, value: null, toolCalls: [] })
- })
- test("returns null when the final top-level statement is not an expression", async () => {
- const result = await Effect.runPromise(CodeMode.execute({ code: `1; const value = 2` }))
- expect(result).toStrictEqual({ ok: true, value: null, toolCalls: [] })
- })
- test("rejects invalid configuration and discovery limits", async () => {
- expect(() => CodeMode.execute({ code: "return 1", limits: { timeoutMs: 0 } })).toThrow(RangeError)
- expect(() => CodeMode.execute({ code: "return 1", limits: { timeoutMs: Number.POSITIVE_INFINITY } })).toThrow(
- RangeError,
- )
- expect(() => CodeMode.execute({ code: "return 1", limits: { maxToolCalls: -1 } })).toThrow(RangeError)
- expect(() => CodeMode.execute({ code: "return 1", limits: { maxOutputBytes: -1 } })).toThrow(RangeError)
- expect(() => CodeMode.make({ tools, discovery: { catalogBudget: -1 } })).toThrow(RangeError)
- const result = await Effect.runPromise(
- CodeMode.make({
- tools,
- discovery: { catalogBudget: 0 },
- }).execute(`return search({ query: "order", limit: 0.5 })`),
- )
- expect(result.ok).toBe(false)
- if (result.ok) return
- expect(result.error.kind).toBe("InvalidToolInput")
- for (const offset of [-1, 0.5, Number.MAX_SAFE_INTEGER + 1, "1"]) {
- const invalidOffset = await Effect.runPromise(
- CodeMode.make({ tools }).execute(`return search({ query: "order", offset: ${JSON.stringify(offset)} })`),
- )
- expect(invalidOffset.ok).toBe(false)
- if (!invalidOffset.ok) expect(invalidOffset.error.kind).toBe("InvalidToolInput")
- }
- })
- test("enforces the tool-call limit as a diagnostic", async () => {
- const result = await Effect.runPromise(CodeMode.execute({ tools, code: source, limits: { maxToolCalls: 0 } }))
- expect(result.ok).toBe(false)
- if (!result.ok) expect(result.error.kind).toBe("ToolCallLimitExceeded")
- })
- test("timeoutMs and maxToolCalls have no defaults: absent means unlimited", async () => {
- // 150 tool calls would have exceeded the old default cap of 100; with no limits
- // provided, there is no cap and no timeout - budgets are host policy.
- const counter = Tool.make({
- description: "Count invocations",
- input: Schema.Struct({}),
- output: Schema.Number,
- run: () => Effect.succeed(1),
- })
- const result = await Effect.runPromise(
- CodeMode.execute({
- tools: { host: { count: counter } },
- code: `
- let total = 0
- for (let i = 0; i < 150; i += 1) total += await tools.host.count({})
- return total
- `,
- }),
- )
- expect(result).toMatchObject({ ok: true, value: 150 })
- if (result.ok) expect(result.toolCalls.length).toBe(150)
- })
- test("the timeout interrupts a busy loop without any operation budget", async () => {
- // Regression: timeout interruption must not depend on interpreter-side work accounting.
- // The Effect fiber runtime auto-yields between interpreter steps, so a pure `while
- // (true) {}` loop is interrupted by `timeoutMs` alone.
- const startedAt = Date.now()
- const result = await Effect.runPromise(CodeMode.execute({ code: "while (true) {}", limits: { timeoutMs: 200 } }))
- const elapsedMs = Date.now() - startedAt
- expect(result.ok).toBe(false)
- if (!result.ok) {
- expect(result.error.kind).toBe("TimeoutExceeded")
- expect(result.error.message).toContain("timed out after 200ms")
- }
- expect(elapsedMs).toBeLessThan(3_000)
- })
- })
|