### Install Dependencies and Run Dev Server Source: https://github.com/better-agent/better-agent/blob/main/examples/tanstack/README.md Installs project dependencies and starts the development server. ```bash npm install npm run dev ``` -------------------------------- ### Install AI SDK Packages Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/ai-sdk/page.mdx Install the necessary npm packages for the AI SDK and its provider. The example uses OpenAI. ```bash npm install @better-agent/ai-sdk ai @ai-sdk/openai ``` -------------------------------- ### Run Scaffold with Options Source: https://github.com/better-agent/better-agent/blob/main/packages/create/README.md Provide scaffold options directly via command-line arguments for non-interactive setup. This allows specifying framework, providers, plugins, and installation behavior. ```bash npm create better-agent my-agent-app -- --framework nextjs --providers openai --plugins logging --no-install ``` -------------------------------- ### Install @better-agent/xai Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/xai/page.mdx Install the xAI package using npm. ```bash npm install @better-agent/xai ``` -------------------------------- ### Install E2B and Daytona SDKs Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Install the necessary SDKs for E2B and Daytona to use the sandbox plugin. ```bash npm install e2b npm install @daytonaio/sdk ``` -------------------------------- ### Install Prisma Adapter and Dependencies Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/prisma/page.mdx Install the Prisma adapter for Better Agent along with Prisma client and Prisma itself. ```bash npm install @better-agent/prisma @prisma/client prisma ``` -------------------------------- ### Copy Environment File Source: https://github.com/better-agent/better-agent/blob/main/examples/tanstack/README.md Copies the example environment file to a new file for configuration. ```bash cp .env.example .env ``` -------------------------------- ### Install Fastify Adapter Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/fastify/page.mdx Install the necessary npm package for the Fastify adapter. ```bash npm install @better-agent/adapters ``` -------------------------------- ### Install Dependencies with Bun Source: https://github.com/better-agent/better-agent/blob/main/CONTRIBUTING.md Installs project dependencies using Bun. Ensure Node.js and Bun are installed. ```sh bun install ``` -------------------------------- ### Install OpenAI Package Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/openai/page.mdx Install the OpenAI provider package for Better Agent. ```bash npm install @better-agent/openai ``` -------------------------------- ### Install Redis Adapter Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/redis/page.mdx Install the necessary packages for the Redis adapter using npm. ```bash npm install @better-agent/redis redis ``` -------------------------------- ### Install Gemini Provider Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/gemini/page.mdx Install the Gemini provider package using npm. ```bash npm install @better-agent/gemini ``` -------------------------------- ### Install OpenRouter Package Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/openrouter/page.mdx Install the OpenRouter package using npm. ```bash npm install @better-agent/openrouter ``` -------------------------------- ### Install Kysely and PostgreSQL Driver Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/kysely/page.mdx Install the Kysely adapter for Better Agent along with the Kysely core library and the PostgreSQL driver. ```bash npm install @better-agent/kysely kysely pg ``` -------------------------------- ### Install Drizzle Adapter and Dependencies Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/drizzle/page.mdx Install the Drizzle adapter for Better Agent along with Drizzle ORM and the PostgreSQL driver. ```bash npm install @better-agent/drizzle drizzle-orm pg ``` -------------------------------- ### Setup Prisma Storage in Better Agent Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/prisma/page.mdx Initialize Better Agent with the Prisma storage adapter by passing an existing Prisma client instance. ```typescript import { betterAgent } from "@better-agent/core"; import { prismaStorage } from "@better-agent/prisma"; import { PrismaClient } from "@prisma/client"; const prisma = new PrismaClient(); export const app = betterAgent({ storage: prismaStorage({ client: prisma, }), agents: [supportAgent], }); ``` -------------------------------- ### Install Better Agent Core and OpenAI Provider Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/get-started/page.mdx Install the necessary packages for Better Agent and the OpenAI provider using npm. ```bash npm install @better-agent/core @better-agent/openai ``` -------------------------------- ### Install Ollama Provider Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/ollama/page.mdx Install the Ollama provider package using npm. ```bash npm install @better-agent/ollama ``` -------------------------------- ### Server-side Agent Setup Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/sveltekit/page.mdx Configure the Better Agent with OpenAI on the server. Ensure your OpenAI API key is available in the environment variables. ```typescript // src/lib/better-agent/server.ts import { env } from "$env/dynamic/private"; import { betterAgent, defineAgent } from "@better-agent/core"; import { createOpenAI } from "@better-agent/openai"; const openai = createOpenAI({ apiKey: env.OPENAI_API_KEY, }); const supportAgent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: "You help customers.", }); const app = betterAgent({ agents: [supportAgent], basePath: "/api/agents", }); export default app; ``` -------------------------------- ### Basic Logging Setup Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/logging/page.mdx Initializes the better-agent with the logging plugin. By default, logs are sent to the console, all logging groups are enabled, and the minimum level is 'info'. ```typescript import { betterAgent } from "@better-agent/core"; import { logging } from "@better-agent/plugins"; export const app = betterAgent({ agents: [supportAgent], plugins: [logging()], }); ``` -------------------------------- ### Install Anthropic Provider Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/anthropic/page.mdx Install the Anthropic provider package using npm. ```bash npm install @better-agent/anthropic ``` -------------------------------- ### Setup Better Agent Server Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/elysia/page.mdx Defines and configures the Better Agent server with specified agents. This code should be placed in your server setup file. ```typescript // lib/better-agent/server.ts import { betterAgent, defineAgent } from "@better-agent/core"; import { openai } from "@better-agent/openai"; const supportAgent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: "You help customers.", }); const app = betterAgent({ agents: [supportAgent], basePath: "/api/agents", }); export default app; ``` -------------------------------- ### Server API Route Setup Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/astro/page.mdx Defines the Better Agent server instance with a support agent and configures the base API path. ```typescript // src/lib/better-agent/server.ts import { betterAgent, defineAgent } from "@better-agent/core"; import { openai } from "@better-agent/openai"; const supportAgent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: "You help customers.", }); const app = betterAgent({ agents: [supportAgent], basePath: "/api/agents", }); export default app; ``` -------------------------------- ### Install CORS Middleware Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/express/page.mdx Install the CORS package to handle cross-origin requests. ```bash npm install cors ``` -------------------------------- ### Install Workers AI Package Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/workers-ai/page.mdx Install the necessary package for using Workers AI with Better Agent. ```bash npm install @better-agent/workers-ai ``` -------------------------------- ### Run Interactive Scaffold Source: https://github.com/better-agent/better-agent/blob/main/packages/create/README.md Execute the interactive command to scaffold a new Better Agent app. This is the default way to start a new project. ```bash npm create better-agent ``` -------------------------------- ### Basic Rate Limiting Setup Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/rate-limit/page.mdx Configure a global rate limit for all requests within a specified time window. This is suitable for single-instance applications or local development. ```typescript import { betterAgent } from "@better-agent/core"; import { rateLimit } from "@better-agent/plugins"; export const app = betterAgent({ agents: [supportAgent], plugins: [ rateLimit({ windowMs: 60_000, max: 100, }), ], }); ``` -------------------------------- ### Install Fastify CORS Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/fastify/page.mdx Install the CORS plugin for Fastify to handle cross-origin requests. ```bash npm install @fastify/cors ``` -------------------------------- ### Connect to MCP Servers and Expose Tools Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx Use `mcpTools` to connect to Model Context Protocol servers and expose their tools to an agent. This example connects to GitHub and a local filesystem server. ```typescript import { mcpTools } from "@better-agent/core/mcp"; const mcp = mcpTools({ servers: { github: { transport: { type: "http", url: "https://api.githubcopilot.com/mcp", }, }, filesystem: { transport: { type: "stdio", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "./data"], }, }, }, }); const agent = defineAgent({ name: "dev", model: openai("gpt-5.5"), instruction: "You help with development tasks.", tools: async (ctx) => [searchTool, ...(await mcp(ctx))], }); ``` -------------------------------- ### Configure In-Memory Storage Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/storage/page.mdx Configure in-memory storage for local development and tests. This is a simple setup for quick iteration. ```typescript import { betterAgent, createInMemoryStorage } from "@better-agent/core"; export const app = betterAgent({ storage: createInMemoryStorage(), agents: [supportAgent], }); ``` -------------------------------- ### Server-side Agent Setup in Remix Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/remix/page.mdx Configure the Better Agent server instance within a Remix lib file. This sets up the agents and their base path for API communication. ```typescript // app/lib/better-agent/server.ts import { betterAgent, defineAgent } from "@better-agent/core"; import { openai } from "@better-agent/openai"; const supportAgent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: "You help customers.", }); const app = betterAgent({ agents: [supportAgent], basePath: "/api/agents", }); export default app; ``` -------------------------------- ### Setup Drizzle Storage with Better Agent Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/drizzle/page.mdx Configure Better Agent to use Drizzle as its storage adapter by providing a Drizzle database instance and dialect. ```typescript import { betterAgent } from "@better-agent/core"; import { drizzleStorage } from "@better-agent/drizzle"; import { drizzle } from "drizzle-orm/node-postgres"; import { Client } from "pg"; import * as betterAgentSchema from "./better-agent.schema"; const client = new Client({ connectionString: process.env.DATABASE_URL, }); await client.connect(); const db = drizzle({ client, schema: { ...betterAgentSchema, }, }); export const app = betterAgent({ storage: drizzleStorage({ db, dialect: "postgres", }), agents: [supportAgent], }); ``` -------------------------------- ### Configure Sandbox Creation Settings Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Set fixed creation settings for the sandbox using `createConfig` and fallback settings with `createDefaults`. This example specifies a Node.js 20 template and development environment variables. ```typescript const plugin = sandbox({ client: createDaytonaSandboxClient({ apiKey: process.env.DAYTONA_API_KEY, }), createConfig: { template: "node:20", envs: { NODE_ENV: "development", }, }, createDefaults: { startupTimeoutMs: 90_000, }, }); ``` -------------------------------- ### Basic Chat Component Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/sveltekit/page.mdx Implement a basic chat interface using the `createAgentChat` Svelte store. This example demonstrates sending messages and displaying chat history and errors. ```svelte
{ event.preventDefault(); const message = input.trim(); if (!message) return; input = ""; chat.sendMessage(message); }}> {#each $chat.messages as message (message.id)}

{message.role}

{/each} {#if $chat.error}

{$chat.error.message}

{/if}
``` -------------------------------- ### Plugin Guard Example Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/auth/page.mdx Implement a plugin guard to enforce authentication. This guard returns an unauthorized response if no auth context is present. ```typescript const workspaceGuard = definePlugin({ id: "workspace-guard", guards: [ async ({ auth }) => { return auth ? null : new Response("Unauthorized", { status: 401 }); }, ], }); ``` -------------------------------- ### Providing Tools via a Plugin Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/plugins/page.mdx This example shows how a plugin can expose custom tools to agents. It defines a `currentTime` tool using `defineTool` and registers it within the plugin using the `tools` property. ```typescript import { definePlugin, defineTool } from "@better-agent/core"; import { z } from "zod"; const currentTime = defineTool({ name: "current_time", target: "server", description: "Return the current UTC time.", inputSchema: z.object({}), execute: async () => ({ time: new Date().toISOString() }), }); export const time = definePlugin({ id: "time", tools: [currentTime], }); ``` -------------------------------- ### Configure App Memory Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/memory/page.mdx Configure memory for the entire application using `createMemory`. This example sets the history window to the last 20 messages. ```typescript import { betterAgent, createMemory } from "@better-agent/core"; export const app = betterAgent({ storage, memory: createMemory({ lastMessages: 20 }), agents: [supportAgent], }); ``` -------------------------------- ### Agent Access with Capabilities Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/auth/page.mdx Require specific agent capabilities for access. This example ensures only callers with the 'support_chat' capability can run the support agent. ```typescript const supportAgent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: "You help customers.", access: ({ auth }) => auth?.scopes?.includes("support_chat") ?? false, }); ``` -------------------------------- ### Setup Kysely Storage with Better Agent Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/kysely/page.mdx Configure Better Agent to use Kysely for storage by passing a Kysely database instance to the `kyselyStorage` function. Ensure your Kysely instance is correctly initialized with a dialect and connection pool. ```typescript import { betterAgent, } from "@better-agent/core"; import { kyselyStorage, } from "@better-agent/kysely"; import { Kysely, PostgresDialect } from "kysely"; import { Pool } from "pg"; const db = new Kysely({ dialect: new PostgresDialect({ pool: new Pool({ connectionString: process.env.DATABASE_URL, }), }), }); export const app = betterAgent({ storage: kyselyStorage({ db, dialect: "postgres", }), agents: [supportAgent], }); ``` -------------------------------- ### Resume an Interrupted Client Tool Run Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx This example shows how to manually resume an agent run after it was interrupted by a client tool, providing the necessary thread ID and resolution payload. ```typescript const threadId = "thread_123"; const result = await app.agent("support").run({ threadId, messages }); if (result.outcome === "interrupt") { const interrupt = result.interrupts[0]; await app.agent("support").run({ threadId, resume: [ { interruptId: interrupt.id, status: "resolved", payload: { status: "success", result: { confirmed: true } }, }, ], }); } ``` -------------------------------- ### Setup Redis Storage with Better Agent Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/redis/page.mdx Configure Better Agent to use Redis for storage by passing a connected Redis client. Ensure the Redis client is connected before passing it to the storage adapter. ```typescript import { betterAgent, } from "@better-agent/core"; import { redisStorage, } from "@better-agent/redis"; import { createClient, } from "redis"; const client = await createClient({ url: process.env.REDIS_URL, }).connect(); export const app = betterAgent({ storage: redisStorage({ client, }), agents: [supportAgent], }); ``` -------------------------------- ### Customize Sandbox Tool Prefixes Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Customize the tool names used by the sandbox plugin by setting a prefix. This example sets the prefix to 'workspace'. ```typescript const plugin = sandbox({ prefix: "workspace", client: createE2BSandboxClient({ apiKey: process.env.E2B_API_KEY, }), }); ``` -------------------------------- ### Control Sandbox Reuse with Session Key Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Configure sandbox reuse by providing a `sessionKey` function. This example reuses sandboxes based on agent name and thread ID. ```typescript const plugin = sandbox({ client: createE2BSandboxClient({ apiKey: process.env.E2B_API_KEY, }), sessionKey: ({ agentName, threadId }) => { if (!threadId) return undefined; return `${agentName}:${threadId}`; }, }); ``` -------------------------------- ### Define Tool with Conditional Approval Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx Use the `approval: { resolve: ... }` option for conditional approval based on tool input. This example refunds an order only if the amount exceeds 50. ```typescript const refundTool = defineTool({ name: "refund", target: "server", description: "Issue a refund.", inputSchema: z.object({ orderId: z.string(), amount: z.number() }), approval: { resolve: ({ toolInput }) => toolInput.amount > 50, }, async execute({ orderId, amount }) { return stripe.refunds.create({ payment_intent: orderId, amount }); }, }); ``` -------------------------------- ### Define Plugin with HTTP Endpoint Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/plugins/page.mdx Example of defining a plugin with a GET endpoint at /health. The handler returns a JSON response. ```typescript const health = definePlugin({ id: "health", endpoints: [ { method: "GET", path: "/health", handler: async () => Response.json({ ok: true }), }, ], }); ``` -------------------------------- ### Defining a Custom Plugin Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/plugins/page.mdx This example demonstrates the basic structure for defining a custom plugin using `definePlugin`. Each plugin requires a unique `id` and can implement various lifecycle hooks like `onEvent` for custom logic. ```typescript import { definePlugin } from "@better-agent/core"; export const analytics = definePlugin({ id: "analytics", onEvent: async (event, ctx) => { await trackEvent({ type: event.type, runId: ctx.runId, agent: ctx.agentName, }); }, }); ``` -------------------------------- ### Basic Chat Interface with useAgent Hook Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/remix/page.mdx Implement a basic chat UI in a Remix component using the `useAgent` hook. This example shows sending messages and displaying agent responses. ```tsx import { useAgent } from "@better-agent/client/react"; import { useState } from "react"; import { client } from "../lib/better-agent/client"; export default function ChatPage() { const [input, setInput] = useState(""); const agent = useAgent(client.agent("support"), { threadId: "main", }); return (
{ event.preventDefault(); const message = input.trim(); if (!message) return; setInput(""); agent.sendMessage(message); }} > {agent.messages.map((message) => (

{message.role}

))} setInput(event.target.value)} />
); } ``` -------------------------------- ### Run and Stream Agent Interactions Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/agent/page.mdx Register agents with `betterAgent` and execute them using `.run()` for a final result or `.stream()` for real-time event processing. This example shows how to initiate a run and consume streamed events. ```typescript import { betterAgent } from "@better-agent/core"; const app = betterAgent({ agents: [agent] }); const result = await app.agent("support").run({ messages: [{ role: "user", content: "I need a refund." }], }); const stream = await app.agent("support").stream({ messages: [{ role: "user", content: "I need a refund." }], }); for await (const event of stream.events) { console.log(event.type); } ``` -------------------------------- ### Observe Events in React with onEvent Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/events/page.mdx Use the `onEvent` hook in React to observe events for observability or custom UI behavior. This example logs tool call start events. ```tsx import { EventType } from "@better-agent/core"; import { useAgent } from "@better-agent/client/react"; import { client } from "@/better-agent/client"; function Chat() { const agent = useAgent(client.agent("support"), { onEvent(event) { if (event.type === EventType.TOOL_CALL_START) { console.log("tool started", event.toolCallName); } }, }); return ; } ``` -------------------------------- ### Loading and Switching Threads Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/sveltekit/page.mdx Manage conversation history by using helper functions to load messages, switch between different threads, or clear the current thread to start a new conversation. ```svelte ``` -------------------------------- ### Stream Events from Agent Run Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/events/page.mdx Use `.stream()` to receive events as they happen. Await `final` to get the finished run result. This example processes text message deltas and logs the final result. ```typescript import { EventType } from "@better-agent/core"; const stream = await app.agent("support").stream({ messages: [{ role: "user", content: "Check my order status." }], }); for await (const event of stream.events) { if (event.type === EventType.TEXT_MESSAGE_CONTENT) { process.stdout.write(event.delta); } } const result = await stream.final; ``` -------------------------------- ### Rate Limiting with Shared Storage Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/rate-limit/page.mdx Implement rate limiting across multiple server instances by using a shared storage mechanism. This example demonstrates a custom in-memory store, but it can be adapted for external databases or caches. ```typescript const rows = new Map(); const plugin = rateLimit({ windowMs: 60_000, max: 100, storage: { async read({ bucket }) { return rows.get(bucket.id) ?? null; }, async write({ bucket, prevVersion, next }) { const current = rows.get(bucket.id) ?? null; if (prevVersion === null) { if (current) return false; rows.set(bucket.id, next); return true; } if (!current || current.version !== prevVersion) return false; rows.set(bucket.id, next); return true; }, }, }); ``` -------------------------------- ### Create a Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/client/page.mdx Initialize the client by passing the server app type and the base URL for the agent handler. Ensure the baseURL points to the route where your app handler is mounted. ```typescript import { createClient } from "@better-agent/client"; import type app from "@/better-agent/server"; export const client = createClient({ baseURL: "/api/agents", }); ``` -------------------------------- ### Create Composite Storage with Table Routing Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/storage/page.mdx Route a single storage area to a specific backend using composite storage for finer control. This example routes 'streamEvents' to Redis while using PostgreSQL as the default. ```typescript const storage = createCompositeStorage({ default: postgresStorage, tables: { streamEvents: redisStorage, }, }); ``` -------------------------------- ### Run Prisma Migrations and Generate Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/prisma/page.mdx After updating your Prisma schema, run database migrations and generate the Prisma client. ```bash npx prisma migrate dev npx prisma generate ``` -------------------------------- ### Create a Support Ticket Tool Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx This server tool demonstrates creating a support ticket, including priority levels and using context for agent and run information. ```typescript const createTicket = defineTool({ name: "create_ticket", target: "server", description: "Create a support ticket.", inputSchema: z.object({ subject: z.string(), body: z.string(), priority: z.enum(["low", "medium", "high"]), }), async execute(input, ctx) { const ticket = await db.tickets.create({ ...input, createdBy: ctx.agentName, runId: ctx.runId, }); return { ticketId: ticket.id }; }, }); ``` -------------------------------- ### Running an Agent with Context Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/agent/page.mdx Demonstrates how to run an agent, passing specific context data that matches the agent's defined context schema. ```typescript await app.agent("analyst").run({ messages, context: { userId: "usr_123", plan: "pro" }, }); ``` -------------------------------- ### Instantiate Image and Video Generation Models Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/xai/page.mdx Create instances for image and video generation models. These are used for direct generation tasks. ```typescript const image = xai.image("grok-2-image"); const video = xai.video("grok-video"); ``` -------------------------------- ### Agent Access Control Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/auth/page.mdx Define agent access using the `access` property. This example restricts access to users with the 'admin' scope. ```typescript const adminAgent = defineAgent({ name: "admin", model: openai("gpt-5.5"), instruction: "You help admins manage the workspace.", access: ({ auth }) => auth?.scopes?.includes("admin") ?? false, }); ``` -------------------------------- ### Client Initialization Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/sveltekit/page.mdx Initialize the Better Agent client for use in your SvelteKit frontend. Align the `baseURL` with the server's `basePath` and the API route. ```typescript // src/lib/better-agent/client.ts import { createClient } from "@better-agent/client"; import type app from "$lib/better-agent/server"; export const client = createClient({ baseURL: "/api/agents", }); ``` -------------------------------- ### Configure Gemini Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/gemini/page.mdx Create a Gemini client instance, typically requiring an API key. ```typescript import { createGemini } from "@better-agent/gemini"; const gemini = createGemini({ apiKey: process.env.GOOGLE_GENERATIVE_AI_API_KEY, }); ``` -------------------------------- ### Scaffold a Better Agent Project with CLI Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/get-started/page.mdx Use the npx command to create a new Better Agent project with a full framework scaffold. ```bash npx create-better-agent ``` -------------------------------- ### Configure xAI Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/xai/page.mdx Create an xAI client instance, typically used for direct model calls or tool integrations. Requires an API key from environment variables. ```typescript import { createXai } from "@better-agent/xai"; const xai = createXai({ apiKey: process.env.XAI_API_KEY, }); ``` -------------------------------- ### Initialize Agent Run with State Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/state/page.mdx Pass an initial state object when starting an agent run. The final state is available in the run result. ```typescript const result = await app.agent("support").run({ messages, state: { step: "triage", selectedOrderId: null, }, }); console.log(result.state); ``` -------------------------------- ### Configure E2B Sandbox Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Set up the sandbox plugin with the E2B client, requiring an E2B API key. ```typescript import { betterAgent } from "@better-agent/core"; import { createE2BSandboxClient, sandbox } from "@better-agent/plugins"; export const app = betterAgent({ agents: [coderAgent], plugins: [ sandbox({ client: createE2BSandboxClient({ apiKey: process.env.E2B_API_KEY, }), }), ], }); ``` -------------------------------- ### Update State from Server Tool Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/state/page.mdx Server-side tools can read and modify the execution context's state using `state.patch()`. This example updates the `selectedOrderId`. ```typescript const selectOrder = defineTool({ name: "select_order", target: "server", description: "Select the order being handled.", inputSchema: z.object({ orderId: z.string(), }), execute: async (input, { state }) => { state.patch([{ op: "replace", path: "/selectedOrderId", value: input.orderId }]); return { selected: true }; }, }); ``` -------------------------------- ### Implement Shared Sandbox Store Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Use a custom `store` object to manage sandbox reuse across different workers or instances, using Redis as an example. ```typescript const plugin = sandbox({ client: createE2BSandboxClient({ apiKey: process.env.E2B_API_KEY, }), store: { get: async (key) => redis.get(key), set: async (key, sandboxId) => { await redis.set(key, sandboxId); }, delete: async (key) => { await redis.del(key); }, }, }); ``` -------------------------------- ### Configure Multiple MCP Servers with Prefixes Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/mcp/page.mdx Combine tools from multiple MCP servers, such as GitHub and a local filesystem, into a single tool source. Use the `prefix` option to prevent tool name collisions. ```typescript const tools = mcpTools({ servers: { github: { transport: { type: "http", url: "https://api.githubcopilot.com/mcp" }, prefix: "gh", }, filesystem: { transport: { type: "stdio", command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "./data"], }, prefix: "fs", }, }, }); ``` -------------------------------- ### Add Provider-Specific Tools like Web Search Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx Providers like OpenAI offer built-in tools. Use the provider helper, e.g., `openai.tools.webSearch`, to add them to an agent's toolset. ```typescript import { openai } from "@better-agent/openai"; const agent = defineAgent({ name: "researcher", model: openai("gpt-5.5"), instruction: "Research the topic using web search.", tools: [ openai.tools.webSearch({ searchContextSize: "medium", }), summarizeTool, ], }); ``` -------------------------------- ### Nuxt Client Initialization Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/nuxt/page.mdx Set up the Better Agent client for use in your Nuxt application. This client is typed against your server configuration. ```typescript // lib/better-agent/client.ts import { createClient } from "@better-agent/client"; import type app from "./server"; export const client = createClient({ baseURL: "/api/agents", }); ``` -------------------------------- ### Configure Agent-Specific Memory Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/memory/page.mdx Define an agent with its own memory configuration, overriding or supplementing app-level memory. This example sets a history window of 50 messages for the support agent. ```typescript const supportAgent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: "You help customers.", memory: createMemory({ lastMessages: 50 }), }); ``` -------------------------------- ### Define a Server Tool Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx Use `defineTool` to create a server-side tool. Provide a name, target, description, input schema, and an execute function. ```typescript import { defineTool } from "@better-agent/core"; import { z } from "zod"; const getWeather = defineTool({ name: "get_weather", target: "server", description: "Get the current weather for a location.", inputSchema: z.object({ location: z.string(), }), async execute({ location }) { const res = await fetch(`https://api.weather.com/${location}`); return res.json(); }, }); ``` -------------------------------- ### Error Shape Example Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/errors/page.mdx HTTP errors return problem details in a structured JSON format. Use `status` for transport handling, `code` for app logic, and `detail` for the message. ```json { "type": "https://better-agent.com/docs/concepts/errors#validation-failed", "title": "Unprocessable Entity", "status": 422, "detail": "Invalid input.", "code": "VALIDATION_FAILED", "issues": [] } ``` -------------------------------- ### Run Development Scripts with Bun Source: https://github.com/better-agent/better-agent/blob/main/CONTRIBUTING.md Executes common development scripts like build, typecheck, lint, and check using Bun. Use 'bun run check' for behavioral changes. ```sh bun run build bun run typecheck bun run lint:ci bun run check ``` -------------------------------- ### AI SDK Text Generation Wrapper Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/ai-sdk/page.mdx Use `aiSdkTextModel` for direct text generation calls outside the agent loop, commonly from server tools. This example defines a 'summarize' tool. ```typescript import { aiSdkTextModel, aiSdkEmbeddingModel, aiSdkImageModel, } from "@better-agent/ai-sdk"; const text = aiSdkTextModel({ model: openai("gpt-5.5"), providerId: "openai", modelId: "gpt-5.5", }); const summarize = defineTool({ name: "summarize", description: "Summarize text with an AI SDK model.", inputSchema: z.object({ content: z.string(), }), execute: async ({ content }) => { const result = await text.generate({ input: `Summarize this in three bullets:\n\n${content}`, }); return { summary: result.text }; }, }); ``` -------------------------------- ### Configure Custom Ollama Server Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/ollama/page.mdx Create an Ollama instance when your server is not at the default location. Specify the baseURL for custom configurations. ```typescript import { createOllama } from "@better-agent/ollama"; const ollama = createOllama({ baseURL: "http://localhost:11434/api", }); ``` -------------------------------- ### Better Agent Client Initialization Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/astro/page.mdx Creates a typed client instance for interacting with the Better Agent API, specifying the base URL. ```typescript // src/lib/better-agent/client.ts import { createClient } from "@better-agent/client"; import type app from "./server"; export const client = createClient({ baseURL: "/api/agents", }); ``` -------------------------------- ### Tool Approval UI Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/sveltekit/page.mdx Render UI for server tools that require user approval by iterating over `$chat.pendingToolApprovals`. Provide buttons to approve or reject the tool call. ```svelte {#each $chat.pendingToolApprovals as approval (approval.interruptId)}

{approval.toolName}

{/each} ``` -------------------------------- ### Create Typed Client Instance Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/typescript/page.mdx Creates a typed client instance by importing the server app's type. This provides the client with knowledge of agent names, context, memory helpers, and client tool handlers. ```typescript // client.ts import { createClient } from "@better-agent/client"; import type app from "@/better-agent/server"; export const client = createClient({ baseURL: "/api/agents", }); ``` -------------------------------- ### Basic Chat Interface with useAgent Hook Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/nuxt/page.mdx Implement a basic chat interface in a Nuxt Vue component using the `useAgent` hook. This example shows sending messages and displaying agent responses. ```vue ``` -------------------------------- ### Client with Request Rewriting Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/client/page.mdx Customize outgoing requests using the `prepareRequest` option. This function allows you to modify request headers, bodies, or other properties before the request is sent, for example, to add a unique request ID. ```typescript const client = createClient({ baseURL: "/api/agents", prepareRequest(request) { request.headers.set("x-request-id", crypto.randomUUID()); return request; }, }); ``` -------------------------------- ### Use Existing MCP Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/mcp/page.mdx Configure `mcpTools` to use an already created and connected MCP `Client` instance by passing it via the `client` option. ```typescript mcpTools({ servers: { internal: { client: existingClient, }, }, }); ``` -------------------------------- ### Configure Daytona Sandbox Client Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/sandbox/page.mdx Configure the sandbox plugin with the Daytona client, including API key, target, template kind, and creation settings. ```typescript import { betterAgent } from "@better-agent/core"; import { createDaytonaSandboxClient, sandbox, } from "@better-agent/plugins"; export const app = betterAgent({ agents: [coderAgent], plugins: [ sandbox({ client: createDaytonaSandboxClient({ apiKey: process.env.DAYTONA_API_KEY, target: process.env.DAYTONA_TARGET, templateKind: "image", }), createConfig: { template: "node:20", lifecycle: { idleStopMs: 60 * 60_000, }, }, }), ], }); ``` -------------------------------- ### SolidStart API Route Handler Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/solidstart/page.mdx Creates a catch-all API route in SolidStart to handle requests for the Better Agent, forwarding them to the server app handler. ```typescript // src/routes/api/agents/[...path]/index.ts import type { APIEvent } from "@solidjs/start/server"; import app from "../../../../lib/better-agent/server"; const handle = (event: APIEvent) => app.handler(event.request); export const GET = handle; export const POST = handle; export const PUT = handle; export const PATCH = handle; export const DELETE = handle; export const OPTIONS = handle; export const HEAD = handle; ``` -------------------------------- ### Configure Provider Options at Runtime Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/xai/page.mdx Pass provider-specific options, such as 'reasoningEffort', to the xAI provider during an agent's run. ```typescript await app.agent("support").run({ messages, providerOptions: { xai: { reasoningEffort: "medium", }, }, }); ``` -------------------------------- ### Client-side Better Agent Initialization Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/remix/page.mdx Create a typed client instance for Better Agent in Remix. This client is used to interact with the server-side agent routes. ```typescript // app/lib/better-agent/client.ts import { createClient } from "@better-agent/client"; import type app from "./server"; export const client = createClient({ baseURL: "/api/agents", }); ``` -------------------------------- ### List Threads and Messages Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/client/page.mdx Access memory helpers to list saved threads and messages. Use `client.agent('name').memory.threads.list()` to get a list of threads and `client.agent('name').memory.messages.list()` to retrieve messages for a specific thread. ```typescript const threads = await client.agent("support").memory.threads.list(); const messages = await client .agent("support") .memory.messages.list("thread_123", { limit: 20 }); ``` -------------------------------- ### Basic IP Allowlist Configuration Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/plugins/ip-allowlist/page.mdx Configure the IP allowlist plugin with a list of allowed IP addresses. By default, it reads common client IP headers. ```typescript import { betterAgent } from "@better-agent/core"; import { ipAllowlist } from "@better-agent/plugins"; export const app = betterAgent({ agents: [supportAgent], plugins: [ ipAllowlist({ allow: ["203.0.113.10"], }), ], }); ``` -------------------------------- ### Define Agent with Dynamic Tools Based on Context Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/tools/page.mdx An agent's `tools` can be a function that dynamically selects tools based on request context, such as user role. This example adds delete and config tools only for admin users. ```typescript const agent = defineAgent({ name: "assistant", model: openai("gpt-5.5"), instruction: "You help users manage their workspace.", contextSchema: z.object({ role: z.enum(["member", "admin"]), }), tools: (ctx) => { const base = [readTool, searchTool]; if (ctx.role === "admin") { base.push(deleteTool, configTool); } return base; }, }); ``` -------------------------------- ### Configure Output Schema Options Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/structured-output/page.mdx Configure optional name and description for the output schema. These can be passed to the provider to give more context about the expected output structure. ```typescript output: { name: "ticket_classification", description: "Classify the support ticket.", schema: z.object({ category: z.enum(["bug", "feature", "question"]), summary: z.string(), }), } ``` -------------------------------- ### Plugin for Tenant Context Management Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/plugins/page.mdx This plugin demonstrates how to use the `onStep` hook to modify messages within the agent's context. It prepends system information, such as the run ID, to the existing messages before a step is executed. ```typescript const tenantContext = definePlugin({ id: "tenant-context", onStep: async (ctx) => { ctx.updateMessages((messages) => [ { role: "system", content: `Run id: ${ctx.runId}`, }, ...messages, ]); }, }); ``` -------------------------------- ### Create In-Memory Storage Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/memory/page.mdx Create an in-memory storage adapter for local development and testing using `createInMemoryStorage`. ```typescript import { createInMemoryStorage } from "@better-agent/core"; const storage = createInMemoryStorage(); ``` -------------------------------- ### Runtime Provider Options Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/gemini/page.mdx Pass provider-specific options, like Gemini's thinking budget, at runtime. ```typescript await app.agent("support").run({ messages, providerOptions: { google: { thinkingConfig: { thinkingBudget: 1024 }, }, }, }); ``` -------------------------------- ### Define Agent with GitHub MCP Tools Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/mcp/page.mdx Create an agent that can access tools from a GitHub MCP server. This snippet demonstrates setting up the `mcpTools` for an HTTP transport and defining an agent that uses these tools. ```typescript import { betterAgent, defineAgent } from "@better-agent/core"; import { mcpTools } from "@better-agent/core/mcp"; import { openai } from "@better-agent/openai"; const githubTools = mcpTools({ servers: { github: { transport: { type: "http", url: "https://api.githubcopilot.com/mcp", }, }, }, }); const devAgent = defineAgent({ name: "dev", model: openai("gpt-5.5"), instruction: "You help with development tasks.", tools: githubTools, }); export const app = betterAgent({ agents: [devAgent] }); ``` -------------------------------- ### Approving or Rejecting Server Tool Calls Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/nextjs/page.mdx Render UI for server tools awaiting approval using `pendingToolApprovals`. Allows users to approve or reject tool calls. ```tsx function Approvals({ agent }: { agent: ReturnType }) { return ( <> {agent.pendingToolApprovals.map((approval) => (

{approval.toolName}

))} ); } ``` -------------------------------- ### Implementing a Workspace Guard Plugin Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/plugins/page.mdx This snippet shows how to create a plugin that acts as a guard, running before app requests. It checks for a workspace ID in the headers and authorization to determine if the request should proceed or be denied. ```typescript const workspaceGuard = definePlugin({ id: "workspace-guard", guards: [ async ({ request, auth }) => { const workspaceId = request.headers.get("x-workspace-id"); if (!auth || !workspaceId) { return new Response("Unauthorized", { status: 401 }); } const allowed = await canAccessWorkspace(auth, workspaceId); return allowed ? null : new Response("Forbidden", { status: 403 }); }, ], }); ``` -------------------------------- ### Agent with Request-Aware Instruction Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/concepts/agent/page.mdx Configures an agent with an instruction function that dynamically adapts based on request context. Requires a context schema to be defined. ```typescript const agent = defineAgent({ name: "support", model: openai("gpt-5.5"), instruction: (context) => `You are a support agent for ${context.company}. Speak ${context.language}.`, contextSchema: z.object({ company: z.string(), language: z.string(), }), }); ``` -------------------------------- ### Generate Prisma Schema with Better Agent Models Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/database/prisma/page.mdx Generate the Prisma schema, including Better Agent's models, for a specified database provider. ```bash npx @better-agent/prisma generate --provider postgresql ``` -------------------------------- ### Define Agent with Hosted Tools Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/openai/page.mdx Configure an agent to use OpenAI's hosted web search tool. Specify parameters like searchContextSize for the tool's behavior. ```typescript const agent = defineAgent({ name: "researcher", model: openai("gpt-5.5"), tools: [ openai.tools.webSearch({ searchContextSize: "medium" }), ], }); ``` -------------------------------- ### Configure OpenAI Provider Options at Runtime Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/providers/openai/page.mdx Pass specific OpenAI provider options, like reasoningEffort, during agent execution. This allows for dynamic adjustment of model behavior per run. ```typescript await app.agent("support").run({ messages, providerOptions: { openai: { reasoningEffort: "medium", }, }, }); ``` -------------------------------- ### Next.js Route Handler for Better Agent Source: https://github.com/better-agent/better-agent/blob/main/docs/app/docs/integrations/nextjs/page.mdx Create a catch-all route to handle all incoming requests and forward them to the Better Agent handler. ```typescript // app/api/agents/[...path]/route.ts import app from "@/lib/better-agent/server"; export const dynamic = "force-dynamic"; const handle = (request: Request) => app.handler(request); export const GET = handle; export const POST = handle; export const PUT = handle; export const PATCH = handle; export const DELETE = handle; export const OPTIONS = handle; export const HEAD = handle; ```