ui starting point

This commit is contained in:
2025-12-07 09:20:51 -07:00
parent 176c4344de
commit 53db70fc29
2 changed files with 19 additions and 161 deletions

View File

@@ -18,24 +18,14 @@ class AgentState(MessagesState):
""" """
Here we define the state of the agent Here we define the state of the agent
In this instance, we're inheriting from CopilotKitState, which will bring in In this instance, we're inheriting from MessagesState, which will bring in
the CopilotKitState fields. We're also adding a custom field, `language`, the messages field for conversation history.
which will be used to set the language of the agent.
""" """
proverbs: List[str]
tools: List[Any] tools: List[Any]
# your_custom_agent_state: str = "" # your_custom_agent_state: str = ""
@tool
def get_weather(location: str):
"""
Get the weather for a given location.
"""
return f"The weather for {location} is 70 degrees."
# @tool # @tool
# def your_tool_here(your_arg: str): # def your_tool_here(your_arg: str):
# """Your tool description here.""" # """Your tool description here."""
@@ -43,7 +33,6 @@ def get_weather(location: str):
# return "Your tool response here." # return "Your tool response here."
backend_tools = [ backend_tools = [
get_weather
# your_tool_here # your_tool_here
] ]
@@ -81,7 +70,7 @@ async def chat_node(state: AgentState, config: RunnableConfig) -> Command[str]:
# 3. Define the system message by which the chat model will be run # 3. Define the system message by which the chat model will be run
system_message = SystemMessage( system_message = SystemMessage(
content=f"You are a helpful assistant. The current proverbs are {state.get('proverbs', [])}." content="You are a helpful assistant."
) )
# 4. Run the model to generate a response # 4. Run the model to generate a response

View File

@@ -1,19 +1,18 @@
"use client"; "use client";
import { useCoAgent, useCopilotAction } from "@copilotkit/react-core"; import { useCopilotAction } from "@copilotkit/react-core";
import { CopilotKitCSSProperties, CopilotChat } from "@copilotkit/react-ui"; import { CopilotKitCSSProperties, CopilotChat } from "@copilotkit/react-ui";
import { useState } from "react"; import { useState } from "react";
export default function CopilotKitPage() { export default function CopilotKitPage() {
const [themeColor, setThemeColor] = useState("#6366f1"); const [themeColor, setThemeColor] = useState("#6366f1");
// 🪁 Frontend Actions: https://docs.copilotkit.ai/guides/frontend-actions
useCopilotAction({ useCopilotAction({
name: "setThemeColor", name: "setThemeColor",
parameters: [{ parameters: [{
name: "themeColor", name: "themeColor",
description: "The theme color to set. Make sure to pick nice colors.", description: "The theme color to set. Make sure to pick nice colors.",
required: true, required: true,
}], }],
handler({ themeColor }) { handler({ themeColor }) {
setThemeColor(themeColor); setThemeColor(themeColor);
@@ -21,150 +20,20 @@ export default function CopilotKitPage() {
}); });
return ( return (
<main style={{ "--copilot-kit-primary-color": themeColor } as CopilotKitCSSProperties}> <main
<YourMainContent themeColor={themeColor} /> style={{ "--copilot-kit-primary-color": themeColor } as CopilotKitCSSProperties}
<CopilotChat className="h-screen w-screen flex justify-center bg-gray-50 py-8 px-2"
instructions={"You assist with looking up any relevant information to caving. This includes but is not limited to Cave Locations, Cave Surveying, Cave History."} >
labels={{ <div className="h-full w-full max-w-5xl flex flex-col">
title: "AI Cartwright", <CopilotChat
initial: "Would you like to lookup a cave location today?", instructions={"You assist with looking up any relevant information to caving. This includes but is not limited to Cave Locations, Cave Surveying, Cave History."}
}} labels={{
/> title: "AI Cartwright",
initial: "Would you like to lookup a cave location today?",
}}
className="h-full w-full"
/>
</div>
</main> </main>
); );
} }
// State of the agent, make sure this aligns with your agent's state.
type AgentState = {
proverbs: string[];
}
function YourMainContent({ themeColor }: { themeColor: string }) {
// 🪁 Shared State: https://docs.copilotkit.ai/coagents/shared-state
const { state, setState } = useCoAgent<AgentState>({
name: "sample_agent",
initialState: {
proverbs: [
"CopilotKit may be new, but its the best thing since sliced bread.",
],
},
})
// 🪁 Frontend Actions: https://docs.copilotkit.ai/coagents/frontend-actions
useCopilotAction({
name: "addProverb",
parameters: [{
name: "proverb",
description: "The proverb to add. Make it witty, short and concise.",
required: true,
}],
handler: ({ proverb }) => {
setState({
...state,
proverbs: [...(state.proverbs || []), proverb],
});
},
});
//🪁 Generative UI: https://docs.copilotkit.ai/coagents/generative-ui
useCopilotAction({
name: "get_weather",
description: "Get the weather for a given location.",
available: "disabled",
parameters: [
{ name: "location", type: "string", required: true },
],
render: ({ args }) => {
return <WeatherCard location={args.location} themeColor={themeColor} />
},
});
return (
<div
style={{ backgroundColor: themeColor }}
className="h-screen w-screen flex justify-center items-center flex-col transition-colors duration-300"
>
<div className="bg-white/20 backdrop-blur-md p-8 rounded-2xl shadow-xl max-w-2xl w-full">
<h1 className="text-4xl font-bold text-white mb-2 text-center">Proverbs</h1>
<p className="text-gray-200 text-center italic mb-6">This is a demonstrative page, but it could be anything you want! 🪁</p>
<hr className="border-white/20 my-6" />
<div className="flex flex-col gap-3">
{state.proverbs?.map((proverb, index) => (
<div
key={index}
className="bg-white/15 p-4 rounded-xl text-white relative group hover:bg-white/20 transition-all"
>
<p className="pr-8">{proverb}</p>
<button
onClick={() => setState({
...state,
proverbs: (state.proverbs || []).filter((_, i) => i !== index),
})}
className="absolute right-3 top-3 opacity-0 group-hover:opacity-100 transition-opacity
bg-red-500 hover:bg-red-600 text-white rounded-full h-6 w-6 flex items-center justify-center"
>
</button>
</div>
))}
</div>
{state.proverbs?.length === 0 && <p className="text-center text-white/80 italic my-8">
No proverbs yet. Ask the assistant to add some!
</p>}
</div>
</div>
);
}
// Simple sun icon for the weather card
function SunIcon() {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-14 h-14 text-yellow-200">
<circle cx="12" cy="12" r="5" />
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" strokeWidth="2" stroke="currentColor" />
</svg>
);
}
// Weather card component where the location and themeColor are based on what the agent
// sets via tool calls.
function WeatherCard({ location, themeColor }: { location?: string, themeColor: string }) {
return (
<div
style={{ backgroundColor: themeColor }}
className="rounded-xl shadow-xl mt-6 mb-4 max-w-md w-full"
>
<div className="bg-white/20 p-4 w-full">
<div className="flex items-center justify-between">
<div>
<h3 className="text-xl font-bold text-white capitalize">{location}</h3>
<p className="text-white">Current Weather</p>
</div>
<SunIcon />
</div>
<div className="mt-4 flex items-end justify-between">
<div className="text-3xl font-bold text-white">70°</div>
<div className="text-sm text-white">Clear skies</div>
</div>
<div className="mt-4 pt-4 border-t border-white">
<div className="grid grid-cols-3 gap-2 text-center">
<div>
<p className="text-white text-xs">Humidity</p>
<p className="text-white font-medium">45%</p>
</div>
<div>
<p className="text-white text-xs">Wind</p>
<p className="text-white font-medium">5 mph</p>
</div>
<div>
<p className="text-white text-xs">Feels Like</p>
<p className="text-white font-medium">72°</p>
</div>
</div>
</div>
</div>
</div>
);
}