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
In this instance, we're inheriting from CopilotKitState, which will bring in
the CopilotKitState fields. We're also adding a custom field, `language`,
which will be used to set the language of the agent.
In this instance, we're inheriting from MessagesState, which will bring in
the messages field for conversation history.
"""
proverbs: List[str]
tools: List[Any]
# 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
# def your_tool_here(your_arg: str):
# """Your tool description here."""
@@ -43,7 +33,6 @@ def get_weather(location: str):
# return "Your tool response here."
backend_tools = [
get_weather
# 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
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

View File

@@ -1,19 +1,18 @@
"use client";
import { useCoAgent, useCopilotAction } from "@copilotkit/react-core";
import { useCopilotAction } from "@copilotkit/react-core";
import { CopilotKitCSSProperties, CopilotChat } from "@copilotkit/react-ui";
import { useState } from "react";
export default function CopilotKitPage() {
const [themeColor, setThemeColor] = useState("#6366f1");
// 🪁 Frontend Actions: https://docs.copilotkit.ai/guides/frontend-actions
useCopilotAction({
name: "setThemeColor",
parameters: [{
name: "themeColor",
description: "The theme color to set. Make sure to pick nice colors.",
required: true,
required: true,
}],
handler({ themeColor }) {
setThemeColor(themeColor);
@@ -21,150 +20,20 @@ export default function CopilotKitPage() {
});
return (
<main style={{ "--copilot-kit-primary-color": themeColor } as CopilotKitCSSProperties}>
<YourMainContent themeColor={themeColor} />
<CopilotChat
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?",
}}
/>
<main
style={{ "--copilot-kit-primary-color": themeColor } as CopilotKitCSSProperties}
className="h-screen w-screen flex justify-center bg-gray-50 py-8 px-2"
>
<div className="h-full w-full max-w-5xl flex flex-col">
<CopilotChat
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>
);
}
// 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>
);
}