import { useCallback, useEffect, useRef } from "react"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { agentChatsApi } from "@/api/agentChats"; import { agentsApi } from "@/api/agents"; import { authApi } from "@/api/auth"; import { useCompany } from "@/context/CompanyContext"; import { useAgentChatEnabled } from "@/hooks/useAgentChatEnabled"; import { recordAgentChatVisit } from "@/lib/recent-agent-chats"; import { queryKeys } from "@/lib/queryKeys"; import { useParams } from "@/lib/router"; import { agentRouteRef } from "@/lib/utils"; import { TaskDetailSurface } from "./IssueDetail"; import { isUuidLike, type Issue } from "@paperclipai/shared"; export function AgentChat() { const { agentRef = "" } = useParams<{ agentRef: string }>(); const { selectedCompanyId } = useCompany(); const { enabled, loaded } = useAgentChatEnabled(); const client = useQueryClient(); const agents = useQuery({ queryKey: queryKeys.agents.list(selectedCompanyId!), queryFn: () => agentsApi.list(selectedCompanyId!), enabled: !!selectedCompanyId, }); const session = useQuery({ queryKey: queryKeys.auth.session, queryFn: () => authApi.getSession(), }); const userId = session.data?.user?.id ?? session.data?.session?.userId ?? null; const rosterAgent = agents.data?.find( (item) => item.id === agentRef || agentRouteRef(item) === agentRef, ); const historyAgent = useQuery({ queryKey: queryKeys.agents.detail(agentRef), queryFn: () => agentsApi.get(agentRef, selectedCompanyId!), enabled: enabled && !!selectedCompanyId && agents.isSuccess && !rosterAgent && isUuidLike(agentRef), }); const agent = rosterAgent ?? (historyAgent.data?.companyId === selectedCompanyId ? historyAgent.data : undefined); const chatKey = queryKeys.agentChats.detail(selectedCompanyId, userId, agent?.id); const chat = useQuery({ queryKey: chatKey, queryFn: () => agentChatsApi.get(selectedCompanyId!, agent!.id), enabled: enabled && !!agent && session.isFetched, }); const creating = useRef | null>(null); useEffect(() => { creating.current = null; }, [selectedCompanyId, userId, agent?.id]); useEffect(() => { if (enabled && agent && session.isSuccess && chat.isSuccess) recordAgentChatVisit(agent.companyId, userId, agent.id, chat.data?.id ?? null); }, [enabled, agent?.id, agent?.companyId, userId, session.isSuccess, chat.isSuccess, chat.data?.id]); const ensureIssue = useCallback(async () => { if (!agent || !selectedCompanyId) throw new Error("Agent not found"); if (chat.data) return chat.data; const promise = (creating.current ??= agentChatsApi.ensure( selectedCompanyId, agent.id, )); try { const issue = await promise; client.setQueryData(queryKeys.issues.detail(issue.id), issue); client.setQueryData(chatKey, issue); void client.invalidateQueries({ queryKey: queryKeys.agentChats.list(selectedCompanyId, userId) }); return issue; } catch (error) { creating.current = null; throw error; } }, [agent, selectedCompanyId, chat.data, client, userId]); if (!loaded || agents.isPending || session.isPending || historyAgent.isFetching && !agent) return (

Loading conversation…

); if (!enabled && !chat.data) return (

Agent Chat is disabled. Enable it in Experimental settings. Existing history remains available through task links.

); if (agents.error || chat.error || !rosterAgent && historyAgent.error) return (

{(agents.error ?? chat.error ?? historyAgent.error)?.message}

); if (!agent) return

Agent not found.

; if (chat.isPending) return (

Loading conversation…

); return ( ); }