'use client'; import type { ReactElement } from 'react'; import type { Message } from '@/lib/types/http'; import { ChatMessage } from '@/components/task/chat/messages/chat-message'; import { PermissionRequestMessage } from '@/components/task/chat/messages/permission-request-message'; import { StatusMessage } from '@/components/task/chat/messages/status-message'; import { ToolCallMessage } from '@/components/task/chat/messages/tool-call-message'; import { ThinkingMessage } from '@/components/task/chat/messages/thinking-message'; import { TodoMessage } from '@/components/task/chat/messages/todo-message'; type AdapterContext = { isTaskDescription: boolean; taskId?: string; permissionsByToolCallId?: Map; }; type MessageAdapter = { matches: (comment: Message, ctx: AdapterContext) => boolean; render: (comment: Message, ctx: AdapterContext) => ReactElement; }; const adapters: MessageAdapter[] = [ { matches: (comment) => comment.type === 'thinking', render: (comment) => , }, { matches: (comment) => comment.type === 'todo', render: (comment) => , }, { matches: (comment) => comment.type === 'tool_call', render: (comment, ctx) => { const toolCallId = (comment.metadata as { tool_call_id?: string } | undefined)?.tool_call_id; const permissionMessage = toolCallId ? ctx.permissionsByToolCallId?.get(toolCallId) : undefined; return ; }, }, { matches: (comment) => comment.type === 'error' || comment.type === 'status' || comment.type === 'progress', render: (comment) => , }, { // Standalone permission requests (no matching tool call) matches: (comment) => comment.type === 'permission_request', render: (comment) => , }, { matches: () => true, render: (comment, ctx) => { if (ctx.isTaskDescription) { return ( ); } if (comment.author_type === 'user') { return ( ); } return ( ); }, }, ]; type MessageRendererProps = { comment: Message; isTaskDescription: boolean; taskId?: string; permissionsByToolCallId?: Map; }; export function MessageRenderer({ comment, isTaskDescription, taskId, permissionsByToolCallId }: MessageRendererProps) { const ctx = { isTaskDescription, taskId, permissionsByToolCallId }; const adapter = adapters.find((entry) => entry.matches(comment, ctx)) ?? adapters[adapters.length - 1]; return adapter.render(comment, ctx); }