RunContext & Session Isolation
RunContext is an isolated key-value store created per Runner.run() execution turn. It threads sensitive application data (userId, orgId, database connections) directly to tools and guardrails without exposing credentials to LLM prompt messages.
Why Isolated Context Matters
In multi-tenant AI applications, passing user IDs or database connections directly inside the LLM prompt is risky:
- Prompt Injections: Malicious users could instruct the model to substitute someone else’s user ID.
- Context Window Waste: Injecting session boilerplate into every turn wastes precious token context.
RunContext solves this by keeping private application context in your Node environment.
Setting & Consuming Context
1. Passing Context to Runner.run()
import { Agent, Runner } from '@kikoyu/core';
import { billingAgent } from './agents';
const runner = new Runner();
// Execute request with isolated session context
const result = await runner.run(billingAgent, 'Show my recent invoices', {
context: {
userId: 'usr_99812',
orgId: 'org_enterprise',
userRole: 'ADMIN',
},
});2. Consuming Context Inside Tools
import { createTool, z } from '@kikoyu/core';
export const getInvoicesTool = createTool({
name: 'get_invoices',
description: 'Fetch invoices for current user.',
parameters: z.object({ limit: z.number().default(5) }),
execute: async ({ limit }, context) => {
// Safely retrieve context parameters set at Runner invocation
const userId = context.get('userId');
const userRole = context.get('userRole');
if (userRole !== 'ADMIN') {
throw new Error('Unauthorized: User does not have invoice viewing permissions.');
}
const invoices = await db.invoices.findMany({ where: { userId }, take: limit });
return { userId, invoices };
},
});Context Lifecycle
- Created: A new
RunContextis instantiated at the start ofrunner.run(). - Inherited: Sub-agent handoffs inherit the parent
RunContextseamlessly. - Destroyed: When
runner.run()completes or throws, the context object is garbage collected.