11"use client" ;
22
3- import { useState , useEffect , useRef } from "react" ;
3+ import { useState , useEffect , useRef , useCallback } from "react" ;
44import MessageList from "./MessageList" ;
55import MessageInput from "./MessageInput" ;
66import { useSearchParams } from "next/navigation" ;
@@ -27,21 +27,33 @@ export default function ChatInterface() {
2727 const [ loading , setLoading ] = useState < boolean > ( false ) ;
2828 const [ serverStatus , setServerStatus ] = useState < string > ( "unknown" ) ;
2929 const searchParams = useSearchParams ( ) ;
30- // null port gets converted to NaN
31- const parsedPort = parseInt ( searchParams . get ( "port" ) as string ) ;
32- // We're setting port via URL query param, not directly with setPort
33- // eslint-disable-next-line @typescript-eslint/no-unused-vars
34- const [ port , setPort ] = useState < number > (
35- isNaN ( parsedPort ) ? 3284 : parsedPort
36- ) ;
37- const [ portInput , setPortInput ] = useState < string > ( port . toString ( ) ) ;
38- const AgentAPIUrl = `http://localhost:${ port } ` ;
30+
31+ const getAgentApiUrl = useCallback ( ( ) => {
32+ const apiUrlFromParam = searchParams . get ( "url" ) ;
33+ if ( apiUrlFromParam ) {
34+ try {
35+ // Validate if it's a proper URL
36+ new URL ( apiUrlFromParam ) ;
37+ return apiUrlFromParam ;
38+ } catch ( e ) {
39+ console . warn ( "Invalid url parameter, defaulting..." , e ) ;
40+ // Fallback if parsing fails or it's not a valid URL.
41+ // Ensure window is defined (for SSR/Node.js environments during build)
42+ return typeof window !== "undefined" ? window . location . origin : "" ;
43+ }
44+ }
45+ // Ensure window is defined
46+ return typeof window !== "undefined" ? window . location . origin : "" ;
47+ } , [ searchParams ] ) ;
48+
49+ const [ agentAPIUrl , setAgentAPIUrl ] = useState < string > ( getAgentApiUrl ( ) ) ;
50+
3951 const eventSourceRef = useRef < EventSource | null > ( null ) ;
4052
41- // Update portInput when port changes
53+ // Update agentAPIUrl when searchParams change (e.g. url is added/removed)
4254 useEffect ( ( ) => {
43- setPortInput ( port . toString ( ) ) ;
44- } , [ port ] ) ;
55+ setAgentAPIUrl ( getAgentApiUrl ( ) ) ;
56+ } , [ getAgentApiUrl , searchParams ] ) ;
4557
4658 // Set up SSE connection to the events endpoint
4759 useEffect ( ( ) => {
@@ -54,7 +66,15 @@ export default function ChatInterface() {
5466 // Reset messages when establishing a new connection
5567 setMessages ( [ ] ) ;
5668
57- const eventSource = new EventSource ( `${ AgentAPIUrl } /events` ) ;
69+ if ( ! agentAPIUrl ) {
70+ console . warn (
71+ "agentAPIUrl is not set, SSE connection cannot be established."
72+ ) ;
73+ setServerStatus ( "offline" ) ; // Or some other appropriate status
74+ return null ; // Don't try to connect if URL is empty
75+ }
76+
77+ const eventSource = new EventSource ( `${ agentAPIUrl } /events` ) ;
5878 eventSourceRef . current = eventSource ;
5979
6080 // Handle message updates
@@ -122,9 +142,12 @@ export default function ChatInterface() {
122142
123143 // Clean up on component unmount
124144 return ( ) => {
125- eventSource . close ( ) ;
145+ if ( eventSource ) {
146+ // Check if eventSource was successfully created
147+ eventSource . close ( ) ;
148+ }
126149 } ;
127- } , [ AgentAPIUrl ] ) ;
150+ } , [ agentAPIUrl ] ) ;
128151
129152 const [ error , setError ] = useState < string | null > ( null ) ;
130153
@@ -145,7 +168,7 @@ export default function ChatInterface() {
145168 }
146169
147170 try {
148- const response = await fetch ( `${ AgentAPIUrl } /message` , {
171+ const response = await fetch ( `${ agentAPIUrl } /message` , {
149172 method : "POST" ,
150173 headers : {
151174 "Content-Type" : "application/json" ,
@@ -193,40 +216,11 @@ export default function ChatInterface() {
193216 }
194217 } ;
195218
196- const updatePort = ( ) => {
197- const newPort = parseInt ( portInput ) ;
198- if ( ! isNaN ( newPort ) && newPort > 0 && newPort < 65536 ) {
199- window . location . href = `?port=${ newPort } ` ;
200- } else {
201- setError ( "Invalid port number. Please enter a number between 1-65535." ) ;
202- setTimeout ( ( ) => setError ( null ) , 5000 ) ;
203- }
204- } ;
205-
206219 return (
207220 < div className = "flex flex-col h-[80vh] bg-gray-100 rounded-lg overflow-hidden border border-gray-300 shadow-lg w-full max-w-[95vw]" >
208221 < div className = "p-3 bg-gray-800 text-white text-sm flex items-center justify-between" >
209222 < span > AgentAPI Chat</ span >
210223 < div className = "flex items-center space-x-3" >
211- < div className = "flex items-center" >
212- < label htmlFor = "port-input" className = "text-white mr-1" >
213- Port:
214- </ label >
215- < input
216- id = "port-input"
217- type = "text"
218- value = { portInput }
219- onChange = { ( e ) => setPortInput ( e . target . value ) }
220- className = "w-16 px-1 py-0.5 text-xs rounded border border-gray-400 bg-gray-700 text-white"
221- onKeyDown = { ( e ) => e . key === "Enter" && updatePort ( ) }
222- />
223- < button
224- onClick = { updatePort }
225- className = "ml-1 px-2 py-0.5 text-xs bg-gray-600 hover:bg-gray-500 rounded"
226- >
227- Apply
228- </ button >
229- </ div >
230224 < div className = "flex items-center" >
231225 < span
232226 className = { `w-2 h-2 rounded-full mr-2 ${
@@ -256,9 +250,8 @@ export default function ChatInterface() {
256250 />
257251 </ svg >
258252 < span >
259- API server is offline. Please start the AgentAPI server on
260- localhost:
261- { port } .
253+ API server is offline. Please start the AgentAPI server.
254+ Attempting to connect to: { agentAPIUrl || "N/A" } .
262255 </ span >
263256 </ div >
264257 < button
0 commit comments