11"use client" ;
22
3- import { useEffect , useState } from "react" ;
3+ import { useCallback , useEffect , useRef , useState } from "react" ;
44import { ExampleLayout } from "@/components/example-layout" ;
55import { useGenerativeUIExamples , useExampleSuggestions } from "@/hooks" ;
66import { ExplainerCardsPortal } from "@/components/explainer-cards" ;
@@ -21,10 +21,22 @@ export default function HomePage() {
2121 const { agent } = useAgent ( ) ;
2222 const { copilotkit } = useCopilotKit ( ) ;
2323
24+ // Ref to always have the latest agent/copilotkit for async callbacks
25+ const agentRef = useRef ( agent ) ;
26+ const copilotkitRef = useRef ( copilotkit ) ;
27+ agentRef . current = agent ;
28+ copilotkitRef . current = copilotkit ;
29+
30+ const sendPrompt = useCallback ( ( prompt : string ) => {
31+ const a = agentRef . current ;
32+ const ck = copilotkitRef . current ;
33+ a . addMessage ( { id : crypto . randomUUID ( ) , content : prompt , role : "user" } ) ;
34+ ck . runAgent ( { agent : a } ) ;
35+ } , [ ] ) ;
36+
2437 const handleTryDemo = ( demo : DemoItem ) => {
2538 setDemoDrawerOpen ( false ) ;
26- agent . addMessage ( { id : crypto . randomUUID ( ) , content : demo . prompt , role : "user" } ) ;
27- copilotkit . runAgent ( { agent } ) ;
39+ sendPrompt ( demo . prompt ) ;
2840 } ;
2941
3042 // Reset scan status when QR modal opens
@@ -35,26 +47,29 @@ export default function HomePage() {
3547 // Poll for QR pick status
3648 useEffect ( ( ) => {
3749 if ( ! qrOpen ) return ;
50+ let picked = false ;
3851 const interval = setInterval ( async ( ) => {
52+ if ( picked ) return ;
3953 try {
4054 const res = await fetch ( `/api/pick?sessionId=${ qrSessionId } ` ) ;
4155 const data = await res . json ( ) ;
4256 if ( data . status === "scanned" ) {
4357 setScanStatus ( "scanned" ) ;
4458 } else if ( data . status === "picked" && data . prompt ) {
59+ picked = true ;
4560 setScanStatus ( "picked" ) ;
61+ clearInterval ( interval ) ;
4662 setTimeout ( ( ) => {
4763 setQrOpen ( false ) ;
48- agent . addMessage ( { id : crypto . randomUUID ( ) , content : data . prompt , role : "user" } ) ;
49- copilotkit . runAgent ( { agent } ) ;
64+ sendPrompt ( data . prompt ) ;
5065 } , 800 ) ;
5166 }
5267 } catch {
5368 // ignore polling errors
5469 }
5570 } , 2000 ) ;
5671 return ( ) => clearInterval ( interval ) ;
57- } , [ qrOpen , qrSessionId , agent , copilotkit ] ) ;
72+ } , [ qrOpen , qrSessionId , sendPrompt ] ) ;
5873
5974 // Widget bridge: handle messages from widget iframes
6075 useEffect ( ( ) => {
0 commit comments