'use client' import * as React from 'react' import { useRef, useEffect } from 'react' import { Loader2 } from 'lucide-react' import Markdown from 'react-markdown' import remarkGfm from 'remark-gfm' import { Button } from '@open-mercato/ui/primitives/button' import type { ToolInfo, ChatMessage, PendingToolCall, OpenCodeQuestion, AgentStatus } from '../../types' import { MessageBubble } from './MessageBubble' import { ToolCallConfirmation } from './ToolCallConfirmation' import { AgentStatusIndicator } from './AgentStatusIndicator' interface ToolChatPageProps { tool: ToolInfo | null // Can be null for general chat messages: ChatMessage[] pendingToolCalls: PendingToolCall[] isStreaming: boolean isThinking?: boolean agentStatus?: AgentStatus onApproveToolCall: (toolCallId: string) => Promise onRejectToolCall: (toolCallId: string) => void pendingQuestion?: OpenCodeQuestion | null onAnswerQuestion?: (answer: number) => Promise } export function ToolChatPage({ tool, messages, pendingToolCalls, isStreaming, isThinking = false, agentStatus = { type: 'idle' }, onApproveToolCall, onRejectToolCall, pendingQuestion, onAnswerQuestion, }: ToolChatPageProps) { const bottomRef = useRef(null) // Auto-scroll to bottom on new messages (debounced) useEffect(() => { const timeoutId = setTimeout(() => { bottomRef.current?.scrollIntoView({ behavior: 'smooth', block: 'end' }) }, 100) return () => clearTimeout(timeoutId) }, [messages, pendingToolCalls, isStreaming, isThinking, agentStatus, pendingQuestion]) return (
{/* Tool description header - only shown if tool is selected */} {tool && (

{tool.description}

)} {/* Chat messages */}
{messages.map((message) => ( ))} {/* Only show tool calls that require user action (pending dangerous tools or errors) */} {pendingToolCalls .filter((tc) => tc.status === 'pending' || tc.status === 'error') .map((toolCall) => ( onApproveToolCall(toolCall.id)} onReject={() => onRejectToolCall(toolCall.id)} /> ))} {/* OpenCode confirmation question */} {pendingQuestion && pendingQuestion.questions[0] && (
{pendingQuestion.questions[0].header || 'Confirmation Required'}
{pendingQuestion.questions[0].question}
{pendingQuestion.questions[0].options.map((option, index) => ( ))}
)} {/* Agent status indicator - shows what the agent is doing */} {!pendingQuestion && } {/* Scroll anchor */}
) }