{"_id":"@agent-runner/core","_rev":"3-96c8301ba407eef9506492068effdbe5","name":"@agent-runner/core","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@agent-runner/core","version":"0.1.0","keywords":["ai","agents","mcp","llm","typescript","sdk"],"author":{"name":"Aaron Bidworthy"},"license":"MIT","_id":"@agent-runner/core@0.1.0","maintainers":[{"name":"aparry3","email":"aaron.parry.18@gmail.com"}],"homepage":"https://github.com/aparry3/agent-runner#readme","bugs":{"url":"https://github.com/aparry3/agent-runner/issues"},"bin":{"agent-runner":"dist/cli.js"},"dist":{"shasum":"f23e89a27f78f91061d6d51cd338279368b674e7","tarball":"https://registry.npmjs.org/@agent-runner/core/-/core-0.1.0.tgz","fileCount":19,"integrity":"sha512-eHvFDLDDuk6qBIZEqphfR6qvpRspF50E6panJvBC+QLzVUv4EVLsTLZeDm5fPsdAch0oK8s476GXx0Ou7+Z+Rg==","signatures":[{"sig":"MEQCIFh6VNVuS3ZOAFKhuXZad3xCdwAzzanibJ2ntW8Cf1FeAiBTE17cTVLLYjXJ5LnQY1bpkrP5Arum/62z3U4JFEOsOg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":395499},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./cli":{"import":"./dist/cli.js"},"./templates":{"types":"./dist/templates/index.d.ts","import":"./dist/templates/index.js"}},"gitHead":"15bbcff48ae585a4816b8d26f0625634da2adbea","scripts":{"dev":"tsup --watch","lint":"biome check src/","test":"vitest run","bench":"vitest bench","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest","prepublishOnly":"tsup"},"_npmUser":{"name":"aparry3","email":"aaron.parry.18@gmail.com"},"repository":{"url":"git+https://github.com/aparry3/agent-runner.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.4","description":"TypeScript SDK for defining, running, and evaluating AI agents with first-class MCP support and pluggable storage","directories":{},"_nodeVersion":"22.21.0","dependencies":{"ai":"^4.3.0","zod":"^3.24.0","nanoid":"^5.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@biomejs/biome":"^1.9.0"},"peerDependencies":{"@ai-sdk/google":"^1.0.0","@ai-sdk/openai":"^1.0.0","@ai-sdk/anthropic":"^1.0.0","@opentelemetry/api":"^1.0.0","@modelcontextprotocol/sdk":"^1.0.0"},"peerDependenciesMeta":{"@ai-sdk/google":{"optional":true},"@ai-sdk/openai":{"optional":true},"@ai-sdk/anthropic":{"optional":true},"@opentelemetry/api":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/core_0.1.0_1773227319187_0.6371191737687101","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@agent-runner/core","version":"0.1.1","keywords":["ai","agents","mcp","llm","typescript","sdk"],"author":{"name":"Aaron Bidworthy"},"license":"MIT","_id":"@agent-runner/core@0.1.1","maintainers":[{"name":"aparry3","email":"aaron.parry.18@gmail.com"}],"homepage":"https://github.com/aparry3/agent-runner#readme","bugs":{"url":"https://github.com/aparry3/agent-runner/issues"},"bin":{"agent-runner":"dist/cli.js"},"dist":{"shasum":"36304f7fbe40b08d37c896c17b3321f4ce23b237","tarball":"https://registry.npmjs.org/@agent-runner/core/-/core-0.1.1.tgz","fileCount":21,"integrity":"sha512-fglTV58PdnqIV2HdIR+oNaZracDCmbLLvN6fEMbcImsXW5JaoudXmVS0uabgkBDO7dBBye5obU5w/YE+2UW0PA==","signatures":[{"sig":"MEUCIQDb8Tzmfrj31VcU7VmJWZbbNYMWvwz8OBFWLYKwqz0P+wIgdNfXbV1r6egIc0Q2D37zx6Lk1eR0H+VzbAXdrtqWMjw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":411909},"main":"./dist/index.js","type":"module","_from":"file:agent-runner-core-0.1.1.tgz","types":"./dist/index.d.ts","engines":{"node":">=20.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./cli":{"import":"./dist/cli.js"},"./templates":{"types":"./dist/templates/index.d.ts","import":"./dist/templates/index.js"}},"scripts":{"dev":"tsup --watch","lint":"biome check src/","test":"vitest run","bench":"vitest bench","build":"tsup","typecheck":"tsc --noEmit","test:watch":"vitest"},"_npmUser":{"name":"aparry3","email":"aaron.parry.18@gmail.com"},"_resolved":"/tmp/7c1d9f840225cbaab215cea8c6dd3899/agent-runner-core-0.1.1.tgz","_integrity":"sha512-fglTV58PdnqIV2HdIR+oNaZracDCmbLLvN6fEMbcImsXW5JaoudXmVS0uabgkBDO7dBBye5obU5w/YE+2UW0PA==","repository":{"url":"git+https://github.com/aparry3/agent-runner.git","type":"git","directory":"packages/core"},"_npmVersion":"10.9.4","description":"TypeScript SDK for defining, running, and evaluating AI agents with first-class MCP support and pluggable storage","directories":{},"_nodeVersion":"22.22.0","dependencies":{"ai":"^4.3.0","zod":"^3.24.0","nanoid":"^5.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.4.0","vitest":"^3.0.0","typescript":"^5.7.0","@types/node":"^22.0.0","@biomejs/biome":"^1.9.0"},"peerDependencies":{"@ai-sdk/google":"^1.0.0","@ai-sdk/openai":"^1.0.0","@ai-sdk/anthropic":"^1.0.0","@opentelemetry/api":"^1.0.0","@modelcontextprotocol/sdk":"^1.0.0"},"peerDependenciesMeta":{"@ai-sdk/google":{"optional":true},"@ai-sdk/openai":{"optional":true},"@ai-sdk/anthropic":{"optional":true},"@opentelemetry/api":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/core_0.1.1_1773230671068_0.24782343190808476","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@agent-runner/core","version":"0.1.2","description":"TypeScript SDK for defining, running, and evaluating AI agents with first-class MCP support and pluggable storage","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./cli":{"import":"./dist/cli.js"},"./templates":{"types":"./dist/templates/index.d.ts","import":"./dist/templates/index.js"}},"bin":{"agent-runner":"dist/cli.js"},"keywords":["ai","agents","mcp","llm","typescript","sdk"],"publishConfig":{"access":"public"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/aparry3/agent-runner.git","directory":"packages/core"},"homepage":"https://github.com/aparry3/agent-runner#readme","author":{"name":"Aaron Bidworthy"},"dependencies":{"ai":"^4.3.0","nanoid":"^5.1.0","zod":"^3.24.0"},"peerDependencies":{"@ai-sdk/anthropic":"^1.0.0","@ai-sdk/google":"^1.0.0","@ai-sdk/openai":"^1.0.0","@modelcontextprotocol/sdk":"^1.0.0","@opentelemetry/api":"^1.0.0"},"peerDependenciesMeta":{"@ai-sdk/anthropic":{"optional":true},"@ai-sdk/google":{"optional":true},"@ai-sdk/openai":{"optional":true},"@modelcontextprotocol/sdk":{"optional":true},"@opentelemetry/api":{"optional":true}},"devDependencies":{"@biomejs/biome":"^1.9.0","@types/node":"^22.0.0","tsup":"^8.4.0","typescript":"^5.7.0","vitest":"^3.0.0"},"engines":{"node":">=20.0.0"},"scripts":{"build":"tsup","dev":"tsup --watch","test":"vitest run","test:watch":"vitest","bench":"vitest bench","lint":"biome check src/","typecheck":"tsc --noEmit"},"_id":"@agent-runner/core@0.1.2","bugs":{"url":"https://github.com/aparry3/agent-runner/issues"},"_integrity":"sha512-/x6KtXbQGslmQO+SnCOLDNHP9SSCOy8zUVd+yDsPm13bqLM2XsS2CTDXM5IYdFbPynE7lQde9w+oBnsM/cdYhQ==","_resolved":"/tmp/b26333122d305b88a2de24b3bf13403d/agent-runner-core-0.1.2.tgz","_from":"file:agent-runner-core-0.1.2.tgz","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-/x6KtXbQGslmQO+SnCOLDNHP9SSCOy8zUVd+yDsPm13bqLM2XsS2CTDXM5IYdFbPynE7lQde9w+oBnsM/cdYhQ==","shasum":"2f1936c2e393f5811945bbb3f5a63d0a62205210","tarball":"https://registry.npmjs.org/@agent-runner/core/-/core-0.1.2.tgz","fileCount":21,"unpackedSize":408672,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDKAoP3XyeIaJgsPY2i9yuDQJtoxgrSsCXQ3xkQ6ySCbQIhAN0hlSZxvwjnOBJWRBFZ+8xEgu8UDWvWQfhGavJORD/8"}]},"_npmUser":{"name":"aparry3","email":"aaron.parry.18@gmail.com"},"directories":{},"maintainers":[{"name":"aparry3","email":"aaron.parry.18@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_0.1.2_1773237330506_0.46223386179533255"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-11T11:08:39.056Z","modified":"2026-03-11T13:55:30.851Z","0.1.0":"2026-03-11T11:08:39.327Z","0.1.1":"2026-03-11T12:04:31.225Z","0.1.2":"2026-03-11T13:55:30.697Z"},"bugs":{"url":"https://github.com/aparry3/agent-runner/issues"},"author":{"name":"Aaron Bidworthy"},"license":"MIT","homepage":"https://github.com/aparry3/agent-runner#readme","keywords":["ai","agents","mcp","llm","typescript","sdk"],"repository":{"type":"git","url":"git+https://github.com/aparry3/agent-runner.git","directory":"packages/core"},"description":"TypeScript SDK for defining, running, and evaluating AI agents with first-class MCP support and pluggable storage","maintainers":[{"name":"aparry3","email":"aaron.parry.18@gmail.com"}],"readme":"# @agent-runner/core\n\n[![npm version](https://img.shields.io/npm/v/@agent-runner/core.svg)](https://www.npmjs.com/package/@agent-runner/core)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n[![Node.js](https://img.shields.io/badge/node-%3E%3D20.0.0-brightgreen.svg)](https://nodejs.org)\n[![TypeScript](https://img.shields.io/badge/TypeScript-5.7+-blue.svg)](https://www.typescriptlang.org/)\n\nTypeScript SDK for defining, running, and evaluating AI agents. Agents are portable, JSON-serializable configurations — not code. Plug in any storage backend, any model provider, any tools.\n\n> This is the core package of the [agent-runner](https://github.com/aparry3/agent-runner) monorepo.\n\n## Install\n\n```bash\nnpm install @agent-runner/core\n# or\npnpm add @agent-runner/core\n# or\nyarn add @agent-runner/core\n```\n\nThen install at least one model provider (all optional peer dependencies):\n\n```bash\nnpm install @ai-sdk/openai    # for OpenAI models\nnpm install @ai-sdk/anthropic  # for Anthropic models\nnpm install @ai-sdk/google     # for Google models\n```\n\nSet your API key:\n\n```bash\nexport OPENAI_API_KEY=sk-...\n# or ANTHROPIC_API_KEY, GOOGLE_GENERATIVE_AI_API_KEY, etc.\n```\n\n## Quick Start\n\n```typescript\nimport { createRunner, defineAgent } from \"@agent-runner/core\";\n\nconst runner = createRunner();\n\nrunner.registerAgent(defineAgent({\n  id: \"greeter\",\n  name: \"Greeter\",\n  systemPrompt: \"You are a friendly greeter. Keep responses under 2 sentences.\",\n  model: { provider: \"openai\", name: \"gpt-4o-mini\" },\n}));\n\nconst result = await runner.invoke(\"greeter\", \"Hello!\");\nconsole.log(result.output);\n// → \"Hey there! Welcome — great to have you here.\"\n```\n\n## Usage\n\n### Defining Agents\n\nAgents are plain data objects — JSON-serializable, portable, and versionable:\n\n```typescript\nimport { defineAgent } from \"@agent-runner/core\";\n\nconst agent = defineAgent({\n  id: \"writer\",\n  name: \"Writer\",\n  description: \"Writes concise, engaging copy\",\n  version: \"1.0.0\",\n  systemPrompt: \"You write concise, engaging copy.\",\n  model: { provider: \"openai\", name: \"gpt-4o\" },\n  tags: [\"content\", \"writing\"],\n});\n```\n\n### Tools\n\nDefine typed tools with Zod schemas and register them with the runner:\n\n```typescript\nimport { createRunner, defineAgent, defineTool } from \"@agent-runner/core\";\nimport { z } from \"zod\";\n\nconst lookupOrder = defineTool({\n  name: \"lookup_order\",\n  description: \"Look up an order by ID\",\n  input: z.object({ orderId: z.string() }),\n  async execute(input) {\n    return { status: \"shipped\", eta: \"Tomorrow\" };\n  },\n});\n\nconst runner = createRunner({ tools: [lookupOrder] });\n\nrunner.registerAgent(defineAgent({\n  id: \"support\",\n  name: \"Support Agent\",\n  systemPrompt: \"Help customers with their orders. Use tools to look up order info.\",\n  model: { provider: \"openai\", name: \"gpt-4o\" },\n  tools: [{ type: \"inline\", name: \"lookup_order\" }],\n}));\n\nconst result = await runner.invoke(\"support\", \"Where's my order #12345?\");\nconsole.log(result.toolCalls);\n// → [{ name: \"lookup_order\", input: { orderId: \"12345\" }, output: { status: \"shipped\", ... } }]\n```\n\n### Sessions (Conversational Memory)\n\n```typescript\n// First message\nawait runner.invoke(\"support\", \"Hi, I need help\", { sessionId: \"sess_abc\" });\n\n// Second message — agent remembers the conversation\nawait runner.invoke(\"support\", \"My order is #12345\", { sessionId: \"sess_abc\" });\n```\n\n### Streaming\n\n```typescript\nconst stream = runner.stream(\"writer\", \"Write a short story about a robot\");\n\nfor await (const event of stream) {\n  if (event.type === \"text-delta\") {\n    process.stdout.write(event.text);\n  } else if (event.type === \"tool-call-start\") {\n    console.log(`\\nCalling tool: ${event.toolCall.name}`);\n  } else if (event.type === \"done\") {\n    console.log(`\\nTokens used: ${event.result.usage.totalTokens}`);\n  }\n}\n```\n\n**Stream events:**\n\n| Event | Description |\n|---|---|\n| `text-delta` | Incremental text chunk from the model |\n| `tool-call-start` | Tool execution is starting |\n| `tool-call-end` | Tool execution completed (with result) |\n| `step-complete` | One iteration of the tool loop finished |\n| `done` | Final result with full `InvokeResult` |\n\n### Agent Chains (Agent-as-Tool)\n\nAgents can invoke other agents as tools:\n\n```typescript\nrunner.registerAgent(defineAgent({\n  id: \"researcher\",\n  name: \"Researcher\",\n  systemPrompt: \"Research topics and return concise findings.\",\n  model: { provider: \"openai\", name: \"gpt-4o\" },\n}));\n\nrunner.registerAgent(defineAgent({\n  id: \"writer\",\n  name: \"Writer\",\n  systemPrompt: \"Write articles. Delegate research to the researcher.\",\n  model: { provider: \"anthropic\", name: \"claude-sonnet-4-20250514\" },\n  tools: [{ type: \"agent\", agentId: \"researcher\" }],\n}));\n\n// Writer invokes researcher as a tool during execution\nconst result = await runner.invoke(\"writer\", \"Write about MCP\");\n```\n\n### Shared Context\n\nContext lets agents share state without tight coupling:\n\n```typescript\n// Researcher writes findings to context\nawait runner.invoke(\"researcher\", \"Find info about MCP\", {\n  contextIds: [\"project-alpha\"],\n});\n\n// Writer reads the same context\nawait runner.invoke(\"writer\", \"Write an article using the research\", {\n  contextIds: [\"project-alpha\"],\n});\n```\n\n### Runtime Tool Context\n\nPass runtime data to tools without going through the LLM:\n\n```typescript\nconst updateProfile = defineTool({\n  name: \"update_profile\",\n  description: \"Update the user's profile\",\n  input: z.object({ field: z.string(), value: z.string() }),\n  async execute(input, ctx) {\n    // ctx.user comes from toolContext — injected at runtime\n    await db.users.update(ctx.user.id, { [input.field]: input.value });\n    return { success: true };\n  },\n});\n\nawait runner.invoke(\"chat\", message, {\n  toolContext: { user: { id: \"u_123\", name: \"Aaron\" } },\n});\n```\n\n### Structured Output\n\n```typescript\nrunner.registerAgent(defineAgent({\n  id: \"analyzer\",\n  name: \"Sentiment Analyzer\",\n  systemPrompt: \"Analyze the sentiment of input text.\",\n  model: { provider: \"openai\", name: \"gpt-4o\" },\n  outputSchema: {\n    type: \"object\",\n    properties: {\n      sentiment: { type: \"string\", enum: [\"positive\", \"negative\", \"neutral\"] },\n      confidence: { type: \"number\" },\n    },\n    required: [\"sentiment\", \"confidence\"],\n  },\n}));\n\nconst { output } = await runner.invoke(\"analyzer\", \"I love this!\");\nconst parsed = JSON.parse(output);\n// → { sentiment: \"positive\", confidence: 0.95 }\n```\n\n### MCP Integration\n\nUse tools from any MCP-compatible server:\n\n```typescript\nconst runner = createRunner({\n  mcp: {\n    servers: {\n      github: { url: \"http://localhost:3001/mcp\" },\n      filesystem: { command: \"npx\", args: [\"-y\", \"@anthropic/mcp-fs\"] },\n    },\n  },\n});\n\nrunner.registerAgent(defineAgent({\n  id: \"code-reviewer\",\n  name: \"Code Reviewer\",\n  systemPrompt: \"Review code from GitHub PRs...\",\n  model: { provider: \"anthropic\", name: \"claude-sonnet-4-20250514\" },\n  tools: [{ type: \"mcp\", server: \"github\", tools: [\"get_file_contents\"] }],\n}));\n```\n\nExpose your agents as an MCP server:\n\n```typescript\nimport { createMCPServer } from \"@agent-runner/core/mcp-server\";\nconst server = createMCPServer(runner);\n```\n\n### Evals\n\nBuilt-in evaluation with assertions, LLM-as-judge, and CI integration:\n\n```typescript\nrunner.registerAgent(defineAgent({\n  id: \"classifier\",\n  name: \"Classifier\",\n  systemPrompt: \"Classify support tickets...\",\n  model: { provider: \"openai\", name: \"gpt-4o\" },\n  eval: {\n    rubric: \"Must correctly classify the ticket category\",\n    testCases: [\n      {\n        name: \"billing issue\",\n        input: \"I was charged twice\",\n        assertions: [\n          { type: \"contains\", value: \"billing\" },\n          { type: \"llm-rubric\", value: \"Response identifies this as a billing issue\" },\n        ],\n      },\n    ],\n  },\n}));\n\nconst results = await runner.eval(\"classifier\");\nconsole.log(results.summary);\n// → { total: 1, passed: 1, failed: 0, score: 1.0 }\n```\n\n**Assertion types:** `contains`, `not-contains`, `regex`, `json-schema`, `llm-rubric`, `semantic-similar`, plus custom assertion plugins.\n\n## Storage\n\nThe default store is in-memory. For persistence, use the built-in `JsonFileStore` or install a database adapter:\n\n```typescript\nimport { createRunner, JsonFileStore } from \"@agent-runner/core\";\n\n// JSON files — good for local dev\nconst runner = createRunner({\n  store: new JsonFileStore(\"./data\"),\n});\n```\n\n**Database adapters:**\n\n| Package | Use Case |\n|---|---|\n| [`@agent-runner/store-sqlite`](../store-sqlite) | Single-server production |\n| [`@agent-runner/store-postgres`](../store-postgres) | Multi-server production |\n\nYou can also split stores by concern:\n\n```typescript\nconst runner = createRunner({\n  agentStore: myPostgresStore,\n  sessionStore: myRedisStore,\n  logStore: myElasticsearchStore,\n});\n```\n\n### Custom Stores\n\nImplement the store interfaces:\n\n```typescript\ninterface AgentStore {\n  getAgent(id: string): Promise<AgentDefinition | null>;\n  listAgents(): Promise<AgentSummary[]>;\n  putAgent(agent: AgentDefinition): Promise<void>;\n  deleteAgent(id: string): Promise<void>;\n}\n\ninterface SessionStore {\n  getMessages(sessionId: string): Promise<Message[]>;\n  append(sessionId: string, messages: Message[]): Promise<void>;\n  deleteSession(sessionId: string): Promise<void>;\n  listSessions(agentId?: string): Promise<SessionSummary[]>;\n}\n\n// Also: ContextStore, LogStore\n// Or implement UnifiedStore for all-in-one\n```\n\n## API Reference\n\n### `createRunner(config?: RunnerConfig): Runner`\n\nCreates the central orchestrator. All options are optional:\n\n```typescript\nconst runner = createRunner({\n  store: new JsonFileStore(\"./data\"),    // Storage backend\n  tools: [myTool1, myTool2],            // Inline tools\n  mcp: { servers: { ... } },            // MCP server config\n  session: {                              // Session trimming\n    maxMessages: 50,\n    strategy: \"sliding\",                  // \"sliding\" | \"summary\" | \"none\"\n  },\n  context: {                              // Context injection\n    maxEntries: 20,\n    maxTokens: 4000,\n    strategy: \"latest\",                   // \"latest\" | \"summary\" | \"all\"\n  },\n  defaults: {                             // Default model config\n    model: { provider: \"openai\", name: \"gpt-4o-mini\" },\n    temperature: 0.7,\n    maxTokens: 4096,\n  },\n  retry: {                                // Retry with backoff\n    maxRetries: 3,\n    initialDelayMs: 1000,\n    backoffMultiplier: 2,\n  },\n  maxRecursionDepth: 3,                   // Agent-as-tool chain limit\n  telemetry: { ... },                     // OpenTelemetry (opt-in)\n});\n```\n\n### `defineAgent(config): AgentDefinition`\n\nCreates a validated agent definition:\n\n```typescript\nconst agent = defineAgent({\n  id: \"my-agent\",\n  name: \"My Agent\",\n  systemPrompt: \"...\",\n  model: { provider: \"openai\", name: \"gpt-4o\" },\n  // ... all fields from AgentDefinition\n});\n```\n\n### `defineTool(config): ToolDefinition`\n\nCreates a typed tool with Zod input validation:\n\n```typescript\nconst tool = defineTool({\n  name: \"my_tool\",\n  description: \"What this tool does\",\n  input: z.object({ ... }),\n  async execute(input, ctx) { ... },\n});\n```\n\n### Runner Methods\n\n| Method | Description |\n|---|---|\n| `runner.invoke(agentId, input, options?)` | Invoke an agent and get the result |\n| `runner.stream(agentId, input, options?)` | Stream an agent invocation |\n| `runner.registerAgent(agent)` | Register an agent definition |\n| `runner.eval(agentId, options?)` | Run evaluations for an agent |\n| `runner.shutdown()` | Clean up MCP connections and flush stores |\n\n### Key Types\n\n| Type | Description |\n|---|---|\n| `AgentDefinition` | Full agent configuration object |\n| `ToolDefinition` | Tool with name, description, schema, and execute function |\n| `ToolReference` | Reference to a tool: `inline`, `mcp`, or `agent` |\n| `InvokeOptions` | Options for `invoke()`: sessionId, contextIds, toolContext, etc. |\n| `InvokeResult` | Result: output, toolCalls, usage, duration, model |\n| `InvokeStream` | Async iterable of `StreamEvent` with `.result` promise |\n| `RunnerConfig` | Full configuration for `createRunner()` |\n| `UnifiedStore` | Combined `AgentStore & SessionStore & ContextStore & LogStore` |\n| `ModelProvider` | Interface for custom model providers |\n\n### Error Types\n\nAll errors extend `AgentRunnerError` with a `code` field:\n\n| Error | Code | Description |\n|---|---|---|\n| `AgentNotFoundError` | `AGENT_NOT_FOUND` | Agent ID doesn't exist |\n| `ToolNotFoundError` | `TOOL_NOT_FOUND` | Tool name not registered |\n| `ToolExecutionError` | `TOOL_EXECUTION_ERROR` | Tool threw during execution |\n| `ModelError` | `MODEL_ERROR` | Model provider returned an error |\n| `ProviderNotFoundError` | `PROVIDER_NOT_FOUND` | No provider SDK installed |\n| `InvocationCancelledError` | `INVOCATION_CANCELLED` | AbortSignal triggered |\n| `MaxStepsExceededError` | `MAX_STEPS_EXCEEDED` | Tool loop hit step limit |\n| `MaxRecursionDepthError` | `MAX_RECURSION_DEPTH` | Agent chain too deep |\n| `RetryExhaustedError` | `RETRY_EXHAUSTED` | All retries failed |\n| `ValidationError` | `VALIDATION_ERROR` | Invalid input |\n\n## Templates\n\nStarter agent configurations for common patterns:\n\n```typescript\nimport { templates } from \"@agent-runner/core/templates\";\nimport { defineAgent } from \"@agent-runner/core\";\n\nrunner.registerAgent(defineAgent({\n  ...templates.chatbot,\n  id: \"my-bot\",\n}));\n```\n\n**Available templates:** `chatbot`, `codeReviewer`, `summarizer`, `dataExtractor`, `creativeWriter`, `customerSupport`, `fitnessCoach`, `researcher`\n\n## CLI\n\n```bash\n# Scaffold a new project\nnpx agent-runner init\n\n# Invoke an agent\nnpx agent-runner invoke greeter \"Hello!\"\n\n# Run evals\nnpx agent-runner eval classifier\n\n# Interactive playground (REPL with session support)\nnpx agent-runner playground greeter\n\n# Launch Studio UI\nnpx agent-runner studio\n```\n\n## Model Providers\n\nagent-runner uses the [Vercel AI SDK](https://sdk.vercel.ai/) internally — calls go directly to providers with your API keys. No middleman.\n\n```typescript\ndefineAgent({\n  model: { provider: \"openai\", name: \"gpt-4o\" },         // OPENAI_API_KEY\n  model: { provider: \"anthropic\", name: \"claude-sonnet-4-20250514\" },  // ANTHROPIC_API_KEY\n  model: { provider: \"google\", name: \"gemini-2.0-flash\" },     // GOOGLE_GENERATIVE_AI_API_KEY\n});\n```\n\nOr bring your own model provider:\n\n```typescript\nconst runner = createRunner({\n  modelProvider: myCustomProvider, // implements ModelProvider interface\n});\n```\n\n## OpenTelemetry\n\nOpt-in observability:\n\n```typescript\nimport { trace } from \"@opentelemetry/api\";\n\nconst runner = createRunner({\n  telemetry: {\n    tracer: trace.getTracer(\"my-app\"),\n    recordIO: false,\n    baseAttributes: { \"service.name\": \"my-app\" },\n  },\n});\n```\n\n**Span hierarchy:** `agent.invoke` → `agent.model.call` / `agent.tool.execute`\n\nZero overhead when telemetry is not configured.\n\n## Related Packages\n\n| Package | Description |\n|---|---|\n| [`@agent-runner/studio`](../studio) | Development UI — agent editor, playground, evals dashboard |\n| [`@agent-runner/store-sqlite`](../store-sqlite) | SQLite storage adapter |\n| [`@agent-runner/store-postgres`](../store-postgres) | PostgreSQL storage adapter |\n\n## Contributing\n\nSee the main [CONTRIBUTING.md](https://github.com/aparry3/agent-runner/blob/main/CONTRIBUTING.md) for guidelines.\n\n## License\n\nMIT © [Aaron Bidworthy](https://github.com/aparry3)\n","readmeFilename":"README.md"}