22
33import { useParams , useSearchParams , useRouter } from "next/navigation" ;
44import { useRealtimeRun , useRealtimeStream } from "@trigger.dev/react-hooks" ;
5- import { Card , CardContent , CardDescription , CardHeader , CardTitle } from "@/components/ui/card" ;
5+ import {
6+ Card ,
7+ CardContent ,
8+ CardDescription ,
9+ CardHeader ,
10+ CardTitle ,
11+ } from "@/components/ui/card" ;
612import { Button } from "@/components/ui/button" ;
713import { Progress } from "@/components/ui/progress" ;
814import { Alert , AlertDescription } from "@/components/ui/alert" ;
9- import { ArrowLeft , AlertCircle , CheckCircle , Loader2 , XCircle } from "lucide-react" ;
15+ import {
16+ ArrowLeft ,
17+ AlertCircle ,
18+ CheckCircle ,
19+ Loader2 ,
20+ XCircle ,
21+ Terminal ,
22+ FileText ,
23+ } from "lucide-react" ;
1024import { agentStream } from "@/trigger/agent-stream" ;
1125import { analyzeRepo } from "@/trigger/analyze-repo" ;
1226import { useState } from "react" ;
1327import ReactMarkdown from "react-markdown" ;
28+ import type { SDKMessage } from "@anthropic-ai/claude-agent-sdk" ;
1429
1530export default function ResponsePage ( ) {
1631 const params = useParams ( ) ;
@@ -30,7 +45,7 @@ export default function ResponsePage() {
3045 // Subscribe to agent stream
3146 const { parts, error : streamError } = useRealtimeStream ( agentStream , runId , {
3247 accessToken,
33- throttleInMs : 100 ,
48+ timeoutInSeconds : 60 ,
3449 } ) ;
3550
3651 const handleAbort = async ( ) => {
@@ -55,27 +70,6 @@ export default function ResponsePage() {
5570 router . push ( "/" ) ;
5671 } ;
5772
58- // Extract text content from agent messages
59- const getResponseText = ( ) => {
60- if ( ! parts || parts . length === 0 ) return "" ;
61-
62- return parts
63- . filter ( ( part : any ) => part . type === "assistant" && part . message ?. content )
64- . map ( ( part : any ) => {
65- const content = part . message . content ;
66- if ( Array . isArray ( content ) ) {
67- return content
68- . filter ( ( c : any ) => c . type === "text" )
69- . map ( ( c : any ) => c . text )
70- . join ( "" ) ;
71- }
72- return "" ;
73- } )
74- . join ( "\n\n" ) ;
75- } ;
76-
77- const responseText = getResponseText ( ) ;
78-
7973 // Determine status
8074 const getStatus = ( ) => {
8175 if ( runError || streamError ) return "error" ;
@@ -107,11 +101,7 @@ export default function ResponsePage() {
107101 < div className = "container mx-auto px-4 py-8 max-w-4xl" >
108102 { /* Header */ }
109103 < div className = "mb-8" >
110- < Button
111- variant = "ghost"
112- onClick = { handleNewQuestion }
113- className = "mb-4"
114- >
104+ < Button variant = "ghost" onClick = { handleNewQuestion } className = "mb-4" >
115105 < ArrowLeft className = "w-4 h-4 mr-2" />
116106 Ask Another Question
117107 </ Button >
@@ -128,15 +118,21 @@ export default function ResponsePage() {
128118 < Card className = "mb-6" >
129119 < CardHeader >
130120 < CardTitle className = "flex items-center gap-2" >
131- { status === "loading" && < Loader2 className = "w-5 h-5 animate-spin" /> }
132- { status === "running" && < Loader2 className = "w-5 h-5 animate-spin text-blue-500" /> }
133- { status === "completed" && < CheckCircle className = "w-5 h-5 text-green-500" /> }
134- { status === "error" && < XCircle className = "w-5 h-5 text-red-500" /> }
121+ { status === "loading" && (
122+ < Loader2 className = "w-5 h-5 animate-spin" />
123+ ) }
124+ { status === "running" && (
125+ < Loader2 className = "w-5 h-5 animate-spin text-blue-500" />
126+ ) }
127+ { status === "completed" && (
128+ < CheckCircle className = "w-5 h-5 text-green-500" />
129+ ) }
130+ { status === "error" && (
131+ < XCircle className = "w-5 h-5 text-red-500" />
132+ ) }
135133 Analysis Status
136134 </ CardTitle >
137- < CardDescription >
138- { statusText }
139- </ CardDescription >
135+ < CardDescription > { statusText } </ CardDescription >
140136 </ CardHeader >
141137 < CardContent >
142138 < Progress value = { progress } className = "mb-2" />
@@ -171,25 +167,39 @@ export default function ResponsePage() {
171167 < Alert variant = "destructive" className = "mb-6" >
172168 < AlertCircle className = "h-4 w-4" />
173169 < AlertDescription >
174- { metadata ?. error || runError ?. message || streamError ?. message || "An error occurred during analysis" }
170+ { metadata ?. error ||
171+ runError ?. message ||
172+ streamError ?. message ||
173+ "An error occurred during analysis" }
175174 </ AlertDescription >
176175 </ Alert >
177176 ) }
178177
179178 { /* Response Content */ }
180- { responseText && (
179+ { parts && parts . length > 0 && (
181180 < Card >
182181 < CardHeader >
183182 < CardTitle > Analysis Result</ CardTitle >
183+ < CardDescription >
184+ Claude is analyzing your repository. Tool usage is shown in
185+ collapsible sections.
186+ </ CardDescription >
184187 </ CardHeader >
185- < CardContent >
186- < div className = "prose prose-sm dark:prose-invert max-w-none " >
187- < ReactMarkdown > { responseText } </ ReactMarkdown >
188- </ div >
189- </ CardContent >
188+ { parts . map ( ( part , i ) => (
189+ < CardContent key = { i } className = "space-y-4 " >
190+ { part }
191+ </ CardContent >
192+ ) ) }
190193 </ Card >
191194 ) }
192195
196+ { /* Show message count for debugging */ }
197+ { parts && (
198+ < div className = "mt-4 text-xs text-muted-foreground text-center" >
199+ Received { parts . length } messages
200+ </ div >
201+ ) }
202+
193203 { /* Completion Actions */ }
194204 { status === "completed" && (
195205 < div className = "mt-6 text-center" >
@@ -201,4 +211,4 @@ export default function ResponsePage() {
201211 </ div >
202212 </ div >
203213 ) ;
204- }
214+ }
0 commit comments