PAIPAI

Runtime Context

Build runtime-only dependencies for models, instructions, and tools.

runtimeContext turns trusted request state into one agent-wide value for an execution episode.

PAI passes that value to model selectors, instructions, provider-tool resolvers, lifecycle hooks, and tool registration callbacks as runtimeContext. A resumed execution builds a fresh value; every model step in the same episode sees the same value.

const agent = defineAgent({
  runtimeContext: async ({ identity, clientData, signal }) => {
    const workspace = await loadWorkspace(identity.workspaceId, { signal });

    return {
      identity,
      workspace,
      clientData,
      models: modelRegistry.forWorkspace(workspace),
    };
  },

  model: ({ runtimeContext }) => runtimeContext.models.primary,
  instructions: ({ runtimeContext }) =>
    `You are helping ${runtimeContext.workspace.name}.`,
});

Use runtimeContext for:

  • loading workspace/project/org records;
  • selecting model providers;
  • dependency injection;
  • policy-aware system data;
  • tool dependencies;
  • model context derived from trusted state;
  • dependencies used by lifecycle helpers.

Do not put durable thread state in runtimeContext. Durable state belongs in thread snapshots, messages, tool parts, queued items, pending actions derived from tool parts, or your application database.

Lifecycle hooks should consume runtimeContext; they should not reload product state that the builder already resolved.

PAI does not forward this value to the AI SDK's separate runtimeContext option. PAI runtime context may contain application services and stays at the PAI orchestration boundary unless application code deliberately maps part of it into another API.

Tool execution has a narrower boundary. A reusable tool declares contextSchema; its agent registration may derive that value with mapContext({ runtimeContext }); and the tool reads it as ctx.context:

const lookupCustomer = defineTool({
  contextSchema: customerContextSchema,
  execute: (ctx) => ctx.context.store.read(ctx.input.customerId),
});

const agent = defineAgent({
  // ...
  tools: {
    lookupCustomer: {
      tool: lookupCustomer,
      mapContext: ({ runtimeContext }) => ({
        store: runtimeContext.stores.customers,
      }),
    },
  },
});

This preserves the useful distinction: runtimeContext is shared agent state; ctx.context is the context for one tool call.