Skip to content

Commit d6a877c

Browse files
Alex HolmbergAlex Holmberg
authored andcommitted
fix(23-01): use CopilotChat component instead of headless API
- Replaced custom useCopilotChat implementation with pre-built CopilotChat - CopilotChat handles message types and streaming internally - Imported CopilotKit styles for proper UI rendering
1 parent 3627bf8 commit d6a877c

1 file changed

Lines changed: 16 additions & 110 deletions

File tree

tests/ag-ui-app/frontend/src/routes/agent.tsx

Lines changed: 16 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,20 @@
22
* Agent Chat Route
33
*
44
* Demonstrates CopilotKit integration with syncable-cli AG-UI server.
5-
* Uses CopilotKit's built-in chat components for agent conversations.
5+
* Uses CopilotKit's built-in CopilotChat component for conversations.
66
*/
77
import { createFileRoute } from "@tanstack/react-router";
8-
import { useState, useCallback, FormEvent } from "react";
9-
import { useCopilotChat } from "@copilotkit/react-core";
10-
import { MessageCircle, Send, Loader2, Bot, User, Terminal } from "lucide-react";
8+
import { CopilotChat } from "@copilotkit/react-ui";
9+
import { Bot, Terminal } from "lucide-react";
10+
11+
// Import CopilotKit styles
12+
import "@copilotkit/react-ui/styles.css";
1113

1214
export const Route = createFileRoute("/agent")({
1315
component: AgentChat,
1416
});
1517

1618
function AgentChat() {
17-
const [input, setInput] = useState("");
18-
19-
const {
20-
visibleMessages,
21-
appendMessage,
22-
isLoading,
23-
} = useCopilotChat();
24-
25-
const handleSubmit = useCallback(
26-
async (e: FormEvent) => {
27-
e.preventDefault();
28-
if (!input.trim() || isLoading) return;
29-
30-
const message = input.trim();
31-
setInput("");
32-
33-
// Append user message and trigger agent response
34-
await appendMessage({
35-
id: crypto.randomUUID(),
36-
role: "user",
37-
content: message,
38-
});
39-
},
40-
[input, isLoading, appendMessage]
41-
);
42-
4319
return (
4420
<main className="min-h-screen bg-slate-950 relative overflow-hidden">
4521
{/* Background */}
@@ -53,7 +29,7 @@ function AgentChat() {
5329
<div className="p-3 rounded-2xl bg-linear-to-br from-emerald-500/20 to-cyan-600/20 border border-emerald-500/30 shadow-[0_0_30px_rgba(16,185,129,0.15)]">
5430
<Bot className="w-8 h-8 text-emerald-400" />
5531
</div>
56-
<h1 className="text-4xl font-bold tracking-tight bg-gradient-to-r from-emerald-400 via-cyan-400 to-blue-400 bg-clip-text text-transparent">
32+
<h1 className="text-4xl font-bold tracking-tight bg-linear-to-r from-emerald-400 via-cyan-400 to-blue-400 bg-clip-text text-transparent">
5733
Agent Chat
5834
</h1>
5935
</div>
@@ -64,85 +40,15 @@ function AgentChat() {
6440
</header>
6541

6642
{/* Chat Container */}
67-
<div className="bg-slate-900/50 border border-slate-800 rounded-2xl overflow-hidden">
68-
{/* Messages Area */}
69-
<div className="h-[500px] overflow-y-auto p-4 space-y-4">
70-
{visibleMessages.length === 0 ? (
71-
<div className="flex flex-col items-center justify-center h-full text-slate-500">
72-
<MessageCircle className="w-12 h-12 mb-4 opacity-50" />
73-
<p className="text-sm">No messages yet. Start a conversation!</p>
74-
</div>
75-
) : (
76-
visibleMessages.map((message) => (
77-
<div
78-
key={message.id}
79-
className={`flex gap-3 ${
80-
message.role === "user" ? "justify-end" : "justify-start"
81-
}`}
82-
>
83-
{message.role !== "user" && (
84-
<div className="flex-shrink-0 w-8 h-8 rounded-lg bg-emerald-500/20 flex items-center justify-center">
85-
<Bot className="w-4 h-4 text-emerald-400" />
86-
</div>
87-
)}
88-
<div
89-
className={`max-w-[80%] rounded-2xl px-4 py-3 ${
90-
message.role === "user"
91-
? "bg-cyan-600/20 border border-cyan-500/30 text-cyan-100"
92-
: "bg-slate-800/50 border border-slate-700/50 text-slate-200"
93-
}`}
94-
>
95-
<p className="text-sm whitespace-pre-wrap">{message.content}</p>
96-
</div>
97-
{message.role === "user" && (
98-
<div className="flex-shrink-0 w-8 h-8 rounded-lg bg-cyan-500/20 flex items-center justify-center">
99-
<User className="w-4 h-4 text-cyan-400" />
100-
</div>
101-
)}
102-
</div>
103-
))
104-
)}
105-
106-
{/* Loading indicator */}
107-
{isLoading && (
108-
<div className="flex gap-3 justify-start">
109-
<div className="flex-shrink-0 w-8 h-8 rounded-lg bg-emerald-500/20 flex items-center justify-center">
110-
<Bot className="w-4 h-4 text-emerald-400" />
111-
</div>
112-
<div className="bg-slate-800/50 border border-slate-700/50 rounded-2xl px-4 py-3">
113-
<div className="flex items-center gap-2 text-slate-400">
114-
<Loader2 className="w-4 h-4 animate-spin" />
115-
<span className="text-sm">Agent is thinking...</span>
116-
</div>
117-
</div>
118-
</div>
119-
)}
120-
</div>
121-
122-
{/* Input Area */}
123-
<form onSubmit={handleSubmit} className="border-t border-slate-800 p-4">
124-
<div className="flex gap-3">
125-
<input
126-
type="text"
127-
value={input}
128-
onChange={(e) => setInput(e.target.value)}
129-
placeholder="Type your message..."
130-
className="flex-1 bg-slate-800/50 border border-slate-700 rounded-xl px-4 py-3 text-slate-100 placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-cyan-500/50 focus:border-cyan-500/50 transition-all"
131-
disabled={isLoading}
132-
/>
133-
<button
134-
type="submit"
135-
disabled={!input.trim() || isLoading}
136-
className="px-6 py-3 rounded-xl bg-gradient-to-r from-emerald-500 to-cyan-500 text-white font-medium shadow-lg shadow-emerald-500/25 hover:shadow-emerald-500/40 hover:scale-105 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100 transition-all duration-200 flex items-center gap-2"
137-
>
138-
{isLoading ? (
139-
<Loader2 className="w-5 h-5 animate-spin" />
140-
) : (
141-
<Send className="w-5 h-5" />
142-
)}
143-
</button>
144-
</div>
145-
</form>
43+
<div className="bg-slate-900/50 border border-slate-800 rounded-2xl overflow-hidden h-[500px]">
44+
<CopilotChat
45+
className="h-full"
46+
labels={{
47+
title: "Syncable Agent",
48+
initial: "Hi! I'm the Syncable agent. How can I help you today?",
49+
placeholder: "Type your message...",
50+
}}
51+
/>
14652
</div>
14753

14854
{/* Connection Info */}

0 commit comments

Comments
 (0)