Files
Atomizer/atomizer-dashboard/frontend/src/hooks/useCanvasChat.ts

185 lines
4.3 KiB
TypeScript
Raw Normal View History

/**
* 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,
};
}