"use client"; import { useState } from "react"; import Chat from "@/components/chat"; import { CopilotChatConfigurationProvider, CopilotThreadsDrawer, CopilotKitProvider, } from "@copilotkit/react-core/v2"; import styles from "./page.module.css"; export type ResearchData = { topic: string; summary: string; findings: Array<{ title: string; description: string; }>; sources: string; }; export type AnalysisData = { topic: string; overview: string; insights: Array<{ title: string; description: string; importance: string; }>; conclusion: string; }; // Disable static optimization for this page export const dynamic = "force-dynamic"; function ResearchAssistant() { const [researchData, setResearchData] = useState(null); const [analysisData, setAnalysisData] = useState(null); return (
{/* Background blur circles - Creating the gradient effect */}

Research Assistant

Multi-Agent A2A Demo:{" "} 1 LangGraph{" "} + 1 ADK{" "} agent

Orchestrator-mediated A2A Protocol

Research Results

Multi-agent coordination: LangGraph + ADK agents with A2A Protocol

{!researchData && !analysisData && (
🔍

Start Your Research

Ask the assistant to research any topic. Watch as 2 specialized agents collaborate through A2A Protocol to gather information and provide insights.

)}
{researchData && (
📚

{researchData.topic}

🔗 Research Agent

Key Points

{researchData.summary}

{researchData.findings.map((finding, index) => (

{finding.title}

{finding.description}

))}

{researchData.sources}

)} {analysisData && (
💡

{analysisData.topic}

✨ Analysis Agent

Insights and Analysis

{analysisData.overview}

{analysisData.insights.map((insight, index) => (

{insight.title}

{insight.description}

💡 {insight.importance}

))}

Conclusion

{analysisData.conclusion}

)}
); } export default function Home() { return ( {/* One UNCONTROLLED CopilotChatConfigurationProvider (no `threadId` prop) owns the active thread for the whole surface. The SDK drives it directly — picking a row sets the active thread, "+ New" resets to a fresh thread — with no host thread-state. The chat (inside ResearchAssistant) reads the same active thread from the provider. A *controlled* provider would block "+ New" from resetting, so uncontrolled-inside-provider is required, not optional. */}
{/* SDK threads drawer (replaces the hand-rolled fork). License-gated: the locked view's Upgrade CTA opens the Intelligence docs by default. */}
); }