/** * Canvas-Chat Bridge Hook * * Bridges the Canvas UI with the Chat system, allowing canvas intents * to be sent to Claude for intelligent execution. */ import { useCallback, useState } from 'react'; import { useChat, ChatMode } from './useChat'; import { OptimizationIntent, formatIntentForChat } from '../lib/canvas/intent'; interface UseCanvasChatOptions { mode?: ChatMode; onError?: (error: string) => void; } interface CanvasChatState { isExecuting: boolean; lastIntent: OptimizationIntent | null; executionResult: ExecutionResult | null; } interface ExecutionResult { success: boolean; action: string; studyName?: string; path?: string; error?: string; message?: string; } export function useCanvasChat({ mode = 'user', onError, }: UseCanvasChatOptions = {}) { const chat = useChat({ mode, onError }); const [state, setState] = useState({ isExecuting: false, lastIntent: null, executionResult: null, }); /** * Submit an intent for validation only (no execution) */ const validateIntent = useCallback( async (intent: OptimizationIntent): Promise => { setState((prev) => ({ ...prev, isExecuting: true, lastIntent: intent, executionResult: null, })); // Format intent for chat and ask Claude to validate const message = `Please validate this canvas optimization intent: ${formatIntentForChat(intent)} Use the validate_canvas_intent tool to check for errors and provide feedback.`; await chat.sendMessage(message); setState((prev) => ({ ...prev, isExecuting: false, })); }, [chat] ); /** * Execute an intent (create study and optionally run) */ const executeIntent = useCallback( async ( intent: OptimizationIntent, studyName: string, autoRun: boolean = false ): Promise => { setState((prev) => ({ ...prev, isExecuting: true, lastIntent: intent, executionResult: null, })); // Format intent for chat and ask Claude to execute const message = `Please execute this canvas optimization intent to create study "${studyName}"${autoRun ? ' and start the optimization' : ''}: ${formatIntentForChat(intent)} Use the execute_canvas_intent tool with: - study_name: "${studyName}" - auto_run: ${autoRun} After execution, provide a summary of what was created.`; await chat.sendMessage(message); setState((prev) => ({ ...prev, isExecuting: false, })); }, [chat] ); /** * Get recommendations for an intent without executing */ const analyzeIntent = useCallback( async (intent: OptimizationIntent): Promise => { setState((prev) => ({ ...prev, isExecuting: true, lastIntent: intent, })); const message = `Please analyze this canvas optimization intent and provide recommendations: ${formatIntentForChat(intent)} Use the interpret_canvas_intent tool to: 1. Analyze the problem characteristics 2. Suggest the best optimization method 3. Recommend trial budget 4. Identify any potential issues Provide your recommendations in a clear, actionable format.`; await chat.sendMessage(message); setState((prev) => ({ ...prev, isExecuting: false, })); }, [chat] ); /** * Send a free-form message about the current canvas state */ const askAboutCanvas = useCallback( async (intent: OptimizationIntent, question: string): Promise => { const message = `Given this canvas optimization intent: ${formatIntentForChat(intent)} ${question}`; await chat.sendMessage(message); }, [chat] ); return { // Chat state messages: chat.messages, isThinking: chat.isThinking || state.isExecuting, isConnected: chat.isConnected, error: chat.error, sessionId: chat.sessionId, mode: chat.mode, // Canvas-specific state isExecuting: state.isExecuting, lastIntent: state.lastIntent, executionResult: state.executionResult, // Actions validateIntent, executeIntent, analyzeIntent, askAboutCanvas, // Base chat actions sendMessage: chat.sendMessage, clearMessages: chat.clearMessages, switchMode: chat.switchMode, }; }