import { useAgent } from "agents/react"; import { useRef, useState, Suspense, useCallback } from "react"; import { createRoot } from "react-dom/client"; import "./styles.css"; interface Message { id: string; text: string; timestamp: Date; type: "incoming" | "outgoing"; } // Mock authentication service async function getAuthToken(): Promise { // Simulate API call delay await new Promise((resolve) => setTimeout(resolve, 500)); return "demo-token-123"; } async function getCurrentUser(): Promise<{ id: string; name: string }> { // Simulate user data fetch await new Promise((resolve) => setTimeout(resolve, 300)); return { id: "demo-user", name: "Demo User" }; } function AsyncAuthApp() { const [messages, setMessages] = useState([]); const inputRef = useRef(null); // Async authentication query const asyncQuery = useCallback(async () => { console.log("🔐 Fetching authentication data..."); const [token, user] = await Promise.all([getAuthToken(), getCurrentUser()]); console.log("✅ Auth data fetched:", { token, userId: user.id }); return { token, userId: user.id, timestamp: Date.now().toString() // Convert to string for WebSocket compatibility }; }, []); // Cross-domain WebSocket connection with async authentication using unified useAgent const agent = useAgent({ agent: "my-agent", host: "http://localhost:8787", query: asyncQuery, // Async function - automatically detected and cached onMessage: (message: MessageEvent) => { const newMessage: Message = { id: Math.random().toString(36).substring(7), text: message.data as string, timestamp: new Date(), type: "incoming" }; setMessages((prev) => [...prev, newMessage]); }, onError: (error: Event) => { console.error("WebSocket error:", error); } }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!inputRef.current || !inputRef.current.value.trim()) return; const text = inputRef.current.value; const newMessage: Message = { id: Math.random().toString(36).substring(7), text, timestamp: new Date(), type: "outgoing" }; agent.send(text); setMessages((prev) => [...prev, newMessage]); inputRef.current.value = ""; }; const handleFetchRequest = async () => { try { // Get fresh auth token for HTTP request const token = await getAuthToken(); const response = await fetch( "http://localhost:8787/agents/my-agent/default", { method: "GET", headers: { Authorization: `Bearer ${token}`, "X-API-Key": "demo-api-key" } } ); const data = await response.text(); const newMessage: Message = { id: Math.random().toString(36).substring(7), text: `HTTP Response: ${data}`, timestamp: new Date(), type: "incoming" }; setMessages((prev) => [...prev, newMessage]); } catch (error) { console.error("Error fetching from server:", error); const errorMessage: Message = { id: Math.random().toString(36).substring(7), text: `HTTP Error: ${error}`, timestamp: new Date(), type: "incoming" }; setMessages((prev) => [...prev, errorMessage]); } }; const formatTime = (date: Date) => { return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }); }; return (

Cross-Domain Authentication Demo (Async)

🚀 Async Authentication:

• Token fetched dynamically from auth service

• User data retrieved from API

• WebSocket connection waits for auth completion

• Uses React Suspense for loading states

🌐 Cross-Domain Setup:

• Client: {window.location.origin} (this page)

• Server: http://localhost:8787 (different port)

Messages

{messages.map((message) => (
{message.text}
{formatTime(message.timestamp)}
))}

Debug Information

Agent: {agent.agent}

Room: {agent.name}

); } function StaticAuthApp() { const [authToken, setAuthToken] = useState("demo-token-123"); const [messages, setMessages] = useState([]); const inputRef = useRef(null); const tokenInputRef = useRef(null); // Cross-domain WebSocket connection with static query parameter authentication const agent = useAgent({ agent: "my-agent", host: "http://localhost:8787", query: { token: authToken, // Authentication token (demo-token-123) userId: "demo-user" // User identifier for server validation }, onMessage: (message) => { const newMessage: Message = { id: Math.random().toString(36).substring(7), text: message.data as string, timestamp: new Date(), type: "incoming" }; setMessages((prev) => [...prev, newMessage]); }, onError: (error) => { console.error("WebSocket auth error:", error); } }); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!inputRef.current || !inputRef.current.value.trim()) return; const text = inputRef.current.value; const newMessage: Message = { id: Math.random().toString(36).substring(7), text, timestamp: new Date(), type: "outgoing" }; agent.send(text); setMessages((prev) => [...prev, newMessage]); inputRef.current.value = ""; }; const handleFetchRequest = async () => { const newMessage: Message = { id: Math.random().toString(36).substring(7), text: "", timestamp: new Date(), type: "incoming" }; try { // Cross-domain HTTP request with header-based authentication const response = await fetch( "http://localhost:8787/agents/my-agent/default", { method: "GET", headers: { Authorization: `Bearer ${authToken}` // Bearer token authentication } } ); const data = await response.text(); newMessage.text = `HTTP Response: ${data}`; } catch (error) { console.error("Error fetching from server:", error); newMessage.text = `HTTP Error: ${error}`; } finally { setMessages((prev) => [...prev, newMessage]); } }; const updateAuthToken = () => { if (tokenInputRef.current?.value) { setAuthToken(tokenInputRef.current.value); } }; const formatTime = (date: Date) => { return date.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" }); }; return (

Cross-Domain Authentication Demo

🌐 Cross-Domain Setup:

• Client: {window.location.origin} (this page)

• Server: http://localhost:8787 (different port)

🔗 WebSocket Auth: Query parameter (token= {authToken})

📡 HTTP Auth: Bearer token + API key in headers

🎯 Valid Token: "demo-token-123"

🎯 Valid API Key: "demo-api-key"

Messages

{messages.map((message) => (
{message.text}
{formatTime(message.timestamp)}
))}

Debug Information

Agent: {agent.agent}

Room: {agent.name}

Auth Token: {authToken}

); } function App() { const [useAsync, setUseAsync] = useState(false); return (

Cross-Domain Authentication Examples

Toggle between static authentication (useAgent) and async authentication (useAgent with async query)

🔐 Loading authentication...
Fetching auth token and user data...
} > {useAsync ? : } ); } const root = createRoot(document.getElementById("root")!); root.render();