@octavus/docs 2.13.0 → 2.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -14,7 +14,7 @@ var docs_default = [
14
14
  section: "getting-started",
15
15
  title: "Quick Start",
16
16
  description: "Get your first Octavus agent running in minutes.",
17
- content: "\n# Quick Start\n\nThis guide will walk you through integrating Octavus into your application in under 10 minutes.\n\n## Prerequisites\n\n- Node.js 18+\n- An Octavus account with API key\n- A Next.js application (or any Node.js backend)\n\n## Test Your Agent First\n\nBefore integrating with SDKs, use **Agent Preview** to test your agent directly in the platform:\n\n1. Open your agent in the platform at `octavus.ai/agents/[agentId]`\n2. Click the **Preview** tab\n3. Configure session inputs and tool mock responses\n4. Start a conversation to test agent behavior\n\nAgent Preview supports all trigger types, file attachments, tool mocking, and real-time streaming. This is the fastest way to iterate on your agent logic before writing any integration code.\n\n## Installation\n\nInstall the Octavus SDKs in your project:\n\n```bash\n# Server SDK for backend\nnpm install @octavus/server-sdk\n\n# React bindings for frontend\nnpm install @octavus/react\n```\n\n## Backend Setup\n\n### 1. Initialize the Client\n\nCreate an Octavus client instance in your backend:\n\n```typescript\n// lib/octavus.ts\nimport { OctavusClient } from '@octavus/server-sdk';\n\nexport const octavus = new OctavusClient({\n baseUrl: process.env.OCTAVUS_API_URL!,\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n```\n\n### 2. Create a Session Endpoint\n\nCreate an API endpoint that creates sessions and returns the session ID:\n\n```typescript\n// app/api/chat/create/route.ts\nimport { NextResponse } from 'next/server';\nimport { octavus } from '@/lib/octavus';\n\n// Agent ID - get from platform or CLI (see below)\nconst SUPPORT_AGENT_ID = process.env.OCTAVUS_SUPPORT_AGENT_ID!;\n\nexport async function POST(request: Request) {\n const { input } = await request.json();\n\n // Create a new session using the agent ID\n const sessionId = await octavus.agentSessions.create(SUPPORT_AGENT_ID, input);\n\n return NextResponse.json({ sessionId });\n}\n```\n\n### Getting Your Agent ID\n\nThere are two ways to create and manage agents:\n\n**Option 1: Platform UI (Recommended for getting started)**\n\n1. Go to [octavus.ai](https://octavus.ai) and create an agent in the web editor\n2. Copy the agent ID from the URL (e.g., `octavus.ai/agents/clxyz123abc456`)\n3. Add it to your `.env.local`: `OCTAVUS_SUPPORT_AGENT_ID=clxyz123abc456`\n\n**Option 2: Local Development with CLI**\n\nFor version-controlled agent definitions, use the [Octavus CLI](/docs/server-sdk/cli):\n\n```bash\nnpm install --save-dev @octavus/cli\noctavus sync ./agents/support-chat\n# Output: Agent ID: clxyz123abc456\n```\n\nThe CLI approach is better for teams and CI/CD pipelines where you want agent definitions in your repository.\n\n### 3. Create a Trigger Endpoint\n\nCreate an endpoint that handles triggers and streams responses:\n\n```typescript\n// app/api/trigger/route.ts\nimport { toSSEStream } from '@octavus/server-sdk';\nimport { octavus } from '@/lib/octavus';\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const { sessionId, ...payload } = body;\n\n // Attach to session with tool handlers\n const session = octavus.agentSessions.attach(sessionId, {\n tools: {\n // Define tool handlers that run on your server\n 'get-user-account': async (args) => {\n const userId = args.userId as string;\n // Fetch from your database\n return {\n name: 'Demo User',\n email: 'demo@example.com',\n plan: 'pro',\n };\n },\n 'create-support-ticket': async (args) => {\n // Create ticket in your system\n return {\n ticketId: 'TICKET-123',\n estimatedResponse: '24 hours',\n };\n },\n },\n });\n\n // Execute the request and convert to SSE stream\n const events = session.execute(payload, { signal: request.signal });\n\n // Return as streaming response\n return new Response(toSSEStream(events), {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n```\n\n## Frontend Setup\n\n### 1. Create a Chat Component\n\nUse the `useOctavusChat` hook with the HTTP transport:\n\n```tsx\n// components/chat.tsx\n'use client';\n\nimport { useState, useMemo } from 'react';\nimport { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';\n\ninterface ChatProps {\n sessionId: string;\n}\n\nexport function Chat({ sessionId }: ChatProps) {\n const [inputValue, setInputValue] = useState('');\n\n // Create a stable transport instance\n const transport = useMemo(\n () =>\n createHttpTransport({\n request: (payload, options) =>\n fetch('/api/trigger', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, ...payload }),\n signal: options?.signal,\n }),\n }),\n [sessionId],\n );\n\n const { messages, status, error, send } = useOctavusChat({ transport });\n\n const isStreaming = status === 'streaming';\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!inputValue.trim() || isStreaming) return;\n\n const message = inputValue.trim();\n setInputValue('');\n\n // Add user message and trigger in one call\n await send('user-message', { USER_MESSAGE: message }, { userMessage: { content: message } });\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Messages */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {messages.map((msg) => (\n <MessageBubble key={msg.id} message={msg} />\n ))}\n </div>\n\n {/* Input */}\n <form onSubmit={handleSubmit} className=\"p-4 border-t\">\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n placeholder=\"Type a message...\"\n className=\"flex-1 px-4 py-2 border rounded-lg\"\n disabled={isStreaming}\n />\n <button\n type=\"submit\"\n disabled={isStreaming}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg disabled:opacity-50\"\n >\n Send\n </button>\n </div>\n </form>\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: UIMessage }) {\n const isUser = message.role === 'user';\n\n return (\n <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>\n <div\n className={`p-3 rounded-lg max-w-md ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'}`}\n >\n {message.parts.map((part, i) => {\n if (part.type === 'text') {\n return <p key={i}>{part.text}</p>;\n }\n return null;\n })}\n\n {/* Streaming indicator */}\n {message.status === 'streaming' && (\n <span className=\"inline-block w-2 h-4 bg-gray-400 animate-pulse ml-1\" />\n )}\n </div>\n </div>\n );\n}\n```\n\n### 2. Create Session and Render Chat\n\n```tsx\n// app/chat/page.tsx\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Chat } from '@/components/chat';\n\nexport default function ChatPage() {\n const [sessionId, setSessionId] = useState<string | null>(null);\n\n useEffect(() => {\n async function createSession() {\n const response = await fetch('/api/chat/create', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n input: {\n COMPANY_NAME: 'Acme Corp',\n PRODUCT_NAME: 'Widget Pro',\n },\n }),\n });\n const { sessionId } = await response.json();\n setSessionId(sessionId);\n }\n\n createSession();\n }, []);\n\n if (!sessionId) {\n return <div>Loading...</div>;\n }\n\n return <Chat sessionId={sessionId} />;\n}\n```\n\n## Environment Variables\n\nAdd these to your `.env.local`:\n\n```bash\nOCTAVUS_API_URL=https://octavus.ai\nOCTAVUS_API_KEY=your-api-key-here\n```\n\n## What's Next?\n\nNow that you have a basic integration working:\n\n- [Learn about the protocol](/docs/protocol/overview) to define custom agent behavior\n- [Explore the Server SDK](/docs/server-sdk/overview) for advanced backend features\n- [Build rich UIs](/docs/client-sdk/overview) with the Client SDK\n- [Handle tools on the client](/docs/client-sdk/client-tools) for interactive UIs and browser APIs\n",
17
+ content: "\n# Quick Start\n\nThis guide will walk you through integrating Octavus into your application in under 10 minutes.\n\n## Prerequisites\n\n- Node.js 18+\n- An Octavus account with API key\n- A Next.js application (or any Node.js backend)\n\n## Test Your Agent First\n\nBefore integrating with SDKs, use **Agent Preview** to test your agent directly in the platform:\n\n1. Open your agent in the platform at `octavus.ai/platform/agents/[agentId]`\n2. Click the **Preview** tab\n3. Configure session inputs and tool mock responses\n4. Start a conversation to test agent behavior\n\nAgent Preview supports all trigger types, file attachments, tool mocking, and real-time streaming. This is the fastest way to iterate on your agent logic before writing any integration code.\n\n## Installation\n\nInstall the Octavus SDKs in your project:\n\n```bash\n# Server SDK for backend\nnpm install @octavus/server-sdk\n\n# React bindings for frontend\nnpm install @octavus/react\n```\n\n## Backend Setup\n\n### 1. Initialize the Client\n\nCreate an Octavus client instance in your backend:\n\n```typescript\n// lib/octavus.ts\nimport { OctavusClient } from '@octavus/server-sdk';\n\nexport const octavus = new OctavusClient({\n baseUrl: process.env.OCTAVUS_API_URL!,\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n```\n\n### 2. Create a Session Endpoint\n\nCreate an API endpoint that creates sessions and returns the session ID:\n\n```typescript\n// app/api/chat/create/route.ts\nimport { NextResponse } from 'next/server';\nimport { octavus } from '@/lib/octavus';\n\n// Agent ID - get from platform or CLI (see below)\nconst SUPPORT_AGENT_ID = process.env.OCTAVUS_SUPPORT_AGENT_ID!;\n\nexport async function POST(request: Request) {\n const { input } = await request.json();\n\n // Create a new session using the agent ID\n const sessionId = await octavus.agentSessions.create(SUPPORT_AGENT_ID, input);\n\n return NextResponse.json({ sessionId });\n}\n```\n\n### Getting Your Agent ID\n\nThere are two ways to create and manage agents:\n\n**Option 1: Platform UI (Recommended for getting started)**\n\n1. Go to [octavus.ai](https://octavus.ai) and create an agent in the web editor\n2. Copy the agent ID from the URL (e.g., `octavus.ai/platform/agents/clxyz123abc456`)\n3. Add it to your `.env.local`: `OCTAVUS_SUPPORT_AGENT_ID=clxyz123abc456`\n\n**Option 2: Local Development with CLI**\n\nFor version-controlled agent definitions, use the [Octavus CLI](/docs/server-sdk/cli):\n\n```bash\nnpm install --save-dev @octavus/cli\noctavus sync ./agents/support-chat\n# Output: Agent ID: clxyz123abc456\n```\n\nThe CLI approach is better for teams and CI/CD pipelines where you want agent definitions in your repository.\n\n### 3. Create a Trigger Endpoint\n\nCreate an endpoint that handles triggers and streams responses:\n\n```typescript\n// app/api/trigger/route.ts\nimport { toSSEStream } from '@octavus/server-sdk';\nimport { octavus } from '@/lib/octavus';\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const { sessionId, ...payload } = body;\n\n // Attach to session with tool handlers\n const session = octavus.agentSessions.attach(sessionId, {\n tools: {\n // Define tool handlers that run on your server\n 'get-user-account': async (args) => {\n const userId = args.userId as string;\n // Fetch from your database\n return {\n name: 'Demo User',\n email: 'demo@example.com',\n plan: 'pro',\n };\n },\n 'create-support-ticket': async (args) => {\n // Create ticket in your system\n return {\n ticketId: 'TICKET-123',\n estimatedResponse: '24 hours',\n };\n },\n },\n });\n\n // Execute the request and convert to SSE stream\n const events = session.execute(payload, { signal: request.signal });\n\n // Return as streaming response\n return new Response(toSSEStream(events), {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n```\n\n## Frontend Setup\n\n### 1. Create a Chat Component\n\nUse the `useOctavusChat` hook with the HTTP transport:\n\n```tsx\n// components/chat.tsx\n'use client';\n\nimport { useState, useMemo } from 'react';\nimport { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';\n\ninterface ChatProps {\n sessionId: string;\n}\n\nexport function Chat({ sessionId }: ChatProps) {\n const [inputValue, setInputValue] = useState('');\n\n // Create a stable transport instance\n const transport = useMemo(\n () =>\n createHttpTransport({\n request: (payload, options) =>\n fetch('/api/trigger', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, ...payload }),\n signal: options?.signal,\n }),\n }),\n [sessionId],\n );\n\n const { messages, status, error, send } = useOctavusChat({ transport });\n\n const isStreaming = status === 'streaming';\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!inputValue.trim() || isStreaming) return;\n\n const message = inputValue.trim();\n setInputValue('');\n\n // Add user message and trigger in one call\n await send('user-message', { USER_MESSAGE: message }, { userMessage: { content: message } });\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Messages */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {messages.map((msg) => (\n <MessageBubble key={msg.id} message={msg} />\n ))}\n </div>\n\n {/* Input */}\n <form onSubmit={handleSubmit} className=\"p-4 border-t\">\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n placeholder=\"Type a message...\"\n className=\"flex-1 px-4 py-2 border rounded-lg\"\n disabled={isStreaming}\n />\n <button\n type=\"submit\"\n disabled={isStreaming}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg disabled:opacity-50\"\n >\n Send\n </button>\n </div>\n </form>\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: UIMessage }) {\n const isUser = message.role === 'user';\n\n return (\n <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>\n <div\n className={`p-3 rounded-lg max-w-md ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'}`}\n >\n {message.parts.map((part, i) => {\n if (part.type === 'text') {\n return <p key={i}>{part.text}</p>;\n }\n return null;\n })}\n\n {/* Streaming indicator */}\n {message.status === 'streaming' && (\n <span className=\"inline-block w-2 h-4 bg-gray-400 animate-pulse ml-1\" />\n )}\n </div>\n </div>\n );\n}\n```\n\n### 2. Create Session and Render Chat\n\n```tsx\n// app/chat/page.tsx\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Chat } from '@/components/chat';\n\nexport default function ChatPage() {\n const [sessionId, setSessionId] = useState<string | null>(null);\n\n useEffect(() => {\n async function createSession() {\n const response = await fetch('/api/chat/create', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n input: {\n COMPANY_NAME: 'Acme Corp',\n PRODUCT_NAME: 'Widget Pro',\n },\n }),\n });\n const { sessionId } = await response.json();\n setSessionId(sessionId);\n }\n\n createSession();\n }, []);\n\n if (!sessionId) {\n return <div>Loading...</div>;\n }\n\n return <Chat sessionId={sessionId} />;\n}\n```\n\n## Environment Variables\n\nAdd these to your `.env.local`:\n\n```bash\nOCTAVUS_API_URL=https://octavus.ai\nOCTAVUS_API_KEY=your-api-key-here\n```\n\n## What's Next?\n\nNow that you have a basic integration working:\n\n- [Learn about the protocol](/docs/protocol/overview) to define custom agent behavior\n- [Explore the Server SDK](/docs/server-sdk/overview) for advanced backend features\n- [Build rich UIs](/docs/client-sdk/overview) with the Client SDK\n- [Handle tools on the client](/docs/client-sdk/client-tools) for interactive UIs and browser APIs\n",
18
18
  excerpt: "Quick Start This guide will walk you through integrating Octavus into your application in under 10 minutes. Prerequisites - Node.js 18+ - An Octavus account with API key - A Next.js application (or...",
19
19
  order: 2
20
20
  },
@@ -68,7 +68,7 @@ var docs_default = [
68
68
  section: "server-sdk",
69
69
  title: "Workers",
70
70
  description: "Executing worker agents with the Server SDK.",
71
- content: "\n# Workers API\n\nThe `WorkersApi` enables executing worker agents from your server. Workers are task-based agents that run steps sequentially and return an output value.\n\n## Basic Usage\n\n```typescript\nimport { OctavusClient } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: 'your-api-key',\n});\n\nconst { output, sessionId } = await client.workers.generate(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nconsole.log('Result:', output);\nconsole.log(`Debug: ${client.baseUrl}/sessions/${sessionId}`);\n```\n\n## WorkersApi Reference\n\n### generate()\n\nExecute a worker and return the output directly.\n\n```typescript\nasync generate(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): Promise<WorkerGenerateResult>\n```\n\nRuns the worker to completion and returns the output value. This is the simplest way to execute a worker.\n\n**Returns:**\n\n```typescript\ninterface WorkerGenerateResult {\n /** The worker's output value */\n output: unknown;\n /** Session ID for debugging (usable for session URLs) */\n sessionId: string;\n}\n```\n\n**Throws:** `WorkerError` if the worker fails or completes without producing output.\n\n### execute()\n\nExecute a worker and stream the response. Use this when you need to observe intermediate events like text deltas, tool calls, or progress tracking.\n\n```typescript\nasync *execute(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\n### continue()\n\nContinue execution after client-side tool handling.\n\n```typescript\nasync *continue(\n agentId: string,\n executionId: string,\n toolResults: ToolResult[],\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\nUse this when the worker has tools without server-side handlers. The execution pauses with a `client-tool-request` event, you execute the tools, then call `continue()` to resume.\n\n### Shared Options\n\nAll methods accept the same options:\n\n```typescript\ninterface WorkerExecuteOptions {\n /** Tool handlers for server-side tool execution */\n tools?: ToolHandlers;\n /** Abort signal to cancel the execution */\n signal?: AbortSignal;\n}\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n| --------- | ------------------------- | --------------------------- |\n| `agentId` | `string` | The worker agent ID |\n| `input` | `Record<string, unknown>` | Input values for the worker |\n| `options` | `WorkerExecuteOptions` | Optional configuration |\n\n## Tool Handlers\n\nProvide tool handlers to execute tools server-side:\n\n```typescript\nconst { output } = await client.workers.generate(\n agentId,\n { TOPIC: 'AI safety' },\n {\n tools: {\n 'web-search': async (args) => {\n return await searchWeb(args.query);\n },\n 'get-user-data': async (args) => {\n return await db.users.findById(args.userId);\n },\n },\n },\n);\n```\n\nTools defined in the worker protocol but not provided as handlers become client tools \u2014 the execution pauses and emits a `client-tool-request` event.\n\n## Error Handling\n\n### WorkerError (generate)\n\n`generate()` throws a `WorkerError` on failure. The error includes an optional `sessionId` for constructing debug URLs:\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\ntry {\n const { output } = await client.workers.generate(agentId, input);\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Worker failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### Stream Errors (execute)\n\nWhen using `execute()`, errors appear as stream events:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'error') {\n console.error(`Error: ${event.message}`);\n console.error(`Type: ${event.errorType}`);\n console.error(`Retryable: ${event.retryable}`);\n }\n\n if (event.type === 'worker-result' && event.error) {\n console.error(`Worker failed: ${event.error}`);\n }\n}\n```\n\n### Error Types\n\n| Type | Description |\n| ------------------ | --------------------- |\n| `validation_error` | Invalid input |\n| `not_found_error` | Worker not found |\n| `provider_error` | LLM provider error |\n| `tool_error` | Tool execution failed |\n| `execution_error` | Worker step failed |\n\n## Cancellation\n\nUse an abort signal to cancel execution:\n\n```typescript\nconst { output } = await client.workers.generate(agentId, input, {\n signal: AbortSignal.timeout(30_000),\n});\n```\n\nWith `execute()` and a manual controller:\n\n```typescript\nconst controller = new AbortController();\nsetTimeout(() => controller.abort(), 30000);\n\ntry {\n for await (const event of client.workers.execute(agentId, input, {\n signal: controller.signal,\n })) {\n // Process events\n }\n} catch (error) {\n if (error.name === 'AbortError') {\n console.log('Worker cancelled');\n }\n}\n```\n\n## Streaming\n\nWhen you need real-time visibility into the worker's execution \u2014 text generation, tool calls, or progress \u2014 use `execute()` instead of `generate()`.\n\n### Basic Streaming\n\n```typescript\nconst events = client.workers.execute(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nfor await (const event of events) {\n if (event.type === 'worker-start') {\n console.log(`Worker ${event.workerSlug} started`);\n }\n if (event.type === 'text-delta') {\n process.stdout.write(event.delta);\n }\n if (event.type === 'worker-result') {\n console.log('Output:', event.output);\n }\n}\n```\n\n### Streaming to HTTP Response\n\nConvert worker events to an SSE stream:\n\n```typescript\nimport { toSSEStream } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const { agentId, input } = await request.json();\n\n const events = client.workers.execute(agentId, input, {\n tools: {\n search: async (args) => await search(args.query),\n },\n });\n\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\n### Client Tool Continuation\n\nWhen workers have tools without handlers, execution pauses:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'client-tool-request') {\n const results = await executeClientTools(event.toolCalls);\n\n for await (const ev of client.workers.continue(agentId, event.executionId, results)) {\n // Handle remaining events\n }\n break;\n }\n}\n```\n\nThe `client-tool-request` event includes:\n\n```typescript\n{\n type: 'client-tool-request',\n executionId: string, // Pass to continue()\n toolCalls: [{\n toolCallId: string,\n toolName: string,\n args: Record<string, unknown>,\n }],\n}\n```\n\n### Stream Events\n\nWorkers emit standard stream events plus worker-specific events.\n\n#### Worker Events\n\n```typescript\n// Worker started\n{\n type: 'worker-start',\n workerId: string, // Unique ID (also used as session ID for debug)\n workerSlug: string, // The worker's slug\n description?: string, // Display description for UI\n}\n\n// Worker completed\n{\n type: 'worker-result',\n workerId: string,\n output?: unknown, // The worker's output value\n error?: string, // Error message if worker failed\n}\n```\n\n#### Common Events\n\n| Event | Description |\n| ----------------------- | --------------------------- |\n| `start` | Execution started |\n| `finish` | Execution completed |\n| `text-start` | Text generation started |\n| `text-delta` | Text chunk received |\n| `text-end` | Text generation ended |\n| `block-start` | Step started |\n| `block-end` | Step completed |\n| `tool-input-available` | Tool arguments ready |\n| `tool-output-available` | Tool result ready |\n| `client-tool-request` | Client tools need execution |\n| `error` | Error occurred |\n\n## Full Examples\n\n### generate()\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\ntry {\n const { output, sessionId } = await client.workers.generate(\n 'research-assistant-id',\n {\n TOPIC: 'AI safety best practices',\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => await performWebSearch(query),\n },\n signal: AbortSignal.timeout(120_000),\n },\n );\n\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### execute()\n\nFor full control over streaming events and progress tracking:\n\n```typescript\nimport { OctavusClient, type StreamEvent } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\nasync function runResearchWorker(topic: string) {\n console.log(`Researching: ${topic}\\n`);\n\n const events = client.workers.execute(\n 'research-assistant-id',\n {\n TOPIC: topic,\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => {\n console.log(`Searching: ${query}`);\n return await performWebSearch(query);\n },\n },\n },\n );\n\n let output: unknown;\n\n for await (const event of events) {\n switch (event.type) {\n case 'worker-start':\n console.log(`Started: ${event.workerSlug}`);\n break;\n\n case 'block-start':\n console.log(`Step: ${event.blockName}`);\n break;\n\n case 'text-delta':\n process.stdout.write(event.delta);\n break;\n\n case 'worker-result':\n if (event.error) {\n throw new Error(event.error);\n }\n output = event.output;\n break;\n\n case 'error':\n throw new Error(event.message);\n }\n }\n\n console.log('\\n\\nResearch complete!');\n return output;\n}\n\nconst result = await runResearchWorker('AI safety best practices');\nconsole.log('Result:', result);\n```\n\n## Next Steps\n\n- [Workers Protocol](/docs/protocol/workers) \u2014 Worker protocol reference\n- [Streaming](/docs/server-sdk/streaming) \u2014 Understanding stream events\n- [Tools](/docs/server-sdk/tools) \u2014 Tool handler patterns\n",
71
+ content: "\n# Workers API\n\nThe `WorkersApi` enables executing worker agents from your server. Workers are task-based agents that run steps sequentially and return an output value.\n\n## Basic Usage\n\n```typescript\nimport { OctavusClient } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: 'your-api-key',\n});\n\nconst { output, sessionId } = await client.workers.generate(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nconsole.log('Result:', output);\nconsole.log(`Debug: ${client.baseUrl}/sessions/${sessionId}`);\n```\n\n## WorkersApi Reference\n\n### generate()\n\nExecute a worker and return the output directly.\n\n```typescript\nasync generate(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): Promise<WorkerGenerateResult>\n```\n\nRuns the worker to completion and returns the output value. This is the simplest way to execute a worker.\n\n**Returns:**\n\n```typescript\ninterface WorkerGenerateResult {\n /** The worker's output value */\n output: unknown;\n /** Session ID for debugging (usable for session URLs) */\n sessionId: string;\n}\n```\n\n**Throws:** `WorkerError` if the worker fails or completes without producing output.\n\n### execute()\n\nExecute a worker and stream the response. Use this when you need to observe intermediate events like text deltas, tool calls, or progress tracking.\n\n```typescript\nasync *execute(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\n### continue()\n\nContinue execution after client-side tool handling.\n\n```typescript\nasync *continue(\n agentId: string,\n executionId: string,\n toolResults: ToolResult[],\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\nUse this when the worker has tools without server-side handlers. The execution pauses with a `client-tool-request` event, you execute the tools, then call `continue()` to resume.\n\n### Shared Options\n\nAll methods accept the same options:\n\n```typescript\ninterface WorkerExecuteOptions {\n /** Tool handlers for server-side tool execution */\n tools?: ToolHandlers;\n /** Abort signal to cancel the execution */\n signal?: AbortSignal;\n}\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n| --------- | ------------------------- | --------------------------- |\n| `agentId` | `string` | The worker agent ID |\n| `input` | `Record<string, unknown>` | Input values for the worker |\n| `options` | `WorkerExecuteOptions` | Optional configuration |\n\n## Tool Handlers\n\nProvide tool handlers to execute tools server-side:\n\n```typescript\nconst { output } = await client.workers.generate(\n agentId,\n { TOPIC: 'AI safety' },\n {\n tools: {\n 'web-search': async (args) => {\n return await searchWeb(args.query);\n },\n 'get-user-data': async (args) => {\n return await db.users.findById(args.userId);\n },\n },\n },\n);\n```\n\nTools defined in the worker protocol but not provided as handlers become client tools \u2014 the execution pauses and emits a `client-tool-request` event.\n\n## Error Handling\n\n### WorkerError (generate)\n\n`generate()` throws a `WorkerError` on failure. The error includes an optional `sessionId` for constructing debug URLs:\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\ntry {\n const { output } = await client.workers.generate(agentId, input);\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Worker failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/platform/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### Stream Errors (execute)\n\nWhen using `execute()`, errors appear as stream events:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'error') {\n console.error(`Error: ${event.message}`);\n console.error(`Type: ${event.errorType}`);\n console.error(`Retryable: ${event.retryable}`);\n }\n\n if (event.type === 'worker-result' && event.error) {\n console.error(`Worker failed: ${event.error}`);\n }\n}\n```\n\n### Error Types\n\n| Type | Description |\n| ------------------ | --------------------- |\n| `validation_error` | Invalid input |\n| `not_found_error` | Worker not found |\n| `provider_error` | LLM provider error |\n| `tool_error` | Tool execution failed |\n| `execution_error` | Worker step failed |\n\n## Cancellation\n\nUse an abort signal to cancel execution:\n\n```typescript\nconst { output } = await client.workers.generate(agentId, input, {\n signal: AbortSignal.timeout(30_000),\n});\n```\n\nWith `execute()` and a manual controller:\n\n```typescript\nconst controller = new AbortController();\nsetTimeout(() => controller.abort(), 30000);\n\ntry {\n for await (const event of client.workers.execute(agentId, input, {\n signal: controller.signal,\n })) {\n // Process events\n }\n} catch (error) {\n if (error.name === 'AbortError') {\n console.log('Worker cancelled');\n }\n}\n```\n\n## Streaming\n\nWhen you need real-time visibility into the worker's execution \u2014 text generation, tool calls, or progress \u2014 use `execute()` instead of `generate()`.\n\n### Basic Streaming\n\n```typescript\nconst events = client.workers.execute(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nfor await (const event of events) {\n if (event.type === 'worker-start') {\n console.log(`Worker ${event.workerSlug} started`);\n }\n if (event.type === 'text-delta') {\n process.stdout.write(event.delta);\n }\n if (event.type === 'worker-result') {\n console.log('Output:', event.output);\n }\n}\n```\n\n### Streaming to HTTP Response\n\nConvert worker events to an SSE stream:\n\n```typescript\nimport { toSSEStream } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const { agentId, input } = await request.json();\n\n const events = client.workers.execute(agentId, input, {\n tools: {\n search: async (args) => await search(args.query),\n },\n });\n\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\n### Client Tool Continuation\n\nWhen workers have tools without handlers, execution pauses:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'client-tool-request') {\n const results = await executeClientTools(event.toolCalls);\n\n for await (const ev of client.workers.continue(agentId, event.executionId, results)) {\n // Handle remaining events\n }\n break;\n }\n}\n```\n\nThe `client-tool-request` event includes:\n\n```typescript\n{\n type: 'client-tool-request',\n executionId: string, // Pass to continue()\n toolCalls: [{\n toolCallId: string,\n toolName: string,\n args: Record<string, unknown>,\n }],\n}\n```\n\n### Stream Events\n\nWorkers emit standard stream events plus worker-specific events.\n\n#### Worker Events\n\n```typescript\n// Worker started\n{\n type: 'worker-start',\n workerId: string, // Unique ID (also used as session ID for debug)\n workerSlug: string, // The worker's slug\n description?: string, // Display description for UI\n}\n\n// Worker completed\n{\n type: 'worker-result',\n workerId: string,\n output?: unknown, // The worker's output value\n error?: string, // Error message if worker failed\n}\n```\n\n#### Common Events\n\n| Event | Description |\n| ----------------------- | --------------------------- |\n| `start` | Execution started |\n| `finish` | Execution completed |\n| `text-start` | Text generation started |\n| `text-delta` | Text chunk received |\n| `text-end` | Text generation ended |\n| `block-start` | Step started |\n| `block-end` | Step completed |\n| `tool-input-available` | Tool arguments ready |\n| `tool-output-available` | Tool result ready |\n| `client-tool-request` | Client tools need execution |\n| `error` | Error occurred |\n\n## Full Examples\n\n### generate()\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\ntry {\n const { output, sessionId } = await client.workers.generate(\n 'research-assistant-id',\n {\n TOPIC: 'AI safety best practices',\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => await performWebSearch(query),\n },\n signal: AbortSignal.timeout(120_000),\n },\n );\n\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/platform/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### execute()\n\nFor full control over streaming events and progress tracking:\n\n```typescript\nimport { OctavusClient, type StreamEvent } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\nasync function runResearchWorker(topic: string) {\n console.log(`Researching: ${topic}\\n`);\n\n const events = client.workers.execute(\n 'research-assistant-id',\n {\n TOPIC: topic,\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => {\n console.log(`Searching: ${query}`);\n return await performWebSearch(query);\n },\n },\n },\n );\n\n let output: unknown;\n\n for await (const event of events) {\n switch (event.type) {\n case 'worker-start':\n console.log(`Started: ${event.workerSlug}`);\n break;\n\n case 'block-start':\n console.log(`Step: ${event.blockName}`);\n break;\n\n case 'text-delta':\n process.stdout.write(event.delta);\n break;\n\n case 'worker-result':\n if (event.error) {\n throw new Error(event.error);\n }\n output = event.output;\n break;\n\n case 'error':\n throw new Error(event.message);\n }\n }\n\n console.log('\\n\\nResearch complete!');\n return output;\n}\n\nconst result = await runResearchWorker('AI safety best practices');\nconsole.log('Result:', result);\n```\n\n## Next Steps\n\n- [Workers Protocol](/docs/protocol/workers) \u2014 Worker protocol reference\n- [Streaming](/docs/server-sdk/streaming) \u2014 Understanding stream events\n- [Tools](/docs/server-sdk/tools) \u2014 Tool handler patterns\n",
72
72
  excerpt: "Workers API The enables executing worker agents from your server. Workers are task-based agents that run steps sequentially and return an output value. Basic Usage WorkersApi Reference generate()...",
73
73
  order: 6
74
74
  },
@@ -658,7 +658,7 @@ See [Streaming Events](/docs/server-sdk/streaming#event-types) for the full list
658
658
  section: "api-reference",
659
659
  title: "Sessions",
660
660
  description: "Session management API endpoints.",
661
- content: '\n# Sessions API\n\nSessions represent conversations with agents. They store conversation history, resources, and variables.\n\nAll session endpoints require an API key with the **Sessions** permission.\n\n## Create Session\n\nCreate a new agent session.\n\n```\nPOST /api/agent-sessions\n```\n\n### Request Body\n\n```json\n{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro",\n "USER_ID": "user-123"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| --------- | ------ | -------- | ------------------------------------- |\n| `agentId` | string | Yes | Agent ID (the `id` field, not `slug`) |\n| `input` | object | No | Input variables for the agent |\n\n> **Getting the agent ID:** Copy the ID from the agent URL in the [platform](https://octavus.ai) (e.g., `octavus.ai/agents/clxyz123`), or use the [CLI](/docs/server-sdk/cli) (`octavus sync ./agents/my-agent`) for local development workflows.\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def"\n}\n```\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n }\n }\'\n```\n\n## Get Session\n\nRetrieve session state. Returns UI-ready messages for active sessions, or expiration info for expired sessions.\n\n```\nGET /api/agent-sessions/:sessionId\n```\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --------- | ------ | ---------------------------------------------------- |\n| `format` | string | Optional. Use `format=ui` for UI-ready messages only |\n\n### Response (Active Session)\n\nWhen the session is active, the response includes `UIMessage` objects:\n\n```json\n{\n "id": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "status": "active",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n },\n "variables": {},\n "resources": {\n "CONVERSATION_SUMMARY": ""\n },\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n },\n {\n "id": "1702345805000-def456b",\n "role": "assistant",\n "parts": [\n { "type": "text", "text": "I can help you reset your password...", "status": "done" }\n ],\n "status": "done",\n "createdAt": "2024-01-15T10:30:05.000Z"\n }\n ],\n "createdAt": "2024-01-15T10:30:00Z",\n "updatedAt": "2024-01-15T10:30:05Z"\n}\n```\n\n### Response (Expired Session)\n\nWhen the session has expired, the response indicates the expiration status:\n\n```json\n{\n "status": "expired",\n "sessionId": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "createdAt": "2024-01-15T10:30:00Z"\n}\n```\n\nUse the [Restore Session](#restore-session) endpoint to restore an expired session from stored messages.\n\n````\n\n### UIMessage Parts\n\nMessages contain typed `parts` that preserve content ordering:\n\n| Part Type | Description |\n|-----------|-------------|\n| `text` | Text content with `text` and `status` fields |\n| `reasoning` | Extended reasoning with `text` and `status` fields |\n| `tool-call` | Tool execution with `toolCallId`, `toolName`, `displayName`, `args`, `result`, `status` |\n| `operation` | Internal operations with `operationId`, `name`, `operationType`, `status` |\n| `file` | File attachment with `id`, `mediaType`, `url`, `filename`, `size` |\n| `source` | Source reference with `sourceType`, `id`, `url`, `title` |\n| `object` | Structured output with `id`, `typeName`, `object`, `status` |\n\n### Example\n\n```bash\ncurl https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n````\n\n## Restore Session\n\nRestore an expired session from stored messages. This allows you to continue a conversation after the server-side state has expired.\n\n```\nPOST /api/agent-sessions/:sessionId/restore\n```\n\n### Request Body\n\n```json\n{\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n }\n ],\n "input": {\n "COMPANY_NAME": "Acme Corp"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| ---------- | ----------- | -------- | -------------------------------------------------------------- |\n| `messages` | UIMessage[] | Yes | Previously stored chat history |\n| `input` | object | No | Session input for system prompt interpolation (same as create) |\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "restored": true\n}\n```\n\n| Field | Type | Description |\n| ----------- | ------- | ----------------------------------------------------------------------- |\n| `sessionId` | string | The session ID |\n| `restored` | boolean | `true` if restored from messages, `false` if session was already active |\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions/:sessionId/restore \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "messages": [...],\n "input": { "COMPANY_NAME": "Acme Corp" }\n }\'\n```\n\n> **Note**: Store the `UIMessage[]` array after each interaction to enable restoration. The restore endpoint reconstructs the conversation state from these messages.\n\n## Clear Session\n\nClear session state, transitioning it to `expired` status. The session can be restored afterwards with the [Restore Session](#restore-session) endpoint.\n\nThis is idempotent \u2014 clearing an already expired session succeeds without error.\n\n```\nDELETE /api/agent-sessions/:sessionId\n```\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "cleared": true\n}\n```\n\n### Example\n\n```bash\ncurl -X DELETE https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n```\n\n## Trigger Session\n\nExecute a trigger on a session. Returns a Server-Sent Events stream.\n\n```\nPOST /api/agent-sessions/:sessionId/trigger\n```\n\n### Request Body\n\n```json\n{\n "triggerName": "user-message",\n "input": {\n "USER_MESSAGE": "How do I reset my password?"\n },\n "toolResults": []\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------- |\n| `triggerName` | string | Yes | Name of the trigger to execute |\n| `input` | object | No | Input variables for the trigger |\n| `toolResults` | array | No | Tool results for continuation (handled by SDK) |\n| `rollbackAfterMessageId` | string \\| null | No | For retry: ID of the last message to keep. Messages after this are removed. `null` = truncate all. |\n\n### Response\n\nReturns `text/event-stream` with SSE events:\n\n```\ndata: {"type":"start","messageId":"msg-123"}\n\ndata: {"type":"block-start","blockId":"b1","blockName":"Add user message","blockType":"add-message","display":"hidden"}\n\ndata: {"type":"block-end","blockId":"b1"}\n\ndata: {"type":"block-start","blockId":"b2","blockName":"Respond to user","blockType":"next-message","display":"stream","outputToChat":true}\n\ndata: {"type":"text-start","id":"t1"}\n\ndata: {"type":"text-delta","id":"t1","delta":"I"}\n\ndata: {"type":"text-delta","id":"t1","delta":" can"}\n\ndata: {"type":"text-delta","id":"t1","delta":" help"}\n\ndata: {"type":"text-delta","id":"t1","delta":" you"}\n\ndata: {"type":"text-delta","id":"t1","delta":" reset"}\n\ndata: {"type":"text-delta","id":"t1","delta":" your"}\n\ndata: {"type":"text-delta","id":"t1","delta":" password"}\n\ndata: {"type":"text-delta","id":"t1","delta":"!"}\n\ndata: {"type":"text-end","id":"t1"}\n\ndata: {"type":"block-end","blockId":"b2"}\n\ndata: {"type":"finish","finishReason":"stop"}\n\ndata: [DONE]\n```\n\n### Event Types\n\n| Event | Description |\n| ----------------------- | ---------------------------------- |\n| `start` | Stream started |\n| `finish` | Execution complete |\n| `error` | Error occurred |\n| `block-start` | Execution block started |\n| `block-end` | Execution block completed |\n| `text-start` | Text generation started |\n| `text-delta` | Incremental text content |\n| `text-end` | Text generation ended |\n| `reasoning-start` | Extended reasoning started |\n| `reasoning-delta` | Reasoning content |\n| `reasoning-end` | Extended reasoning ended |\n| `tool-input-start` | Tool call initiated |\n| `tool-input-delta` | Tool arguments streaming |\n| `tool-input-end` | Tool arguments streaming ended |\n| `tool-input-available` | Tool input complete |\n| `tool-output-available` | Tool completed with result |\n| `tool-output-error` | Tool failed |\n| `tool-request` | Platform requesting tool execution |\n| `file-available` | File ready for display/download |\n| `resource-update` | Resource value changed |\n\n### Example\n\n```bash\ncurl -N -X POST https://octavus.ai/api/agent-sessions/:sessionId/trigger \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "How do I reset my password?" }\n }\'\n```\n\n## Tool Continuation\n\nWhen the agent calls external tools, you\'ll receive a `tool-request` event. Execute the tools and send results back:\n\n```json\n{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "..." },\n "toolResults": [\n {\n "toolCallId": "tc_123",\n "toolName": "get-user-account",\n "result": {\n "name": "Demo User",\n "email": "demo@example.com"\n }\n }\n ]\n}\n```\n\nThe Server SDK handles this continuation pattern automatically.\n\n## Upload URLs\n\nGet presigned URLs for file uploads. Files are uploaded directly to S3.\n\n```\nPOST /api/files/upload-urls\n```\n\n### Request Body\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "files": [\n {\n "filename": "photo.jpg",\n "mediaType": "image/jpeg",\n "size": 102400\n }\n ]\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------- | ------ | -------- | ----------------------------------- |\n| `sessionId` | string | Yes | Session ID to associate files with |\n| `files` | array | Yes | Array of file metadata (1-20 files) |\n| `files[].filename` | string | Yes | Original filename |\n| `files[].mediaType` | string | Yes | MIME type (e.g., `image/png`) |\n| `files[].size` | number | Yes | File size in bytes |\n\n### Response\n\n```json\n{\n "files": [\n {\n "id": "file-abc123",\n "uploadUrl": "https://s3.amazonaws.com/bucket/key?...",\n "downloadUrl": "https://s3.amazonaws.com/bucket/key?..."\n }\n ]\n}\n```\n\n### Upload Flow\n\n1. Request upload URLs from the platform\n2. PUT file content to `uploadUrl` with `Content-Type` header\n3. Use `downloadUrl` as the `url` in `FileReference`\n4. Include `FileReference` in trigger input\n\n### Supported Types\n\n| Category | Media Types |\n| --------- | -------------------------------------------------------------------- |\n| Images | `image/jpeg`, `image/png`, `image/gif`, `image/webp` |\n| Documents | `application/pdf`, `text/plain`, `text/markdown`, `application/json` |\n\n### Limits\n\n| Limit | Value |\n| --------------------- | ---------- |\n| Max file size | 10 MB |\n| Max total per request | 50 MB |\n| Max files per request | 20 |\n| Upload URL expiry | 15 minutes |\n| Download URL expiry | 24 hours |\n',
661
+ content: '\n# Sessions API\n\nSessions represent conversations with agents. They store conversation history, resources, and variables.\n\nAll session endpoints require an API key with the **Sessions** permission.\n\n## Create Session\n\nCreate a new agent session.\n\n```\nPOST /api/agent-sessions\n```\n\n### Request Body\n\n```json\n{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro",\n "USER_ID": "user-123"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| --------- | ------ | -------- | ------------------------------------- |\n| `agentId` | string | Yes | Agent ID (the `id` field, not `slug`) |\n| `input` | object | No | Input variables for the agent |\n\n> **Getting the agent ID:** Copy the ID from the agent URL in the [platform](https://octavus.ai) (e.g., `octavus.ai/platform/agents/clxyz123`), or use the [CLI](/docs/server-sdk/cli) (`octavus sync ./agents/my-agent`) for local development workflows.\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def"\n}\n```\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n }\n }\'\n```\n\n## Get Session\n\nRetrieve session state. Returns UI-ready messages for active sessions, or expiration info for expired sessions.\n\n```\nGET /api/agent-sessions/:sessionId\n```\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --------- | ------ | ---------------------------------------------------- |\n| `format` | string | Optional. Use `format=ui` for UI-ready messages only |\n\n### Response (Active Session)\n\nWhen the session is active, the response includes `UIMessage` objects:\n\n```json\n{\n "id": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "status": "active",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n },\n "variables": {},\n "resources": {\n "CONVERSATION_SUMMARY": ""\n },\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n },\n {\n "id": "1702345805000-def456b",\n "role": "assistant",\n "parts": [\n { "type": "text", "text": "I can help you reset your password...", "status": "done" }\n ],\n "status": "done",\n "createdAt": "2024-01-15T10:30:05.000Z"\n }\n ],\n "createdAt": "2024-01-15T10:30:00Z",\n "updatedAt": "2024-01-15T10:30:05Z"\n}\n```\n\n### Response (Expired Session)\n\nWhen the session has expired, the response indicates the expiration status:\n\n```json\n{\n "status": "expired",\n "sessionId": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "createdAt": "2024-01-15T10:30:00Z"\n}\n```\n\nUse the [Restore Session](#restore-session) endpoint to restore an expired session from stored messages.\n\n````\n\n### UIMessage Parts\n\nMessages contain typed `parts` that preserve content ordering:\n\n| Part Type | Description |\n|-----------|-------------|\n| `text` | Text content with `text` and `status` fields |\n| `reasoning` | Extended reasoning with `text` and `status` fields |\n| `tool-call` | Tool execution with `toolCallId`, `toolName`, `displayName`, `args`, `result`, `status` |\n| `operation` | Internal operations with `operationId`, `name`, `operationType`, `status` |\n| `file` | File attachment with `id`, `mediaType`, `url`, `filename`, `size` |\n| `source` | Source reference with `sourceType`, `id`, `url`, `title` |\n| `object` | Structured output with `id`, `typeName`, `object`, `status` |\n\n### Example\n\n```bash\ncurl https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n````\n\n## Restore Session\n\nRestore an expired session from stored messages. This allows you to continue a conversation after the server-side state has expired.\n\n```\nPOST /api/agent-sessions/:sessionId/restore\n```\n\n### Request Body\n\n```json\n{\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n }\n ],\n "input": {\n "COMPANY_NAME": "Acme Corp"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| ---------- | ----------- | -------- | -------------------------------------------------------------- |\n| `messages` | UIMessage[] | Yes | Previously stored chat history |\n| `input` | object | No | Session input for system prompt interpolation (same as create) |\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "restored": true\n}\n```\n\n| Field | Type | Description |\n| ----------- | ------- | ----------------------------------------------------------------------- |\n| `sessionId` | string | The session ID |\n| `restored` | boolean | `true` if restored from messages, `false` if session was already active |\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions/:sessionId/restore \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "messages": [...],\n "input": { "COMPANY_NAME": "Acme Corp" }\n }\'\n```\n\n> **Note**: Store the `UIMessage[]` array after each interaction to enable restoration. The restore endpoint reconstructs the conversation state from these messages.\n\n## Clear Session\n\nClear session state, transitioning it to `expired` status. The session can be restored afterwards with the [Restore Session](#restore-session) endpoint.\n\nThis is idempotent \u2014 clearing an already expired session succeeds without error.\n\n```\nDELETE /api/agent-sessions/:sessionId\n```\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "cleared": true\n}\n```\n\n### Example\n\n```bash\ncurl -X DELETE https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n```\n\n## Trigger Session\n\nExecute a trigger on a session. Returns a Server-Sent Events stream.\n\n```\nPOST /api/agent-sessions/:sessionId/trigger\n```\n\n### Request Body\n\n```json\n{\n "triggerName": "user-message",\n "input": {\n "USER_MESSAGE": "How do I reset my password?"\n },\n "toolResults": []\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------- |\n| `triggerName` | string | Yes | Name of the trigger to execute |\n| `input` | object | No | Input variables for the trigger |\n| `toolResults` | array | No | Tool results for continuation (handled by SDK) |\n| `rollbackAfterMessageId` | string \\| null | No | For retry: ID of the last message to keep. Messages after this are removed. `null` = truncate all. |\n\n### Response\n\nReturns `text/event-stream` with SSE events:\n\n```\ndata: {"type":"start","messageId":"msg-123"}\n\ndata: {"type":"block-start","blockId":"b1","blockName":"Add user message","blockType":"add-message","display":"hidden"}\n\ndata: {"type":"block-end","blockId":"b1"}\n\ndata: {"type":"block-start","blockId":"b2","blockName":"Respond to user","blockType":"next-message","display":"stream","outputToChat":true}\n\ndata: {"type":"text-start","id":"t1"}\n\ndata: {"type":"text-delta","id":"t1","delta":"I"}\n\ndata: {"type":"text-delta","id":"t1","delta":" can"}\n\ndata: {"type":"text-delta","id":"t1","delta":" help"}\n\ndata: {"type":"text-delta","id":"t1","delta":" you"}\n\ndata: {"type":"text-delta","id":"t1","delta":" reset"}\n\ndata: {"type":"text-delta","id":"t1","delta":" your"}\n\ndata: {"type":"text-delta","id":"t1","delta":" password"}\n\ndata: {"type":"text-delta","id":"t1","delta":"!"}\n\ndata: {"type":"text-end","id":"t1"}\n\ndata: {"type":"block-end","blockId":"b2"}\n\ndata: {"type":"finish","finishReason":"stop"}\n\ndata: [DONE]\n```\n\n### Event Types\n\n| Event | Description |\n| ----------------------- | ---------------------------------- |\n| `start` | Stream started |\n| `finish` | Execution complete |\n| `error` | Error occurred |\n| `block-start` | Execution block started |\n| `block-end` | Execution block completed |\n| `text-start` | Text generation started |\n| `text-delta` | Incremental text content |\n| `text-end` | Text generation ended |\n| `reasoning-start` | Extended reasoning started |\n| `reasoning-delta` | Reasoning content |\n| `reasoning-end` | Extended reasoning ended |\n| `tool-input-start` | Tool call initiated |\n| `tool-input-delta` | Tool arguments streaming |\n| `tool-input-end` | Tool arguments streaming ended |\n| `tool-input-available` | Tool input complete |\n| `tool-output-available` | Tool completed with result |\n| `tool-output-error` | Tool failed |\n| `tool-request` | Platform requesting tool execution |\n| `file-available` | File ready for display/download |\n| `resource-update` | Resource value changed |\n\n### Example\n\n```bash\ncurl -N -X POST https://octavus.ai/api/agent-sessions/:sessionId/trigger \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "How do I reset my password?" }\n }\'\n```\n\n## Tool Continuation\n\nWhen the agent calls external tools, you\'ll receive a `tool-request` event. Execute the tools and send results back:\n\n```json\n{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "..." },\n "toolResults": [\n {\n "toolCallId": "tc_123",\n "toolName": "get-user-account",\n "result": {\n "name": "Demo User",\n "email": "demo@example.com"\n }\n }\n ]\n}\n```\n\nThe Server SDK handles this continuation pattern automatically.\n\n## Upload URLs\n\nGet presigned URLs for file uploads. Files are uploaded directly to S3.\n\n```\nPOST /api/files/upload-urls\n```\n\n### Request Body\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "files": [\n {\n "filename": "photo.jpg",\n "mediaType": "image/jpeg",\n "size": 102400\n }\n ]\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------- | ------ | -------- | ----------------------------------- |\n| `sessionId` | string | Yes | Session ID to associate files with |\n| `files` | array | Yes | Array of file metadata (1-20 files) |\n| `files[].filename` | string | Yes | Original filename |\n| `files[].mediaType` | string | Yes | MIME type (e.g., `image/png`) |\n| `files[].size` | number | Yes | File size in bytes |\n\n### Response\n\n```json\n{\n "files": [\n {\n "id": "file-abc123",\n "uploadUrl": "https://s3.amazonaws.com/bucket/key?...",\n "downloadUrl": "https://s3.amazonaws.com/bucket/key?..."\n }\n ]\n}\n```\n\n### Upload Flow\n\n1. Request upload URLs from the platform\n2. PUT file content to `uploadUrl` with `Content-Type` header\n3. Use `downloadUrl` as the `url` in `FileReference`\n4. Include `FileReference` in trigger input\n\n### Supported Types\n\n| Category | Media Types |\n| --------- | -------------------------------------------------------------------- |\n| Images | `image/jpeg`, `image/png`, `image/gif`, `image/webp` |\n| Documents | `application/pdf`, `text/plain`, `text/markdown`, `application/json` |\n\n### Limits\n\n| Limit | Value |\n| --------------------- | ---------- |\n| Max file size | 10 MB |\n| Max total per request | 50 MB |\n| Max files per request | 20 |\n| Upload URL expiry | 15 minutes |\n| Download URL expiry | 24 hours |\n',
662
662
  excerpt: "Sessions API Sessions represent conversations with agents. They store conversation history, resources, and variables. All session endpoints require an API key with the Sessions permission. Create...",
663
663
  order: 2
664
664
  },
@@ -731,7 +731,7 @@ var sections_default = [
731
731
  section: "getting-started",
732
732
  title: "Quick Start",
733
733
  description: "Get your first Octavus agent running in minutes.",
734
- content: "\n# Quick Start\n\nThis guide will walk you through integrating Octavus into your application in under 10 minutes.\n\n## Prerequisites\n\n- Node.js 18+\n- An Octavus account with API key\n- A Next.js application (or any Node.js backend)\n\n## Test Your Agent First\n\nBefore integrating with SDKs, use **Agent Preview** to test your agent directly in the platform:\n\n1. Open your agent in the platform at `octavus.ai/agents/[agentId]`\n2. Click the **Preview** tab\n3. Configure session inputs and tool mock responses\n4. Start a conversation to test agent behavior\n\nAgent Preview supports all trigger types, file attachments, tool mocking, and real-time streaming. This is the fastest way to iterate on your agent logic before writing any integration code.\n\n## Installation\n\nInstall the Octavus SDKs in your project:\n\n```bash\n# Server SDK for backend\nnpm install @octavus/server-sdk\n\n# React bindings for frontend\nnpm install @octavus/react\n```\n\n## Backend Setup\n\n### 1. Initialize the Client\n\nCreate an Octavus client instance in your backend:\n\n```typescript\n// lib/octavus.ts\nimport { OctavusClient } from '@octavus/server-sdk';\n\nexport const octavus = new OctavusClient({\n baseUrl: process.env.OCTAVUS_API_URL!,\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n```\n\n### 2. Create a Session Endpoint\n\nCreate an API endpoint that creates sessions and returns the session ID:\n\n```typescript\n// app/api/chat/create/route.ts\nimport { NextResponse } from 'next/server';\nimport { octavus } from '@/lib/octavus';\n\n// Agent ID - get from platform or CLI (see below)\nconst SUPPORT_AGENT_ID = process.env.OCTAVUS_SUPPORT_AGENT_ID!;\n\nexport async function POST(request: Request) {\n const { input } = await request.json();\n\n // Create a new session using the agent ID\n const sessionId = await octavus.agentSessions.create(SUPPORT_AGENT_ID, input);\n\n return NextResponse.json({ sessionId });\n}\n```\n\n### Getting Your Agent ID\n\nThere are two ways to create and manage agents:\n\n**Option 1: Platform UI (Recommended for getting started)**\n\n1. Go to [octavus.ai](https://octavus.ai) and create an agent in the web editor\n2. Copy the agent ID from the URL (e.g., `octavus.ai/agents/clxyz123abc456`)\n3. Add it to your `.env.local`: `OCTAVUS_SUPPORT_AGENT_ID=clxyz123abc456`\n\n**Option 2: Local Development with CLI**\n\nFor version-controlled agent definitions, use the [Octavus CLI](/docs/server-sdk/cli):\n\n```bash\nnpm install --save-dev @octavus/cli\noctavus sync ./agents/support-chat\n# Output: Agent ID: clxyz123abc456\n```\n\nThe CLI approach is better for teams and CI/CD pipelines where you want agent definitions in your repository.\n\n### 3. Create a Trigger Endpoint\n\nCreate an endpoint that handles triggers and streams responses:\n\n```typescript\n// app/api/trigger/route.ts\nimport { toSSEStream } from '@octavus/server-sdk';\nimport { octavus } from '@/lib/octavus';\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const { sessionId, ...payload } = body;\n\n // Attach to session with tool handlers\n const session = octavus.agentSessions.attach(sessionId, {\n tools: {\n // Define tool handlers that run on your server\n 'get-user-account': async (args) => {\n const userId = args.userId as string;\n // Fetch from your database\n return {\n name: 'Demo User',\n email: 'demo@example.com',\n plan: 'pro',\n };\n },\n 'create-support-ticket': async (args) => {\n // Create ticket in your system\n return {\n ticketId: 'TICKET-123',\n estimatedResponse: '24 hours',\n };\n },\n },\n });\n\n // Execute the request and convert to SSE stream\n const events = session.execute(payload, { signal: request.signal });\n\n // Return as streaming response\n return new Response(toSSEStream(events), {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n```\n\n## Frontend Setup\n\n### 1. Create a Chat Component\n\nUse the `useOctavusChat` hook with the HTTP transport:\n\n```tsx\n// components/chat.tsx\n'use client';\n\nimport { useState, useMemo } from 'react';\nimport { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';\n\ninterface ChatProps {\n sessionId: string;\n}\n\nexport function Chat({ sessionId }: ChatProps) {\n const [inputValue, setInputValue] = useState('');\n\n // Create a stable transport instance\n const transport = useMemo(\n () =>\n createHttpTransport({\n request: (payload, options) =>\n fetch('/api/trigger', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, ...payload }),\n signal: options?.signal,\n }),\n }),\n [sessionId],\n );\n\n const { messages, status, error, send } = useOctavusChat({ transport });\n\n const isStreaming = status === 'streaming';\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!inputValue.trim() || isStreaming) return;\n\n const message = inputValue.trim();\n setInputValue('');\n\n // Add user message and trigger in one call\n await send('user-message', { USER_MESSAGE: message }, { userMessage: { content: message } });\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Messages */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {messages.map((msg) => (\n <MessageBubble key={msg.id} message={msg} />\n ))}\n </div>\n\n {/* Input */}\n <form onSubmit={handleSubmit} className=\"p-4 border-t\">\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n placeholder=\"Type a message...\"\n className=\"flex-1 px-4 py-2 border rounded-lg\"\n disabled={isStreaming}\n />\n <button\n type=\"submit\"\n disabled={isStreaming}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg disabled:opacity-50\"\n >\n Send\n </button>\n </div>\n </form>\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: UIMessage }) {\n const isUser = message.role === 'user';\n\n return (\n <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>\n <div\n className={`p-3 rounded-lg max-w-md ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'}`}\n >\n {message.parts.map((part, i) => {\n if (part.type === 'text') {\n return <p key={i}>{part.text}</p>;\n }\n return null;\n })}\n\n {/* Streaming indicator */}\n {message.status === 'streaming' && (\n <span className=\"inline-block w-2 h-4 bg-gray-400 animate-pulse ml-1\" />\n )}\n </div>\n </div>\n );\n}\n```\n\n### 2. Create Session and Render Chat\n\n```tsx\n// app/chat/page.tsx\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Chat } from '@/components/chat';\n\nexport default function ChatPage() {\n const [sessionId, setSessionId] = useState<string | null>(null);\n\n useEffect(() => {\n async function createSession() {\n const response = await fetch('/api/chat/create', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n input: {\n COMPANY_NAME: 'Acme Corp',\n PRODUCT_NAME: 'Widget Pro',\n },\n }),\n });\n const { sessionId } = await response.json();\n setSessionId(sessionId);\n }\n\n createSession();\n }, []);\n\n if (!sessionId) {\n return <div>Loading...</div>;\n }\n\n return <Chat sessionId={sessionId} />;\n}\n```\n\n## Environment Variables\n\nAdd these to your `.env.local`:\n\n```bash\nOCTAVUS_API_URL=https://octavus.ai\nOCTAVUS_API_KEY=your-api-key-here\n```\n\n## What's Next?\n\nNow that you have a basic integration working:\n\n- [Learn about the protocol](/docs/protocol/overview) to define custom agent behavior\n- [Explore the Server SDK](/docs/server-sdk/overview) for advanced backend features\n- [Build rich UIs](/docs/client-sdk/overview) with the Client SDK\n- [Handle tools on the client](/docs/client-sdk/client-tools) for interactive UIs and browser APIs\n",
734
+ content: "\n# Quick Start\n\nThis guide will walk you through integrating Octavus into your application in under 10 minutes.\n\n## Prerequisites\n\n- Node.js 18+\n- An Octavus account with API key\n- A Next.js application (or any Node.js backend)\n\n## Test Your Agent First\n\nBefore integrating with SDKs, use **Agent Preview** to test your agent directly in the platform:\n\n1. Open your agent in the platform at `octavus.ai/platform/agents/[agentId]`\n2. Click the **Preview** tab\n3. Configure session inputs and tool mock responses\n4. Start a conversation to test agent behavior\n\nAgent Preview supports all trigger types, file attachments, tool mocking, and real-time streaming. This is the fastest way to iterate on your agent logic before writing any integration code.\n\n## Installation\n\nInstall the Octavus SDKs in your project:\n\n```bash\n# Server SDK for backend\nnpm install @octavus/server-sdk\n\n# React bindings for frontend\nnpm install @octavus/react\n```\n\n## Backend Setup\n\n### 1. Initialize the Client\n\nCreate an Octavus client instance in your backend:\n\n```typescript\n// lib/octavus.ts\nimport { OctavusClient } from '@octavus/server-sdk';\n\nexport const octavus = new OctavusClient({\n baseUrl: process.env.OCTAVUS_API_URL!,\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n```\n\n### 2. Create a Session Endpoint\n\nCreate an API endpoint that creates sessions and returns the session ID:\n\n```typescript\n// app/api/chat/create/route.ts\nimport { NextResponse } from 'next/server';\nimport { octavus } from '@/lib/octavus';\n\n// Agent ID - get from platform or CLI (see below)\nconst SUPPORT_AGENT_ID = process.env.OCTAVUS_SUPPORT_AGENT_ID!;\n\nexport async function POST(request: Request) {\n const { input } = await request.json();\n\n // Create a new session using the agent ID\n const sessionId = await octavus.agentSessions.create(SUPPORT_AGENT_ID, input);\n\n return NextResponse.json({ sessionId });\n}\n```\n\n### Getting Your Agent ID\n\nThere are two ways to create and manage agents:\n\n**Option 1: Platform UI (Recommended for getting started)**\n\n1. Go to [octavus.ai](https://octavus.ai) and create an agent in the web editor\n2. Copy the agent ID from the URL (e.g., `octavus.ai/platform/agents/clxyz123abc456`)\n3. Add it to your `.env.local`: `OCTAVUS_SUPPORT_AGENT_ID=clxyz123abc456`\n\n**Option 2: Local Development with CLI**\n\nFor version-controlled agent definitions, use the [Octavus CLI](/docs/server-sdk/cli):\n\n```bash\nnpm install --save-dev @octavus/cli\noctavus sync ./agents/support-chat\n# Output: Agent ID: clxyz123abc456\n```\n\nThe CLI approach is better for teams and CI/CD pipelines where you want agent definitions in your repository.\n\n### 3. Create a Trigger Endpoint\n\nCreate an endpoint that handles triggers and streams responses:\n\n```typescript\n// app/api/trigger/route.ts\nimport { toSSEStream } from '@octavus/server-sdk';\nimport { octavus } from '@/lib/octavus';\n\nexport async function POST(request: Request) {\n const body = await request.json();\n const { sessionId, ...payload } = body;\n\n // Attach to session with tool handlers\n const session = octavus.agentSessions.attach(sessionId, {\n tools: {\n // Define tool handlers that run on your server\n 'get-user-account': async (args) => {\n const userId = args.userId as string;\n // Fetch from your database\n return {\n name: 'Demo User',\n email: 'demo@example.com',\n plan: 'pro',\n };\n },\n 'create-support-ticket': async (args) => {\n // Create ticket in your system\n return {\n ticketId: 'TICKET-123',\n estimatedResponse: '24 hours',\n };\n },\n },\n });\n\n // Execute the request and convert to SSE stream\n const events = session.execute(payload, { signal: request.signal });\n\n // Return as streaming response\n return new Response(toSSEStream(events), {\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n Connection: 'keep-alive',\n },\n });\n}\n```\n\n## Frontend Setup\n\n### 1. Create a Chat Component\n\nUse the `useOctavusChat` hook with the HTTP transport:\n\n```tsx\n// components/chat.tsx\n'use client';\n\nimport { useState, useMemo } from 'react';\nimport { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';\n\ninterface ChatProps {\n sessionId: string;\n}\n\nexport function Chat({ sessionId }: ChatProps) {\n const [inputValue, setInputValue] = useState('');\n\n // Create a stable transport instance\n const transport = useMemo(\n () =>\n createHttpTransport({\n request: (payload, options) =>\n fetch('/api/trigger', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, ...payload }),\n signal: options?.signal,\n }),\n }),\n [sessionId],\n );\n\n const { messages, status, error, send } = useOctavusChat({ transport });\n\n const isStreaming = status === 'streaming';\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!inputValue.trim() || isStreaming) return;\n\n const message = inputValue.trim();\n setInputValue('');\n\n // Add user message and trigger in one call\n await send('user-message', { USER_MESSAGE: message }, { userMessage: { content: message } });\n };\n\n return (\n <div className=\"flex flex-col h-full\">\n {/* Messages */}\n <div className=\"flex-1 overflow-y-auto p-4 space-y-4\">\n {messages.map((msg) => (\n <MessageBubble key={msg.id} message={msg} />\n ))}\n </div>\n\n {/* Input */}\n <form onSubmit={handleSubmit} className=\"p-4 border-t\">\n <div className=\"flex gap-2\">\n <input\n type=\"text\"\n value={inputValue}\n onChange={(e) => setInputValue(e.target.value)}\n placeholder=\"Type a message...\"\n className=\"flex-1 px-4 py-2 border rounded-lg\"\n disabled={isStreaming}\n />\n <button\n type=\"submit\"\n disabled={isStreaming}\n className=\"px-4 py-2 bg-blue-500 text-white rounded-lg disabled:opacity-50\"\n >\n Send\n </button>\n </div>\n </form>\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: UIMessage }) {\n const isUser = message.role === 'user';\n\n return (\n <div className={`flex ${isUser ? 'justify-end' : 'justify-start'}`}>\n <div\n className={`p-3 rounded-lg max-w-md ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-100'}`}\n >\n {message.parts.map((part, i) => {\n if (part.type === 'text') {\n return <p key={i}>{part.text}</p>;\n }\n return null;\n })}\n\n {/* Streaming indicator */}\n {message.status === 'streaming' && (\n <span className=\"inline-block w-2 h-4 bg-gray-400 animate-pulse ml-1\" />\n )}\n </div>\n </div>\n );\n}\n```\n\n### 2. Create Session and Render Chat\n\n```tsx\n// app/chat/page.tsx\n'use client';\n\nimport { useEffect, useState } from 'react';\nimport { Chat } from '@/components/chat';\n\nexport default function ChatPage() {\n const [sessionId, setSessionId] = useState<string | null>(null);\n\n useEffect(() => {\n async function createSession() {\n const response = await fetch('/api/chat/create', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n input: {\n COMPANY_NAME: 'Acme Corp',\n PRODUCT_NAME: 'Widget Pro',\n },\n }),\n });\n const { sessionId } = await response.json();\n setSessionId(sessionId);\n }\n\n createSession();\n }, []);\n\n if (!sessionId) {\n return <div>Loading...</div>;\n }\n\n return <Chat sessionId={sessionId} />;\n}\n```\n\n## Environment Variables\n\nAdd these to your `.env.local`:\n\n```bash\nOCTAVUS_API_URL=https://octavus.ai\nOCTAVUS_API_KEY=your-api-key-here\n```\n\n## What's Next?\n\nNow that you have a basic integration working:\n\n- [Learn about the protocol](/docs/protocol/overview) to define custom agent behavior\n- [Explore the Server SDK](/docs/server-sdk/overview) for advanced backend features\n- [Build rich UIs](/docs/client-sdk/overview) with the Client SDK\n- [Handle tools on the client](/docs/client-sdk/client-tools) for interactive UIs and browser APIs\n",
735
735
  excerpt: "Quick Start This guide will walk you through integrating Octavus into your application in under 10 minutes. Prerequisites - Node.js 18+ - An Octavus account with API key - A Next.js application (or...",
736
736
  order: 2
737
737
  }
@@ -793,7 +793,7 @@ var sections_default = [
793
793
  section: "server-sdk",
794
794
  title: "Workers",
795
795
  description: "Executing worker agents with the Server SDK.",
796
- content: "\n# Workers API\n\nThe `WorkersApi` enables executing worker agents from your server. Workers are task-based agents that run steps sequentially and return an output value.\n\n## Basic Usage\n\n```typescript\nimport { OctavusClient } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: 'your-api-key',\n});\n\nconst { output, sessionId } = await client.workers.generate(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nconsole.log('Result:', output);\nconsole.log(`Debug: ${client.baseUrl}/sessions/${sessionId}`);\n```\n\n## WorkersApi Reference\n\n### generate()\n\nExecute a worker and return the output directly.\n\n```typescript\nasync generate(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): Promise<WorkerGenerateResult>\n```\n\nRuns the worker to completion and returns the output value. This is the simplest way to execute a worker.\n\n**Returns:**\n\n```typescript\ninterface WorkerGenerateResult {\n /** The worker's output value */\n output: unknown;\n /** Session ID for debugging (usable for session URLs) */\n sessionId: string;\n}\n```\n\n**Throws:** `WorkerError` if the worker fails or completes without producing output.\n\n### execute()\n\nExecute a worker and stream the response. Use this when you need to observe intermediate events like text deltas, tool calls, or progress tracking.\n\n```typescript\nasync *execute(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\n### continue()\n\nContinue execution after client-side tool handling.\n\n```typescript\nasync *continue(\n agentId: string,\n executionId: string,\n toolResults: ToolResult[],\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\nUse this when the worker has tools without server-side handlers. The execution pauses with a `client-tool-request` event, you execute the tools, then call `continue()` to resume.\n\n### Shared Options\n\nAll methods accept the same options:\n\n```typescript\ninterface WorkerExecuteOptions {\n /** Tool handlers for server-side tool execution */\n tools?: ToolHandlers;\n /** Abort signal to cancel the execution */\n signal?: AbortSignal;\n}\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n| --------- | ------------------------- | --------------------------- |\n| `agentId` | `string` | The worker agent ID |\n| `input` | `Record<string, unknown>` | Input values for the worker |\n| `options` | `WorkerExecuteOptions` | Optional configuration |\n\n## Tool Handlers\n\nProvide tool handlers to execute tools server-side:\n\n```typescript\nconst { output } = await client.workers.generate(\n agentId,\n { TOPIC: 'AI safety' },\n {\n tools: {\n 'web-search': async (args) => {\n return await searchWeb(args.query);\n },\n 'get-user-data': async (args) => {\n return await db.users.findById(args.userId);\n },\n },\n },\n);\n```\n\nTools defined in the worker protocol but not provided as handlers become client tools \u2014 the execution pauses and emits a `client-tool-request` event.\n\n## Error Handling\n\n### WorkerError (generate)\n\n`generate()` throws a `WorkerError` on failure. The error includes an optional `sessionId` for constructing debug URLs:\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\ntry {\n const { output } = await client.workers.generate(agentId, input);\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Worker failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### Stream Errors (execute)\n\nWhen using `execute()`, errors appear as stream events:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'error') {\n console.error(`Error: ${event.message}`);\n console.error(`Type: ${event.errorType}`);\n console.error(`Retryable: ${event.retryable}`);\n }\n\n if (event.type === 'worker-result' && event.error) {\n console.error(`Worker failed: ${event.error}`);\n }\n}\n```\n\n### Error Types\n\n| Type | Description |\n| ------------------ | --------------------- |\n| `validation_error` | Invalid input |\n| `not_found_error` | Worker not found |\n| `provider_error` | LLM provider error |\n| `tool_error` | Tool execution failed |\n| `execution_error` | Worker step failed |\n\n## Cancellation\n\nUse an abort signal to cancel execution:\n\n```typescript\nconst { output } = await client.workers.generate(agentId, input, {\n signal: AbortSignal.timeout(30_000),\n});\n```\n\nWith `execute()` and a manual controller:\n\n```typescript\nconst controller = new AbortController();\nsetTimeout(() => controller.abort(), 30000);\n\ntry {\n for await (const event of client.workers.execute(agentId, input, {\n signal: controller.signal,\n })) {\n // Process events\n }\n} catch (error) {\n if (error.name === 'AbortError') {\n console.log('Worker cancelled');\n }\n}\n```\n\n## Streaming\n\nWhen you need real-time visibility into the worker's execution \u2014 text generation, tool calls, or progress \u2014 use `execute()` instead of `generate()`.\n\n### Basic Streaming\n\n```typescript\nconst events = client.workers.execute(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nfor await (const event of events) {\n if (event.type === 'worker-start') {\n console.log(`Worker ${event.workerSlug} started`);\n }\n if (event.type === 'text-delta') {\n process.stdout.write(event.delta);\n }\n if (event.type === 'worker-result') {\n console.log('Output:', event.output);\n }\n}\n```\n\n### Streaming to HTTP Response\n\nConvert worker events to an SSE stream:\n\n```typescript\nimport { toSSEStream } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const { agentId, input } = await request.json();\n\n const events = client.workers.execute(agentId, input, {\n tools: {\n search: async (args) => await search(args.query),\n },\n });\n\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\n### Client Tool Continuation\n\nWhen workers have tools without handlers, execution pauses:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'client-tool-request') {\n const results = await executeClientTools(event.toolCalls);\n\n for await (const ev of client.workers.continue(agentId, event.executionId, results)) {\n // Handle remaining events\n }\n break;\n }\n}\n```\n\nThe `client-tool-request` event includes:\n\n```typescript\n{\n type: 'client-tool-request',\n executionId: string, // Pass to continue()\n toolCalls: [{\n toolCallId: string,\n toolName: string,\n args: Record<string, unknown>,\n }],\n}\n```\n\n### Stream Events\n\nWorkers emit standard stream events plus worker-specific events.\n\n#### Worker Events\n\n```typescript\n// Worker started\n{\n type: 'worker-start',\n workerId: string, // Unique ID (also used as session ID for debug)\n workerSlug: string, // The worker's slug\n description?: string, // Display description for UI\n}\n\n// Worker completed\n{\n type: 'worker-result',\n workerId: string,\n output?: unknown, // The worker's output value\n error?: string, // Error message if worker failed\n}\n```\n\n#### Common Events\n\n| Event | Description |\n| ----------------------- | --------------------------- |\n| `start` | Execution started |\n| `finish` | Execution completed |\n| `text-start` | Text generation started |\n| `text-delta` | Text chunk received |\n| `text-end` | Text generation ended |\n| `block-start` | Step started |\n| `block-end` | Step completed |\n| `tool-input-available` | Tool arguments ready |\n| `tool-output-available` | Tool result ready |\n| `client-tool-request` | Client tools need execution |\n| `error` | Error occurred |\n\n## Full Examples\n\n### generate()\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\ntry {\n const { output, sessionId } = await client.workers.generate(\n 'research-assistant-id',\n {\n TOPIC: 'AI safety best practices',\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => await performWebSearch(query),\n },\n signal: AbortSignal.timeout(120_000),\n },\n );\n\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### execute()\n\nFor full control over streaming events and progress tracking:\n\n```typescript\nimport { OctavusClient, type StreamEvent } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\nasync function runResearchWorker(topic: string) {\n console.log(`Researching: ${topic}\\n`);\n\n const events = client.workers.execute(\n 'research-assistant-id',\n {\n TOPIC: topic,\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => {\n console.log(`Searching: ${query}`);\n return await performWebSearch(query);\n },\n },\n },\n );\n\n let output: unknown;\n\n for await (const event of events) {\n switch (event.type) {\n case 'worker-start':\n console.log(`Started: ${event.workerSlug}`);\n break;\n\n case 'block-start':\n console.log(`Step: ${event.blockName}`);\n break;\n\n case 'text-delta':\n process.stdout.write(event.delta);\n break;\n\n case 'worker-result':\n if (event.error) {\n throw new Error(event.error);\n }\n output = event.output;\n break;\n\n case 'error':\n throw new Error(event.message);\n }\n }\n\n console.log('\\n\\nResearch complete!');\n return output;\n}\n\nconst result = await runResearchWorker('AI safety best practices');\nconsole.log('Result:', result);\n```\n\n## Next Steps\n\n- [Workers Protocol](/docs/protocol/workers) \u2014 Worker protocol reference\n- [Streaming](/docs/server-sdk/streaming) \u2014 Understanding stream events\n- [Tools](/docs/server-sdk/tools) \u2014 Tool handler patterns\n",
796
+ content: "\n# Workers API\n\nThe `WorkersApi` enables executing worker agents from your server. Workers are task-based agents that run steps sequentially and return an output value.\n\n## Basic Usage\n\n```typescript\nimport { OctavusClient } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: 'your-api-key',\n});\n\nconst { output, sessionId } = await client.workers.generate(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nconsole.log('Result:', output);\nconsole.log(`Debug: ${client.baseUrl}/sessions/${sessionId}`);\n```\n\n## WorkersApi Reference\n\n### generate()\n\nExecute a worker and return the output directly.\n\n```typescript\nasync generate(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): Promise<WorkerGenerateResult>\n```\n\nRuns the worker to completion and returns the output value. This is the simplest way to execute a worker.\n\n**Returns:**\n\n```typescript\ninterface WorkerGenerateResult {\n /** The worker's output value */\n output: unknown;\n /** Session ID for debugging (usable for session URLs) */\n sessionId: string;\n}\n```\n\n**Throws:** `WorkerError` if the worker fails or completes without producing output.\n\n### execute()\n\nExecute a worker and stream the response. Use this when you need to observe intermediate events like text deltas, tool calls, or progress tracking.\n\n```typescript\nasync *execute(\n agentId: string,\n input: Record<string, unknown>,\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\n### continue()\n\nContinue execution after client-side tool handling.\n\n```typescript\nasync *continue(\n agentId: string,\n executionId: string,\n toolResults: ToolResult[],\n options?: WorkerExecuteOptions\n): AsyncGenerator<StreamEvent>\n```\n\nUse this when the worker has tools without server-side handlers. The execution pauses with a `client-tool-request` event, you execute the tools, then call `continue()` to resume.\n\n### Shared Options\n\nAll methods accept the same options:\n\n```typescript\ninterface WorkerExecuteOptions {\n /** Tool handlers for server-side tool execution */\n tools?: ToolHandlers;\n /** Abort signal to cancel the execution */\n signal?: AbortSignal;\n}\n```\n\n**Parameters:**\n\n| Parameter | Type | Description |\n| --------- | ------------------------- | --------------------------- |\n| `agentId` | `string` | The worker agent ID |\n| `input` | `Record<string, unknown>` | Input values for the worker |\n| `options` | `WorkerExecuteOptions` | Optional configuration |\n\n## Tool Handlers\n\nProvide tool handlers to execute tools server-side:\n\n```typescript\nconst { output } = await client.workers.generate(\n agentId,\n { TOPIC: 'AI safety' },\n {\n tools: {\n 'web-search': async (args) => {\n return await searchWeb(args.query);\n },\n 'get-user-data': async (args) => {\n return await db.users.findById(args.userId);\n },\n },\n },\n);\n```\n\nTools defined in the worker protocol but not provided as handlers become client tools \u2014 the execution pauses and emits a `client-tool-request` event.\n\n## Error Handling\n\n### WorkerError (generate)\n\n`generate()` throws a `WorkerError` on failure. The error includes an optional `sessionId` for constructing debug URLs:\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\ntry {\n const { output } = await client.workers.generate(agentId, input);\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Worker failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/platform/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### Stream Errors (execute)\n\nWhen using `execute()`, errors appear as stream events:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'error') {\n console.error(`Error: ${event.message}`);\n console.error(`Type: ${event.errorType}`);\n console.error(`Retryable: ${event.retryable}`);\n }\n\n if (event.type === 'worker-result' && event.error) {\n console.error(`Worker failed: ${event.error}`);\n }\n}\n```\n\n### Error Types\n\n| Type | Description |\n| ------------------ | --------------------- |\n| `validation_error` | Invalid input |\n| `not_found_error` | Worker not found |\n| `provider_error` | LLM provider error |\n| `tool_error` | Tool execution failed |\n| `execution_error` | Worker step failed |\n\n## Cancellation\n\nUse an abort signal to cancel execution:\n\n```typescript\nconst { output } = await client.workers.generate(agentId, input, {\n signal: AbortSignal.timeout(30_000),\n});\n```\n\nWith `execute()` and a manual controller:\n\n```typescript\nconst controller = new AbortController();\nsetTimeout(() => controller.abort(), 30000);\n\ntry {\n for await (const event of client.workers.execute(agentId, input, {\n signal: controller.signal,\n })) {\n // Process events\n }\n} catch (error) {\n if (error.name === 'AbortError') {\n console.log('Worker cancelled');\n }\n}\n```\n\n## Streaming\n\nWhen you need real-time visibility into the worker's execution \u2014 text generation, tool calls, or progress \u2014 use `execute()` instead of `generate()`.\n\n### Basic Streaming\n\n```typescript\nconst events = client.workers.execute(agentId, {\n TOPIC: 'AI safety',\n DEPTH: 'detailed',\n});\n\nfor await (const event of events) {\n if (event.type === 'worker-start') {\n console.log(`Worker ${event.workerSlug} started`);\n }\n if (event.type === 'text-delta') {\n process.stdout.write(event.delta);\n }\n if (event.type === 'worker-result') {\n console.log('Output:', event.output);\n }\n}\n```\n\n### Streaming to HTTP Response\n\nConvert worker events to an SSE stream:\n\n```typescript\nimport { toSSEStream } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const { agentId, input } = await request.json();\n\n const events = client.workers.execute(agentId, input, {\n tools: {\n search: async (args) => await search(args.query),\n },\n });\n\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\n### Client Tool Continuation\n\nWhen workers have tools without handlers, execution pauses:\n\n```typescript\nfor await (const event of client.workers.execute(agentId, input)) {\n if (event.type === 'client-tool-request') {\n const results = await executeClientTools(event.toolCalls);\n\n for await (const ev of client.workers.continue(agentId, event.executionId, results)) {\n // Handle remaining events\n }\n break;\n }\n}\n```\n\nThe `client-tool-request` event includes:\n\n```typescript\n{\n type: 'client-tool-request',\n executionId: string, // Pass to continue()\n toolCalls: [{\n toolCallId: string,\n toolName: string,\n args: Record<string, unknown>,\n }],\n}\n```\n\n### Stream Events\n\nWorkers emit standard stream events plus worker-specific events.\n\n#### Worker Events\n\n```typescript\n// Worker started\n{\n type: 'worker-start',\n workerId: string, // Unique ID (also used as session ID for debug)\n workerSlug: string, // The worker's slug\n description?: string, // Display description for UI\n}\n\n// Worker completed\n{\n type: 'worker-result',\n workerId: string,\n output?: unknown, // The worker's output value\n error?: string, // Error message if worker failed\n}\n```\n\n#### Common Events\n\n| Event | Description |\n| ----------------------- | --------------------------- |\n| `start` | Execution started |\n| `finish` | Execution completed |\n| `text-start` | Text generation started |\n| `text-delta` | Text chunk received |\n| `text-end` | Text generation ended |\n| `block-start` | Step started |\n| `block-end` | Step completed |\n| `tool-input-available` | Tool arguments ready |\n| `tool-output-available` | Tool result ready |\n| `client-tool-request` | Client tools need execution |\n| `error` | Error occurred |\n\n## Full Examples\n\n### generate()\n\n```typescript\nimport { OctavusClient, WorkerError } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\ntry {\n const { output, sessionId } = await client.workers.generate(\n 'research-assistant-id',\n {\n TOPIC: 'AI safety best practices',\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => await performWebSearch(query),\n },\n signal: AbortSignal.timeout(120_000),\n },\n );\n\n console.log('Result:', output);\n} catch (error) {\n if (error instanceof WorkerError) {\n console.error('Failed:', error.message);\n if (error.sessionId) {\n console.error(`Debug: ${client.baseUrl}/platform/sessions/${error.sessionId}`);\n }\n }\n}\n```\n\n### execute()\n\nFor full control over streaming events and progress tracking:\n\n```typescript\nimport { OctavusClient, type StreamEvent } from '@octavus/server-sdk';\n\nconst client = new OctavusClient({\n baseUrl: 'https://octavus.ai',\n apiKey: process.env.OCTAVUS_API_KEY!,\n});\n\nasync function runResearchWorker(topic: string) {\n console.log(`Researching: ${topic}\\n`);\n\n const events = client.workers.execute(\n 'research-assistant-id',\n {\n TOPIC: topic,\n DEPTH: 'detailed',\n },\n {\n tools: {\n 'web-search': async ({ query }) => {\n console.log(`Searching: ${query}`);\n return await performWebSearch(query);\n },\n },\n },\n );\n\n let output: unknown;\n\n for await (const event of events) {\n switch (event.type) {\n case 'worker-start':\n console.log(`Started: ${event.workerSlug}`);\n break;\n\n case 'block-start':\n console.log(`Step: ${event.blockName}`);\n break;\n\n case 'text-delta':\n process.stdout.write(event.delta);\n break;\n\n case 'worker-result':\n if (event.error) {\n throw new Error(event.error);\n }\n output = event.output;\n break;\n\n case 'error':\n throw new Error(event.message);\n }\n }\n\n console.log('\\n\\nResearch complete!');\n return output;\n}\n\nconst result = await runResearchWorker('AI safety best practices');\nconsole.log('Result:', result);\n```\n\n## Next Steps\n\n- [Workers Protocol](/docs/protocol/workers) \u2014 Worker protocol reference\n- [Streaming](/docs/server-sdk/streaming) \u2014 Understanding stream events\n- [Tools](/docs/server-sdk/tools) \u2014 Tool handler patterns\n",
797
797
  excerpt: "Workers API The enables executing worker agents from your server. Workers are task-based agents that run steps sequentially and return an output value. Basic Usage WorkersApi Reference generate()...",
798
798
  order: 6
799
799
  },
@@ -1407,7 +1407,7 @@ See [Streaming Events](/docs/server-sdk/streaming#event-types) for the full list
1407
1407
  section: "api-reference",
1408
1408
  title: "Sessions",
1409
1409
  description: "Session management API endpoints.",
1410
- content: '\n# Sessions API\n\nSessions represent conversations with agents. They store conversation history, resources, and variables.\n\nAll session endpoints require an API key with the **Sessions** permission.\n\n## Create Session\n\nCreate a new agent session.\n\n```\nPOST /api/agent-sessions\n```\n\n### Request Body\n\n```json\n{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro",\n "USER_ID": "user-123"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| --------- | ------ | -------- | ------------------------------------- |\n| `agentId` | string | Yes | Agent ID (the `id` field, not `slug`) |\n| `input` | object | No | Input variables for the agent |\n\n> **Getting the agent ID:** Copy the ID from the agent URL in the [platform](https://octavus.ai) (e.g., `octavus.ai/agents/clxyz123`), or use the [CLI](/docs/server-sdk/cli) (`octavus sync ./agents/my-agent`) for local development workflows.\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def"\n}\n```\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n }\n }\'\n```\n\n## Get Session\n\nRetrieve session state. Returns UI-ready messages for active sessions, or expiration info for expired sessions.\n\n```\nGET /api/agent-sessions/:sessionId\n```\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --------- | ------ | ---------------------------------------------------- |\n| `format` | string | Optional. Use `format=ui` for UI-ready messages only |\n\n### Response (Active Session)\n\nWhen the session is active, the response includes `UIMessage` objects:\n\n```json\n{\n "id": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "status": "active",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n },\n "variables": {},\n "resources": {\n "CONVERSATION_SUMMARY": ""\n },\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n },\n {\n "id": "1702345805000-def456b",\n "role": "assistant",\n "parts": [\n { "type": "text", "text": "I can help you reset your password...", "status": "done" }\n ],\n "status": "done",\n "createdAt": "2024-01-15T10:30:05.000Z"\n }\n ],\n "createdAt": "2024-01-15T10:30:00Z",\n "updatedAt": "2024-01-15T10:30:05Z"\n}\n```\n\n### Response (Expired Session)\n\nWhen the session has expired, the response indicates the expiration status:\n\n```json\n{\n "status": "expired",\n "sessionId": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "createdAt": "2024-01-15T10:30:00Z"\n}\n```\n\nUse the [Restore Session](#restore-session) endpoint to restore an expired session from stored messages.\n\n````\n\n### UIMessage Parts\n\nMessages contain typed `parts` that preserve content ordering:\n\n| Part Type | Description |\n|-----------|-------------|\n| `text` | Text content with `text` and `status` fields |\n| `reasoning` | Extended reasoning with `text` and `status` fields |\n| `tool-call` | Tool execution with `toolCallId`, `toolName`, `displayName`, `args`, `result`, `status` |\n| `operation` | Internal operations with `operationId`, `name`, `operationType`, `status` |\n| `file` | File attachment with `id`, `mediaType`, `url`, `filename`, `size` |\n| `source` | Source reference with `sourceType`, `id`, `url`, `title` |\n| `object` | Structured output with `id`, `typeName`, `object`, `status` |\n\n### Example\n\n```bash\ncurl https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n````\n\n## Restore Session\n\nRestore an expired session from stored messages. This allows you to continue a conversation after the server-side state has expired.\n\n```\nPOST /api/agent-sessions/:sessionId/restore\n```\n\n### Request Body\n\n```json\n{\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n }\n ],\n "input": {\n "COMPANY_NAME": "Acme Corp"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| ---------- | ----------- | -------- | -------------------------------------------------------------- |\n| `messages` | UIMessage[] | Yes | Previously stored chat history |\n| `input` | object | No | Session input for system prompt interpolation (same as create) |\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "restored": true\n}\n```\n\n| Field | Type | Description |\n| ----------- | ------- | ----------------------------------------------------------------------- |\n| `sessionId` | string | The session ID |\n| `restored` | boolean | `true` if restored from messages, `false` if session was already active |\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions/:sessionId/restore \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "messages": [...],\n "input": { "COMPANY_NAME": "Acme Corp" }\n }\'\n```\n\n> **Note**: Store the `UIMessage[]` array after each interaction to enable restoration. The restore endpoint reconstructs the conversation state from these messages.\n\n## Clear Session\n\nClear session state, transitioning it to `expired` status. The session can be restored afterwards with the [Restore Session](#restore-session) endpoint.\n\nThis is idempotent \u2014 clearing an already expired session succeeds without error.\n\n```\nDELETE /api/agent-sessions/:sessionId\n```\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "cleared": true\n}\n```\n\n### Example\n\n```bash\ncurl -X DELETE https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n```\n\n## Trigger Session\n\nExecute a trigger on a session. Returns a Server-Sent Events stream.\n\n```\nPOST /api/agent-sessions/:sessionId/trigger\n```\n\n### Request Body\n\n```json\n{\n "triggerName": "user-message",\n "input": {\n "USER_MESSAGE": "How do I reset my password?"\n },\n "toolResults": []\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------- |\n| `triggerName` | string | Yes | Name of the trigger to execute |\n| `input` | object | No | Input variables for the trigger |\n| `toolResults` | array | No | Tool results for continuation (handled by SDK) |\n| `rollbackAfterMessageId` | string \\| null | No | For retry: ID of the last message to keep. Messages after this are removed. `null` = truncate all. |\n\n### Response\n\nReturns `text/event-stream` with SSE events:\n\n```\ndata: {"type":"start","messageId":"msg-123"}\n\ndata: {"type":"block-start","blockId":"b1","blockName":"Add user message","blockType":"add-message","display":"hidden"}\n\ndata: {"type":"block-end","blockId":"b1"}\n\ndata: {"type":"block-start","blockId":"b2","blockName":"Respond to user","blockType":"next-message","display":"stream","outputToChat":true}\n\ndata: {"type":"text-start","id":"t1"}\n\ndata: {"type":"text-delta","id":"t1","delta":"I"}\n\ndata: {"type":"text-delta","id":"t1","delta":" can"}\n\ndata: {"type":"text-delta","id":"t1","delta":" help"}\n\ndata: {"type":"text-delta","id":"t1","delta":" you"}\n\ndata: {"type":"text-delta","id":"t1","delta":" reset"}\n\ndata: {"type":"text-delta","id":"t1","delta":" your"}\n\ndata: {"type":"text-delta","id":"t1","delta":" password"}\n\ndata: {"type":"text-delta","id":"t1","delta":"!"}\n\ndata: {"type":"text-end","id":"t1"}\n\ndata: {"type":"block-end","blockId":"b2"}\n\ndata: {"type":"finish","finishReason":"stop"}\n\ndata: [DONE]\n```\n\n### Event Types\n\n| Event | Description |\n| ----------------------- | ---------------------------------- |\n| `start` | Stream started |\n| `finish` | Execution complete |\n| `error` | Error occurred |\n| `block-start` | Execution block started |\n| `block-end` | Execution block completed |\n| `text-start` | Text generation started |\n| `text-delta` | Incremental text content |\n| `text-end` | Text generation ended |\n| `reasoning-start` | Extended reasoning started |\n| `reasoning-delta` | Reasoning content |\n| `reasoning-end` | Extended reasoning ended |\n| `tool-input-start` | Tool call initiated |\n| `tool-input-delta` | Tool arguments streaming |\n| `tool-input-end` | Tool arguments streaming ended |\n| `tool-input-available` | Tool input complete |\n| `tool-output-available` | Tool completed with result |\n| `tool-output-error` | Tool failed |\n| `tool-request` | Platform requesting tool execution |\n| `file-available` | File ready for display/download |\n| `resource-update` | Resource value changed |\n\n### Example\n\n```bash\ncurl -N -X POST https://octavus.ai/api/agent-sessions/:sessionId/trigger \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "How do I reset my password?" }\n }\'\n```\n\n## Tool Continuation\n\nWhen the agent calls external tools, you\'ll receive a `tool-request` event. Execute the tools and send results back:\n\n```json\n{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "..." },\n "toolResults": [\n {\n "toolCallId": "tc_123",\n "toolName": "get-user-account",\n "result": {\n "name": "Demo User",\n "email": "demo@example.com"\n }\n }\n ]\n}\n```\n\nThe Server SDK handles this continuation pattern automatically.\n\n## Upload URLs\n\nGet presigned URLs for file uploads. Files are uploaded directly to S3.\n\n```\nPOST /api/files/upload-urls\n```\n\n### Request Body\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "files": [\n {\n "filename": "photo.jpg",\n "mediaType": "image/jpeg",\n "size": 102400\n }\n ]\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------- | ------ | -------- | ----------------------------------- |\n| `sessionId` | string | Yes | Session ID to associate files with |\n| `files` | array | Yes | Array of file metadata (1-20 files) |\n| `files[].filename` | string | Yes | Original filename |\n| `files[].mediaType` | string | Yes | MIME type (e.g., `image/png`) |\n| `files[].size` | number | Yes | File size in bytes |\n\n### Response\n\n```json\n{\n "files": [\n {\n "id": "file-abc123",\n "uploadUrl": "https://s3.amazonaws.com/bucket/key?...",\n "downloadUrl": "https://s3.amazonaws.com/bucket/key?..."\n }\n ]\n}\n```\n\n### Upload Flow\n\n1. Request upload URLs from the platform\n2. PUT file content to `uploadUrl` with `Content-Type` header\n3. Use `downloadUrl` as the `url` in `FileReference`\n4. Include `FileReference` in trigger input\n\n### Supported Types\n\n| Category | Media Types |\n| --------- | -------------------------------------------------------------------- |\n| Images | `image/jpeg`, `image/png`, `image/gif`, `image/webp` |\n| Documents | `application/pdf`, `text/plain`, `text/markdown`, `application/json` |\n\n### Limits\n\n| Limit | Value |\n| --------------------- | ---------- |\n| Max file size | 10 MB |\n| Max total per request | 50 MB |\n| Max files per request | 20 |\n| Upload URL expiry | 15 minutes |\n| Download URL expiry | 24 hours |\n',
1410
+ content: '\n# Sessions API\n\nSessions represent conversations with agents. They store conversation history, resources, and variables.\n\nAll session endpoints require an API key with the **Sessions** permission.\n\n## Create Session\n\nCreate a new agent session.\n\n```\nPOST /api/agent-sessions\n```\n\n### Request Body\n\n```json\n{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro",\n "USER_ID": "user-123"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| --------- | ------ | -------- | ------------------------------------- |\n| `agentId` | string | Yes | Agent ID (the `id` field, not `slug`) |\n| `input` | object | No | Input variables for the agent |\n\n> **Getting the agent ID:** Copy the ID from the agent URL in the [platform](https://octavus.ai) (e.g., `octavus.ai/platform/agents/clxyz123`), or use the [CLI](/docs/server-sdk/cli) (`octavus sync ./agents/my-agent`) for local development workflows.\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def"\n}\n```\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "agentId": "cm5xvz7k80001abcd",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n }\n }\'\n```\n\n## Get Session\n\nRetrieve session state. Returns UI-ready messages for active sessions, or expiration info for expired sessions.\n\n```\nGET /api/agent-sessions/:sessionId\n```\n\n### Query Parameters\n\n| Parameter | Type | Description |\n| --------- | ------ | ---------------------------------------------------- |\n| `format` | string | Optional. Use `format=ui` for UI-ready messages only |\n\n### Response (Active Session)\n\nWhen the session is active, the response includes `UIMessage` objects:\n\n```json\n{\n "id": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "status": "active",\n "input": {\n "COMPANY_NAME": "Acme Corp",\n "PRODUCT_NAME": "Widget Pro"\n },\n "variables": {},\n "resources": {\n "CONVERSATION_SUMMARY": ""\n },\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n },\n {\n "id": "1702345805000-def456b",\n "role": "assistant",\n "parts": [\n { "type": "text", "text": "I can help you reset your password...", "status": "done" }\n ],\n "status": "done",\n "createdAt": "2024-01-15T10:30:05.000Z"\n }\n ],\n "createdAt": "2024-01-15T10:30:00Z",\n "updatedAt": "2024-01-15T10:30:05Z"\n}\n```\n\n### Response (Expired Session)\n\nWhen the session has expired, the response indicates the expiration status:\n\n```json\n{\n "status": "expired",\n "sessionId": "cm5xyz123abc456def",\n "agentId": "cm5xvz7k80001abcd",\n "createdAt": "2024-01-15T10:30:00Z"\n}\n```\n\nUse the [Restore Session](#restore-session) endpoint to restore an expired session from stored messages.\n\n````\n\n### UIMessage Parts\n\nMessages contain typed `parts` that preserve content ordering:\n\n| Part Type | Description |\n|-----------|-------------|\n| `text` | Text content with `text` and `status` fields |\n| `reasoning` | Extended reasoning with `text` and `status` fields |\n| `tool-call` | Tool execution with `toolCallId`, `toolName`, `displayName`, `args`, `result`, `status` |\n| `operation` | Internal operations with `operationId`, `name`, `operationType`, `status` |\n| `file` | File attachment with `id`, `mediaType`, `url`, `filename`, `size` |\n| `source` | Source reference with `sourceType`, `id`, `url`, `title` |\n| `object` | Structured output with `id`, `typeName`, `object`, `status` |\n\n### Example\n\n```bash\ncurl https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n````\n\n## Restore Session\n\nRestore an expired session from stored messages. This allows you to continue a conversation after the server-side state has expired.\n\n```\nPOST /api/agent-sessions/:sessionId/restore\n```\n\n### Request Body\n\n```json\n{\n "messages": [\n {\n "id": "1702345800000-xyz789a",\n "role": "user",\n "parts": [{ "type": "text", "text": "How do I reset my password?", "status": "done" }],\n "status": "done",\n "createdAt": "2024-01-15T10:30:00.000Z"\n }\n ],\n "input": {\n "COMPANY_NAME": "Acme Corp"\n }\n}\n```\n\n| Field | Type | Required | Description |\n| ---------- | ----------- | -------- | -------------------------------------------------------------- |\n| `messages` | UIMessage[] | Yes | Previously stored chat history |\n| `input` | object | No | Session input for system prompt interpolation (same as create) |\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "restored": true\n}\n```\n\n| Field | Type | Description |\n| ----------- | ------- | ----------------------------------------------------------------------- |\n| `sessionId` | string | The session ID |\n| `restored` | boolean | `true` if restored from messages, `false` if session was already active |\n\n### Example\n\n```bash\ncurl -X POST https://octavus.ai/api/agent-sessions/:sessionId/restore \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "messages": [...],\n "input": { "COMPANY_NAME": "Acme Corp" }\n }\'\n```\n\n> **Note**: Store the `UIMessage[]` array after each interaction to enable restoration. The restore endpoint reconstructs the conversation state from these messages.\n\n## Clear Session\n\nClear session state, transitioning it to `expired` status. The session can be restored afterwards with the [Restore Session](#restore-session) endpoint.\n\nThis is idempotent \u2014 clearing an already expired session succeeds without error.\n\n```\nDELETE /api/agent-sessions/:sessionId\n```\n\n### Response\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "cleared": true\n}\n```\n\n### Example\n\n```bash\ncurl -X DELETE https://octavus.ai/api/agent-sessions/:sessionId \\\n -H "Authorization: Bearer YOUR_API_KEY"\n```\n\n## Trigger Session\n\nExecute a trigger on a session. Returns a Server-Sent Events stream.\n\n```\nPOST /api/agent-sessions/:sessionId/trigger\n```\n\n### Request Body\n\n```json\n{\n "triggerName": "user-message",\n "input": {\n "USER_MESSAGE": "How do I reset my password?"\n },\n "toolResults": []\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------------ | -------------- | -------- | -------------------------------------------------------------------------------------------------- |\n| `triggerName` | string | Yes | Name of the trigger to execute |\n| `input` | object | No | Input variables for the trigger |\n| `toolResults` | array | No | Tool results for continuation (handled by SDK) |\n| `rollbackAfterMessageId` | string \\| null | No | For retry: ID of the last message to keep. Messages after this are removed. `null` = truncate all. |\n\n### Response\n\nReturns `text/event-stream` with SSE events:\n\n```\ndata: {"type":"start","messageId":"msg-123"}\n\ndata: {"type":"block-start","blockId":"b1","blockName":"Add user message","blockType":"add-message","display":"hidden"}\n\ndata: {"type":"block-end","blockId":"b1"}\n\ndata: {"type":"block-start","blockId":"b2","blockName":"Respond to user","blockType":"next-message","display":"stream","outputToChat":true}\n\ndata: {"type":"text-start","id":"t1"}\n\ndata: {"type":"text-delta","id":"t1","delta":"I"}\n\ndata: {"type":"text-delta","id":"t1","delta":" can"}\n\ndata: {"type":"text-delta","id":"t1","delta":" help"}\n\ndata: {"type":"text-delta","id":"t1","delta":" you"}\n\ndata: {"type":"text-delta","id":"t1","delta":" reset"}\n\ndata: {"type":"text-delta","id":"t1","delta":" your"}\n\ndata: {"type":"text-delta","id":"t1","delta":" password"}\n\ndata: {"type":"text-delta","id":"t1","delta":"!"}\n\ndata: {"type":"text-end","id":"t1"}\n\ndata: {"type":"block-end","blockId":"b2"}\n\ndata: {"type":"finish","finishReason":"stop"}\n\ndata: [DONE]\n```\n\n### Event Types\n\n| Event | Description |\n| ----------------------- | ---------------------------------- |\n| `start` | Stream started |\n| `finish` | Execution complete |\n| `error` | Error occurred |\n| `block-start` | Execution block started |\n| `block-end` | Execution block completed |\n| `text-start` | Text generation started |\n| `text-delta` | Incremental text content |\n| `text-end` | Text generation ended |\n| `reasoning-start` | Extended reasoning started |\n| `reasoning-delta` | Reasoning content |\n| `reasoning-end` | Extended reasoning ended |\n| `tool-input-start` | Tool call initiated |\n| `tool-input-delta` | Tool arguments streaming |\n| `tool-input-end` | Tool arguments streaming ended |\n| `tool-input-available` | Tool input complete |\n| `tool-output-available` | Tool completed with result |\n| `tool-output-error` | Tool failed |\n| `tool-request` | Platform requesting tool execution |\n| `file-available` | File ready for display/download |\n| `resource-update` | Resource value changed |\n\n### Example\n\n```bash\ncurl -N -X POST https://octavus.ai/api/agent-sessions/:sessionId/trigger \\\n -H "Authorization: Bearer YOUR_API_KEY" \\\n -H "Content-Type: application/json" \\\n -d \'{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "How do I reset my password?" }\n }\'\n```\n\n## Tool Continuation\n\nWhen the agent calls external tools, you\'ll receive a `tool-request` event. Execute the tools and send results back:\n\n```json\n{\n "triggerName": "user-message",\n "input": { "USER_MESSAGE": "..." },\n "toolResults": [\n {\n "toolCallId": "tc_123",\n "toolName": "get-user-account",\n "result": {\n "name": "Demo User",\n "email": "demo@example.com"\n }\n }\n ]\n}\n```\n\nThe Server SDK handles this continuation pattern automatically.\n\n## Upload URLs\n\nGet presigned URLs for file uploads. Files are uploaded directly to S3.\n\n```\nPOST /api/files/upload-urls\n```\n\n### Request Body\n\n```json\n{\n "sessionId": "cm5xyz123abc456def",\n "files": [\n {\n "filename": "photo.jpg",\n "mediaType": "image/jpeg",\n "size": 102400\n }\n ]\n}\n```\n\n| Field | Type | Required | Description |\n| ------------------- | ------ | -------- | ----------------------------------- |\n| `sessionId` | string | Yes | Session ID to associate files with |\n| `files` | array | Yes | Array of file metadata (1-20 files) |\n| `files[].filename` | string | Yes | Original filename |\n| `files[].mediaType` | string | Yes | MIME type (e.g., `image/png`) |\n| `files[].size` | number | Yes | File size in bytes |\n\n### Response\n\n```json\n{\n "files": [\n {\n "id": "file-abc123",\n "uploadUrl": "https://s3.amazonaws.com/bucket/key?...",\n "downloadUrl": "https://s3.amazonaws.com/bucket/key?..."\n }\n ]\n}\n```\n\n### Upload Flow\n\n1. Request upload URLs from the platform\n2. PUT file content to `uploadUrl` with `Content-Type` header\n3. Use `downloadUrl` as the `url` in `FileReference`\n4. Include `FileReference` in trigger input\n\n### Supported Types\n\n| Category | Media Types |\n| --------- | -------------------------------------------------------------------- |\n| Images | `image/jpeg`, `image/png`, `image/gif`, `image/webp` |\n| Documents | `application/pdf`, `text/plain`, `text/markdown`, `application/json` |\n\n### Limits\n\n| Limit | Value |\n| --------------------- | ---------- |\n| Max file size | 10 MB |\n| Max total per request | 50 MB |\n| Max files per request | 20 |\n| Upload URL expiry | 15 minutes |\n| Download URL expiry | 24 hours |\n',
1411
1411
  excerpt: "Sessions API Sessions represent conversations with agents. They store conversation history, resources, and variables. All session endpoints require an API key with the Sessions permission. Create...",
1412
1412
  order: 2
1413
1413
  },
@@ -1506,4 +1506,4 @@ export {
1506
1506
  getDocSlugs,
1507
1507
  getSectionBySlug
1508
1508
  };
1509
- //# sourceMappingURL=chunk-PYLADDXH.js.map
1509
+ //# sourceMappingURL=chunk-LAUGGZQI.js.map