Use proper chat widget instead of sidebar

This commit is contained in:
Yiorgis Gozadinos 2025-10-17 14:16:38 +03:00
parent 2d86c0fd61
commit cc3d1c7e43
No known key found for this signature in database
2 changed files with 106 additions and 74 deletions

View file

@ -5,7 +5,7 @@ import {
useCoAgent, useCoAgent,
useCoAgentStateRender, useCoAgentStateRender,
} from "@copilotkit/react-core"; } from "@copilotkit/react-core";
import { CopilotSidebar } from "@copilotkit/react-ui"; import { CopilotChat } from "@copilotkit/react-ui";
import "@copilotkit/react-ui/styles.css"; import "@copilotkit/react-ui/styles.css";
import StateDisplay from "./StateDisplay"; import StateDisplay from "./StateDisplay";
@ -113,50 +113,24 @@ function AgentContent() {
}); });
return ( return (
<>
<style>{`
.chat-container {
width: 50%;
height: 100vh;
border-right: 1px solid #e2e8f0;
display: flex;
flex-direction: column;
}
.chat-container > * {
flex: 1;
min-height: 0;
}
`}</style>
<div style={{ display: "flex", height: "100vh" }}> <div style={{ display: "flex", height: "100vh" }}>
<div {/* Chat on the left */}
style={{ <div className="chat-container">
flex: 1, <CopilotChat
padding: "2rem",
overflow: "auto",
}}
>
<div
style={{
maxWidth: "800px",
margin: "0 auto",
}}
>
<header style={{ marginBottom: "2rem" }}>
<h1
style={{
fontSize: "2.5rem",
fontWeight: "bold",
marginBottom: "0.5rem",
color: "#1a202c",
}}
>
Haiku.rag Research Assistant
</h1>
<p
style={{
fontSize: "1.125rem",
color: "#4a5568",
lineHeight: "1.6",
}}
>
Interactive research powered by <strong>Haiku.rag</strong>,{" "}
<strong>Pydantic AI</strong>, and <strong>AG-UI</strong>
</p>
</header>
<StateDisplay state={state} />
</div>
</div>
<CopilotSidebar
defaultOpen={true}
clickOutsideToClose={false}
labels={{ labels={{
title: "Research Assistant", title: "Research Assistant",
initial: initial:
@ -164,6 +138,44 @@ function AgentContent() {
}} }}
/> />
</div> </div>
{/* State display on the right */}
<div
style={{
width: "50%",
height: "100vh",
overflow: "auto",
background: "#f7fafc",
}}
>
<div style={{ padding: "2rem" }}>
<header style={{ marginBottom: "2rem" }}>
<h1
style={{
fontSize: "2rem",
fontWeight: "bold",
marginBottom: "0.5rem",
color: "#1a202c",
}}
>
Research State
</h1>
<p
style={{
fontSize: "0.875rem",
color: "#4a5568",
lineHeight: "1.6",
}}
>
Live updates from the research agent
</p>
</header>
<StateDisplay state={state} />
</div>
</div>
</div>
</>
); );
} }

View file

@ -70,28 +70,22 @@ export default function StateDisplay({ state }: StateDisplayProps) {
const currentPhaseIndex = phases.indexOf(state.phase); const currentPhaseIndex = phases.indexOf(state.phase);
return ( return (
<div
style={{
display: "flex",
flexDirection: "column",
gap: "1rem",
}}
>
{/* Phase Progress */}
<div <div
style={{ style={{
background: "white", background: "white",
borderRadius: "8px", borderRadius: "8px",
padding: "1.5rem", padding: "1.5rem",
boxShadow: "0 1px 3px rgba(0,0,0,0.1)", boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
marginTop: "2rem",
}} }}
> >
<h2
style={{
fontSize: "1.5rem",
fontWeight: "600",
marginBottom: "1rem",
color: "#2d3748",
}}
>
Research State
</h2>
{/* Phase Progress */}
<div style={{ marginBottom: "2rem" }}>
<div <div
style={{ style={{
fontSize: "0.875rem", fontSize: "0.875rem",
@ -144,11 +138,10 @@ export default function StateDisplay({ state }: StateDisplayProps) {
{state.question && ( {state.question && (
<div <div
style={{ style={{
padding: "1rem", background: "white",
background: "#f7fafc", borderRadius: "8px",
borderRadius: "4px", padding: "1.5rem",
border: "1px solid #e2e8f0", boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
marginBottom: "1rem",
}} }}
> >
<div <div
@ -176,11 +169,10 @@ export default function StateDisplay({ state }: StateDisplayProps) {
{state.confidence > 0 && ( {state.confidence > 0 && (
<div <div
style={{ style={{
padding: "1rem", background: "white",
background: "#f7fafc", borderRadius: "8px",
borderRadius: "4px", padding: "1.5rem",
border: "1px solid #e2e8f0", boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
marginBottom: "1rem",
}} }}
> >
<div <div
@ -236,7 +228,14 @@ export default function StateDisplay({ state }: StateDisplayProps) {
{/* Research Plan */} {/* Research Plan */}
{state.plan.length > 0 && ( {state.plan.length > 0 && (
<div style={{ marginBottom: "1rem" }}> <div
style={{
background: "white",
borderRadius: "8px",
boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
overflow: "hidden",
}}
>
<button <button
type="button" type="button"
onClick={() => toggleSection("plan")} onClick={() => toggleSection("plan")}
@ -317,7 +316,14 @@ export default function StateDisplay({ state }: StateDisplayProps) {
{/* Current Search Results */} {/* Current Search Results */}
{state.current_search && ( {state.current_search && (
<div style={{ marginBottom: "1rem" }}> <div
style={{
background: "white",
borderRadius: "8px",
boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
overflow: "hidden",
}}
>
<button <button
type="button" type="button"
onClick={() => toggleSection("search")} onClick={() => toggleSection("search")}
@ -440,7 +446,14 @@ export default function StateDisplay({ state }: StateDisplayProps) {
{/* Insights */} {/* Insights */}
{state.insights.length > 0 && ( {state.insights.length > 0 && (
<div style={{ marginBottom: "1rem" }}> <div
style={{
background: "white",
borderRadius: "8px",
boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
overflow: "hidden",
}}
>
<button <button
type="button" type="button"
onClick={() => toggleSection("insights")} onClick={() => toggleSection("insights")}
@ -528,7 +541,14 @@ export default function StateDisplay({ state }: StateDisplayProps) {
{/* Final Report */} {/* Final Report */}
{state.final_report && ( {state.final_report && (
<div> <div
style={{
background: "white",
borderRadius: "8px",
boxShadow: "0 1px 3px rgba(0,0,0,0.1)",
overflow: "hidden",
}}
>
<button <button
type="button" type="button"
onClick={() => toggleSection("report")} onClick={() => toggleSection("report")}