xiaohongshu
xiaohongshu
castella-agent-ui
Build chat interfaces and agent management UIs with Castella. Create chat components, display tool calls, manage multiple agents, and build agent hubs.
Full skill instructions
High-level components for building conversational interfaces and agent management UIs.
When to use: "create a chat UI", "AgentChat", "chat with agent", "display tool calls", "multi-agent chat", "AgentHub", "message history", "MultiAgentChat"
Create a chat UI connected to an A2A agent:
from castella.agent import AgentChat
chat = AgentChat.from_a2a("http://localhost:8080")
chat.run()
uv sync --extra agent # Agent UI + A2A + A2UI support
High-level chat component with minimal setup:
from castella.agent import AgentChat
# Connect to A2A agent
chat = AgentChat.from_a2a("http://localhost:8080")
chat.run()
# Or use custom handler function
chat = AgentChat(
handler=lambda msg: f"Echo: {msg}",
title="Echo Bot",
system_message="Welcome! How can I help?",
)
chat.run()
AgentChat(
a2a_client=None, # A2AClient instance
handler=None, # Custom handler: (str) -> str
title="Agent Chat", # Window title
placeholder="Type...", # Input placeholder
system_message=None, # Initial system message
show_agent_card=True, # Show agent card for A2A
width=700, # Window width
height=550, # Window height
)
# From A2A agent URL
chat = AgentChat.from_a2a("http://localhost:8080")
# From A2A client
from castella.a2a import A2AClient
client = A2AClient("http://localhost:8080")
chat = AgentChat.from_a2a(client)
Build custom chat UIs with lower-level components.
Complete chat UI (messages + input):
from castella.agent import ChatContainer, ChatMessageData
from castella.core import ListState
messages = ListState([])
def on_send(text: str):
messages.append(ChatMessageData(role="user", content=text))
# Get response from agent...
response = get_response(text)
messages.append(ChatMessageData(role="assistant", content=response))
container = ChatContainer(
messages,
on_send=on_send,
title="My Chat",
placeholder="Type a message...",
)
Display a single message:
from castella.agent import ChatMessage, ChatMessageData
msg = ChatMessageData(
role="assistant", # "user", "assistant", or "system"
content="Hello! How can I help you today?",
)
widget = ChatMessage(msg)
Text input with send button:
from castella.agent import ChatInput
input_widget = ChatInput(
placeholder="Type a message...",
on_send=lambda text: print(f"Sent: {text}"),
)
Scrollable message list:
from castella.agent import ChatView
from castella.core import ScrollState
scroll_state = ScrollState()
view = ChatView(messages, scroll_state=scroll_state)
Message data structure:
from castella.agent import ChatMessageData, ToolCallData
msg = ChatMessageData(
role="assistant",
content="Let me check the weather for you.",
tool_calls=[
ToolCallData(
id="call_1",
name="get_weather",
arguments={"location": "Tokyo"},
result="Sunny, 22°C",
)
],
)
Display a single tool call:
from castella.agent import ToolCallView
tool = ToolCallView(
name="get_weather",
arguments={"location": "Tokyo"},
result="Sunny, 22°C",
)
Display history of tool calls:
from castella.agent import ToolHistoryPanel
from castella.core import ListState
tool_calls = ListState([...])
panel = ToolHistoryPanel(tool_calls)
Show agent information:
from castella.agent import AgentCardView
from castella.a2a import A2AClient
client = A2AClient("http://agent.example.com")
card_view = AgentCardView(
client.agent_card,
show_skills=True,
compact=False,
)
Display multiple agents:
from castella.agent import AgentListView
agent_list = AgentListView(
agents=[client1.agent_card, client2.agent_card],
on_select=lambda card: print(f"Selected: {card.name}"),
)
Tabbed interface for multiple agents:
from castella.agent import MultiAgentChat
from castella.a2a import A2AClient
chat = MultiAgentChat({
"weather": A2AClient("http://localhost:8081"),
"travel": A2AClient("http://localhost:8082"),
"restaurant": A2AClient("http://localhost:8083"),
})
chat.run()
Each agent gets its own chat tab with independent message history.
Agent discovery and management dashboard:
from castella.agent import AgentHub
from castella.a2a import A2AClient
# Create hub
hub = AgentHub(title="Agent Hub")
# Add agents
hub.add_agent("http://localhost:8081")
hub.add_agent(A2AClient("http://localhost:8082"))
hub.run()
Or initialize with agents:
hub = AgentHub(agents=[
A2AClient("http://agent1.example.com"),
A2AClient("http://agent2.example.com"),
])
Features:
Important pattern for chat UIs - set scroll before adding message:
class ChatComponent(Component):
def __init__(self):
super().__init__()
self._messages = ListState([])
self._messages.attach(self)
self._scroll_state = ScrollState()
# DON'T attach scroll state
def _send_message(self, text: str):
# Add user message
self._messages.append(ChatMessageData(role="user", content=text))
# Get response...
response = get_response(text)
# Set scroll BEFORE adding response (so re-render picks it up)
self._scroll_state.y = 999999
self._messages.append(ChatMessageData(role="assistant", content=response))
For components created before App exists (like AgentHub):
class MyComponent(Component):
def __init__(self):
super().__init__()
self._state = State(0)
self._states_attached = False
# DON'T attach here - App may not exist yet
def view(self):
# Attach lazily when view() is called
if not self._states_attached:
self._state.attach(self)
self._states_attached = True
return Text(str(self._state()))
Messages support Markdown formatting:
msg = ChatMessageData(
role="assistant",
content="""
# Weather Report
**Tokyo**: Sunny, 22°C
| Day | High | Low |
|-----|------|-----|
| Mon | 24°C | 18°C |
| Tue | 22°C | 17°C |
""",
)
references/components.md - Component API referencereferences/data_classes.md - ChatMessageData, ToolCallData typesscripts/ - Executable examples (simple_chat.py, multi_agent.py, agent_hub.py)xiaohongshu
technical spec
product ux expert
database patterns
Conduct multi-agent task orchestration and workflow coordination.
Initialize project with Conductor artifacts (product definition,
Expert in web animations, transitions, and motion design using Framer Motion and CSS
Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...
PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.
Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...
Display project status, active tracks, and next actions
Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience