PAIPAI

createTestRuntime()

Real PAI runtime, in-memory storage, usually a mocked model.

import { createTestRuntime, createTestUtils, stubTools } from "@pai/test-utils";

const t = createTestUtils(assistantAgent);
const model = t.model.queue((m) => [
  m.response([m.toolCall("searchDocs", { query: "tenancy" })]),
  m.response([m.text("See the identity guide.")]),
]);

await using runtime = createTestRuntime({ agent: assistantAgent, model });
const client = runtime.client({
  identity: { userId: "test-user", workspaceId: "test-workspace" },
});

Import

import { createTestRuntime, createTestUtils, stubTools } from "@pai/test-utils";

Signature

function createTestRuntime(options: {
  agent: AgentDefinition;
  model?: LanguageModel;
  identity?: { identity };
  overrideRuntimeContext?;
  storage?;
  scopeKey?;
}): AgentRuntime & AsyncDisposable & { client(); admin() };

Parameters

options: CreateTestRuntimeOptions

agent: AgentDefinition

model?: LanguageModel

Usually t.model.queue(...).

identity?: { identity }

Default client identity.

overrideRuntimeContext?: TRuntimeContext

Skip the agent's runtimeContext builder.

storage?: ThreadStore

Defaults to in-memory.

scopeKey?: (identity) => ScopeKey

Defaults to one shared partition so two test identities can share a thread. Pass the app's real derivation to assert isolation.

Returns

A AgentRuntime & { client(); admin() } & AsyncDisposable.

Same as createAgentRuntime(), plus:

client: (input?) => AgentClient

In-process client. Identity defaults from options.identity.

admin: (input?) => TrustedAgentClient

stubTools(agent, { unhandled: "fail", tools: { … } }) replaces execute. Model helpers: createTestUtils().

Examples

Send and idle

await using runtime = createTestRuntime({ agent: assistantAgent, model });
const client = runtime.client({
  identity: { userId: "test-user", workspaceId: "test-workspace" },
});
const thread = client.thread(client.newThreadId());
const run = await thread.send("Where is tenancy documented?");
const state = await run.waitUntilIdle();
expect(t.getTool(state, "searchDocs").output?.hits[0]?.title).toBe("Identity");

Wait for a tool or an approval

const tool = await t.waitForTool(thread, "searchDocs");
expect(tool.state).toBe("output-available");

const action = await t.waitForPending(
  thread,
  t.actionName("publishPost", "approve"),
);
await action.submit({ approved: true });

Stub tools / override context

const agent = stubTools(assistantAgent, {
  unhandled: "fail",
  tools: {
    searchDocs: async () => ({
      hits: [{ title: "Identity", url: "/guides/identity" }],
    }),
  },
});

await using runtime = createTestRuntime({
  agent,
  model,
  overrideRuntimeContext: {
    workspaceId: "test-workspace",
    docs: fakeDocs,
  },
});

Learn more

On this page