mirror of
https://github.com/anomalyco/opencode.git
synced 2026-11-08 18:51:24 +03:00
73 lines
2.4 KiB
TypeScript
73 lines
2.4 KiB
TypeScript
import { expect, test } from "bun:test"
|
|
import { Effect, Schema } from "effect"
|
|
import { CodeMode, Extension, Tool } from "../src/index.js"
|
|
|
|
test("Lua calls only declared capabilities; denied calls can be recovered without crossing a host error object", async () => {
|
|
const calls: string[] = []
|
|
const extensions = [
|
|
Extension.lua({
|
|
name: "example",
|
|
globals: {
|
|
lookup: (id) =>
|
|
Effect.sync(() => {
|
|
if (typeof id !== "string") throw new TypeError("expected an id")
|
|
calls.push(id)
|
|
return { id }
|
|
}),
|
|
},
|
|
}),
|
|
]
|
|
const run = CodeMode.make({
|
|
language: "lua",
|
|
extensions,
|
|
hooks: {
|
|
"extension.before": (call) =>
|
|
call.args[0] === "denied" ? Effect.fail(new Error("permission denied")) : Effect.void,
|
|
},
|
|
})
|
|
expect(
|
|
await Effect.runPromise(
|
|
run.execute(`
|
|
local ok, message = pcall(lookup, "denied")
|
|
return { ok = ok, message = message, id = lookup("allowed").id }
|
|
`),
|
|
),
|
|
).toMatchObject({ ok: true, value: { ok: false, message: "permission denied", id: "allowed" } })
|
|
expect(calls).toEqual(["allowed"])
|
|
expect(() => CodeMode.make({ extensions })).toThrow("requires language")
|
|
expect(() =>
|
|
CodeMode.make({ language: "lua", extensions: [Extension.make({ name: "js", globals: { fs: {} } })] }),
|
|
).toThrow("Extension.lua")
|
|
})
|
|
|
|
test("Lua table shapes survive a validated tool round trip, including empty containers and nested nulls", async () => {
|
|
const shape = Schema.Struct({
|
|
list: Schema.Array(Schema.NullOr(Schema.String)),
|
|
record: Schema.Record(Schema.String, Schema.Json),
|
|
})
|
|
const runtime = CodeMode.make({
|
|
language: "lua",
|
|
tools: { echo: Tool.make({ description: "Echo", input: shape, output: shape, execute: Effect.succeed }) },
|
|
})
|
|
expect(
|
|
await Effect.runPromise(
|
|
runtime.execute(`
|
|
local a = tools.echo({ list = {json.null}, record = { omitted = nil, kept = json.null } })
|
|
a.list[1] = nil
|
|
return { tools.echo(a), tools.echo({ list = json.array(), record = {} }) }
|
|
`),
|
|
),
|
|
).toMatchObject({
|
|
ok: true,
|
|
value: [
|
|
{ list: [], record: { kept: null } },
|
|
{ list: [], record: {} },
|
|
],
|
|
})
|
|
expect(await Effect.runPromise(runtime.execute("return tools.echo({list = {}, record = {}})"))).toMatchObject({
|
|
ok: false,
|
|
error: { kind: "InvalidToolInput" },
|
|
toolCalls: [],
|
|
})
|
|
})
|