// ─── App Mode ──────────────────────────────────────────────────────────────── export type AppMode = 'classroom' | 'homework'; // ─── Response Mode ────────────────────────────────────────────────────────── export interface ResponseMode { hintMode: boolean; // true = AI proactively suggests hints strict: boolean; // true = only the exact required approach is accepted } // ─── Languages & Topics ──────────────────────────────────────────────────── export type SupportedLanguage = 'python' | 'html'; export interface Topic { id: string; label: string; language: SupportedLanguage; description: string; starterCode: string; } // ─── Tasks (AI generated) ────────────────────────────────────────────────── export interface Task { title: string; description: string; hints: string[]; starterCode: string; } // ─── Messages ────────────────────────────────────────────────────────────── export type MessageRole = 'user' | 'assistant'; export type MessageType = 'task' | 'review' | 'chat'; export interface Message { id: string; role: MessageRole; content: string; timestamp: number; type: MessageType; } // ─── Provider Config ─────────────────────────────────────────────────────── export type ProviderId = 'anthropic' | 'openrouter' | 'lmstudio' | 'ollama'; export interface ProviderConfig { provider: ProviderId; model: string; apiKey?: string; // Anthropic key override or OpenRouter key baseUrl?: string; // LM Studio / Ollama custom host:port } // ─── AI API ──────────────────────────────────────────────────────────────── export type AIMode = 'generate_task' | 'review_code' | 'chat' | 'generate_lesson' | 'classroom_chat'; export interface AIRequestBody { mode: AIMode; topic: Topic; code: string; executionResult?: ExecutionResult; messages: Pick[]; userMessage?: string; providerConfig: ProviderConfig; responseMode?: ResponseMode; } // ─── Code Execution ──────────────────────────────────────────────────────── export interface ExecutionResult { stdout: string; stderr: string; exitCode: number; timedOut: boolean; error?: string; } export interface ExecuteRequestBody { language: SupportedLanguage; code: string; stdin?: string; } // ─── App State (useReducer) ──────────────────────────────────────────────── export type AppPhase = | 'selecting' | 'loading_task' | 'ready' | 'executing' | 'reviewing'; export interface AppState { phase: AppPhase; appMode: AppMode; topic: Topic | null; task: Task | null; code: string; messages: Message[]; classroomMessages: Message[]; lessonContent: string | null; executionResult: ExecutionResult | null; streamingContent: string; isStreaming: boolean; error: string | null; responseMode: ResponseMode; } // ─── Auth ─────────────────────────────────────────────────────────────────── export interface AuthUser { id: string; email: string; } // ─── App Actions ─────────────────────────────────────────────────────────── export type AppAction = | { type: 'SELECT_TOPIC'; payload: Topic } | { type: 'TASK_STREAM_START' } | { type: 'TASK_STREAM_CHUNK'; payload: string } | { type: 'TASK_STREAM_DONE'; payload: Task } | { type: 'CODE_CHANGE'; payload: string } | { type: 'EXECUTE_START' } | { type: 'EXECUTE_DONE'; payload: ExecutionResult } | { type: 'REVIEW_START' } | { type: 'STREAM_CHUNK'; payload: string } | { type: 'STREAM_DONE'; payload: Message } | { type: 'SEND_USER_MESSAGE'; payload: string } | { type: 'SET_APP_MODE'; payload: AppMode } | { type: 'LESSON_STREAM_START' } | { type: 'LESSON_STREAM_DONE'; payload: string } | { type: 'SEND_CLASSROOM_MESSAGE'; payload: string } | { type: 'CLASSROOM_MESSAGE_DONE'; payload: Message } | { type: 'SET_ERROR'; payload: string } | { type: 'CLEAR_ERROR' } | { type: 'SET_RESPONSE_MODE'; payload: Partial } | { type: 'RESET' } | { type: 'RESTORE_SESSION'; payload: { topic: Topic; task: Task; code: string; messages: Message[]; executionResult: ExecutionResult | null; }; };