### Clone and Install Project Dependencies Source: https://github.com/lleverage-ai/agent-sdk/blob/main/CONTRIBUTING.md Clone the repository and install project dependencies using Bun. This is the initial setup step for contributing. ```bash git clone https://github.com/lleverage-ai/agent-sdk.git cd agent-sdk bun install ``` -------------------------------- ### Full Agent Stream v1 Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/migration/agent-stream-v1.md This example demonstrates wiring together the InMemoryEventStore, Projector, WsServer, and WsClient for a complete agent stream setup. It includes type definitions for agent events and transcript state, store initialization, projector configuration, and server/client setup for real-time event handling and subscription. ```typescript import { InMemoryEventStore } from "@lleverage-ai/agent-threads/stores/event-memory"; import { Projector } from "@lleverage-ai/agent-threads"; import { WsServer } from "@lleverage-ai/agent-threads/server"; import { WsClient } from "@lleverage-ai/agent-threads/client"; import type { StoredEvent } from "@lleverage-ai/agent-threads"; // -- Types -- type AgentEvent = | { kind: "text-delta"; text: string } | { kind: "tool-call"; name: string; args: unknown } | { kind: "step-finished" }; interface TranscriptState { text: string; toolCalls: string[]; steps: number; } // -- Store -- const store = new InMemoryEventStore(); // -- Projector -- const projector = new Projector({ initialState: { text: "", toolCalls: [], steps: 0 }, reducer: (state, event: StoredEvent) => { switch (event.event.kind) { case "text-delta": return { ...state, text: state.text + event.event.text }; case "tool-call": return { ...state, toolCalls: [...state.toolCalls, event.event.name], }; case "step-finished": return { ...state, steps: state.steps + 1 }; } }, }); // -- Server -- const wsServer = new WsServer({ store }); // When your agent produces events: async function onAgentEvent(sessionId: string, event: AgentEvent) { const stored = await store.append(sessionId, [event]); wsServer.broadcast(sessionId, stored); } // -- Client -- const client = new WsClient({ url: "ws://localhost:8080" }); client.connect(); async function watchSession(sessionId: string) { for await (const item of client.subscribe(sessionId)) { if ("type" in item && item.type === "replay-end") { console.log("Replay complete, now live"); continue; } projector.apply([item as StoredEvent); console.log("Transcript:", projector.getState()); } } ``` -------------------------------- ### Quick Start Agent Creation Source: https://github.com/lleverage-ai/agent-sdk/blob/main/packages/agent-sdk/README.md Create a basic AI agent using the SDK, defining its model, system prompt, and tools. This example demonstrates setting up an agent with the Anthropic Claude model and a simple 'greet' tool. ```typescript import { anthropic, } from "@ai-sdk/anthropic"; import { createAgent, } from "@lleverage-ai/agent-sdk"; import { tool, } from "ai"; import { z, } from "zod"; const agent = createAgent({ model: anthropic("claude-sonnet-4-20250514"), systemPrompt: "You are a helpful assistant.", tools: { greet: tool({ description: "Greet a person by name", inputSchema: z.object({ name: z.string(), }), execute: async ({ name }) => `Hello, ${name}!`, }), }, }); const result = await agent.generate({ prompt: "Say hello to Alice", }); console.log(result.text); ``` -------------------------------- ### Complete CLI Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/agent-session.md A full command-line interface example demonstrating agent creation, session initialization, and interactive chat loop with interrupt handling and output streaming. ```typescript import * as readline from "node:readline"; import { createAgent, createAgentSession, FilesystemBackend, } from "@lleverage-ai/agent-sdk"; const backend = new FilesystemBackend({ rootDir: process.cwd(), enableBash: true, }); const agent = createAgent({ model: "anthropic/claude-sonnet-4", systemPrompt: "You are a helpful assistant.", backend, }); const session = createAgentSession({ agent, threadId: `cli-${Date.now()}`, }); const rl = readline.createInterface({ input: process.stdin, output: process.stdout, }); console.log("Chat started. Type 'exit' to quit.\n"); async function runSession() { for await (const output of session.run()) { switch (output.type) { case "waiting_for_input": rl.question("You: ", (input) => { if (input.trim().toLowerCase() === "exit") { session.stop(); rl.close(); process.exit(0); } session.sendMessage(input.trim()); }); break; case "text_delta": if (output.text) { process.stdout.write(`Assistant: ${output.text}`); } break; case "generation_complete": process.stdout.write("\n\n"); break; case "interrupt": console.log(`\n[Interrupt: ${output.interrupt.type}]`); rl.question("Your response: ", (response) => { session.respondToInterrupt(output.interrupt.id, { answer: response }); }); break; case "error": console.error("\nError:", output.error.message); break; } } } runSession().catch(console.error); ``` -------------------------------- ### Install @lleverage-ai/agent-threads Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/migration/agent-stream-v1.md Install the agent-threads library using npm. ```bash npm install @lleverage-ai/agent-threads ``` -------------------------------- ### Install Dependencies with Bun Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Use this command to install all project dependencies using Bun. ```bash bun install ``` -------------------------------- ### Quick Start: Create and Use an Agent Source: https://github.com/lleverage-ai/agent-sdk/blob/main/README.md Initialize an agent with a model, system prompt, and a simple 'greet' tool. Then, generate a response by prompting the agent. ```typescript import { createAgent } from "@lleverage-ai/agent-sdk"; import { anthropic } from "@ai-sdk/anthropic"; import { tool } from "ai"; import { z } from "zod"; const agent = createAgent({ model: anthropic("claude-sonnet-4-20250514"), systemPrompt: "You are a friendly assistant.", tools: { greet: tool({ description: "Greet a person by name", inputSchema: z.object({ name: z.string().describe("The name of the person to greet"), }), execute: async ({ name }) => `Hello, ${name}!`, }), }, }); const result = await agent.generate({ prompt: "Say hello to Alice", }); console.log(result.text); ``` -------------------------------- ### Install @lleverage-ai/agent-sdk Source: https://github.com/lleverage-ai/agent-sdk/blob/main/packages/agent-sdk/README.md Install the core agent SDK package along with AI and Zod dependencies. ```bash bun add @lleverage-ai/agent-sdk ai zod ``` -------------------------------- ### Install agent-threads Source: https://github.com/lleverage-ai/agent-sdk/blob/main/packages/agent-threads/README.md Install the agent-threads package and zod using bun. ```bash bun add @lleverage-ai/agent-threads zod ``` -------------------------------- ### Quick Production Agent Setup Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/security.md Use `createProductionAgent` for a one-line setup combining security, observability, and recommended hooks for production. It automatically configures security presets, logging, metrics, tracing, and secrets filtering. ```typescript import { createProductionAgent } from "@lleverage-ai/agent-sdk"; import { anthropic } from "@ai-sdk/anthropic"; // One-line production agent setup const { agent, observability } = createProductionAgent({ model: anthropic("claude-sonnet-4-20250514"), }); // Access observability primitives observability.logger?.info("Agent started"); observability.metrics?.requests.inc(); ``` -------------------------------- ### Complete Production Security Setup Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/security.md Combine `applySecurityPolicy` with production presets, guardrails, and secrets filtering for a robust security configuration. This example also disables the 'bash' core tool. ```typescript import { createAgent } from "@lleverage-ai/agent-sdk"; import { applySecurityPolicy } from "@lleverage-ai/agent-sdk/security"; import { createGuardrailsHooks, createSecretsFilterHooks, COMMON_SECRET_PATTERNS, } from "@lleverage-ai/agent-sdk/hooks"; const agent = createAgent({ model, // Apply production security preset ...applySecurityPolicy("production"), // Add guardrails and secrets filtering hooks: { ...createGuardrailsHooks({ blockedInputPatterns: [/ignore\s+previous\s+instructions/i], blockedOutputPatterns: [/\d{3}-\d{2}-\d{4}/g], }), ...createSecretsFilterHooks({ patterns: Object.values(COMMON_SECRET_PATTERNS), }), }, // Additional tool restrictions disabledCoreTools: ["bash"], }); ``` -------------------------------- ### Install Agent SDK and AI Provider Source: https://github.com/lleverage-ai/agent-sdk/blob/main/README.md Install the core agent SDK along with Zod for schema validation and an AI provider like Anthropic or OpenAI. ```bash bun add @lleverage-ai/agent-sdk ai zod bun add @ai-sdk/anthropic # or @ai-sdk/openai ``` -------------------------------- ### Install an AI Provider Source: https://github.com/lleverage-ai/agent-sdk/blob/main/packages/agent-sdk/README.md Install at least one AI provider package, such as the Anthropic provider. ```bash bun add @ai-sdk/anthropic ``` -------------------------------- ### FilesystemBackend File Operations Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/backends.md Provides examples of common file operations using the FilesystemBackend, including reading, writing, editing, globbing, searching, checking existence, and getting file stats. ```APIDOC ## FilesystemBackend File Operations ### Description Perform various file operations using the `FilesystemBackend`. ### File Operations - **Read file**: `await backend.read(path: string): Promise` - **Write file**: `await backend.write(path: string, content: string): Promise` - **Edit file**: `await backend.edit(path: string, options: { oldText: string; newText: string }): Promise` - **Glob pattern matching**: `await backend.glob(pattern: string): Promise` - **Search with grep**: `await backend.grep(path: string, pattern: string): Promise` - **Check if path exists**: `await backend.exists(path: string): Promise` - **Get file stats**: `await backend.stat(path: string): Promise` ### Request Example ```typescript // Read file const content = await backend.read("/project/src/index.ts"); // Write file await backend.write("/project/src/new-file.ts", "content"); // Edit file (find and replace) await backend.edit("/project/src/index.ts", { oldText: "old content", newText: "new content", }); // Glob pattern matching const files = await backend.glob("/project/src/**/*.ts"); // Search with grep const matches = await backend.grep("/project/src", "pattern"); // Check if path exists const exists = await backend.exists("/project/src/index.ts"); // Get file stats const stats = await backend.stat("/project/src/index.ts"); ``` ``` -------------------------------- ### One-Line Setup for Common Observability Needs Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/observability.md This preset provides a one-line setup for common observability needs, including logging, metrics, and tracing. It automatically wires hooks together for request counters, latency histograms, tool metrics, and spans. ```typescript import { createConsoleTransport, createConsoleSpanExporter, createObservabilityPreset, } from "@lleverage-ai/agent-sdk"; const { logger, metrics, tracer, hooks } = createObservabilityPreset({ name: "my-agent", enableMetrics: true, enableTracing: true, loggerOptions: { level: "info", transports: [createConsoleTransport()], }, spanExporters: [createConsoleSpanExporter()], }); const agent = createAgent({ model, hooks, }); ``` -------------------------------- ### Create Production Agent Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Set up a production-ready agent with default configurations for logging, metrics, and tracing. This provides a robust starting point for agents deployed in production. ```typescript import { createProductionAgent, createSecureProductionAgent, DEFAULT_BLOCKED_INPUT_PATTERNS, DEFAULT_BLOCKED_OUTPUT_PATTERNS, } from "@lleverage-ai/agent-sdk"; // Full production setup with hooks, logging, metrics const { agent, logger, metrics, hooks } = await createProductionAgent({ model, systemPrompt: "You are a helpful assistant.", tools: myTools, // Automatically includes: logging, metrics, tracing, guardrails }); ``` -------------------------------- ### Install Agent Threads for Persistence Source: https://github.com/lleverage-ai/agent-sdk/blob/main/README.md If durable transcript or transport primitives are needed, install the agent-threads package. ```bash bun add @lleverage-ai/agent-threads ``` -------------------------------- ### Skill Tool Content Payload Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md An example of the XML-style content payload returned by the skill tool, detailing the skill's name, instructions, tools, path, and resources. ```xml Use git tools for repository operations. git_status /path/to/skills/git /path/to/skills/git/scripts/status.sh ``` -------------------------------- ### Accessing Skill Resources with SDK Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md Demonstrates how to get resource paths for scripts, references, and assets within a skill using `getSkillResourcePath` and read them using `fs.promises.readFile`. ```typescript import { getSkillResourcePath } from "@lleverage-ai/agent-sdk"; import { readFile } from "node:fs/promises"; // Get path to a script const scriptPath = getSkillResourcePath(skill, "scripts", "extract.py"); // Read a reference document const refPath = getSkillResourcePath(skill, "references", "REFERENCE.md"); const reference = await readFile(refPath, "utf-8"); // Load a template const templatePath = getSkillResourcePath(skill, "assets", "template.json"); const template = JSON.parse(await readFile(templatePath, "utf-8")); ``` -------------------------------- ### Initialize KeyValueStoreSaver Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/persistence.md Implement a checkpointer using a generic key-value store. Examples include using an in-memory store or integrating with external stores like Redis by implementing the `KeyValueStore` interface. ```typescript import { createKeyValueStoreSaver, InMemoryStore, } from "@lleverage-ai/agent-sdk"; // In-memory store const store = new InMemoryStore(); const checkpointer = createKeyValueStoreSaver({ store }); // Redis store (custom implementation) class RedisStore implements KeyValueStore { async get(key: string) { /* ... */ } async set(key: string, value: any) { /* ... */ } async delete(key: string) { /* ... */ } async list(prefix?: string) { /* ... */ } } const redisCheckpointer = createKeyValueStoreSaver({ store: new RedisStore(), }); ``` -------------------------------- ### Define a Plugin Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Define a plugin with a name, description, and associated tools. You can also configure skills, hooks, an MCP server, and a setup function that runs when the agent is initialized. ```typescript const plugin = definePlugin({ name: string, description?: string, tools?: Record, skills?: Skill[], hooks?: PluginHooks, mcpServer?: MCPServerConfig, setup?: (agent: Agent) => Promise, }); ``` -------------------------------- ### Example Test Structure Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Demonstrates a typical test file structure using Vitest. It includes mocking external dependencies and setting up test suites with beforeEach hooks for clearing mocks. ```typescript import { describe, it, expect, vi, beforeEach } from "vitest"; vi.mock("ai", async () => { const actual = await vi.importActual("ai"); return { ...actual, generateText: vi.fn() }; }); describe("feature", () => { beforeEach(() => { vi.clearAllMocks(); }); it("does something", () => { // test }); }); ``` -------------------------------- ### FilesystemBackend Initialization Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/backends.md Demonstrates how to initialize the FilesystemBackend with various configuration options, including enabling shell command execution. ```APIDOC ## FilesystemBackend Initialization ### Description Initialize the FilesystemBackend with configuration options to control its behavior, such as root directory, allowed paths, file size limits, and shell execution capabilities. ### Configuration Options - `rootDir` (string): Required. Base directory for all operations. - `allowedPaths` (string[]): Paths the agent can access. Defaults to all under `rootDir`. - `maxFileSize` (number): Maximum file size in bytes. Defaults to 10MB. - `followSymlinks` (boolean): Whether to follow symbolic links. Defaults to `false`. - `encoding` (string): Default file encoding. Defaults to "utf-8". - `enableBash` (boolean): Enable shell command execution. Defaults to `false`. - `timeout` (number): Command timeout in ms (when `enableBash` is true). Defaults to 120000. - `maxOutputSize` (number): Max stdout/stderr size in bytes (when `enableBash` is true). Defaults to 100000. - `blockedCommands` (RegExp[]): Commands to reject (when `enableBash` is true). Defaults to `[]`. - `allowedCommands` (string[]): Allowlist of commands (when `enableBash` is true). Defaults to all. - `allowDangerous` (boolean): Allow dangerous patterns (when `enableBash` is true). Defaults to `false`. - `shell` (string): Shell to use for execution. Defaults to `/bin/bash` or `cmd` on Windows. - `env` (object): Additional environment variables. Defaults to `{}`. ### Request Example ```typescript import { FilesystemBackend, hasExecuteCapability, } from "@lleverage-ai/agent-sdk"; const backend = new FilesystemBackend({ rootDir: "/project", allowedPaths: ["/project/src", "/project/tests"], maxFileSize: 10 * 1024 * 1024, // 10MB followSymlinks: false, // Enable shell command execution enableBash: true, timeout: 30000, // 30 seconds maxOutputSize: 100000, blockedCommands: [/rm -rf \/ /, /sudo/], }); // Check if backend supports command execution if (hasExecuteCapability(backend)) { const result = await backend.execute("npm test"); console.log(result.output); console.log(result.exitCode); } ``` ``` -------------------------------- ### Set up WebSocket Server and Client Source: https://github.com/lleverage-ai/agent-sdk/blob/main/packages/agent-threads/README.md Initializes a WebSocket server with a store and a WebSocket client connecting to a specified URL. ```typescript import { WsServer } from "@lleverage-ai/agent-threads/server"; import { WsClient } from "@lleverage-ai/agent-threads/client"; const server = new WsServer({ store }); // Call server.handleConnection(ws) from your HTTP server's upgrade handler const client = new WsClient({ url: "ws://localhost:8080" }); ``` -------------------------------- ### StateBackend Initialization and Usage Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/backends.md Demonstrates how to initialize and use the StateBackend for in-memory, sandboxed file operations, useful for testing and simulation. ```APIDOC ## StateBackend ### Description Use the `StateBackend` for in-memory, sandboxed filesystem operations. It's ideal for testing agent behavior without affecting the actual filesystem or for simulating specific file states. ### Initialization and Usage - **Create agent state**: `const state = createAgentState()` - **Initialize backend**: `const backend = new StateBackend(state)` Operations are similar to `FilesystemBackend` but operate solely in memory. ### Request Example ```typescript import { StateBackend, createAgentState } from "@lleverage-ai/agent-sdk"; const state = createAgentState(); const backend = new StateBackend(state); // Pre-populate files state.files.set("/project/index.ts", "console.log('hello');"); // Operations work the same as FilesystemBackend const content = await backend.read("/project/index.ts"); await backend.write("/project/new.ts", "new content"); ``` ### Use Cases - **Testing**: Test agent behavior without touching the real filesystem. - **Sandboxing**: Run untrusted operations in isolation. - **Simulation**: Simulate filesystem states for specific scenarios. **Note**: `StateBackend` does not support command execution. Use `FilesystemBackend` with `enableBash: true` for that capability. ``` -------------------------------- ### Initialize FilesystemBackend Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/backends.md Instantiate FilesystemBackend with root directory, allowed paths, file size limits, and optional shell execution capabilities. Configure security settings like blocked commands and timeouts for command execution. ```typescript import { FilesystemBackend, hasExecuteCapability, } from "@lleverage-ai/agent-sdk"; const backend = new FilesystemBackend({ rootDir: "/project", allowedPaths: ["/project/src", "/project/tests"], maxFileSize: 10 * 1024 * 1024, // 10MB followSymlinks: false, // Enable shell command execution enableBash: true, timeout: 30000, // 30 seconds maxOutputSize: 100000, blockedCommands: [/rm -rf \/ /, /sudo/], }); // Check if backend supports command execution if (hasExecuteCapability(backend)) { const result = await backend.execute("npm test"); console.log(result.output); console.log(result.exitCode); } ``` -------------------------------- ### Create Core Tools with Filesystem Backend and Bash Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Initializes core tools using a filesystem backend, enabling bash command execution. Configure root directory and command timeout. ```typescript const fsBackend = new FilesystemBackend({ rootDir: process.cwd(), enableBash: true, // Enable shell command execution timeout: 30000, // Optional: command timeout in ms }); const { tools: fsTools } = createCoreTools({ backend: fsBackend, state, // Optional: enable subagent delegation subagents: [researcherAgent, coderAgent], parentAgent, defaultModel, // Optional: enable MCP tool search mcpManager, }); ``` -------------------------------- ### Set up an event store Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/migration/agent-stream-v1.md Initialize an in-memory event store. For persistence, use SQLiteEventStore. ```typescript import { InMemoryEventStore } from "@lleverage-ai/agent-threads/stores/event-memory"; // Or for persistence: // import { SQLiteEventStore } from "@lleverage-ai/agent-threads/stores/event-sqlite"; const store = new InMemoryEventStore(); ``` -------------------------------- ### Set Up Production Observability Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/observability.md Configure logger, metrics registry, tracer, and event store for comprehensive observability. Ensure correct environment variables and ports are set. ```typescript import { createAgent, createLogger, createMetricsRegistry, createTracer, createLoggingHooks, createObservabilityEventHooks, } from "@lleverage-ai/agent-sdk"; // Set up observability const logger = createLogger({ level: process.env.LOG_LEVEL || "info", transports: [ createJsonTransport({ stream: process.stdout }), ], }); const metrics = createMetricsRegistry({ exporters: [ createPrometheusExporter({ port: 9090 }), ], }); const tracer = createTracer({ serviceName: "my-agent", exporters: [ createOTLPExporter({ endpoint: process.env.OTLP_ENDPOINT }), ], }); const eventStore = createObservabilityEventStore(); // Create agent with full observability const agent = createAgent({ model, hooks: { ...createLoggingHooks({ logger }), ...createObservabilityEventHooks(eventStore), }, }); // Graceful shutdown process.on("SIGTERM", async () => { await tracer.flush(); await metrics.flush(); process.exit(0); }); ``` -------------------------------- ### Production MCP Security Configuration Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/mcp.md Example of a secure production MCP configuration using `http` type. It demonstrates restricting operations to read-only with `allowedTools`, enabling input validation with `validateInputs`, and enforcing schemas with `requireSchema`. ```typescript // Production configuration with all security controls const docsPlugin = definePlugin({ name: "docs", mcpServer: { type: "http", url: "https://docs.example.com/mcp", headers: { Authorization: "Bearer ${DOCS_API_TOKEN}" }, // Only allow read-only operations allowedTools: ["search_docs", "get_document", "list_categories"], // Validate all inputs validateInputs: true, // Require schemas for all tools requireSchema: true, }, }); ``` -------------------------------- ### Wire up the WebSocket server Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/migration/agent-stream-v1.md Initialize the WsServer and handle incoming WebSocket connections. Broadcast events after appending them to the store. ```typescript import { WsServer } from "@lleverage-ai/agent-threads/server"; const server = new WsServer({ store, heartbeatIntervalMs: 30_000, heartbeatTimeoutMs: 10_000, maxBufferSize: 1000, }); // In your HTTP upgrade handler (works with any WebSocket library): httpServer.on("upgrade", (req, socket, head) => { wss.handleUpgrade(req, socket, head, (ws) => { server.handleConnection(ws); }); }); // After appending events, broadcast to connected clients: const stored = await store.append("session-123", [ { kind: "message", text: "Hello!" }, ]); server.broadcast("session-123", stored); ``` -------------------------------- ### agent.streamDataResponse Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Get a data stream response. ```APIDOC ## agent.streamDataResponse ### Description Get a data stream response. ### Parameters #### Request Body - **options** (object) - Optional - Options for streaming the data response. (Specific fields not detailed in source) ``` -------------------------------- ### Creating an Agent with Agent Teams Plugin Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/subagents.md Demonstrates how to set up an agent with the agent-teams plugin, defining teammates with their IDs, names, descriptions, and creation logic, along with a coordinator. ```typescript import { createAgent, createAgentTeamsPlugin, InMemoryTeamCoordinator, } from "@lleverage-ai/agent-sdk"; const teamsPlugin = createAgentTeamsPlugin({ teammates: [ { id: "researcher", name: "Researcher", description: "Researches topics and gathers information", create: ({ model }) => createAgent({ model, systemPrompt: "You are a research specialist.", }), }, { id: "writer", name: "Writer", description: "Writes content based on research", create: ({ model }) => createAgent({ model, systemPrompt: "You are a content writer.", }), }, ], coordinator: new InMemoryTeamCoordinator(), }); const agent = createAgent({ model, systemPrompt: "You are a team lead. Coordinate research and writing.", plugins: [teamsPlugin], }); ``` -------------------------------- ### Create Core Tools with Filesystem Backend Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Initialize core tools, including filesystem operations and optional shell execution, by providing a `FilesystemBackend` instance. You can disable specific tools like 'bash' if needed. ```typescript import { createCoreTools, FilesystemBackend } from "@lleverage-ai/agent-sdk"; const backend = new FilesystemBackend({ rootDir: "/project", enableBash: true, // Enable bash tool }); const { tools } = createCoreTools({ backend, state, disabled: ["bash"], // Optionally disable specific tools }); ``` -------------------------------- ### agent.streamRaw Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Get the raw AI SDK stream. ```APIDOC ## agent.streamRaw ### Description Get the raw AI SDK stream. ### Parameters #### Request Body - **options** (object) - Optional - Options for streaming the raw response. (Specific fields not detailed in source) ``` -------------------------------- ### Initialize Task Store Options Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Demonstrates initializing different types of task stores: in-memory for development, file-based for persistence, and key-value for cloud environments. Choose the store that best fits your persistence needs. ```typescript import { MemoryTaskStore, FileTaskStore, KVTaskStore, createBackgroundTask, updateBackgroundTask, recoverRunningTasks, recoverFailedTasks, } from "@lleverage-ai/agent-sdk"; // In-memory (development) const memoryStore = new MemoryTaskStore(); // File-based (persistence) const fileStore = new FileTaskStore({ dir: ".agent/tasks" }); // Key-value store (cloud) const kvStore = new KVTaskStore({ store: myKVStore }); ``` -------------------------------- ### Linear Conversation Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/architecture/canonical-schema.md Illustrates a simple, linear conversation flow where each message directly follows the previous one. ```text M1 (user) → M2 (assistant) → M3 (user) → M4 (assistant) parentMessageId: null → M1 → M2 → M3 ``` -------------------------------- ### Skill Registry Operations Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md Provides examples of common operations on a `SkillRegistry`, including registering, checking existence, listing, loading, and unregistering skills. ```typescript // Register additional skills registry.register(newSkill); // Check if skill exists if (registry.has("git")) { console.log("Git skill is available"); } // Check if skill is loaded if (registry.isLoaded("git")) { console.log("Git skill is active"); } // List available (unloaded) skills const available = registry.listAvailable(); // List loaded skills const loaded = registry.listLoaded(); // List all skills const all = registry.listAll(); // Load a skill const result = registry.load("git"); if (result.success) { // Inject tools and instructions into agent } // Unregister a skill registry.unregister("old-skill"); // Reset all skills to unloaded state registry.reset(); ``` -------------------------------- ### Creating a Skill Registry Instance Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md Shows how to initialize a `SkillRegistry` with a list of skills and an optional callback for when a skill is loaded. ```typescript import { SkillRegistry } from "@lleverage-ai/agent-sdk"; const registry = new SkillRegistry({ skills: [gitSkill, dockerSkill, kubernetesSkill], onSkillLoaded: (name, result) => { console.log(`Loaded skill: ${name}`); console.log(`Tools: ${Object.keys(result.tools).join(", ")}`); }, }); ``` -------------------------------- ### Branched Conversation Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/architecture/canonical-schema.md Demonstrates a branched conversation where a new message M3' forks from an earlier point (M2), creating an alternative history. ```text M1 → M2 → M3 (original) ↘ M3' (regenerated) parentMessageId of M3: M2 parentMessageId of M3': M2 ``` -------------------------------- ### Build All Packages with Bun Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Execute this command to build all packages within the workspace. ```bash bun run build ``` -------------------------------- ### Get and Log Token Budget Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/context-compaction.md Retrieves the current token budget for a given set of messages and logs the usage percentage and remaining tokens. ```typescript const budget = contextManager.getBudget(messages); console.log(`Usage: ${(budget.usage * 100).toFixed(1)}%`); console.log(`Remaining: ${budget.remaining} tokens`); ``` -------------------------------- ### Logging Middleware Options Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/middleware.md Customize the behavior of the logging middleware. Control what gets logged, redact sensitive information, and provide a custom logger. ```typescript createLoggingMiddleware({ level: "debug", // "debug" | "info" | "warn" | "error" logRequests: true, logResponses: true, logToolCalls: true, redactSecrets: true, logger: customLogger, // Optional custom logger }); ``` -------------------------------- ### Configure FilesystemBackend Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Instantiate `FilesystemBackend` to manage file operations. Configure options like the root directory, allowed paths, and maximum file size. You can also enable shell execution and set security options for commands. ```typescript const backend = new FilesystemBackend({ rootDir: string, allowedPaths?: string[], maxFileSize?: number, followSymlinks?: boolean, encoding?: string, // Shell execution options enableBash?: boolean, // Enable execute() method timeout?: number, // Command timeout in ms maxOutputSize?: number, // Max stdout/stderr size blockedCommands?: (string | RegExp)[], allowedCommands?: (string | RegExp)[], allowDangerous?: boolean, shell?: string, env?: Record, }); ``` -------------------------------- ### Configure Agent with FilesystemBackend Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/backends.md Create an agent using the FilesystemBackend, which provides file system access. Enable bash commands by setting `enableBash: true` if the backend supports execution capabilities. ```typescript import { createAgent, FilesystemBackend } from "@lleverage-ai/agent-sdk"; // Filesystem backend with bash enabled const agent = createAgent({ model, backend: new FilesystemBackend({ rootDir: "/project", enableBash: true, }), }); // The agent's core tools (read, write, edit, glob, grep, bash) will use the configured backend. // The bash tool is only available when the backend has execute capability. ``` -------------------------------- ### Connect from the client Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/migration/agent-stream-v1.md Initialize the WsClient to connect to the server. Subscribe to a session to receive events and apply them using the projector. ```typescript import { WsClient } from "@lleverage-ai/agent-threads/client"; const client = new WsClient({ url: "ws://localhost:8080", // WebSocket constructor is optional — defaults to globalThis.WebSocket reconnect: true, maxReconnectAttempts: 10, baseReconnectDelayMs: 1_000, maxReconnectDelayMs: 30_000, }); client.on("stateChange", (state) => { console.log("Connection state:", state); }); client.connect(); // Subscribe returns an AsyncIterable for await (const item of client.subscribe("session-123")) { if ("type" in item && item.type === "replay-end") { console.log("Caught up! Now receiving live events."); continue; } // item is a StoredEvent projector.apply([item]); console.log("State:", projector.getState()); } ``` -------------------------------- ### Basic AgentSession Usage with Event Loop Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/agent-session.md Demonstrates setting up an AgentSession and running its event loop to handle user input, text deltas, generation completion, interrupts, and errors. ```typescript import { createAgent, createAgentSession, FilesystemBackend, } from "@lleverage-ai/agent-sdk"; const backend = new FilesystemBackend({ rootDir: process.cwd(), enableBash: true, }); const agent = createAgent({ model: "anthropic/claude-sonnet-4", systemPrompt: "You are a helpful assistant.", backend, }); const session = createAgentSession({ agent, threadId: "session-123", // Enable checkpointing }); // Run the event loop for await (const output of session.run()) { switch (output.type) { case "waiting_for_input": const input = await getUserInput(); if (input === "exit") { session.stop(); } else { session.sendMessage(input); } break; case "text_delta": process.stdout.write(output.text); break; case "generation_complete": console.log("\n"); break; case "interrupt": const response = await handleInterrupt(output.interrupt); session.respondToInterrupt(output.interrupt.id, response); break; case "error": console.error("Error:", output.error); break; } } ``` -------------------------------- ### Create and Use a Tracer Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/observability.md Initialize a tracer with a service name and span exporter. Start spans for operations, set attributes, and end them to record trace data. ```typescript import { createTracer, createConsoleSpanExporter, SemanticAttributes, } from "@lleverage-ai/agent-sdk"; const tracer = createTracer({ serviceName: "my-agent", exporters: [createConsoleSpanExporter()], }); const span = tracer.startSpan("agent.generate"); span.setAttribute(SemanticAttributes.MODEL_NAME, "claude-3"); // ... do work span.end(); ``` -------------------------------- ### Initialize FilesystemBackend with Bash Execution Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Instantiate FilesystemBackend for file operations and bash execution. Use `hasExecuteCapability` to check for bash support. ```typescript import { FilesystemBackend, hasExecuteCapability } from "@lleverage-ai/agent-sdk"; // Single backend for both file ops and bash execution const backend = new FilesystemBackend({ rootDir: process.cwd(), enableBash: true, }); const { tools } = createCoreTools({ backend, state }); // Check for bash capability if (hasExecuteCapability(backend)) { const result = await backend.execute("npm test"); } ``` -------------------------------- ### Configure FilesystemBackend with Bash Execution Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Initialize a `FilesystemBackend` with options to enable bash execution, set command timeouts, control output size, specify the shell, and configure environment variables and command filtering. ```typescript import { FilesystemBackend, hasExecuteCapability } from "@lleverage-ai/agent-sdk"; const backend = new FilesystemBackend({ rootDir: process.cwd(), enableBash: true, // Enable shell command execution timeout: 30000, // Command timeout (default: 120000ms) maxOutputSize: 100000, // Max output size (default: 100000 chars) shell: "/bin/bash", // Shell to use (default: /bin/bash or cmd on Windows) env: { NODE_ENV: "dev" }, // Additional environment variables blockedCommands: [/rm -rf/],// Block dangerous commands allowedCommands: [/npm/], // Allowlist (if set, only these are allowed) allowDangerous: false, // Allow dangerous patterns (default: false) }); // Check if backend supports execute if (hasExecuteCapability(backend)) { const result = await backend.execute("echo hello"); console.log(result.output); // "hello\n" } ``` -------------------------------- ### Create Stateful Middleware Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/middleware.md Implement middleware that maintains its own state across requests. This example shows a middleware that tracks the number of requests it has processed and exposes a method to retrieve statistics. ```typescript function createStatefulMiddleware() { let requestCount = 0; return { name: "stateful", async onRequest(context: MiddlewareContext) { requestCount++; context.metadata = { ...context.metadata, requestNumber: requestCount }; return context; }, getStats() { return { requestCount }; }, }; } const middleware = createStatefulMiddleware(); const agent = createAgent({ model, middleware: [middleware] }); // Later console.log(middleware.getStats()); // { requestCount: 42 } ``` -------------------------------- ### Get User-Friendly Error Messages Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/errors.md Employ the `getUserMessage` utility to translate SDK errors into messages suitable for end-users. This abstracts away technical details and provides clear feedback. ```typescript import { getUserMessage } from "@lleverage-ai/agent-sdk"; try { await agent.generate({ prompt }); } catch (error) { // Get a message suitable for displaying to users const message = getUserMessage(error); console.log(message); // "The request timed out. Please try again." } ``` -------------------------------- ### FilesystemBackend Command Execution Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/backends.md Illustrates how to execute shell commands using the FilesystemBackend when `enableBash` is set to true. ```APIDOC ## FilesystemBackend Command Execution ### Description Execute shell commands using the `FilesystemBackend` when the `enableBash` option is true. ### Command Execution - **Execute command**: `await backend.execute(command: string): Promise<{ output: string; exitCode: number; truncated: boolean }>` ### Request Example ```typescript const backend = new FilesystemBackend({ rootDir: "/project", enableBash: true, timeout: 30000, blockedCommands: [/rm -rf/, /sudo/], }); // Execute command const result = await backend.execute("npm test"); console.log(result.output); // stdout + stderr console.log(result.exitCode); // 0 for success console.log(result.truncated); // true if output was truncated ``` ``` -------------------------------- ### Create a File-Based PDF Processing Skill Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md Define a file-based skill using a Markdown file with YAML frontmatter. This example shows how to specify metadata, features, and usage for PDF processing. ```markdown --- name: pdf-processing description: Extract text and tables from PDF files, fill forms, and merge documents. Use when working with PDF files. license: Apache-2.0 compatibility: Requires Python 3.8+, PyPDF2, and pdfplumber metadata: author: acme-corp version: "2.1.0" category: document-processing --- # PDF Processing Skill Comprehensive PDF manipulation capabilities. ## Features ### 1. Text Extraction Extract text content from PDF files while preserving formatting. **Script:** `scripts/extract_text.py` ### 2. Table Extraction Extract tables from PDFs into CSV or JSON format. **Script:** `scripts/extract_tables.py` ### 3. Form Filling Populate PDF form fields programmatically. **Script:** `scripts/fill_form.py` ### 4. PDF Merging Combine multiple PDF files into a single document. **Script:** `scripts/merge_pdfs.py` ## Usage All scripts accept a `-h` flag for detailed help. Example: ```bash python scripts/extract_text.py input.pdf output.txt ``` See `references/REFERENCE.md` for complete API documentation. ``` -------------------------------- ### createBashTool Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Create a tool for executing shell commands. ```APIDOC ## createBashTool ### Description Create shell execution tool. ### Parameters #### Request Body - **options** (object) - Required - Options for creating the bash tool. (Specific fields not detailed in source) ``` -------------------------------- ### Good vs. Poor Skill Description Example Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md Illustrates effective and ineffective skill descriptions. A good description clearly states the skill's purpose, use cases, and relevant keywords. ```typescript // Good description description: "Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF documents or when user mentions PDFs, forms, or document extraction." // Poor description description: "PDF stuff" ``` -------------------------------- ### Create Secure Production Agent Source: https://github.com/lleverage-ai/agent-sdk/blob/main/AGENTS.md Instantiate a secure production agent, specifying the 'production' security policy for enhanced protections. This variant includes additional security measures beyond the standard production setup. ```typescript // Secure variant with additional protections const { agent } = await createSecureProductionAgent({ model, systemPrompt: "...", securityPolicy: "production", }); ``` -------------------------------- ### Level 2: Loading Skill Instructions and Tools Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/skills.md Illustrates loading a skill to access its full instructions and tools, typically done when an agent decides to activate a specific skill. ```typescript // Agent decides to load the git skill const result = registry.load("git"); // Now has access to: // - result.tools (inline tools) // - result.instructions (Markdown body from SKILL.md) ``` -------------------------------- ### Initialize FilesystemMemoryStore Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/persistence.md Set up a memory store that persists agent memory to the filesystem. Specify the root directory for storing memory files. ```typescript import { FilesystemMemoryStore, loadAgentMemory, } from "@lleverage-ai/agent-sdk"; const store = new FilesystemMemoryStore({ rootDir: ".agent/memory", }); // Load all memory for an agent const memory = await loadAgentMemory({ store, agentId: "my-agent", }); ``` -------------------------------- ### Define External MCP Server Plugin Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/mcp.md Use `definePlugin` with `mcpServer` to connect to an external MCP server. Configure the server type, command, arguments, and environment variables. The `GITHUB_TOKEN` environment variable is shown as an example that expands from `process.env`. ```typescript import { definePlugin } from "@lleverage-ai/agent-sdk"; const githubPlugin = definePlugin({ name: "github", mcpServer: { type: "stdio", command: "npx", args: ["-y", "@modelcontextprotocol/server-github"], env: { GITHUB_TOKEN: "${GITHUB_TOKEN}" }, // Expands from process.env }, }); ``` -------------------------------- ### Create Agent with a Plugin Source: https://github.com/lleverage-ai/agent-sdk/blob/main/README.md Initialize an agent and include the custom 'myPlugin' in its configuration. Tools within the plugin will be accessible. ```typescript const agent = createAgent({ model, plugins: [myPlugin], }); // Inline plugin tool available as: my-plugin__myTool ``` -------------------------------- ### Create Agent with Model, Prompt, and Max Steps Source: https://github.com/lleverage-ai/agent-sdk/blob/main/README.md Configure an agent with a specific language model, a system prompt, and a maximum number of execution steps. Custom tools and plugins can also be provided. ```typescript const agent = createAgent({ model: anthropic("claude-sonnet-4-20250514"), systemPrompt: "You are a helpful assistant.", maxSteps: 10, tools: { /* custom tools */ }, plugins: [ /* plugins */ ], }); ``` -------------------------------- ### Create an Agent Instance Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Use `createAgent` to instantiate a new agent. Configure its behavior with options like the language model, system prompt, tools, and plugins. ```typescript const agent = createAgent({ // Required model: LanguageModel, // Optional systemPrompt?: string, maxSteps?: number, tools?: Record, plugins?: Plugin[], hooks?: AgentHooks, middleware?: Middleware[], backend?: Backend, // FilesystemBackend or StateBackend checkpointer?: Checkpointer, contextManager?: ContextManager, subagents?: Subagent[], taskStore?: TaskStore, disabledCoreTools?: string[], allowedTools?: string[], pluginLoading?: "eager" | "proxy", mcpManager?: MCPManager, mcpEagerLoad?: boolean, toolSearch?: ToolSearchOptions, }); ``` -------------------------------- ### createCoreTools Source: https://github.com/lleverage-ai/agent-sdk/blob/main/docs/api-reference.md Create all core tools provided by the SDK. ```APIDOC ## createCoreTools ### Description Create all core tools. ### Parameters #### Request Body - **backend** (FilesystemBackend) - Required - The backend to use for filesystem operations. - **state** - Required - The state object. - **disabled** (string[]) - Optional - An array of core tool names to disable. ```