feat(opencode): run code mode on the vendored rune interpreter
Replace the in-process AsyncFunction engine with Rune.execute. MCP tools
are exposed as a host-tool tree (tools.<server>.<tool>) plus top-level
search/describe; each call is permission-gated and coerced to the
{ result, attachments? } envelope. Raise data limits for base64 media.
This adds real sandboxing: host globals are isolated and runaway loops
terminate via the operation limit instead of hanging the event loop.
This commit is contained in:
@@ -182,7 +182,7 @@ describe("code mode execute", () => {
|
||||
test("returns a readable error when the program throws", async () => {
|
||||
const tool = await build({})
|
||||
const output = await Effect.runPromise(tool.execute({ code: "throw new Error('boom')" }, ctx))
|
||||
expect(output.output).toBe("boom")
|
||||
expect(output.output).toBe("Uncaught: boom")
|
||||
expect(output.metadata.error).toBe(true)
|
||||
})
|
||||
|
||||
@@ -190,7 +190,7 @@ describe("code mode execute", () => {
|
||||
const tool = await build({ known_tool: mcpTool("tool", () => "ok") })
|
||||
const output = await Effect.runPromise(tool.execute({ code: "return await tools.known.missing({})" }, ctx))
|
||||
expect(output.metadata.error).toBe(true)
|
||||
expect(output.output).toContain("Unknown tool 'tools.known.missing'")
|
||||
expect(output.output).toContain("Unknown tool 'known.missing'")
|
||||
expect(output.output).toContain("tools.search")
|
||||
})
|
||||
|
||||
@@ -251,6 +251,19 @@ describe("code mode execute", () => {
|
||||
expect(formatValue(undefined)).toBe("undefined")
|
||||
})
|
||||
|
||||
test("terminates a runaway loop via the operation limit instead of hanging", async () => {
|
||||
const tool = await build({})
|
||||
const output = await Effect.runPromise(tool.execute({ code: "while (true) {}" }, ctx))
|
||||
expect(output.metadata.error).toBe(true)
|
||||
expect(output.output.toLowerCase()).toContain("operation")
|
||||
})
|
||||
|
||||
test("isolates the sandbox from host globals", async () => {
|
||||
const tool = await build({})
|
||||
const output = await Effect.runPromise(tool.execute({ code: "return process.env" }, ctx))
|
||||
expect(output.metadata.error).toBe(true)
|
||||
})
|
||||
|
||||
test("describe shows the structured return type when the tool declares an outputSchema", async () => {
|
||||
const tools = { weather_current: mcpTool("current", () => "", { type: "object", properties: { city: { type: "string" } } }) }
|
||||
const defs: Record<string, MCPToolDef> = {
|
||||
|
||||
Reference in New Issue
Block a user