Files
Atomizer/atomizer-dashboard/frontend/src/hooks/useCanvasChat.ts
Anto01 1ae35382da feat: Phase 2 - LLM Integration for Canvas
- Add canvas.ts MCP tool with validate_canvas_intent, execute_canvas_intent, interpret_canvas_intent
- Add useCanvasChat.ts bridge hook connecting canvas to chat system
- Update context_builder.py with canvas tool instructions
- Add ExecuteDialog for study name input
- Add ChatPanel for canvas-integrated Claude responses
- Connect AtomizerCanvas to Claude via useCanvasChat

Canvas workflow now:
1. Build graph visually
2. Click Validate/Analyze/Execute
3. Claude processes intent via MCP tools
4. Response shown in integrated chat panel

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-14 20:18:46 -05:00

185 lines
4.3 KiB
TypeScript

/**
* 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<CanvasChatState>({
isExecuting: false,
lastIntent: null,
executionResult: null,
});
/**
* Submit an intent for validation only (no execution)
*/
const validateIntent = useCallback(
async (intent: OptimizationIntent): Promise<void> => {
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<void> => {
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<void> => {
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<void> => {
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,
};
}