feat(core): expose deferred tools through execute (#35361)

This commit is contained in:
Aiden Cline 2026-07-04 16:20:56 -05:00 committed by GitHub
commit d65ecd4a90
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 367 additions and 89 deletions

View file

@ -79,12 +79,17 @@ it.effect("waits for permission before calling an MCP tool", () =>
const permission = yield* Deferred.make<void>()
decision = Deferred.await(permission)
const registry = yield* ToolRegistry.Service
yield* waitForTool(registry, "demo_search")
yield* waitForTool(registry, "execute")
const fiber = yield* settleTool(registry, {
sessionID: SessionV2.ID.make("ses_mcp_permission"),
...toolIdentity,
call: { type: "tool-call", id: "call_mcp_permission", name: "demo_search", input: {} },
call: {
type: "tool-call",
id: "call_mcp_permission",
name: "execute",
input: { code: "return await tools.demo.search({})" },
},
}).pipe(Effect.forkScoped)
expect(yield* Deferred.await(assertion)).toEqual({
action: "demo_search",
@ -113,15 +118,23 @@ it.effect("does not call MCP when permission is rejected", () =>
assertion = yield* Deferred.make<PermissionV2.AssertInput>()
decision = Effect.fail(new PermissionV2.RejectedError())
const registry = yield* ToolRegistry.Service
yield* waitForTool(registry, "demo_search")
yield* waitForTool(registry, "execute")
expect(
yield* settleTool(registry, {
sessionID: SessionV2.ID.make("ses_mcp_rejected"),
...toolIdentity,
call: { type: "tool-call", id: "call_mcp_rejected", name: "demo_search", input: {} },
}),
).toEqual({ result: { type: "error", value: "Unable to execute demo_search" } })
const settlement = yield* settleTool(registry, {
sessionID: SessionV2.ID.make("ses_mcp_rejected"),
...toolIdentity,
call: {
type: "tool-call",
id: "call_mcp_rejected",
name: "execute",
input: { code: "return await tools.demo.search({})" },
},
})
expect(settlement.result).toEqual({ type: "text", value: "Unable to execute demo_search" })
expect(settlement.output?.structured).toEqual({
toolCalls: [{ tool: "demo.search", status: "error" }],
error: true,
})
expect(calls).toBe(0)
}),
)

View file

@ -154,6 +154,7 @@ describe("PluginV2", () => {
expect((yield* registry.materialize({ model: testModel })).definitions.map((tool) => tool.name)).toEqual([
"plain",
"context_7_look_up",
"execute",
])
}),
)