Skip to main content

useAgentSession

The useAgentSession hook manages AI agent sessions, including ticket exchange for impersonation, agent selection, and session validation.

Parameters

ticket
string | undefined
Optional ticket token for session exchange (typically from URL query param)

Return Value

hasSession
boolean
Whether a valid session exists
sessionLoading
boolean
Whether session data is loading
sessionError
Error | null
Any session error that occurred
sessionId
string | null
The current session ID
contextGroup
string | null
The context group for this session
agents
AgentWithIntegrations[]
Available agents for this session
activeAgent
AgentWithIntegrations | null
The currently selected agent
setActiveAgent
ticketExchanged
boolean
Whether the ticket has been exchanged
ticketLoading
boolean
Whether the ticket exchange is in progress
refetch

Behavior

  1. Ticket Exchange - If a ticket is provided, exchanges it for a session
  2. Agent Selection - Auto-selects the first available agent
  3. Session Refresh - Continues to validate and refresh the session

Data Structures

Examples

With Ticket Exchange

import { useAgentSession } from "@wacht/react-router";
import { useSearchParams } from "react-router";

function AgentChat() {
  const [searchParams, setSearchParams] = useSearchParams();
  const ticket = searchParams.get("ticket");

  const {
    sessionLoading,
    hasSession,
    agents,
    activeAgent,
    setActiveAgent,
    ticketExchanged,
  } = useAgentSession(ticket || undefined);

  // Clear ticket from URL after exchange
  if (ticket && ticketExchanged) {
    setSearchParams((params) => {
      params.delete("ticket");
      return params;
    });
  }

  if (sessionLoading) {
    return <div>Establishing session...</div>;
  }

  if (!hasSession) {
    return <div>Invalid or expired ticket</div>;
  }

  return (
    <div>
      <select onChange={(e) => setActiveAgent(agents[e.target.value])}>
        {agents.map((agent) => (
          <option key={agent.id} value={agent.id}>
            {agent.name}
          </option>
        ))}
      </select>
      <div>Selected: {activeAgent?.name}</div>
    </div>
  );
}

Agent Selector Dropdown

import { useAgentSession } from "@wacht/react-router";

function AgentSelector() {
  const { agents, activeAgent, setActiveAgent } = useAgentSession();

  return (
    <select
      value={activeAgent?.id || ""}
      onChange={(e) => {
        const agent = agents.find((a) => a.id === e.target.value);
        if (agent) setActiveAgent(agent);
      }}
    >
      {agents.map((agent) => (
        <option key={agent.id} value={agent.id}>
          {agent.name}
          {agent.description && ` - ${agent.description}`}
        </option>
      ))}
    </select>
  );
}

Session Provider Pattern

import { createContext, useContext } from "react";
import { useAgentSession } from "@wacht/react-router";

const AgentContext = createContext<{
  hasSession: boolean;
  agents: AgentWithIntegrations[];
  activeAgent: AgentWithIntegrations | null;
  setActiveAgent: (agent: AgentWithIntegrations) => void;
} | null>(null);

export function AgentProvider({ ticket, children }: { ticket?: string; children: React.ReactNode }) {
  const { hasSession, agents, activeAgent, setActiveAgent } = useAgentSession(ticket);

  return (
    <AgentContext.Provider value={{ hasSession, agents, activeAgent, setActiveAgent }}>
      {children}
    </AgentContext.Provider>
  );
}

export function useActiveAgent() {
  const context = useContext(AgentContext);
  if (!context) throw new Error("useActiveAgent must be used within AgentProvider");
  return context;
}