The @openrouter/agent package introduces type-safe shared state and local tool context.
Shared Context
Define a sharedContextSchema using Zod in callModel. This state is accessible to all tools in the conversation.
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Process this data',
sharedContextSchema: z.object({
userId: z.string(),
sessionData: z.record(z.unknown()),
}),
context: {
shared: { userId: '123', sessionData: {} },
},
tools: [myTool],
});
Tool Context
Tools can declare their own contextSchema and access both local and shared context within the execute function.
const myTool = tool({
name: 'my_tool',
description: 'A tool with context',
inputSchema: z.object({ query: z.string() }),
contextSchema: z.object({ apiKey: z.string() }),
execute: async (params, context) => {
// context.local — this tool's own context
// context.shared — shared context across all tools
// context.setContext({ ... }) — update this tool's context
// context.setSharedContext({ ... }) — update shared context
return { result: 'done' };
},
});
import { OpenRouter } from '@openrouter/agent';
import { tool } from '@openrouter/agent/tool';
import { z } from 'zod';
const client = new OpenRouter({ apiKey: '...' });
const result = client.callModel({
model: 'openai/gpt-5-nano',
input: 'Process this data',
sharedContextSchema: z.object({
userId: z.string(),
sessionData: z.record(z.unknown()),
}),
context: {
shared: { userId: '123', sessionData: {} },
},
tools: [myTool],
});
const myTool = tool({
name: 'my_tool',
description: 'A tool with context',
inputSchema: z.object({ query: z.string() }),
contextSchema: z.object({ apiKey: z.string() }),
execute: async (params, context) => {
// context.local — this tool's own context
// context.shared — shared context across all tools
// context.setContext({ ... }) — update this tool's context
// context.setSharedContext({ ... }) — update shared context
return { result: 'done' };
},
});