runTool()
Execute one tool with no model, no HTTP, no thread runtime.
import { runTool } from "@pai/test-utils";
const result = await runTool(searchDocs, {
input: { query: "tenancy" },
context: { workspaceId: "ws_1", docs: fakeDocs },
});
expect(result.expectOutput().hits[0]?.title).toBe("Identity");Import
import { runTool } from "@pai/test-utils";Signature
function runTool(tool, options: {
input;
context?;
capabilities?;
signal?;
threadId?;
agentId?;
}): Promise<RunToolHandle>;Parameters
tool: ToolDefinition
options: object
input: parsed inputSchema
context?: parsed contextSchema
capabilities?: object
A facade for each capability the tool declares, keyed as its
capabilities declares them (sandbox for sandbox tools): required
when the tool declares any, and a type error otherwise. For
the sandbox, use createInMemorySandbox().
signal?: AbortSignal
threadId?: string
agentId?: string
Returns
A RunToolHandle.
Outcome checks and resume. The handle also has status, data, attempts, suspendHistory, and union fields output / error / suspend.
expectOutput: () => output
Throws if the tool did not return.
expectSuspended: () => { name, input }
Throws if the tool is not waiting.
expectFailed: () => { code, message, retryable? }
Deliberate ctx.fail. { code: "tool_failed", message }.
expectThrew: () => unknown
Raw exception.
expectCancelled: () => unknown
resume: (name, payload) => Promise<RunToolHandle>
dataWrites: Array
agentRuns: Array
Delegated ctx.agents runs.
ctx.fail("…") → expectFailed() is { code: "tool_failed", message }. Nested tools maps need createTestRuntime().
Examples
Suspend and resume
const waiting = await runTool(publishPost, {
input: { draftId: "draft_1" },
context: { drafts: fakeDrafts },
});
expect(waiting.expectSuspended().name).toBe("approve");
const done = await waiting.resume("approve", { approved: true });
expect(done.expectOutput()).toEqual({ published: true });Fail vs throw
const failed = await runTool(getRecord, {
input: { id: "missing" },
context: { records: fakeRecords },
});
expect(failed.expectFailed()).toEqual({
code: "tool_failed",
message: "No record missing.",
});
const threw = await runTool(getRecord, {
input: { id: "x" },
context: { records: explodingRecords },
});
expect(threw.expectThrew()).toBeInstanceOf(DatabaseDownError);Cancellation
const controller = new AbortController();
const pending = runTool(slowSearch, {
input: { query: "tenancy" },
context: { docs: fakeDocs },
signal: controller.signal,
});
controller.abort();
expect((await pending).expectCancelled()).toBeDefined();