diff --git a/apps/web/src/app/agents/[id]/chat/[chatId]/page.tsx b/apps/web/src/app/agents/[id]/chat/[chatId]/page.tsx index 99089d4..4788e0f 100644 --- a/apps/web/src/app/agents/[id]/chat/[chatId]/page.tsx +++ b/apps/web/src/app/agents/[id]/chat/[chatId]/page.tsx @@ -292,6 +292,7 @@ export default function PublicAgentChatPage(): React.ReactElement { }, [agent, conversationId]); // Load older messages when scrolling up + // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Virtuoso scroll handler with pagination logic const loadMoreMessages = useCallback(async () => { if (!agent || isLoadingMore || !hasMoreMessages || messages.length === 0) return; @@ -341,6 +342,7 @@ export default function PublicAgentChatPage(): React.ReactElement { } }, [agent, fetchMessages]); + // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Chat send handler with streaming and tool calls const handleSend = async () => { if (!input.trim() || !agent || isSending) return; @@ -730,234 +732,242 @@ export default function PublicAgentChatPage(): React.ReactElement { {/* Messages */}
{messages.length === 0 && !streamingContent ? ( -
-
-
- -
-

Start a conversation

-

- Send a message to start chatting with {agent.name}. -

-
-
- ) : ( - - hasMoreMessages ? ( -
- {isLoadingMore ? ( -
- - Loading older messages... -
- ) : ( - - )} +
+
+
+
- ) : null, - Footer: () => ( -
- {/* Live tool calls during streaming */} - {toolCalls.length > 0 && ( -
- {toolCalls.map((tc) => ( -
-
- toggleToolCall(tc.toolCallId)} - /> -
-
- ))} -
- )} - - {streamingContent && ( -
-
-

{streamingContent}

- -
-
- )} - - {isSending && !streamingContent && toolCalls.length === 0 && ( -
-
-
- - Thinking... -
-
-
- )} +

+ Start a conversation +

+

+ Send a message to start chatting with {agent.name}. +

- ), - }} - itemContent={(_index, message) => { - // Parse tool output safely - const getToolOutput = () => { - if (message.toolResult) return message.toolResult; - try { - return JSON.parse(message.content || '{}'); - } catch { - return { result: message.content }; - } - }; - - // Build a lookup map for tool call inputs from ASSISTANT messages - // This allows us to show the input args when rendering TOOL messages - const getToolCallInput = (toolCallId: string): unknown => { - for (const msg of messages) { - if (msg.role === 'ASSISTANT' && msg.toolCalls) { - const tc = msg.toolCalls.find((t) => t.toolCallId === toolCallId); - if (tc) return tc.args; - } - } - return undefined; - }; - - // Check if a tool call has a corresponding TOOL message (meaning it completed) - const hasToolResult = (toolCallId: string): boolean => { - return messages.some((m) => m.role === 'TOOL' && m.toolCallId === toolCallId); - }; - - return ( -
- {/* TOOL message - shows the result of a tool call */} - {message.role === 'TOOL' && ( -
-
- toggleToolCall(message.toolCallId || message.id)} - /> -
-
- )} - - {/* USER message */} - {message.role === 'USER' && ( -
-
-

{message.content}

-
-
- )} - - {/* ASSISTANT message - may contain text and/or tool calls */} - {message.role === 'ASSISTANT' && ( -
- {/* Assistant text content */} - {message.content && ( -
-
-

{message.content}

- {/* Token usage for debugging */} - {(message.inputTokens || message.outputTokens) && ( -
- {message.inputTokens && In: {message.inputTokens}} - {message.inputTokens && message.outputTokens && ( - - )} - {message.outputTokens && ( - Out: {message.outputTokens} - )} -
- )} +
+ ) : ( + + hasMoreMessages ? ( +
+ {isLoadingMore ? ( +
+ + Loading older messages...
-
- )} - - {/* Show tool calls from this assistant message that don't have results yet */} - {message.toolCalls && - message.toolCalls - .filter((tc) => !hasToolResult(tc.toolCallId)) - .map((tc) => ( + ) : ( + + )} +
+ ) : null, + Footer: () => ( +
+ {/* Live tool calls during streaming */} + {toolCalls.length > 0 && ( +
+ {toolCalls.map((tc) => (
toggleToolCall(tc.toolCallId)} />
))} +
+ )} + + {streamingContent && ( +
+
+

{streamingContent}

+ +
+
+ )} + + {isSending && !streamingContent && toolCalls.length === 0 && ( +
+
+
+ + Thinking... +
+
+
+ )}
- )} -
- ); - }} - /> - )} -
+ ), + }} + itemContent={(_index, message) => { + // Parse tool output safely + const getToolOutput = () => { + if (message.toolResult) return message.toolResult; + try { + return JSON.parse(message.content || '{}'); + } catch { + return { result: message.content }; + } + }; - {/* Error Message */} - {error && ( -
-

{error}

-
- )} + // Build a lookup map for tool call inputs from ASSISTANT messages + // This allows us to show the input args when rendering TOOL messages + // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Helper in virtuoso render callback + const getToolCallInput = (toolCallId: string): unknown => { + for (const msg of messages) { + if (msg.role === 'ASSISTANT' && msg.toolCalls) { + const tc = msg.toolCalls.find((t) => t.toolCallId === toolCallId); + if (tc) return tc.args; + } + } + return undefined; + }; - {/* Input Area */} -
-
-