### Chat Setup Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of setting up a floating chat interface with Cedar-OS. ```tsx import { FloatingCedarChat } from 'cedar-os'; function ChatApp() { return (
{/* This automatically works */}
); } ``` -------------------------------- ### Using CLI flags Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of using the `--yes` flag to skip prompts during installation. ```bash npx cedar-os-cli plant-seed --project-name my-cedar-tree --yes ``` -------------------------------- ### Add your API key Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of setting up the `.env.local` file with OpenAI API keys for client-side and server-side access. ```bash # For client-side access (Cedar-OS components in browser) NEXT_PUBLIC_OPENAI_API_KEY=your-openai-api-key # For server-side access (API routes, server components) OPENAI_API_KEY=your-openai-api-key ``` -------------------------------- ### Install cedar-os package using npm, yarn, pnpm, or bun Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Commands to install the cedar-os package using different package managers. ```bash npm install cedar-os ``` ```bash yarn add cedar-os ``` ```bash pnpm add cedar-os ``` ```bash bun add cedar-os ``` -------------------------------- ### Install runtime dependencies for Cedar-OS components Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Commands to install the necessary runtime dependencies for Cedar-OS components using npm, yarn, pnpm, or bun. ```bash npm install lucide-react motion motion-plus-react uuid react-markdown framer-motion @radix-ui/react-slot class-variance-authority ``` ```bash yarn add lucide-react motion motion-plus-react uuid react-markdown framer-motion @radix-ui/react-slot class-variance-authority ``` ```bash pnpm add lucide-react motion motion-plus-react uuid react-markdown framer-motion @radix-ui/react-slot class-variance-authority ``` ```bash bun add lucide-react motion motion-plus-react uuid react-markdown framer-motion @radix-ui/react-slot class-variance-authority ``` -------------------------------- ### Development Commands Source: https://github.com/cedarcopilot/cedar-os/blob/main/src/app/examples/product-roadmap/README.md Commands to install dependencies, run the development server, and access the product roadmap example. ```bash # Install dependencies npm install # Run development server npm run dev # Navigate to http://localhost:3000/examples/product-roadmap ``` -------------------------------- ### Initialize CedarCopilot with OpenAI provider Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of configuring CedarCopilot with the OpenAI LLM provider. ```tsx "use client"; import { CedarCopilot } from 'cedar-os'; function App() { return ( ); } ``` -------------------------------- ### Basic Setup Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os/docs/THREAD_SYSTEM_SUMMARY.md Example of how to set up Cedar Copilot with FloatingCedarChat, specifying LLM provider and message storage. ```tsx import { FloatingCedarChat } from 'cedar-os-components'; ``` -------------------------------- ### LLM Provider Configuration Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of configuring a custom LLM provider with CedarCopilot. ```tsx function App() { return ( ); } ``` -------------------------------- ### State Access Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of registering and managing application state with `useRegisterState` for AI interaction. ```tsx import { useRegisterState } from 'cedar-os'; import { useState } from 'react'; import { z } from 'zod'; function TodoApp() { const [todos, setTodos] = useState([]); useRegisterState({ key: 'todos', value: todos, setValue: setTodos, description: 'User todo list manageable by AI', stateSetters: { addTodo: { name: 'addTodo', description: 'Add a new todo item', argsSchema: z.object({ text: z.string().describe('Todo text') }), execute: (currentTodos, args) => { const { text } = args; setTodos([...currentTodos, { id: Date.now(), text, completed: false }]); } }, toggleTodo: { name: 'toggleTodo', description: 'Toggle todo completion status', argsSchema: z.object({ id: z.number().describe('Todo ID') }), execute: (currentTodos, args) => { const { id } = args; setTodos(currentTodos.map(t => t.id === id ? { ...t, completed: !t.completed } : t )); } } } }); return (
{todos.map(todo => (
setTodos(todos.map(t => t.id === todo.id ? { ...t, completed: !t.completed } : t ))} /> {todo.text}
))}
); } ``` -------------------------------- ### Initialize CedarCopilot with Mastra provider Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of wrapping your app with CedarCopilot and configuring the Mastra LLM provider. ```tsx "use client"; import { CedarCopilot } from 'cedar-os'; function App() { return ( ); } ``` -------------------------------- ### Initialize CedarCopilot with AI SDK provider Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of configuring CedarCopilot with the AI SDK provider, supporting multiple LLM services. ```tsx "use client"; import { CedarCopilot } from 'cedar-os'; function App() { return ( // You don't need to put every model, // but if you try to use a model without a key it will fail ); } ``` -------------------------------- ### Install Dependencies Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/hackathon-starter.mdx Navigate to your project and install dependencies. ```bash cd your-project-name npm install && cd src/backend && npm install && cd ../.. ``` -------------------------------- ### Manual Installation Fails Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/cli.mdx If automatic installation fails, the CLI will show manual installation steps. ```bash # Manual Next.js creation npx create-next-app@latest my-project cd my-project npx cedar-os-cli add-sapling # Or follow the manual installation guide ``` -------------------------------- ### Add Cedar components to an existing project Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Use this command if `plant-seed` fails to add Cedar components and dependencies. ```bash # Add Cedar components and install dependencies only npx cedar-os-cli add-sapling ``` -------------------------------- ### Initialize CedarCopilot with Custom Backend Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Placeholder for configuring CedarCopilot with a custom backend provider. ```tsx "use client"; import { CedarCopilot } from 'cedar-os'; ``` -------------------------------- ### Initialize CedarCopilot with Anthropic provider Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of configuring CedarCopilot with the Anthropic LLM provider. ```tsx "use client"; import { CedarCopilot } from 'cedar-os'; function App() { return ( ); } ``` -------------------------------- ### Installation Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os/README.md Provides commands for installing Cedar-OS, recommending the CLI for automatic setup and offering a manual npm installation option. ```bash # Recommended: Use our CLI for automatic setup (new and existing projects) npx cedar-os-cli plant-seed # Or install manually npm install cedar-os ``` -------------------------------- ### Example Implementation Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/chat/message-storage-configuration.mdx An example implementation of a custom storage adapter for CedarCopilot. ```typescript import { CedarCopilot } from 'cedar-os'; // Your custom storage implementation const myCustomAdapter = { async listThreads(userId) { return await myDatabase.getThreads(userId); }, async loadMessages(userId, threadId) { return await myDatabase.getMessages(userId, threadId); }, await persistMessage(userId, threadId, message) { await myDatabase.appendMessage(userId, threadId, message); }, }; function App() { return ( ); } ``` -------------------------------- ### Install Mintlify CLI Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/README.md Command to install the Mintlify CLI globally. ```bash npm i -g mint ``` -------------------------------- ### Storage Abstraction API Source: https://github.com/cedarcopilot/cedar-os/blob/main/src/app/examples/product-roadmap/README.md Example functions demonstrating the consistent API for interacting with storage backends (Supabase or localStorage). ```typescript // These functions work with both storage backends await getNodes(); // Fetch all nodes await saveNodes(nodes); // Save nodes await getEdges(); // Fetch all edges await saveEdges(edges); // Save edges await deleteNode(id); // Soft delete a node ``` -------------------------------- ### File Selection Collapse Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx Real-world example of collapse configuration for file selection. ```tsx const [selectedFiles, setSelectedFiles] = useState([]); useSubscribeStateToAgentContext( 'selectedFiles', (files) => ({ selectedFiles: files }), { labelField: 'filename', icon: , color: '#EF4444', // Boolean with default behavior collapse: true, // Uses default threshold of 5 } ); ``` -------------------------------- ### Installation Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os-components/README.md Install the cedar-os-components package using npm. ```bash npm install cedar-os-components ``` -------------------------------- ### Installation Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os-backend/README.md Install the @cedar-os/backend package using npm, yarn, or pnpm. ```bash npm install @cedar-os/backend # or yarn add @cedar-os/backend # or pnpm add @cedar-os/backend ``` -------------------------------- ### Multiple Context Keys Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx Example demonstrating returning multiple keys from `mapFn` with different data structures. ```tsx useSubscribeStateToAgentContext('appState', (state) => ({ currentUser: state.user, // Single object → single entry act iveTasks: state.tasks, // Array → array of entries selectedItems: [state.selected], // Single-item array → array preferences: state.prefs, // Single object → single entry })); // Agent receives all four keys with appropriate structures ``` -------------------------------- ### Basic Usage Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx A simple example demonstrating how to use `useSubscribeStateToAgentContext` with a todo list. ```tsx import { useCedarState, useSubscribeStateToAgentContext } from 'cedar-os'; import { CheckCircle } from 'lucide-react'; function TodoApp() { // 1) Register the state in Cedar const [todos, setTodos] = useCedarState( 'todos', [ { id: 1, text: 'Buy groceries', completed: false }, { id: 2, text: 'Walk the dog', completed: true }, ], 'Todo items' ); // 2) Subscribe that state to input context useSubscribeStateToAgentContext( 'todos', (todoList) => ({ todos: todoList, // Key 'todos' will be available to the agent }), { icon: , color: '#10B981', // Green color labelField: 'text', // Use the 'text' field as label for each todo } ); return (
{/* Agent can now see todos in context */}
); } ``` -------------------------------- ### Label Template Examples Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx Examples demonstrating different label templates for the collapsed badge. ```tsx // Examples of label templates collapse: { threshold: 3, label: '{count} Items', } collapse: { threshold: 8, label: 'Multiple Selections ({count})', } collapse: { threshold: 5, label: 'Batch Selection', } ``` -------------------------------- ### Task Management Collapse Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx Real-world example of collapse configuration for task management. ```tsx const [selectedTasks, setSelectedTasks] = useState([]); useSubscribeStateToAgentContext( 'selectedTasks', (tasks) => ({ selectedTasks: tasks }), { labelField: 'title', icon: , color: '#6366F1', // Simple numeric threshold collapse: 7, // Collapse when more than 7 tasks selected } ); ``` -------------------------------- ### Shopping Cart Collapse Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx Real-world example of collapse configuration for a shopping cart. ```tsx const [cartItems, setCartItems] = useState([ { id: 1, name: 'Laptop', price: 999 }, { id: 2, name: 'Mouse', price: 29 }, { id: 3, name: 'Keyboard', price: 79 }, // ... more items ]); useSubscribeStateToAgentContext( 'cart', (items) => ({ cartItems: items }), { labelField: 'name', icon: , color: '#10B981', // Collapse when cart has more than 3 items collapse: { threshold: 3, label: '{count} Items in Cart', icon: , }, } ); ``` -------------------------------- ### Auto-Thread Creation Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/chat/thread-management.mdx Example demonstrating how to automatically create a new thread if none exist when using storage adapters. ```typescript // In messageStorage.ts - automatically creates a thread if none exist const loadAndSelectThreads = async ( userId: string, autoCreateThread: boolean = true ) => { if (threads.length === 0 && autoCreateThread) { const newThreadId = `thread-${Date.now()}-${Math.random() .toString(36) .substring(2, 9)}`; await adapter.createThread(userId, newThreadId, { id: newThreadId, title: 'New Chat', updatedAt: new Date().toISOString(), }); } }; ``` -------------------------------- ### Report Retrieval Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-backend-connection/agent-backend-connection.mdx Example demonstrating how to retrieve a report from the backend with custom headers and how to access its typed properties. ```javascript import { CedarClient } from "@cedarcopilot/cedar-client"; const cedarClient = new CedarClient({ // You can pass in custom headers here. headers: { 'X-Custom-Auth': 'bearer-token', 'X-Report-Format': 'structured', }, }); // reportResponse.object is fully typed as Report console.log(reportResponse.object.summary); // string console.log(reportResponse.object.metrics.conversionRate); // number (0-1) console.log(reportResponse.object.insights[0].impact); // 'positive' | 'negative' | 'neutral' console.log(reportResponse.object.recommendations); // string[] ``` -------------------------------- ### Component-Level Styling Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/customising/styling.mdx Example showing how a component like FloatingCedarChat uses global styling and how to set custom colors before rendering. ```tsx import { FloatingCedarChat } from '@/chatComponents/FloatingCedarChat'; import { useCedarStore } from 'cedar-os'; function StyledChat() { const { setStyling } = useCedarStore(); // Set custom colors before rendering useEffect(() => { setStyling({ color: '#8B5CF6', // Purple secondaryColor: '#7C3AED', accentColor: '#F97316', // Orange }); }, []); return ; } ``` -------------------------------- ### Programmatic Control Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os/docs/THREAD_SYSTEM_SUMMARY.md Example demonstrating how to use the `useThreadController` hook for programmatic control of threads. ```typescript import { useThreadController } from 'cedar-os'; const { createThread, switchThread, deleteThread } = useThreadController(); // Create and switch to new thread const newId = createThread(); switchThread(newId); ``` -------------------------------- ### Streaming Response Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/voice/agentic-backend.mdx An example of how to implement streaming audio responses for voice interactions, sending audio data in chunks to the client. ```typescript // Example streaming response app.post('/api/chat/voice-stream', async (req, res) => { res.writeHead(200, { 'Content-Type': 'audio/mpeg', 'Transfer-Encoding': 'chunked', }); const audioStream = await generateAudioStream(transcription); audioStream.on('data', (chunk) => { res.write(chunk); }); audioStream.on('end', () => { res.end(); }); }); ``` -------------------------------- ### Spells Integration Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/getting-started.mdx Example of registering a spell with `useSpells` for custom actions. ```tsx import { useSpells } from 'cedar-os'; import { useEffect } from 'react'; function SpellsApp() { const { registerSpell } = useSpells(); useEffect(() => { registerSpell({ id: 'quick-action', name: 'Quick Action', icon: '⚡', action: () => console.log('Spell activated!'), trigger: 'cmd+k' }); }, []); return (

Press Cmd+K to activate spells

); } ``` -------------------------------- ### Start Development Server Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/hackathon-starter.mdx Make sure you're in the main project directory and run the development server. ```bash cd path-to-root-project # if not already there npm run dev ``` -------------------------------- ### Supabase Environment Variables Source: https://github.com/cedarcopilot/cedar-os/blob/main/src/app/examples/product-roadmap/README.md Environment variables required to configure Supabase as the primary storage backend for the product roadmap. ```bash NEXT_PUBLIC_SUPABASE_URL=your-supabase-url NEXT_PUBLIC_SUPABASE_KEY=your-supabase-anon-key ``` -------------------------------- ### Quick Start CLI Command Source: https://github.com/cedarcopilot/cedar-os/blob/main/README.md Command to initialize a new Cedar OS project. ```bash npx cedar-os-cli plant-seed ``` -------------------------------- ### Quick Start Commands Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cli/README.md Commands to quickly scaffold a new Cedar-OS project or add Cedar to an existing project. ```bash npx cedar-os-cli npx cedar-os-cli plant-seed npx cedar-os-cli add-sapling ``` -------------------------------- ### Using `useTypedAgentConnection` for Specific Providers Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os/docs/agent-connection-examples.md Example of using the `useTypedAgentConnection` hook to get type-safe `callLLM` and `streamLLM` functions for a known provider (e.g., 'openai' or 'mastra'). ```typescript import { useTypedAgentConnection } from 'cedar-os'; function MyOpenAIComponent() { const { callLLM, streamLLM } = useTypedAgentConnection('openai'); const handleClick = async () => { // TypeScript knows this needs model, not route const response = await callLLM({ model: 'gpt-4', // ✅ Required and type-checked prompt: 'Hello, world!', }); // streamLLM is also properly typed const stream = streamLLM( { model: 'gpt-4', // ✅ Required prompt: 'Tell me a story', }, (event) => { if (event.type === 'chunk') { console.log(event.content); } } ); }; } function MyMastraComponent() { const { callLLM } = useTypedAgentConnection('mastra'); const handleClick = async () => { // TypeScript knows this needs route, not model const response = await callLLM({ route: '/chat/completions', // ✅ Required and type-checked prompt: 'Hello, world!', }); }; } ``` -------------------------------- ### cedar pluck-component Usage Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/cli.mdx Downloads specific Cedar components locally from an existing npm installation. Use this when you've installed `cedar-os-components` via npm but want to customize specific components. ```bash npx cedar-os-cli pluck-component ``` -------------------------------- ### Quick Start Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/spells/spells.mdx Example of how to use the useSpell hook to create a custom spell with activation conditions and lifecycle callbacks. ```tsx import { useSpell, Hotkey, ActivationMode } from 'cedar-os'; function MyComponent() { const { isActive, activate, deactivate, toggle } = useSpell({ id: 'my-spell', activationConditions: { events: [Hotkey.SPACE], mode: ActivationMode.HOLD, }, onActivate: () => console.log('Spell activated!'), onDeactivate: () => console.log('Spell deactivated!'), }); // You can also trigger spells programmatically const handleButtonClick = () => { toggle(); // or activate() / deactivate() }; return ( <> {isActive ?
✨ Magic is happening!
: null} ); } ``` -------------------------------- ### Advanced Dynamic Configuration Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx A comprehensive example showing dynamic icons based on node status, conditional display (`showInChat`), and collapsing of context badges when multiple nodes are selected. ```tsx import { Box } from 'lucide-react'; interface FeatureNodeData { title: string; status: 'done' | 'in progress' | 'planned' | 'backlog'; priority: 'high' | 'medium' | 'low'; } const [selectedNodes, setSelectedNodes] = useState[]>([]); useSubscribeStateToAgentContext( 'selectedNodes', (nodes) => ({ selectedNodes: nodes }), { // Dynamic icons based on node status icon: (node) => { const status = node?.data?.status; switch (status) { case 'done': return '✅'; case 'in progress': return '🔄'; case 'planned': return '📋'; case 'backlog': return '📝'; default: return ; } }, color: '#8B5CF6', labelField: (node) => node?.data?.title, // Only show nodes that are not in backlog status in chat context showInChat: (entry) => { const node = entry.data; return node?.data?.status !== 'backlog'; }, order: 2, // Collapse into a single badge when more than 5 nodes are selected collapse: { threshold: 5, label: '{count} Selected Nodes', icon: , }, } ); ``` -------------------------------- ### Getting Current User ID Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/chat/message-storage-configuration.mdx Provides an example of how to retrieve the currently set user ID using the `getCedarState` function. ```typescript import { getCedarState } from 'cedar-os'; function CurrentUserDisplay() { const userId = getCedarState('userId'); return
Current user: {userId || 'Not logged in'}
; } ``` -------------------------------- ### Message Grouping Logic Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/components/chat-bubbles.mdx Example demonstrating how consistent 'role' values in messages lead to grouping, while a change in 'role' starts a new group. ```tsx // Messages need consistent role values const messages = [ { id: '1', role: 'user', content: 'Hello' }, { id: '2', role: 'user', content: 'How are you?' }, // Same role = grouped { id: '3', role: 'assistant', content: 'I am well' }, // Different role = new group ]; ``` -------------------------------- ### Stringified Context Access Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/agent-context.mdx Example demonstrating how to get stringified versions of the editor input, compiled additional context, and the combined input context using `useCedarStore`. ```tsx import { useCedarStore } from 'cedar-os'; function ContextStringifier() { const { stringifyEditor, compileAdditionalContext, stringifyInputContext } = useCedarStore(); const inspectContext = () => { // Get just the user's text input const userText = stringifyEditor(); console.log('User text:', userText); // Get additional context as object (includes state data, setters, and schemas) const contextData = compileAdditionalContext(); console.log('Context data:', contextData); // Get combined input and context (what gets sent to AI) const fullContext = stringifyInputContext(); console.log('Full context:', fullContext); }; return ; } ``` -------------------------------- ### cedar add-sapling Usage Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/cli.mdx Installs the latest version of Cedar-OS and optionally downloads Cedar UI components. Use to refresh your environment after Cedar updaes. ```bash npx cedar-os-cli add-sapling ``` -------------------------------- ### Download specific components Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/cli.mdx Pass one or more component names with -c to download them directly. ```bash npx cedar-os-cli pluck-component -c FloatingCedarChat TooltipMenu ``` -------------------------------- ### Mastra Backend Connection Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-backend-connection/agent-backend-connection.mdx Demonstrates how to use `useTypedAgentConnection` to get a typed connection for the Mastra backend, including examples for basic `callLLM`, streaming, and structured responses. ```typescript import { useTypedAgentConnection } from 'cedar-os'; import { z } from 'zod'; // Get a typed connection for Mastra const { callLLM, streamLLM, callLLMStructured } = useTypedAgentConnection('mastra'); interface MastraParams extends BaseParams { route: string; resourceId?: string; // User ID in Cedar threadId?: string; } // Example usage const response = await callLLM({ route: '/chat/completions', // Full route path prompt: 'Hello, AI!', }); // Response is fully typed as LLMResponse console.log(response.content); // string console.log(response.usage?.totalTokens); // number | undefined console.log(response.object); // unknown (for structured responses) // Example with additional Mastra features // Note: When using sendMessage(), the default route is automatically constructed // as `${chatPath}` (e.g., '/chat') const advancedResponse = await callLLM({ route: '/chat', // This would be the default for sendMessage() prompt: 'Remember my name is John', // Additional Mastra-specific parameters can be added sessionId: 'user-123', tools: ['web_search', 'calculator'], knowledgeBaseId: 'kb-456', }); // Structured response example with Mastra const TaskPlanSchema = z.object({ title: z.string(), steps: z.array( z.object({ id: z.number(), description: z.string(), estimatedTime: z.string(), dependencies: z.array(z.number()).optional(), toolsRequired: z.array(z.string()).optional(), }) ), totalEstimatedTime: z.string(), complexity: z.enum(['simple', 'moderate', 'complex']), requiredTools: z.array(z.string()), }); type TaskPlan = z.infer; const taskPlanResponse: TaskPlan = await callLLMStructured({ route: '/chat/structured', prompt: 'Create a plan to build a todo app with user authentication', schema: TaskPlanSchema, // Mastra-specific parameters sessionId: 'user-123', tools: ['web_search', 'code_generator'], knowledgeBaseId: 'development-kb', }); // taskPlanResponse.object is fully typed as TaskPlan console.log(taskPlanResponse.object.title); // string console.log(taskPlanResponse.object.steps[0].estimatedTime); // string console.log(taskPlanResponse.object.complexity); // 'simple' | 'moderate' | 'complex' console.log(taskPlanResponse.object.requiredTools); // string[] ``` -------------------------------- ### Node.js WebSocket Server Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/voice/websockets.mdx This code snippet demonstrates a basic Node.js WebSocket server setup for handling voice interactions, including text response streaming and audio generation. ```typescript import WebSocket from 'ws'; import { VoiceSession } from './voice-session'; // Assuming VoiceSession is defined elsewhere import OpenAI from 'openai'; const openai = new OpenAI(); const server = new WebSocket.Server({ noServer: true }); // In-memory store for active sessions (replace with a more robust solution for production) const sessions = new Map(); // Handle WebSocket upgrade requests server.on('upgrade', (request, socket, head) => { // Authenticate and authorize the connection here if needed // For simplicity, we'll accept all connections server.handleUpgrade(request, socket, head, (ws) => { server.emit('connection', ws, request); }); }); server.on('connection', (ws) => { console.log('Client connected'); // Initialize a new voice session for this client const session: VoiceSession = { ws: ws, settings: { voiceId: 'alloy', // Default voice rate: 1.0, // Default rate }, // Add other session-specific properties as needed }; sessions.set(ws, session); ws.on('message', async (message: string) => { console.log('Received message:', message); try { const parsedMessage = JSON.parse(message); switch (parsedMessage.type) { case 'text_input': await handleTextInput(session, parsedMessage.text); break; case 'set_voice': session.settings.voiceId = parsedMessage.voiceId; break; case 'set_rate': session.settings.rate = parsedMessage.rate; break; default: console.warn('Unknown message type:', parsedMessage.type); } } catch (error) { console.error('Failed to process message:', error); ws.send(JSON.stringify({ type: 'error', message: 'Invalid message format' })); } }); ws.on('close', () => { console.log('Client disconnected'); sessions.delete(ws); }); ws.on('error', (error) => { console.error('WebSocket error:', error); sessions.delete(ws); }); }); async function handleTextInput(session: VoiceSession, text: string) { try { // Simulate response generation let fullResponse = ''; const responseChunks = ['This is the first part of the response. ', 'And this is the second part. ', 'Finally, the end of the response.']; for (const chunk of responseChunks) { fullResponse += chunk; // Send response chunk session.ws.send( JSON.stringify({ type: 'response_chunk', text: chunk, }) ); // Simulate delay for streaming effect await new Promise((resolve) => setTimeout(resolve, 500)); } // Send complete response session.ws.send( JSON.stringify({ type: 'response_complete', text: fullResponse, }) ); // Generate and stream audio response await generateStreamingAudio(session, fullResponse); } catch (error) { console.error('Response generation error:', error); session.ws.send( JSON.stringify({ type: 'error', message: 'Failed to generate response', }) ); } } async function generateStreamingAudio(session: VoiceSession, text: string) { try { // Generate speech const speech = await openai.audio.speech.create({ model: 'tts-1', voice: session.settings.voiceId || 'alloy', input: text, response_format: 'mp3', speed: session.settings.rate || 1.0, }); const audioBuffer = Buffer.from(await speech.arrayBuffer()); // Stream audio in chunks const chunkSize = 4096; for (let i = 0; i < audioBuffer.length; i += chunkSize) { const chunk = audioBuffer.slice(i, i + chunkSize); const base64Chunk = chunk.toString('base64'); session.ws.send( JSON.stringify({ type: 'audio_chunk', data: base64Chunk, isLast: i + chunkSize >= audioBuffer.length, }) ); // Small delay to prevent overwhelming the client await new Promise((resolve) => setTimeout(resolve, 30)); } // Mark audio complete session.ws.send( JSON.stringify({ type: 'audio_complete', }) ); } catch (error) { console.error('TTS generation error:', error); session.ws.send( JSON.stringify({ type: 'error', message: 'Failed to generate speech', }) ); } } // Start server const PORT = process.env.PORT || 8080; server.listen(PORT, () => { console.log(`WebSocket voice server running on port ${PORT}`); }); ``` -------------------------------- ### Complete Custom Provider Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-backend-connection/custom.mdx A full TypeScript example demonstrating the implementation of a custom LLM provider, including methods for calling the LLM, handling responses, and streaming. ```typescript import type { CustomParams, ProviderImplementation, InferProviderConfig, StructuredParams, LLMResponse, StreamHandler, StreamResponse, StreamEvent, } from '@cedar-os/core'; type CustomConfig = InferProviderConfig<'custom'>; export const myCustomProvider: ProviderImplementation< CustomParams, CustomConfig > = { callLLM: async (params, config) => { const { prompt, systemPrompt, temperature, maxTokens, ...rest } = params; const response = await fetch(`${config.config.baseURL}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${config.config.apiKey}`, }, body: JSON.stringify({ messages: [ ...(systemPrompt ? [{ role: 'system', content: systemPrompt }] : []), { role: 'user', content: prompt }, ], temperature, max_tokens: maxTokens, ...rest, }), }); return myCustomProvider.handleResponse(response); }, callLLMStructured: async (params, config) => { // Implementation similar to callLLM but with schema handling // ... (see example above) }, streamLLM: (params, config, handler) => { // Implementation for streaming // ... (see example above) }, handleResponse: async (response) => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } const data = await response.json(); return { content: data.response || data.text || '', usage: data.usage, metadata: { model: data.model, id: data.id }, }; }, }; ``` -------------------------------- ### Add API Key Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/hackathon-starter.mdx Create a .env file in the project root and add your OpenAI API key. ```bash echo "OPENAI_API_KEY=your-api-key-here" > .env ``` -------------------------------- ### Multi-Step Workflow Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os/docs/agent-connection-examples.md An example of a multi-step workflow using `useCedarStore` to call an LLM for different stages of code review: structure analysis, security checks, and improvement suggestions. ```typescript function useCodeReviewFlow() { const store = useCedarStore(); const reviewCode = async (code: string) => { // Step 1: Analyze code structure const structureAnalysis = await store.callLLM({ model: 'gpt-3.5-turbo', prompt: `Analyze the structure of this code: ${code}`, }); // Step 2: Check for security issues (using a different model) const securityCheck = await store.callLLM({ model: 'gpt-4', // Use GPT-4 for security analysis prompt: `Check for security vulnerabilities: ${code}`, systemPrompt: 'You are a security expert. Be thorough.', }); // Step 3: Generate improvement suggestions const improvements = await store.callLLM({ model: 'gpt-4', prompt: `Suggest improvements based on: Structure: ${structureAnalysis.content} Security: ${securityCheck.content} Code: ${code}`, }); return { structure: structureAnalysis, security: securityCheck, improvements: improvements, }; }; return { reviewCode }; } ``` -------------------------------- ### FrontendTool Response Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/state-access/agentic-actions.mdx Example of a JSON response for a frontendTool type action. ```json { "type": "frontendTool", "toolName": "showNotification", "args": { "message": "Feature added successfully!", "type": "success" } } ``` -------------------------------- ### setState Response Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/state-access/agentic-actions.mdx Example of a JSON response for a setState type action. ```json { "type": "setState", "stateKey": "nodes", "setterKey": "addNode", "args": { /* node data */ } } ``` -------------------------------- ### Basic Order Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/subscribing-state.mdx Demonstrates how to use the `order` option in `useSubscribeStateToAgentContext` to control the display priority of different types of context data. ```tsx function PrioritizedContext() { const [criticalAlerts, setCriticalAlerts] = useState([]); const [normalTasks, setNormalTasks] = useState([]); const [archivedItems, setArchivedItems] = useState([]); // Critical alerts appear first (order: 1) useSubscribeStateToAgentContext( criticalAlerts, (alerts) => ({ criticalAlerts: alerts }), { icon: , color: '#EF4444', order: 1, // Highest priority - appears first } ); // Normal tasks appear second (order: 10) useSubscribeStateToAgentContext( normalTasks, (tasks) => ({ activeTasks: tasks }), { icon: , color: '#3B82F6', order: 10, // Medium priority } ); // Archived items appear last (order: 100) useSubscribeStateToAgentContext( archivedItems, (items) => ({ archivedItems: items }), { icon: , color: '#6B7280', order: 100, // Low priority - appears last } ); return ; } ``` -------------------------------- ### Streaming AI Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/components/markdown-renderer.mdx Example of using MarkdownRenderer with streaming AI messages. ```tsx import { MarkdownRenderer } from 'cedar-os-components/chatMessages/MarkdownRenderer'; import { useChat } from '@ai-sdk/react'; export default function Chat() { const { messages } = useChat(); return messages.map((message) => ( )); } ``` -------------------------------- ### Recommended Configuration Pattern Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/getting-started/organizing-a-cedar-project.mdx Example of defining message renderers and response handlers in separate files within the `cedar/` directory and importing them for `CedarCopilot` initialization. ```tsx // cedar/messageRenderers.ts export const messageRenderers = { // Your custom message renderers }; // cedar/responseHandlers.ts export const responseHandlers = { // Your response handling logic }; // In your main component import { messageRenderers } from '../cedar/messageRenderers'; import { responseHandlers } from '../cedar/responseHandlers'; ; ``` -------------------------------- ### Custom Debug Flow Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os/docs/agent-connection-examples.md An example of a custom `useDebugFlow` hook that demonstrates how to build a specific prompt for debugging, make a streaming LLM call, and handle the response with custom logic. ```typescript import { useCedarStore } from 'cedar-os'; function useDebugFlow() { const store = useCedarStore(); const debugFlow = async () => { // 1. Parse context from the current state const context = store.getCedarState('debugContext'); const userCode = store.getCedarState('currentCode'); const errorMessage = store.getCedarState('lastError'); // 2. Build a specific prompt for debugging const debugPrompt = ` Debug the following code: Code: ${userCode} Error: ${errorMessage} Context: ${JSON.stringify(context, null, 2)} Please provide: 1. The root cause of the error 2. A fix for the code 3. An explanation of what went wrong `; // 3. Make the LLM call with specific configuration const response = await store.streamLLM( { prompt: debugPrompt, model: 'gpt-4', // Use GPT-4 for complex debugging temperature: 0.2, // Low temperature for precise debugging systemPrompt: 'You are an expert debugger. Be concise and accurate.', }, // 4. Handle the streaming response with custom logic (event) => { switch (event.type) { case 'chunk': // Parse the response and update UI in real-time const lines = event.content.split('\n'); // Look for specific patterns in the response if (event.content.includes('ROOT CAUSE:')) { store.setCedarState('debugRootCause', event.content); } else if (event.content.includes('FIX:')) { store.setCedarState('suggestedFix', event.content); } // Update the debug output store.setCedarState( 'debugOutput', (prev: string) => prev + event.content ); break; case 'done': // Execute post-processing store.setCedarState('debugStatus', 'complete'); // Automatically apply the fix if confidence is high const output = store.getCedarState('debugOutput'); if (output.includes('CONFIDENCE: HIGH')) { applyDebugFix(); } break; case 'error': console.error('Debug flow error:', event.error); store.setCedarState('debugStatus', 'error'); break; } } ); return response; }; const applyDebugFix = () => { const suggestedFix = store.getCedarState('suggestedFix'); // Apply the fix to the code editor store.setCedarState('currentCode', suggestedFix); }; return { debugFlow }; } ``` -------------------------------- ### Container Styling Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/components/chat-bubbles.mdx Examples of applying background and border styles to the ChatBubbles container. ```tsx // Default flexible container // Fixed height with custom styling ``` -------------------------------- ### Advanced Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/components/typewriter-text.mdx An advanced example combining multiple props for a complex typewriter effect. ```tsx setShowNextSection(true)} /> ``` -------------------------------- ### Quick Start: Extracting Schemas Source: https://github.com/cedarcopilot/cedar-os/blob/main/packages/cedar-os-backend/README.md Demonstrates how to extract frontend tool and state setter schemas using the @cedar-os/backend package and how to use them directly with AI agent's experimental_output. ```typescript import { getFrontendToolSchemas, getStateSetterSchemas, getFrontendToolSchema, getStateSetterSchema, } from '@cedar-os/backend'; // Extract all frontend tool schemas (returns JSON Schemas directly) const frontendSchemas = getFrontendToolSchemas(requestBody); // Extract all state setter schemas (returns JSON Schemas directly) const setterSchemas = getStateSetterSchemas(requestBody); // Extract a specific frontend tool schema const notificationSchema = getFrontendToolSchema( requestBody, 'showNotification' ); // Extract a specific state setter schema const addNodeSchema = getStateSetterSchema({ requestBody, setterKey: 'addNode', stateKey: 'nodes', }); // Use directly with experimental_output const response = await agent.generate({ messages: [{ role: 'user', content: body.prompt }], experimental_output: { schema: notificationSchema, // JSON Schema works directly }, }); ``` -------------------------------- ### Mentions System Example Source: https://github.com/cedarcopilot/cedar-os/blob/main/docs/agent-context/agent-context.mdx Example of creating a mention provider for documents using useStateBasedMentionProvider. ```tsx import { useStateBasedMentionProvider } from 'cedar-os'; import { FileText } from 'lucide-react'; function DocumentChat() { const [documents] = useCedarState('documents', [ { id: 'doc1', title: 'Project Proposal', type: 'pdf' }, { id: 'doc2', title: 'Meeting Notes', type: 'doc' }, ]); // Create a mention provider for documents useStateBasedMentionProvider({ stateKey: 'documents', trigger: '@', labelField: 'title', searchFields: ['title', 'type'], description: 'Documents', icon: , color: '#8b5cf6', order: 5, // Control display order when mentioned }); return ; } ```