@octavus/docs 2.3.0 → 2.4.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.
- package/content/04-protocol/07-agent-config.md +6 -6
- package/content/07-migration/01-v1-to-v2.md +1 -1
- package/dist/{chunk-NXHCNS7O.js → chunk-SX6AIMRO.js} +11 -11
- package/dist/chunk-SX6AIMRO.js.map +1 -0
- package/dist/{chunk-LACIU65C.js → chunk-WQ7BTD5T.js} +3 -3
- package/dist/chunk-WQ7BTD5T.js.map +1 -0
- package/dist/content.js +1 -1
- package/dist/docs.json +5 -5
- package/dist/index.js +1 -1
- package/dist/search-index.json +1 -1
- package/dist/search.js +1 -1
- package/dist/search.js.map +1 -1
- package/dist/sections.json +5 -5
- package/package.json +3 -3
- package/dist/chunk-3ER2T7S7.js +0 -663
- package/dist/chunk-3ER2T7S7.js.map +0 -1
- package/dist/chunk-CYA6VJUI.js +0 -1471
- package/dist/chunk-CYA6VJUI.js.map +0 -1
- package/dist/chunk-ELQKUF7H.js +0 -1471
- package/dist/chunk-ELQKUF7H.js.map +0 -1
- package/dist/chunk-GI574O6S.js +0 -1435
- package/dist/chunk-GI574O6S.js.map +0 -1
- package/dist/chunk-HFF2TVGV.js +0 -663
- package/dist/chunk-HFF2TVGV.js.map +0 -1
- package/dist/chunk-JGWOMZWD.js +0 -1435
- package/dist/chunk-JGWOMZWD.js.map +0 -1
- package/dist/chunk-KUB6BGPR.js +0 -1435
- package/dist/chunk-KUB6BGPR.js.map +0 -1
- package/dist/chunk-LACIU65C.js.map +0 -1
- package/dist/chunk-NXHCNS7O.js.map +0 -1
- package/dist/chunk-OVK6L7X4.js +0 -1435
- package/dist/chunk-OVK6L7X4.js.map +0 -1
- package/dist/chunk-S5JUVAKE.js +0 -1409
- package/dist/chunk-S5JUVAKE.js.map +0 -1
- package/dist/chunk-TMJG4CJH.js +0 -1409
- package/dist/chunk-TMJG4CJH.js.map +0 -1
- package/dist/chunk-WBR3NHBM.js +0 -1471
- package/dist/chunk-WBR3NHBM.js.map +0 -1
- package/dist/chunk-WKCT4ABS.js +0 -1435
- package/dist/chunk-WKCT4ABS.js.map +0 -1
- package/dist/chunk-YJPO6KOJ.js +0 -1435
- package/dist/chunk-YJPO6KOJ.js.map +0 -1
- package/dist/chunk-ZSCRYD5P.js +0 -1409
- package/dist/chunk-ZSCRYD5P.js.map +0 -1
package/dist/content.js
CHANGED
package/dist/docs.json
CHANGED
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"section": "server-sdk",
|
|
23
23
|
"title": "Overview",
|
|
24
24
|
"description": "Introduction to the Octavus Server SDK for backend integration.",
|
|
25
|
-
"content": "\n# Server SDK Overview\n\nThe `@octavus/server-sdk` package provides a Node.js SDK for integrating Octavus agents into your backend application. It handles session management, streaming, and the tool execution continuation loop.\n\n**Current version:** `2.
|
|
25
|
+
"content": "\n# Server SDK Overview\n\nThe `@octavus/server-sdk` package provides a Node.js SDK for integrating Octavus agents into your backend application. It handles session management, streaming, and the tool execution continuation loop.\n\n**Current version:** `2.4.0`\n\n## Installation\n\n```bash\nnpm install @octavus/server-sdk\n```\n\nFor agent management (sync, validate), install the CLI as a dev dependency:\n\n```bash\nnpm install --save-dev @octavus/cli\n```\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```\n\n## Key Features\n\n### Agent Management\n\nAgent definitions are managed via the CLI. See the [CLI documentation](/docs/server-sdk/cli) for details.\n\n```bash\n# Sync agent from local files\noctavus sync ./agents/support-chat\n\n# Output: Created: support-chat\n# Agent ID: clxyz123abc456\n```\n\n### Session Management\n\nCreate and manage agent sessions using the agent ID:\n\n```typescript\n// Create a new session (use agent ID from CLI sync)\nconst sessionId = await client.agentSessions.create('clxyz123abc456', {\n COMPANY_NAME: 'Acme Corp',\n PRODUCT_NAME: 'Widget Pro',\n});\n\n// Get UI-ready session messages (for session restore)\nconst session = await client.agentSessions.getMessages(sessionId);\n```\n\n### Tool Handlers\n\nTools run on your server with your data:\n\n```typescript\nconst session = client.agentSessions.attach(sessionId, {\n tools: {\n 'get-user-account': async (args) => {\n // Access your database, APIs, etc.\n return await db.users.findById(args.userId);\n },\n },\n});\n```\n\n### Streaming\n\nAll responses stream in real-time:\n\n```typescript\nimport { toSSEStream } from '@octavus/server-sdk';\n\n// execute() returns an async generator of events\nconst events = session.execute({\n type: 'trigger',\n triggerName: 'user-message',\n input: { USER_MESSAGE: 'Hello!' },\n});\n\n// Convert to SSE stream for HTTP responses\nreturn new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n});\n```\n\n## API Reference\n\n### OctavusClient\n\nThe main entry point for interacting with Octavus.\n\n```typescript\ninterface OctavusClientConfig {\n baseUrl: string; // Octavus API URL\n apiKey?: string; // Your API key\n}\n\nclass OctavusClient {\n readonly agents: AgentsApi;\n readonly agentSessions: AgentSessionsApi;\n readonly workers: WorkersApi;\n readonly files: FilesApi;\n\n constructor(config: OctavusClientConfig);\n}\n```\n\n### AgentSessionsApi\n\nManages agent sessions.\n\n```typescript\nclass AgentSessionsApi {\n // Create a new session\n async create(agentId: string, input?: Record<string, unknown>): Promise<string>;\n\n // Get full session state (for debugging/internal use)\n async get(sessionId: string): Promise<SessionState>;\n\n // Get UI-ready messages (for client display)\n async getMessages(sessionId: string): Promise<UISessionState>;\n\n // Attach to a session for triggering\n attach(sessionId: string, options?: SessionAttachOptions): AgentSession;\n}\n\n// Full session state (internal format)\ninterface SessionState {\n id: string;\n agentId: string;\n input: Record<string, unknown>;\n variables: Record<string, unknown>;\n resources: Record<string, unknown>;\n messages: ChatMessage[]; // Internal message format\n createdAt: string;\n updatedAt: string;\n}\n\n// UI-ready session state\ninterface UISessionState {\n sessionId: string;\n agentId: string;\n messages: UIMessage[]; // UI-ready messages for frontend\n}\n```\n\n### AgentSession\n\nHandles request execution and streaming for a specific session.\n\n```typescript\nclass AgentSession {\n // Execute a request and stream parsed events\n execute(request: SessionRequest, options?: TriggerOptions): AsyncGenerator<StreamEvent>;\n\n // Get the session ID\n getSessionId(): string;\n}\n\ntype SessionRequest = TriggerRequest | ContinueRequest;\n\ninterface TriggerRequest {\n type: 'trigger';\n triggerName: string;\n input?: Record<string, unknown>;\n}\n\ninterface ContinueRequest {\n type: 'continue';\n executionId: string;\n toolResults: ToolResult[];\n}\n\n// Helper to convert events to SSE stream\nfunction toSSEStream(events: AsyncIterable<StreamEvent>): ReadableStream<Uint8Array>;\n```\n\n### FilesApi\n\nHandles file uploads for sessions.\n\n```typescript\nclass FilesApi {\n // Get presigned URLs for file uploads\n async getUploadUrls(sessionId: string, files: FileUploadRequest[]): Promise<UploadUrlsResponse>;\n}\n\ninterface FileUploadRequest {\n filename: string;\n mediaType: string;\n size: number;\n}\n\ninterface UploadUrlsResponse {\n files: {\n id: string; // File ID for references\n uploadUrl: string; // PUT to this URL\n downloadUrl: string; // GET URL after upload\n }[];\n}\n```\n\nThe client uploads files directly to S3 using the presigned upload URL. See [File Uploads](/docs/client-sdk/file-uploads) for the full integration pattern.\n\n## Next Steps\n\n- [Sessions](/docs/server-sdk/sessions) — Deep dive into session management\n- [Tools](/docs/server-sdk/tools) — Implementing tool handlers\n- [Streaming](/docs/server-sdk/streaming) — Understanding stream events\n- [Workers](/docs/server-sdk/workers) — Executing worker agents\n",
|
|
26
26
|
"excerpt": "Server SDK Overview The package provides a Node.js SDK for integrating Octavus agents into your backend application. It handles session management, streaming, and the tool execution continuation...",
|
|
27
27
|
"order": 1
|
|
28
28
|
},
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
"section": "server-sdk",
|
|
59
59
|
"title": "CLI",
|
|
60
60
|
"description": "Command-line interface for validating and syncing agent definitions.",
|
|
61
|
-
"content": "\n# Octavus CLI\n\nThe `@octavus/cli` package provides a command-line interface for validating and syncing agent definitions from your local filesystem to the Octavus platform.\n\n**Current version:** `2.
|
|
61
|
+
"content": "\n# Octavus CLI\n\nThe `@octavus/cli` package provides a command-line interface for validating and syncing agent definitions from your local filesystem to the Octavus platform.\n\n**Current version:** `2.4.0`\n\n## Installation\n\n```bash\nnpm install --save-dev @octavus/cli\n```\n\n## Configuration\n\nThe CLI requires an API key with the **Agents** permission.\n\n### Environment Variables\n\n| Variable | Description |\n| --------------------- | ---------------------------------------------- |\n| `OCTAVUS_CLI_API_KEY` | API key with \"Agents\" permission (recommended) |\n| `OCTAVUS_API_KEY` | Fallback if `OCTAVUS_CLI_API_KEY` not set |\n| `OCTAVUS_API_URL` | Optional, defaults to `https://octavus.ai` |\n\n### Two-Key Strategy (Recommended)\n\nFor production deployments, use separate API keys with minimal permissions:\n\n```bash\n# CI/CD or .env.local (not committed)\nOCTAVUS_CLI_API_KEY=oct_sk_... # \"Agents\" permission only\n\n# Production .env\nOCTAVUS_API_KEY=oct_sk_... # \"Sessions\" permission only\n```\n\nThis ensures production servers only have session permissions (smaller blast radius if leaked), while agent management is restricted to development/CI environments.\n\n### Multiple Environments\n\nUse separate Octavus projects for staging and production, each with their own API keys. The `--env` flag lets you load different environment files:\n\n```bash\n# Local development (default: .env)\noctavus sync ./agents/my-agent\n\n# Staging project\noctavus --env .env.staging sync ./agents/my-agent\n\n# Production project\noctavus --env .env.production sync ./agents/my-agent\n```\n\nExample environment files:\n\n```bash\n# .env.staging (syncs to your staging project)\nOCTAVUS_CLI_API_KEY=oct_sk_staging_project_key...\n\n# .env.production (syncs to your production project)\nOCTAVUS_CLI_API_KEY=oct_sk_production_project_key...\n```\n\nEach project has its own agents, so you'll get different agent IDs per environment.\n\n## Global Options\n\n| Option | Description |\n| -------------- | ------------------------------------------------------- |\n| `--env <file>` | Load environment from a specific file (default: `.env`) |\n| `--help` | Show help |\n| `--version` | Show version |\n\n## Commands\n\n### `octavus sync <path>`\n\nSync an agent definition to the platform. Creates the agent if it doesn't exist, or updates it if it does.\n\n```bash\noctavus sync ./agents/my-agent\n```\n\n**Options:**\n\n- `--json` — Output as JSON (for CI/CD parsing)\n- `--quiet` — Suppress non-essential output\n\n**Example output:**\n\n```\nℹ Reading agent from ./agents/my-agent...\nℹ Syncing support-chat...\n✓ Created: support-chat\n Agent ID: clxyz123abc456\n```\n\n### `octavus validate <path>`\n\nValidate an agent definition without saving. Useful for CI/CD pipelines.\n\n```bash\noctavus validate ./agents/my-agent\n```\n\n**Exit codes:**\n\n- `0` — Validation passed\n- `1` — Validation errors\n- `2` — Configuration errors (missing API key, etc.)\n\n### `octavus list`\n\nList all agents in your project.\n\n```bash\noctavus list\n```\n\n**Example output:**\n\n```\nSLUG NAME FORMAT ID\n────────────────────────────────────────────────────────────────────────────\nsupport-chat Support Chat Agent interactive clxyz123abc456\n\n1 agent(s)\n```\n\n### `octavus get <slug>`\n\nGet details about a specific agent by its slug.\n\n```bash\noctavus get support-chat\n```\n\n## Agent Directory Structure\n\nThe CLI expects agent definitions in a specific directory structure:\n\n```\nmy-agent/\n├── settings.json # Required: Agent metadata\n├── protocol.yaml # Required: Agent protocol\n└── prompts/ # Optional: Prompt templates\n ├── system.md\n └── user-message.md\n```\n\n### settings.json\n\n```json\n{\n \"slug\": \"my-agent\",\n \"name\": \"My Agent\",\n \"description\": \"A helpful assistant\",\n \"format\": \"interactive\"\n}\n```\n\n### protocol.yaml\n\nSee the [Protocol documentation](/docs/protocol/overview) for details on protocol syntax.\n\n## CI/CD Integration\n\n### GitHub Actions\n\n```yaml\nname: Validate and Sync Agents\n\non:\n push:\n branches: [main]\n paths:\n - 'agents/**'\n\njobs:\n sync:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n\n - uses: actions/setup-node@v4\n with:\n node-version: '22'\n\n - run: npm install\n\n - name: Validate agent\n run: npx octavus validate ./agents/support-chat\n env:\n OCTAVUS_CLI_API_KEY: ${{ secrets.OCTAVUS_CLI_API_KEY }}\n\n - name: Sync agent\n run: npx octavus sync ./agents/support-chat\n env:\n OCTAVUS_CLI_API_KEY: ${{ secrets.OCTAVUS_CLI_API_KEY }}\n```\n\n### Package.json Scripts\n\nAdd sync scripts to your `package.json`:\n\n```json\n{\n \"scripts\": {\n \"agents:validate\": \"octavus validate ./agents/my-agent\",\n \"agents:sync\": \"octavus sync ./agents/my-agent\"\n },\n \"devDependencies\": {\n \"@octavus/cli\": \"^0.1.0\"\n }\n}\n```\n\n## Workflow\n\nThe recommended workflow for managing agents:\n\n1. **Define agent locally** — Create `settings.json`, `protocol.yaml`, and prompts\n2. **Validate** — Run `octavus validate ./my-agent` to check for errors\n3. **Sync** — Run `octavus sync ./my-agent` to push to platform\n4. **Store agent ID** — Save the output ID in an environment variable\n5. **Use in app** — Read the ID from env and pass to `client.agentSessions.create()`\n\n```bash\n# After syncing: octavus sync ./agents/support-chat\n# Output: Agent ID: clxyz123abc456\n\n# Add to your .env file\nOCTAVUS_SUPPORT_AGENT_ID=clxyz123abc456\n```\n\n```typescript\nconst agentId = process.env.OCTAVUS_SUPPORT_AGENT_ID;\n\nconst sessionId = await client.agentSessions.create(agentId, {\n COMPANY_NAME: 'Acme Corp',\n});\n```\n",
|
|
62
62
|
"excerpt": "Octavus CLI The package provides a command-line interface for validating and syncing agent definitions from your local filesystem to the Octavus platform. Current version: Installation ...",
|
|
63
63
|
"order": 5
|
|
64
64
|
},
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"section": "client-sdk",
|
|
77
77
|
"title": "Overview",
|
|
78
78
|
"description": "Introduction to the Octavus Client SDKs for building chat interfaces.",
|
|
79
|
-
"content": "\n# Client SDK Overview\n\nOctavus provides two packages for frontend integration:\n\n| Package | Purpose | Use When |\n| --------------------- | ------------------------ | ----------------------------------------------------- |\n| `@octavus/react` | React hooks and bindings | Building React applications |\n| `@octavus/client-sdk` | Framework-agnostic core | Using Vue, Svelte, vanilla JS, or custom integrations |\n\n**Most users should install `@octavus/react`** — it includes everything from `@octavus/client-sdk` plus React-specific hooks.\n\n## Installation\n\n### React Applications\n\n```bash\nnpm install @octavus/react\n```\n\n**Current version:** `2.3.0`\n\n### Other Frameworks\n\n```bash\nnpm install @octavus/client-sdk\n```\n\n**Current version:** `2.3.0`\n\n## Transport Pattern\n\nThe Client SDK uses a **transport abstraction** to handle communication with your backend. This gives you flexibility in how events are delivered:\n\n| Transport | Use Case | Docs |\n| ----------------------- | -------------------------------------------- | ----------------------------------------------------- |\n| `createHttpTransport` | HTTP/SSE (Next.js, Express, etc.) | [HTTP Transport](/docs/client-sdk/http-transport) |\n| `createSocketTransport` | WebSocket, SockJS, or other socket protocols | [Socket Transport](/docs/client-sdk/socket-transport) |\n\nWhen the transport changes (e.g., when `sessionId` changes), the `useOctavusChat` hook automatically reinitializes with the new transport.\n\n> **Recommendation**: Use HTTP transport unless you specifically need WebSocket features (custom real-time events, Meteor/Phoenix, etc.).\n\n## React Usage\n\nThe `useOctavusChat` hook provides state management and streaming for React applications:\n\n```tsx\nimport { useMemo } from 'react';\nimport { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';\n\nfunction Chat({ sessionId }: { sessionId: string }) {\n // Create a stable transport instance (memoized on sessionId)\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, send } = useOctavusChat({ transport });\n\n const sendMessage = async (text: string) => {\n await send('user-message', { USER_MESSAGE: text }, { userMessage: { content: text } });\n };\n\n return (\n <div>\n {messages.map((msg) => (\n <MessageBubble key={msg.id} message={msg} />\n ))}\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: UIMessage }) {\n return (\n <div>\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 </div>\n );\n}\n```\n\n## Framework-Agnostic Usage\n\nThe `OctavusChat` class can be used with any framework or vanilla JavaScript:\n\n```typescript\nimport { OctavusChat, createHttpTransport } from '@octavus/client-sdk';\n\nconst transport = 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\nconst chat = new OctavusChat({ transport });\n\n// Subscribe to state changes\nconst unsubscribe = chat.subscribe(() => {\n console.log('Messages:', chat.messages);\n console.log('Status:', chat.status);\n // Update your UI here\n});\n\n// Send a message\nawait chat.send('user-message', { USER_MESSAGE: 'Hello' }, { userMessage: { content: 'Hello' } });\n\n// Cleanup when done\nunsubscribe();\n```\n\n## Key Features\n\n### Unified Send Function\n\nThe `send` function handles both user message display and agent triggering in one call:\n\n```tsx\nconst { send } = useOctavusChat({ transport });\n\n// Add user message to UI and trigger agent\nawait send('user-message', { USER_MESSAGE: text }, { userMessage: { content: text } });\n\n// Trigger without adding a user message (e.g., button click)\nawait send('request-human');\n```\n\n### Message Parts\n\nMessages contain ordered `parts` for rich content:\n\n```tsx\nconst { messages } = useOctavusChat({ transport });\n\n// Each message has typed parts\nmessage.parts.map((part) => {\n switch (part.type) {\n case 'text': // Text content\n case 'reasoning': // Extended reasoning/thinking\n case 'tool-call': // Tool execution\n case 'operation': // Internal operations (set-resource, etc.)\n }\n});\n```\n\n### Status Tracking\n\n```tsx\nconst { status } = useOctavusChat({ transport });\n\n// status: 'idle' | 'streaming' | 'error' | 'awaiting-input'\n// 'awaiting-input' occurs when interactive client tools need user action\n```\n\n### Stop Streaming\n\n```tsx\nconst { stop } = useOctavusChat({ transport });\n\n// Stop current stream and finalize message\nstop();\n```\n\n## Hook Reference (React)\n\n### useOctavusChat\n\n```typescript\nfunction useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn;\n\ninterface OctavusChatOptions {\n // Required: Transport for streaming events\n transport: Transport;\n\n // Optional: Function to request upload URLs for file uploads\n requestUploadUrls?: (\n files: { filename: string; mediaType: string; size: number }[],\n ) => Promise<UploadUrlsResponse>;\n\n // Optional: Client-side tool handlers\n // - Function: executes automatically and returns result\n // - 'interactive': appears in pendingClientTools for user input\n clientTools?: Record<string, ClientToolHandler>;\n\n // Optional: Pre-populate with existing messages (session restore)\n initialMessages?: UIMessage[];\n\n // Optional: Callbacks\n onError?: (error: OctavusError) => void; // Structured error with type, source, retryable\n onFinish?: () => void;\n onStop?: () => void; // Called when user stops generation\n onResourceUpdate?: (name: string, value: unknown) => void;\n}\n\ninterface UseOctavusChatReturn {\n // State\n messages: UIMessage[];\n status: ChatStatus; // 'idle' | 'streaming' | 'error' | 'awaiting-input'\n error: OctavusError | null; // Structured error with type, source, retryable\n\n // Connection (socket transport only - undefined for HTTP)\n connectionState: ConnectionState | undefined; // 'disconnected' | 'connecting' | 'connected' | 'error'\n connectionError: Error | undefined;\n\n // Client tools (interactive tools awaiting user input)\n pendingClientTools: Record<string, InteractiveTool[]>; // Keyed by tool name\n\n // Actions\n send: (\n triggerName: string,\n input?: Record<string, unknown>,\n options?: { userMessage?: UserMessageInput },\n ) => Promise<void>;\n stop: () => void;\n\n // Connection management (socket transport only - undefined for HTTP)\n connect: (() => Promise<void>) | undefined;\n disconnect: (() => void) | undefined;\n\n // File uploads (requires requestUploadUrls)\n uploadFiles: (\n files: FileList | File[],\n onProgress?: (fileIndex: number, progress: number) => void,\n ) => Promise<FileReference[]>;\n}\n\ninterface UserMessageInput {\n content?: string;\n files?: FileList | File[] | FileReference[];\n}\n```\n\n## Transport Reference\n\n### createHttpTransport\n\nCreates an HTTP/SSE transport using native `fetch()`:\n\n```typescript\nimport { createHttpTransport } from '@octavus/react';\n\nconst transport = 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```\n\n### createSocketTransport\n\nCreates a WebSocket/SockJS transport for real-time connections:\n\n```typescript\nimport { createSocketTransport } from '@octavus/react';\n\nconst transport = createSocketTransport({\n connect: () =>\n new Promise((resolve, reject) => {\n const ws = new WebSocket(`wss://api.example.com/stream?sessionId=${sessionId}`);\n ws.onopen = () => resolve(ws);\n ws.onerror = () => reject(new Error('Connection failed'));\n }),\n});\n```\n\nSocket transport provides additional connection management:\n\n```typescript\n// Access connection state directly\ntransport.connectionState; // 'disconnected' | 'connecting' | 'connected' | 'error'\n\n// Subscribe to state changes\ntransport.onConnectionStateChange((state, error) => {\n /* ... */\n});\n\n// Eager connection (instead of lazy on first send)\nawait transport.connect();\n\n// Manual disconnect\ntransport.disconnect();\n```\n\nFor detailed WebSocket/SockJS usage including custom events, reconnection patterns, and server-side implementation, see [Socket Transport](/docs/client-sdk/socket-transport).\n\n## Class Reference (Framework-Agnostic)\n\n### OctavusChat\n\n```typescript\nclass OctavusChat {\n constructor(options: OctavusChatOptions);\n\n // State (read-only)\n readonly messages: UIMessage[];\n readonly status: ChatStatus; // 'idle' | 'streaming' | 'error' | 'awaiting-input'\n readonly error: OctavusError | null; // Structured error\n readonly pendingClientTools: Record<string, InteractiveTool[]>; // Interactive tools\n\n // Actions\n send(\n triggerName: string,\n input?: Record<string, unknown>,\n options?: { userMessage?: UserMessageInput },\n ): Promise<void>;\n stop(): void;\n\n // Subscription\n subscribe(callback: () => void): () => void; // Returns unsubscribe function\n}\n```\n\n## Next Steps\n\n- [HTTP Transport](/docs/client-sdk/http-transport) — HTTP/SSE integration (recommended)\n- [Socket Transport](/docs/client-sdk/socket-transport) — WebSocket and SockJS integration\n- [Messages](/docs/client-sdk/messages) — Working with message state\n- [Streaming](/docs/client-sdk/streaming) — Building streaming UIs\n- [Client Tools](/docs/client-sdk/client-tools) — Interactive browser-side tool handling\n- [Operations](/docs/client-sdk/execution-blocks) — Showing agent progress\n- [Error Handling](/docs/client-sdk/error-handling) — Handling errors with type guards\n- [File Uploads](/docs/client-sdk/file-uploads) — Uploading images and documents\n- [Examples](/docs/examples/overview) — Complete working examples\n",
|
|
79
|
+
"content": "\n# Client SDK Overview\n\nOctavus provides two packages for frontend integration:\n\n| Package | Purpose | Use When |\n| --------------------- | ------------------------ | ----------------------------------------------------- |\n| `@octavus/react` | React hooks and bindings | Building React applications |\n| `@octavus/client-sdk` | Framework-agnostic core | Using Vue, Svelte, vanilla JS, or custom integrations |\n\n**Most users should install `@octavus/react`** — it includes everything from `@octavus/client-sdk` plus React-specific hooks.\n\n## Installation\n\n### React Applications\n\n```bash\nnpm install @octavus/react\n```\n\n**Current version:** `2.4.0`\n\n### Other Frameworks\n\n```bash\nnpm install @octavus/client-sdk\n```\n\n**Current version:** `2.4.0`\n\n## Transport Pattern\n\nThe Client SDK uses a **transport abstraction** to handle communication with your backend. This gives you flexibility in how events are delivered:\n\n| Transport | Use Case | Docs |\n| ----------------------- | -------------------------------------------- | ----------------------------------------------------- |\n| `createHttpTransport` | HTTP/SSE (Next.js, Express, etc.) | [HTTP Transport](/docs/client-sdk/http-transport) |\n| `createSocketTransport` | WebSocket, SockJS, or other socket protocols | [Socket Transport](/docs/client-sdk/socket-transport) |\n\nWhen the transport changes (e.g., when `sessionId` changes), the `useOctavusChat` hook automatically reinitializes with the new transport.\n\n> **Recommendation**: Use HTTP transport unless you specifically need WebSocket features (custom real-time events, Meteor/Phoenix, etc.).\n\n## React Usage\n\nThe `useOctavusChat` hook provides state management and streaming for React applications:\n\n```tsx\nimport { useMemo } from 'react';\nimport { useOctavusChat, createHttpTransport, type UIMessage } from '@octavus/react';\n\nfunction Chat({ sessionId }: { sessionId: string }) {\n // Create a stable transport instance (memoized on sessionId)\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, send } = useOctavusChat({ transport });\n\n const sendMessage = async (text: string) => {\n await send('user-message', { USER_MESSAGE: text }, { userMessage: { content: text } });\n };\n\n return (\n <div>\n {messages.map((msg) => (\n <MessageBubble key={msg.id} message={msg} />\n ))}\n </div>\n );\n}\n\nfunction MessageBubble({ message }: { message: UIMessage }) {\n return (\n <div>\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 </div>\n );\n}\n```\n\n## Framework-Agnostic Usage\n\nThe `OctavusChat` class can be used with any framework or vanilla JavaScript:\n\n```typescript\nimport { OctavusChat, createHttpTransport } from '@octavus/client-sdk';\n\nconst transport = 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\nconst chat = new OctavusChat({ transport });\n\n// Subscribe to state changes\nconst unsubscribe = chat.subscribe(() => {\n console.log('Messages:', chat.messages);\n console.log('Status:', chat.status);\n // Update your UI here\n});\n\n// Send a message\nawait chat.send('user-message', { USER_MESSAGE: 'Hello' }, { userMessage: { content: 'Hello' } });\n\n// Cleanup when done\nunsubscribe();\n```\n\n## Key Features\n\n### Unified Send Function\n\nThe `send` function handles both user message display and agent triggering in one call:\n\n```tsx\nconst { send } = useOctavusChat({ transport });\n\n// Add user message to UI and trigger agent\nawait send('user-message', { USER_MESSAGE: text }, { userMessage: { content: text } });\n\n// Trigger without adding a user message (e.g., button click)\nawait send('request-human');\n```\n\n### Message Parts\n\nMessages contain ordered `parts` for rich content:\n\n```tsx\nconst { messages } = useOctavusChat({ transport });\n\n// Each message has typed parts\nmessage.parts.map((part) => {\n switch (part.type) {\n case 'text': // Text content\n case 'reasoning': // Extended reasoning/thinking\n case 'tool-call': // Tool execution\n case 'operation': // Internal operations (set-resource, etc.)\n }\n});\n```\n\n### Status Tracking\n\n```tsx\nconst { status } = useOctavusChat({ transport });\n\n// status: 'idle' | 'streaming' | 'error' | 'awaiting-input'\n// 'awaiting-input' occurs when interactive client tools need user action\n```\n\n### Stop Streaming\n\n```tsx\nconst { stop } = useOctavusChat({ transport });\n\n// Stop current stream and finalize message\nstop();\n```\n\n## Hook Reference (React)\n\n### useOctavusChat\n\n```typescript\nfunction useOctavusChat(options: OctavusChatOptions): UseOctavusChatReturn;\n\ninterface OctavusChatOptions {\n // Required: Transport for streaming events\n transport: Transport;\n\n // Optional: Function to request upload URLs for file uploads\n requestUploadUrls?: (\n files: { filename: string; mediaType: string; size: number }[],\n ) => Promise<UploadUrlsResponse>;\n\n // Optional: Client-side tool handlers\n // - Function: executes automatically and returns result\n // - 'interactive': appears in pendingClientTools for user input\n clientTools?: Record<string, ClientToolHandler>;\n\n // Optional: Pre-populate with existing messages (session restore)\n initialMessages?: UIMessage[];\n\n // Optional: Callbacks\n onError?: (error: OctavusError) => void; // Structured error with type, source, retryable\n onFinish?: () => void;\n onStop?: () => void; // Called when user stops generation\n onResourceUpdate?: (name: string, value: unknown) => void;\n}\n\ninterface UseOctavusChatReturn {\n // State\n messages: UIMessage[];\n status: ChatStatus; // 'idle' | 'streaming' | 'error' | 'awaiting-input'\n error: OctavusError | null; // Structured error with type, source, retryable\n\n // Connection (socket transport only - undefined for HTTP)\n connectionState: ConnectionState | undefined; // 'disconnected' | 'connecting' | 'connected' | 'error'\n connectionError: Error | undefined;\n\n // Client tools (interactive tools awaiting user input)\n pendingClientTools: Record<string, InteractiveTool[]>; // Keyed by tool name\n\n // Actions\n send: (\n triggerName: string,\n input?: Record<string, unknown>,\n options?: { userMessage?: UserMessageInput },\n ) => Promise<void>;\n stop: () => void;\n\n // Connection management (socket transport only - undefined for HTTP)\n connect: (() => Promise<void>) | undefined;\n disconnect: (() => void) | undefined;\n\n // File uploads (requires requestUploadUrls)\n uploadFiles: (\n files: FileList | File[],\n onProgress?: (fileIndex: number, progress: number) => void,\n ) => Promise<FileReference[]>;\n}\n\ninterface UserMessageInput {\n content?: string;\n files?: FileList | File[] | FileReference[];\n}\n```\n\n## Transport Reference\n\n### createHttpTransport\n\nCreates an HTTP/SSE transport using native `fetch()`:\n\n```typescript\nimport { createHttpTransport } from '@octavus/react';\n\nconst transport = 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```\n\n### createSocketTransport\n\nCreates a WebSocket/SockJS transport for real-time connections:\n\n```typescript\nimport { createSocketTransport } from '@octavus/react';\n\nconst transport = createSocketTransport({\n connect: () =>\n new Promise((resolve, reject) => {\n const ws = new WebSocket(`wss://api.example.com/stream?sessionId=${sessionId}`);\n ws.onopen = () => resolve(ws);\n ws.onerror = () => reject(new Error('Connection failed'));\n }),\n});\n```\n\nSocket transport provides additional connection management:\n\n```typescript\n// Access connection state directly\ntransport.connectionState; // 'disconnected' | 'connecting' | 'connected' | 'error'\n\n// Subscribe to state changes\ntransport.onConnectionStateChange((state, error) => {\n /* ... */\n});\n\n// Eager connection (instead of lazy on first send)\nawait transport.connect();\n\n// Manual disconnect\ntransport.disconnect();\n```\n\nFor detailed WebSocket/SockJS usage including custom events, reconnection patterns, and server-side implementation, see [Socket Transport](/docs/client-sdk/socket-transport).\n\n## Class Reference (Framework-Agnostic)\n\n### OctavusChat\n\n```typescript\nclass OctavusChat {\n constructor(options: OctavusChatOptions);\n\n // State (read-only)\n readonly messages: UIMessage[];\n readonly status: ChatStatus; // 'idle' | 'streaming' | 'error' | 'awaiting-input'\n readonly error: OctavusError | null; // Structured error\n readonly pendingClientTools: Record<string, InteractiveTool[]>; // Interactive tools\n\n // Actions\n send(\n triggerName: string,\n input?: Record<string, unknown>,\n options?: { userMessage?: UserMessageInput },\n ): Promise<void>;\n stop(): void;\n\n // Subscription\n subscribe(callback: () => void): () => void; // Returns unsubscribe function\n}\n```\n\n## Next Steps\n\n- [HTTP Transport](/docs/client-sdk/http-transport) — HTTP/SSE integration (recommended)\n- [Socket Transport](/docs/client-sdk/socket-transport) — WebSocket and SockJS integration\n- [Messages](/docs/client-sdk/messages) — Working with message state\n- [Streaming](/docs/client-sdk/streaming) — Building streaming UIs\n- [Client Tools](/docs/client-sdk/client-tools) — Interactive browser-side tool handling\n- [Operations](/docs/client-sdk/execution-blocks) — Showing agent progress\n- [Error Handling](/docs/client-sdk/error-handling) — Handling errors with type guards\n- [File Uploads](/docs/client-sdk/file-uploads) — Uploading images and documents\n- [Examples](/docs/examples/overview) — Complete working examples\n",
|
|
80
80
|
"excerpt": "Client SDK Overview Octavus provides two packages for frontend integration: | Package | Purpose | Use When | |...",
|
|
81
81
|
"order": 1
|
|
82
82
|
},
|
|
@@ -220,7 +220,7 @@
|
|
|
220
220
|
"section": "protocol",
|
|
221
221
|
"title": "Agent Config",
|
|
222
222
|
"description": "Configuring the agent model and behavior.",
|
|
223
|
-
"content": "\n# Agent Config\n\nThe `agent` section configures the LLM model, system prompt, tools, and behavior.\n\n## Basic Configuration\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system # References prompts/system.md\n tools: [get-user-account] # Available tools\n skills: [qr-code] # Available skills\n```\n\n## Configuration Options\n\n| Field | Required | Description |\n| ------------- | -------- | --------------------------------------------------------- |\n| `model` | Yes | Model identifier or variable reference |\n| `system` | Yes | System prompt filename (without .md) |\n| `input` | No | Variables to interpolate in system prompt |\n| `tools` | No | List of tools the LLM can call |\n| `skills` | No | List of Octavus skills the LLM can use |\n| `imageModel` | No | Image generation model (enables agentic image generation) |\n| `agentic` | No | Allow multiple tool call cycles |\n| `maxSteps` | No | Maximum agentic steps (default: 10) |\n| `temperature` | No | Model temperature (0-2) |\n| `thinking` | No | Extended reasoning level |\n| `anthropic` | No | Anthropic-specific options (tools, skills) |\n\n## Models\n\nSpecify models in `provider/model-id` format. Any model supported by the provider's SDK will work.\n\n### Supported Providers\n\n| Provider | Format | Examples |\n| --------- | ---------------------- | ------------------------------------------------------------ |\n| Anthropic | `anthropic/{model-id}` | `claude-opus-4-5`, `claude-sonnet-4-5`, `claude-haiku-4-5` |\n| Google | `google/{model-id}` | `gemini-3-pro-preview`, `gemini-3-flash`, `gemini-2.5-flash` |\n| OpenAI | `openai/{model-id}` | `gpt-5`, `gpt-4o`, `o4-mini`, `o3`, `o3-mini`, `o1` |\n\n### Examples\n\n```yaml\n# Anthropic Claude 4.5\nagent:\n model: anthropic/claude-sonnet-4-5\n\n# Google Gemini 3\nagent:\n model: google/gemini-3-flash\n\n# OpenAI GPT-5\nagent:\n model: openai/gpt-5\n\n# OpenAI reasoning models\nagent:\n model: openai/o3-mini\n```\n\n> **Note**: Model IDs are passed directly to the provider SDK. Check the provider's documentation for the latest available models.\n\n### Dynamic Model Selection\n\nThe model field can also reference an input variable, allowing consumers to choose the model when creating a session:\n\n```yaml\ninput:\n MODEL:\n type: string\n description: The LLM model to use\n\nagent:\n model: MODEL # Resolved from session input\n system: system\n```\n\nWhen creating a session, pass the model:\n\n```typescript\nconst sessionId = await client.agentSessions.create('my-agent', {\n MODEL: 'anthropic/claude-sonnet-4-5',\n});\n```\n\nThis enables:\n\n- **Multi-provider support** — Same agent works with different providers\n- **A/B testing** — Test different models without protocol changes\n- **User preferences** — Let users choose their preferred model\n\nThe model value is validated at runtime to ensure it's in the correct `provider/model-id` format.\n\n> **Note**: When using dynamic models, provider-specific options (like `anthropic:`) may not apply if the model resolves to a different provider.\n\n## System Prompt\n\nThe system prompt sets the agent's persona and instructions:\n\n```yaml\nagent:\n system: system # Uses prompts/system.md\n input:\n - COMPANY_NAME\n - PRODUCT_NAME\n```\n\nExample `prompts/system.md`:\n\n```markdown\nYou are a friendly support agent for {{COMPANY_NAME}}.\n\n## Your Role\n\nHelp users with questions about {{PRODUCT_NAME}}.\n\n## Guidelines\n\n- Be helpful and professional\n- If you can't help, offer to escalate\n- Never share internal information\n```\n\n## Agentic Mode\n\nEnable multi-step tool calling:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n tools: [get-user-account, search-docs, create-ticket]\n agentic: true # LLM can call multiple tools\n maxSteps: 10 # Limit cycles to prevent runaway\n```\n\n**How it works:**\n\n1. LLM receives user message\n2. LLM decides to call a tool\n3. Tool executes, result returned to LLM\n4. LLM decides if more tools needed\n5. Repeat until LLM responds or maxSteps reached\n\n## Extended Thinking\n\nEnable extended reasoning for complex tasks:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n thinking: medium # low | medium | high\n```\n\n| Level | Token Budget | Use Case |\n| -------- | ------------ | ------------------- |\n| `low` | ~5,000 | Simple reasoning |\n| `medium` | ~10,000 | Moderate complexity |\n| `high` | ~20,000 | Complex analysis |\n\nThinking content streams to the UI and can be displayed to users.\n\n## Skills\n\nEnable Octavus skills for code execution and file generation:\n\n```yaml\nskills:\n qr-code:\n display: description\n description: Generating QR codes\n\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n skills: [qr-code] # Enable skills\n agentic: true\n```\n\nSkills provide provider-agnostic code execution in isolated sandboxes. When enabled, the LLM can execute Python/Bash code, run skill scripts, and generate files.\n\nSee [Skills](/docs/protocol/skills) for full documentation.\n\n## Image Generation\n\nEnable the LLM to generate images autonomously:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n imageModel: google/gemini-2.5-flash-image\n agentic: true\n```\n\nWhen `imageModel` is configured, the `octavus_generate_image` tool becomes available. The LLM can decide when to generate images based on user requests.\n\n### Supported Image Providers\n\n| Provider | Model Types | Examples |\n| -------- | --------------------------------------- | --------------------------------------------------------- |\n| OpenAI | Dedicated image models | `gpt-image-1` |\n| Google | Gemini native (contains \"image\") | `gemini-2.5-flash-image`, `gemini-3-flash-image-generate` |\n| Google | Imagen dedicated (starts with \"imagen\") | `imagen-4.0-generate-001` |\n\n> **Note**: Google has two image generation approaches. Gemini \"native\" models (containing \"image\" in the ID) generate images using the language model API with `responseModalities`. Imagen models (starting with \"imagen\") use a dedicated image generation API.\n\n### Image Sizes\n\nThe tool supports three image sizes:\n\n- `1024x1024` (default) — Square\n- `1792x1024` — Landscape (16:9)\n- `1024x1792` — Portrait (9:16)\n\n### Agentic vs Deterministic\n\nUse `imageModel` in agent config when:\n\n- The LLM should decide when to generate images\n- Users ask for images in natural language\n\nUse `generate-image` block (see [Handlers](/docs/protocol/handlers#generate-image)) when:\n\n- You want explicit control over image generation\n- Building prompt engineering pipelines\n- Images are generated at specific handler steps\n\n## Temperature\n\nControl response randomness:\n\n```yaml\nagent:\n model: openai/gpt-4o\n temperature: 0.7 # 0 = deterministic, 2 = creative\n```\n\n**Guidelines:**\n\n- `0 - 0.3`: Factual, consistent responses\n- `0.4 - 0.7`: Balanced (good default)\n- `0.8 - 1.2`: Creative, varied responses\n- `> 1.2`: Very creative (may be inconsistent)\n\n## Provider Options\n\nEnable provider-specific features like Anthropic's built-in tools and skills:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n anthropic:\n tools:\n web-search:\n display: description\n description: Searching the web\n skills:\n pdf:\n type: anthropic\n description: Processing PDF\n```\n\nProvider options are validated against the model—using `anthropic:` with a non-Anthropic model will fail validation.\n\nSee [Provider Options](/docs/protocol/provider-options) for full documentation.\n\n## Thread-Specific Config\n\nOverride config for named threads:\n\n```yaml\nhandlers:\n request-human:\n Start summary thread:\n block: start-thread\n thread: summary\n model: anthropic/claude-sonnet-4-5 # Different model\n thinking: low # Different thinking\n maxSteps: 1 # Limit tool calls\n system: escalation-summary # Different prompt\n```\n\n## Full Example\n\n```yaml\ninput:\n COMPANY_NAME: { type: string }\n PRODUCT_NAME: { type: string }\n USER_ID: { type: string, optional: true }\n\nresources:\n CONVERSATION_SUMMARY:\n type: string\n default: ''\n\ntools:\n get-user-account:\n description: Look up user account\n parameters:\n userId: { type: string }\n\n search-docs:\n description: Search help documentation\n parameters:\n query: { type: string }\n\n create-support-ticket:\n description: Create a support ticket\n parameters:\n summary: { type: string }\n priority: { type: string } # low, medium, high\n\nskills:\n qr-code:\n display: description\n description: Generating QR codes\n\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n input:\n - COMPANY_NAME\n - PRODUCT_NAME\n tools:\n - get-user-account\n - search-docs\n - create-support-ticket\n skills: [qr-code] # Octavus skills\n agentic: true\n maxSteps: 10\n thinking: medium\n # Anthropic-specific options\n anthropic:\n tools:\n web-search:\n display: description\n description: Searching the web\n skills:\n pdf:\n type: anthropic\n description: Processing PDF\n\ntriggers:\n user-message:\n input:\n USER_MESSAGE: { type: string }\n\nhandlers:\n user-message:\n Add message:\n block: add-message\n role: user\n prompt: user-message\n input: [USER_MESSAGE]\n display: hidden\n\n Respond:\n block: next-message\n```\n",
|
|
223
|
+
"content": "\n# Agent Config\n\nThe `agent` section configures the LLM model, system prompt, tools, and behavior.\n\n## Basic Configuration\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system # References prompts/system.md\n tools: [get-user-account] # Available tools\n skills: [qr-code] # Available skills\n```\n\n## Configuration Options\n\n| Field | Required | Description |\n| ------------- | -------- | --------------------------------------------------------- |\n| `model` | Yes | Model identifier or variable reference |\n| `system` | Yes | System prompt filename (without .md) |\n| `input` | No | Variables to interpolate in system prompt |\n| `tools` | No | List of tools the LLM can call |\n| `skills` | No | List of Octavus skills the LLM can use |\n| `imageModel` | No | Image generation model (enables agentic image generation) |\n| `agentic` | No | Allow multiple tool call cycles |\n| `maxSteps` | No | Maximum agentic steps (default: 10) |\n| `temperature` | No | Model temperature (0-2) |\n| `thinking` | No | Extended reasoning level |\n| `anthropic` | No | Anthropic-specific options (tools, skills) |\n\n## Models\n\nSpecify models in `provider/model-id` format. Any model supported by the provider's SDK will work.\n\n### Supported Providers\n\n| Provider | Format | Examples |\n| --------- | ---------------------- | -------------------------------------------------------------------- |\n| Anthropic | `anthropic/{model-id}` | `claude-opus-4-5`, `claude-sonnet-4-5`, `claude-haiku-4-5` |\n| Google | `google/{model-id}` | `gemini-3-pro-preview`, `gemini-3-flash-preview`, `gemini-2.5-flash` |\n| OpenAI | `openai/{model-id}` | `gpt-5`, `gpt-4o`, `o4-mini`, `o3`, `o3-mini`, `o1` |\n\n### Examples\n\n```yaml\n# Anthropic Claude 4.5\nagent:\n model: anthropic/claude-sonnet-4-5\n\n# Google Gemini 3\nagent:\n model: google/gemini-3-flash-preview\n\n# OpenAI GPT-5\nagent:\n model: openai/gpt-5\n\n# OpenAI reasoning models\nagent:\n model: openai/o3-mini\n```\n\n> **Note**: Model IDs are passed directly to the provider SDK. Check the provider's documentation for the latest available models.\n\n### Dynamic Model Selection\n\nThe model field can also reference an input variable, allowing consumers to choose the model when creating a session:\n\n```yaml\ninput:\n MODEL:\n type: string\n description: The LLM model to use\n\nagent:\n model: MODEL # Resolved from session input\n system: system\n```\n\nWhen creating a session, pass the model:\n\n```typescript\nconst sessionId = await client.agentSessions.create('my-agent', {\n MODEL: 'anthropic/claude-sonnet-4-5',\n});\n```\n\nThis enables:\n\n- **Multi-provider support** — Same agent works with different providers\n- **A/B testing** — Test different models without protocol changes\n- **User preferences** — Let users choose their preferred model\n\nThe model value is validated at runtime to ensure it's in the correct `provider/model-id` format.\n\n> **Note**: When using dynamic models, provider-specific options (like `anthropic:`) may not apply if the model resolves to a different provider.\n\n## System Prompt\n\nThe system prompt sets the agent's persona and instructions:\n\n```yaml\nagent:\n system: system # Uses prompts/system.md\n input:\n - COMPANY_NAME\n - PRODUCT_NAME\n```\n\nExample `prompts/system.md`:\n\n```markdown\nYou are a friendly support agent for {{COMPANY_NAME}}.\n\n## Your Role\n\nHelp users with questions about {{PRODUCT_NAME}}.\n\n## Guidelines\n\n- Be helpful and professional\n- If you can't help, offer to escalate\n- Never share internal information\n```\n\n## Agentic Mode\n\nEnable multi-step tool calling:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n tools: [get-user-account, search-docs, create-ticket]\n agentic: true # LLM can call multiple tools\n maxSteps: 10 # Limit cycles to prevent runaway\n```\n\n**How it works:**\n\n1. LLM receives user message\n2. LLM decides to call a tool\n3. Tool executes, result returned to LLM\n4. LLM decides if more tools needed\n5. Repeat until LLM responds or maxSteps reached\n\n## Extended Thinking\n\nEnable extended reasoning for complex tasks:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n thinking: medium # low | medium | high\n```\n\n| Level | Token Budget | Use Case |\n| -------- | ------------ | ------------------- |\n| `low` | ~5,000 | Simple reasoning |\n| `medium` | ~10,000 | Moderate complexity |\n| `high` | ~20,000 | Complex analysis |\n\nThinking content streams to the UI and can be displayed to users.\n\n## Skills\n\nEnable Octavus skills for code execution and file generation:\n\n```yaml\nskills:\n qr-code:\n display: description\n description: Generating QR codes\n\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n skills: [qr-code] # Enable skills\n agentic: true\n```\n\nSkills provide provider-agnostic code execution in isolated sandboxes. When enabled, the LLM can execute Python/Bash code, run skill scripts, and generate files.\n\nSee [Skills](/docs/protocol/skills) for full documentation.\n\n## Image Generation\n\nEnable the LLM to generate images autonomously:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n imageModel: google/gemini-2.5-flash-image\n agentic: true\n```\n\nWhen `imageModel` is configured, the `octavus_generate_image` tool becomes available. The LLM can decide when to generate images based on user requests.\n\n### Supported Image Providers\n\n| Provider | Model Types | Examples |\n| -------- | --------------------------------------- | --------------------------------------------------------- |\n| OpenAI | Dedicated image models | `gpt-image-1` |\n| Google | Gemini native (contains \"image\") | `gemini-2.5-flash-image`, `gemini-3-flash-image-generate` |\n| Google | Imagen dedicated (starts with \"imagen\") | `imagen-4.0-generate-001` |\n\n> **Note**: Google has two image generation approaches. Gemini \"native\" models (containing \"image\" in the ID) generate images using the language model API with `responseModalities`. Imagen models (starting with \"imagen\") use a dedicated image generation API.\n\n### Image Sizes\n\nThe tool supports three image sizes:\n\n- `1024x1024` (default) — Square\n- `1792x1024` — Landscape (16:9)\n- `1024x1792` — Portrait (9:16)\n\n### Agentic vs Deterministic\n\nUse `imageModel` in agent config when:\n\n- The LLM should decide when to generate images\n- Users ask for images in natural language\n\nUse `generate-image` block (see [Handlers](/docs/protocol/handlers#generate-image)) when:\n\n- You want explicit control over image generation\n- Building prompt engineering pipelines\n- Images are generated at specific handler steps\n\n## Temperature\n\nControl response randomness:\n\n```yaml\nagent:\n model: openai/gpt-4o\n temperature: 0.7 # 0 = deterministic, 2 = creative\n```\n\n**Guidelines:**\n\n- `0 - 0.3`: Factual, consistent responses\n- `0.4 - 0.7`: Balanced (good default)\n- `0.8 - 1.2`: Creative, varied responses\n- `> 1.2`: Very creative (may be inconsistent)\n\n## Provider Options\n\nEnable provider-specific features like Anthropic's built-in tools and skills:\n\n```yaml\nagent:\n model: anthropic/claude-sonnet-4-5\n anthropic:\n tools:\n web-search:\n display: description\n description: Searching the web\n skills:\n pdf:\n type: anthropic\n description: Processing PDF\n```\n\nProvider options are validated against the model—using `anthropic:` with a non-Anthropic model will fail validation.\n\nSee [Provider Options](/docs/protocol/provider-options) for full documentation.\n\n## Thread-Specific Config\n\nOverride config for named threads:\n\n```yaml\nhandlers:\n request-human:\n Start summary thread:\n block: start-thread\n thread: summary\n model: anthropic/claude-sonnet-4-5 # Different model\n thinking: low # Different thinking\n maxSteps: 1 # Limit tool calls\n system: escalation-summary # Different prompt\n```\n\n## Full Example\n\n```yaml\ninput:\n COMPANY_NAME: { type: string }\n PRODUCT_NAME: { type: string }\n USER_ID: { type: string, optional: true }\n\nresources:\n CONVERSATION_SUMMARY:\n type: string\n default: ''\n\ntools:\n get-user-account:\n description: Look up user account\n parameters:\n userId: { type: string }\n\n search-docs:\n description: Search help documentation\n parameters:\n query: { type: string }\n\n create-support-ticket:\n description: Create a support ticket\n parameters:\n summary: { type: string }\n priority: { type: string } # low, medium, high\n\nskills:\n qr-code:\n display: description\n description: Generating QR codes\n\nagent:\n model: anthropic/claude-sonnet-4-5\n system: system\n input:\n - COMPANY_NAME\n - PRODUCT_NAME\n tools:\n - get-user-account\n - search-docs\n - create-support-ticket\n skills: [qr-code] # Octavus skills\n agentic: true\n maxSteps: 10\n thinking: medium\n # Anthropic-specific options\n anthropic:\n tools:\n web-search:\n display: description\n description: Searching the web\n skills:\n pdf:\n type: anthropic\n description: Processing PDF\n\ntriggers:\n user-message:\n input:\n USER_MESSAGE: { type: string }\n\nhandlers:\n user-message:\n Add message:\n block: add-message\n role: user\n prompt: user-message\n input: [USER_MESSAGE]\n display: hidden\n\n Respond:\n block: next-message\n```\n",
|
|
224
224
|
"excerpt": "Agent Config The section configures the LLM model, system prompt, tools, and behavior. Basic Configuration Configuration Options | Field | Required | Description ...",
|
|
225
225
|
"order": 7
|
|
226
226
|
},
|
|
@@ -319,7 +319,7 @@
|
|
|
319
319
|
"section": "migration",
|
|
320
320
|
"title": "Migrating from v1 to v2",
|
|
321
321
|
"description": "Complete guide for upgrading from Octavus SDK v1.x to v2.0.",
|
|
322
|
-
"content": "\n# Migrating from v1 to v2\n\nThis guide covers all breaking changes and new features in Octavus SDK v2.0.0.\n\n## Overview\n\nVersion 2.0.0 introduces **client-side tool execution**, allowing tools to run in the browser with support for both automatic execution and interactive user input. This required changes to the transport layer and streaming protocol.\n\n## Breaking Changes\n\n### HTTP Transport Configuration\n\nThe `triggerRequest` option has been renamed to `request` and the function signature changed to support both trigger and continuation requests.\n\n**Before (v1):**\n\n```typescript\nimport { createHttpTransport } from '@octavus/client-sdk';\n\nconst transport = createHttpTransport({\n triggerRequest: (triggerName, input, options) =>\n fetch('/api/trigger', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, triggerName, input }),\n signal: options?.signal,\n }),\n});\n```\n\n**After (v2):**\n\n```typescript\nimport { createHttpTransport } from '@octavus/client-sdk';\n\nconst transport = 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```\n\nThe `payload` parameter is a discriminated union with `type: 'trigger' | 'continue'`:\n\n- **Trigger request:** `{ type: 'trigger', triggerName: string, input?: Record<string, unknown> }`\n- **Continue request:** `{ type: 'continue', executionId: string, toolResults: ToolResult[] }`\n\n### Server SDK Route Handler\n\nServer-side route handlers should use the new `execute()` method which handles both triggers and continuations via the request type.\n\n**Before (v1):**\n\n```typescript\n// app/api/trigger/route.ts\nimport { AgentSession, toSSEStream } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const { sessionId, triggerName, input } = await request.json();\n\n const session = new AgentSession({\n sessionId,\n agentId: 'your-agent-id',\n apiKey: process.env.OCTAVUS_API_KEY!,\n });\n\n const events = session.trigger(triggerName, input, { signal: request.signal });\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\n**After (v2):**\n\n```typescript\n// app/api/trigger/route.ts\nimport { AgentSession, toSSEStream, type SessionRequest } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const body = (await request.json()) as { sessionId: string } & SessionRequest;\n const { sessionId, ...sessionRequest } = body;\n\n const session = new AgentSession({\n sessionId,\n agentId: 'your-agent-id',\n apiKey: process.env.OCTAVUS_API_KEY!,\n });\n\n const events = session.execute(sessionRequest, { signal: request.signal });\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\nThe `SessionRequest` type is a discriminated union:\n\n- **Trigger:** `{ type: 'trigger', triggerName: string, input?: Record<string, unknown> }`\n- **Continue:** `{ type: 'continue', executionId: string, toolResults: ToolResult[] }`\n\n### Export Changes\n\nThe SDKs no longer use star exports (`export * from '@octavus/core'`). Instead, they use explicit type exports and value exports. This improves tree-shaking but may require import adjustments.\n\n**If you were importing schemas:**\n\nSome Zod schemas are no longer re-exported from `@octavus/server-sdk`. If you need validation schemas, import them directly from `@octavus/core`:\n\n```typescript\n// Before (v1) - some schemas were re-exported\nimport { fileUploadRequestSchema } from '@octavus/server-sdk';\n\n// After (v2) - import from core if needed\nimport { fileReferenceSchema } from '@octavus/core';\n```\n\n**Type imports remain the same:**\n\n```typescript\n// Types are still available\nimport type { StreamEvent, UIMessage, FileReference } from '@octavus/client-sdk';\n```\n\n### Custom Transport Interface\n\nCustom transport implementations must now implement the `continueWithToolResults()` method:\n\n```typescript\ninterface Transport {\n trigger(triggerName: string, input?: Record<string, unknown>): AsyncIterable<StreamEvent>;\n continueWithToolResults(executionId: string, results: ToolResult[]): AsyncIterable<StreamEvent>;\n stop(): void;\n}\n```\n\n### New ChatStatus Value\n\nThe `ChatStatus` type now includes `'awaiting-input'`:\n\n```typescript\n// v1\ntype ChatStatus = 'idle' | 'streaming' | 'error';\n\n// v2\ntype ChatStatus = 'idle' | 'streaming' | 'error' | 'awaiting-input';\n```\n\nUpdate any status checks that assume only three values.\n\n### Stream Event Changes\n\nTwo stream events have been modified:\n\n**StartEvent and FinishEvent now include executionId:**\n\n```typescript\ninterface StartEvent {\n type: 'start';\n messageId?: string;\n executionId?: string; // New in v2\n}\n\ninterface FinishEvent {\n type: 'finish';\n finishReason: FinishReason;\n executionId?: string; // New in v2\n}\n```\n\n**New FinishReason:**\n\n```typescript\n// Added 'client-tool-calls' to FinishReason\ntype FinishReason =\n | 'stop'\n | 'tool-calls'\n | 'client-tool-calls' // New in v2\n | 'length'\n | 'content-filter'\n | 'error'\n | 'other';\n```\n\n**New ClientToolRequestEvent:**\n\n```typescript\ninterface ClientToolRequestEvent {\n type: 'client-tool-request';\n executionId: string;\n toolCalls: PendingToolCall[];\n serverToolResults?: ToolResult[];\n}\n```\n\n## New Features\n\n### Client-Side Tools\n\nv2 introduces client-side tool execution, allowing tools to run in the browser. This is useful for:\n\n- Accessing browser APIs (geolocation, clipboard, etc.)\n- Interactive tools requiring user input (confirmations, forms, selections)\n- Tools that need access to client-side state\n\nSee the [Client Tools guide](/docs/client-sdk/client-tools) for full documentation.\n\n#### Automatic Client Tools\n\nTools that execute automatically without user interaction:\n\n```typescript\nimport { useOctavusChat, createHttpTransport } from '@octavus/react';\n\nfunction Chat() {\n const { messages, send, status } = useOctavusChat({\n transport: 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 clientTools: {\n 'get-browser-location': async (args, ctx) => {\n const pos = await new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject);\n });\n return { lat: pos.coords.latitude, lng: pos.coords.longitude };\n },\n 'get-clipboard': async () => {\n return await navigator.clipboard.readText();\n },\n },\n });\n\n // ... rest of component\n}\n```\n\n#### Interactive Client Tools\n\nTools that require user interaction before completing:\n\n```typescript\nimport { useOctavusChat, createHttpTransport } from '@octavus/react';\n\nfunction Chat() {\n const { messages, send, status, pendingClientTools } = useOctavusChat({\n transport: 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 clientTools: {\n 'request-confirmation': 'interactive',\n 'select-option': 'interactive',\n },\n });\n\n // Render UI for pending interactive tools\n const confirmationTools = pendingClientTools['request-confirmation'] ?? [];\n\n return (\n <div>\n {/* Chat messages */}\n\n {/* Interactive tool UI */}\n {confirmationTools.map((tool) => (\n <ConfirmationModal\n key={tool.toolCallId}\n message={tool.args.message as string}\n onConfirm={() => tool.submit({ confirmed: true })}\n onCancel={() => tool.cancel('User declined')}\n />\n ))}\n </div>\n );\n}\n```\n\n### New Types for Client Tools\n\n```typescript\n// Context provided to automatic tool handlers\ninterface ClientToolContext {\n toolCallId: string;\n toolName: string;\n signal: AbortSignal;\n}\n\n// Handler types\ntype ClientToolHandler =\n | ((args: Record<string, unknown>, ctx: ClientToolContext) => Promise<unknown>)\n | 'interactive';\n\n// Interactive tool with bound submit/cancel methods\ninterface InteractiveTool {\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n submit: (result: unknown) => void;\n cancel: (reason?: string) => void;\n}\n```\n\n### pendingClientTools Property\n\nBoth `OctavusChat` and `useOctavusChat` now expose `pendingClientTools`:\n\n```typescript\n// Record keyed by tool name, with array of pending tools\nconst pendingClientTools: Record<string, InteractiveTool[]>;\n```\n\nThis allows multiple simultaneous calls to the same tool (e.g., batch confirmations).\n\n## Migration Checklist\n\nUse this checklist to ensure you've addressed all breaking changes:\n\n- [ ] Update all Octavus packages to v2.0.0\n- [ ] Update HTTP transport from `triggerRequest` to `request` with new signature\n- [ ] Update server route handlers to use `execute()` with `SessionRequest` type\n- [ ] Update any status checks to handle `'awaiting-input'`\n- [ ] Update custom transport implementations to include `continueWithToolResults()`\n- [ ] Review any direct schema imports and update if needed\n- [ ] (Optional) Add client-side tools for browser-based functionality\n\n## Package Versions\n\nAll packages should be updated together to ensure compatibility:\n\n```json\n{\n \"dependencies\": {\n \"@octavus/core\": \"^2.0.0\",\n \"@octavus/client-sdk\": \"^2.0.0\",\n \"@octavus/server-sdk\": \"^2.0.0\",\n \"@octavus/react\": \"^2.0.0\"\n }\n}\n```\n\n## Need Help?\n\nIf you encounter issues during migration:\n\n- Check the [Client Tools documentation](/docs/client-sdk/client-tools) for the new features\n- Review the [HTTP Transport](/docs/client-sdk/http-transport) and [Server SDK Sessions](/docs/server-sdk/sessions) docs for updated APIs\n- [Open an issue](https://github.com/octavus-ai/js-sdk/issues) on GitHub if you find a bug\n",
|
|
322
|
+
"content": "\n# Migrating from v1 to v2\n\nThis guide covers all breaking changes and new features in Octavus SDK v2.0.0.\n\n## Overview\n\nVersion 2.0.0 introduces **client-side tool execution**, allowing tools to run in the browser with support for both automatic execution and interactive user input. This required changes to the transport layer and streaming protocol.\n\n## Breaking Changes\n\n### HTTP Transport Configuration\n\nThe `triggerRequest` option has been renamed to `request` and the function signature changed to support both trigger and continuation requests.\n\n**Before (v1):**\n\n```typescript\nimport { createHttpTransport } from '@octavus/client-sdk';\n\nconst transport = createHttpTransport({\n triggerRequest: (triggerName, input, options) =>\n fetch('/api/trigger', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ sessionId, triggerName, input }),\n signal: options?.signal,\n }),\n});\n```\n\n**After (v2):**\n\n```typescript\nimport { createHttpTransport } from '@octavus/client-sdk';\n\nconst transport = 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```\n\nThe `payload` parameter is a discriminated union with `type: 'trigger' | 'continue'`:\n\n- **Trigger request:** `{ type: 'trigger', triggerName: string, input?: Record<string, unknown> }`\n- **Continue request:** `{ type: 'continue', executionId: string, toolResults: ToolResult[] }`\n\n### Server SDK Route Handler\n\nServer-side route handlers should use the new `execute()` method which handles both triggers and continuations via the request type.\n\n**Before (v1):**\n\n```typescript\n// app/api/trigger/route.ts\nimport { AgentSession, toSSEStream } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const { sessionId, triggerName, input } = await request.json();\n\n const session = new AgentSession({\n sessionId,\n agentId: 'your-agent-id',\n apiKey: process.env.OCTAVUS_API_KEY!,\n });\n\n const events = session.trigger(triggerName, input, { signal: request.signal });\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\n**After (v2):**\n\n```typescript\n// app/api/trigger/route.ts\nimport { AgentSession, toSSEStream, type SessionRequest } from '@octavus/server-sdk';\n\nexport async function POST(request: Request) {\n const body = (await request.json()) as { sessionId: string } & SessionRequest;\n const { sessionId, ...sessionRequest } = body;\n\n const session = new AgentSession({\n sessionId,\n agentId: 'your-agent-id',\n apiKey: process.env.OCTAVUS_API_KEY!,\n });\n\n const events = session.execute(sessionRequest, { signal: request.signal });\n return new Response(toSSEStream(events), {\n headers: { 'Content-Type': 'text/event-stream' },\n });\n}\n```\n\nThe `SessionRequest` type is a discriminated union:\n\n- **Trigger:** `{ type: 'trigger', triggerName: string, input?: Record<string, unknown> }`\n- **Continue:** `{ type: 'continue', executionId: string, toolResults: ToolResult[] }`\n\n### Export Changes\n\nThe SDKs no longer use star exports (`export * from '@octavus/core'`). Instead, they use explicit type exports and value exports. This improves tree-shaking but may require import adjustments.\n\n**If you were importing schemas:**\n\nSome Zod schemas are no longer re-exported from `@octavus/server-sdk`. If you need validation schemas, import them directly from `@octavus/core`:\n\n```typescript\n// Before (v1) - some schemas were re-exported\nimport { fileUploadRequestSchema } from '@octavus/server-sdk';\n\n// After (v2) - import from core if needed\nimport { fileReferenceSchema } from '@octavus/core';\n```\n\n**Type imports remain the same:**\n\n```typescript\n// Types are still available\nimport type { StreamEvent, UIMessage, FileReference } from '@octavus/client-sdk';\n```\n\n### Custom Transport Interface\n\nCustom transport implementations must now implement the `continueWithToolResults()` method:\n\n```typescript\ninterface Transport {\n trigger(triggerName: string, input?: Record<string, unknown>): AsyncIterable<StreamEvent>;\n continueWithToolResults(executionId: string, results: ToolResult[]): AsyncIterable<StreamEvent>;\n stop(): void;\n}\n```\n\n### New ChatStatus Value\n\nThe `ChatStatus` type now includes `'awaiting-input'`:\n\n```typescript\n// v1\ntype ChatStatus = 'idle' | 'streaming' | 'error';\n\n// v2\ntype ChatStatus = 'idle' | 'streaming' | 'error' | 'awaiting-input';\n```\n\nUpdate any status checks that assume only three values.\n\n### Stream Event Changes\n\nTwo stream events have been modified:\n\n**StartEvent and FinishEvent now include executionId:**\n\n```typescript\ninterface StartEvent {\n type: 'start';\n messageId?: string;\n executionId?: string; // New in v2\n}\n\ninterface FinishEvent {\n type: 'finish';\n finishReason: FinishReason;\n executionId?: string; // New in v2\n}\n```\n\n**New FinishReason:**\n\n```typescript\n// Added 'client-tool-calls' to FinishReason\ntype FinishReason =\n | 'stop'\n | 'tool-calls'\n | 'client-tool-calls' // New in v2\n | 'length'\n | 'content-filter'\n | 'error'\n | 'other';\n```\n\n**New ClientToolRequestEvent:**\n\n```typescript\ninterface ClientToolRequestEvent {\n type: 'client-tool-request';\n executionId: string;\n toolCalls: PendingToolCall[];\n serverToolResults?: ToolResult[];\n}\n```\n\n## New Features\n\n### Client-Side Tools\n\nv2 introduces client-side tool execution, allowing tools to run in the browser. This is useful for:\n\n- Accessing browser APIs (geolocation, clipboard, etc.)\n- Interactive tools requiring user input (confirmations, forms, selections)\n- Tools that need access to client-side state\n\nSee the [Client Tools guide](/docs/client-sdk/client-tools) for full documentation.\n\n#### Automatic Client Tools\n\nTools that execute automatically without user interaction:\n\n```typescript\nimport { useOctavusChat, createHttpTransport } from '@octavus/react';\n\nfunction Chat() {\n const { messages, send, status } = useOctavusChat({\n transport: 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 clientTools: {\n 'get-browser-location': async (args, ctx) => {\n const pos = await new Promise((resolve, reject) => {\n navigator.geolocation.getCurrentPosition(resolve, reject);\n });\n return { lat: pos.coords.latitude, lng: pos.coords.longitude };\n },\n 'get-clipboard': async () => {\n return await navigator.clipboard.readText();\n },\n },\n });\n\n // ... rest of component\n}\n```\n\n#### Interactive Client Tools\n\nTools that require user interaction before completing:\n\n```typescript\nimport { useOctavusChat, createHttpTransport } from '@octavus/react';\n\nfunction Chat() {\n const { messages, send, status, pendingClientTools } = useOctavusChat({\n transport: 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 clientTools: {\n 'request-confirmation': 'interactive',\n 'select-option': 'interactive',\n },\n });\n\n // Render UI for pending interactive tools\n const confirmationTools = pendingClientTools['request-confirmation'] ?? [];\n\n return (\n <div>\n {/* Chat messages */}\n\n {/* Interactive tool UI */}\n {confirmationTools.map((tool) => (\n <ConfirmationModal\n key={tool.toolCallId}\n message={tool.args.message as string}\n onConfirm={() => tool.submit({ confirmed: true })}\n onCancel={() => tool.cancel('User declined')}\n />\n ))}\n </div>\n );\n}\n```\n\n### New Types for Client Tools\n\n```typescript\n// Context provided to automatic tool handlers\ninterface ClientToolContext {\n toolCallId: string;\n toolName: string;\n signal: AbortSignal;\n}\n\n// Handler types\ntype ClientToolHandler =\n | ((args: Record<string, unknown>, ctx: ClientToolContext) => Promise<unknown>)\n | 'interactive';\n\n// Interactive tool with bound submit/cancel methods\ninterface InteractiveTool {\n toolCallId: string;\n toolName: string;\n args: Record<string, unknown>;\n submit: (result: unknown) => void;\n cancel: (reason?: string) => void;\n}\n```\n\n### pendingClientTools Property\n\nBoth `OctavusChat` and `useOctavusChat` now expose `pendingClientTools`:\n\n```typescript\n// Record keyed by tool name, with array of pending tools\nconst pendingClientTools: Record<string, InteractiveTool[]>;\n```\n\nThis allows multiple simultaneous calls to the same tool (e.g., batch confirmations).\n\n## Migration Checklist\n\nUse this checklist to ensure you've addressed all breaking changes:\n\n- [ ] Update all Octavus packages to v2.0.0\n- [ ] Update HTTP transport from `triggerRequest` to `request` with new signature\n- [ ] Update server route handlers to use `execute()` with `SessionRequest` type\n- [ ] Update any status checks to handle `'awaiting-input'`\n- [ ] Update custom transport implementations to include `continueWithToolResults()`\n- [ ] Review any direct schema imports and update if needed\n- [ ] (Optional) Add client-side tools for browser-based functionality\n\n## Package Versions\n\nAll packages should be updated together to ensure compatibility:\n\n```json\n{\n \"dependencies\": {\n \"@octavus/core\": \"^2.0.0\",\n \"@octavus/client-sdk\": \"^2.0.0\",\n \"@octavus/server-sdk\": \"^2.0.0\",\n \"@octavus/react\": \"^2.0.0\"\n }\n}\n```\n\n## Need Help?\n\nIf you encounter issues during migration:\n\n- Check the [Client Tools documentation](/docs/client-sdk/client-tools) for the new features\n- Review the [HTTP Transport](/docs/client-sdk/http-transport) and [Server SDK Sessions](/docs/server-sdk/sessions) docs for updated APIs\n- [Open an issue](https://github.com/octavus-ai/agent-sdk/issues) on GitHub if you find a bug\n",
|
|
323
323
|
"excerpt": "Migrating from v1 to v2 This guide covers all breaking changes and new features in Octavus SDK v2.0.0. Overview Version 2.0.0 introduces client-side tool execution, allowing tools to run in the...",
|
|
324
324
|
"order": 1
|
|
325
325
|
}
|