Skip to content

Commit e465303

Browse files
committed
feat: add beautiful-chat to agno + stub unsupported interrupt demos
Beautiful Chat (simplified) — polished landing-style chat shell over the shared agentic_chat agent with gradient theming, suggestion pills, and an example dashboard surface (BarChart + PieChart re-used from byoc-json- render). Mirrors the spring-ai simplified port; full A2UI demonstration catalog is out of scope while Agno lacks an A2UI middleware adapter. gen-ui-interrupt + interrupt-headless — stubbed as not_supported_features in manifest.yaml. Agno has no graph-level interrupt primitive, so each stub page documents the gap and links to the closest Agno-supported pattern (hitl-in-chat for in-chat blocking, hitl-in-app for out-of-chat blocking via async useFrontendTool).
1 parent 9d1a70d commit e465303

7 files changed

Lines changed: 392 additions & 0 deletions

File tree

showcase/integrations/agno/manifest.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ features:
5656
- tool-rendering-reasoning-chain
5757
- headless-complete
5858
- auth
59+
- beautiful-chat
60+
not_supported_features:
61+
- gen-ui-interrupt
62+
- interrupt-headless
5963
demos:
6064
- id: cli-start
6165
name: CLI Start Command
@@ -474,6 +478,19 @@ demos:
474478
- src/app/demos/byoc-json-render/registry.tsx
475479
- src/app/demos/byoc-json-render/catalog.ts
476480
- src/app/api/copilotkit-byoc-json-render/route.ts
481+
- id: beautiful-chat
482+
name: Beautiful Chat
483+
description: Polished landing-style chat shell over the shared Agno agent — gradient background, suggestion pills, and an example dashboard surface
484+
tags:
485+
- chat-ui
486+
route: /demos/beautiful-chat
487+
animated_preview_url:
488+
highlight:
489+
- src/agents/main.py
490+
- src/app/demos/beautiful-chat/page.tsx
491+
- src/app/demos/byoc-json-render/charts/bar-chart.tsx
492+
- src/app/demos/byoc-json-render/charts/pie-chart.tsx
493+
- src/app/api/copilotkit/route.ts
477494
managed_platform:
478495
name: Agent OS
479496
url: https://os.agno.com
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# Beautiful Chat (Agno port — simplified)
2+
3+
## What this demo shows
4+
5+
A polished, landing-style chat surface backed by the shared Agno
6+
`agentic_chat` agent. The page is split into two columns:
7+
8+
- **Left** — an example app surface with a couple of demonstration charts
9+
(weekly sessions bar chart, surface-mix pie chart). Useful as a target
10+
for the assistant to talk about.
11+
- **Right** — a `CopilotChat` panel skinned with the brand gradient,
12+
rounded card, and seeded suggestion pills.
13+
14+
## How to interact
15+
16+
Use one of the seeded suggestion pills, or ask the assistant something
17+
like:
18+
19+
- "Summarize the dashboard on the left."
20+
- "Plan a 3-day Tokyo trip for a solo traveler."
21+
- "Draft a launch email for our new chat feature."
22+
23+
## Adaptation note
24+
25+
The canonical `langgraph-python` beautiful-chat ships a much larger
26+
surface — a full A2UI demonstration catalog, a declarative-generative-UI
27+
catalog, per-tool renderers wired through `injectA2UITool: false`, custom
28+
theming, and a `GenerativeUIExamples` hook. That ecosystem depends on
29+
A2UI middleware that the Agno integration does not yet expose.
30+
31+
The Agno port follows the simplified `spring-ai` pattern: the polished
32+
chat shell over the shared Agno chat agent, with suggestion pills and a
33+
few static charts on the side. The cosmetic layer (suggestions, theming,
34+
composer skin, side canvas) lives entirely on the frontend; the runtime
35+
stays on the shared `/api/copilotkit` endpoint.
36+
37+
## Related
38+
39+
- Backend agent: `src/agents/main.py` (the same one `agentic-chat` uses)
40+
- Charts: re-uses `src/app/demos/byoc-json-render/charts/` for the
41+
Recharts-backed `BarChart` and `PieChart` components.
42+
- Full reference: `showcase/integrations/langgraph-python/src/app/demos/beautiful-chat/`
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
"use client";
2+
3+
/**
4+
* Beautiful Chat (Agno port — simplified).
5+
*
6+
* A polished landing-style chat cell with brand theming, suggestion pills,
7+
* and an example app surface that swaps in a couple of demonstration
8+
* charts the user can ask the agent to talk about. The canonical
9+
* langgraph-python version of beautiful-chat ships a much larger surface
10+
* (full A2UI demonstration catalog, declarative-generative-UI catalog,
11+
* per-tool renderers wired through `injectA2UITool: false`, custom
12+
* theming + GenerativeUIExamples). Agno does not yet expose an A2UI
13+
* adapter, so this port mirrors the `spring-ai` simplified port: it
14+
* keeps the polished shell, suggestion pills, and a couple of static
15+
* charts on the side, and runs against the main `/api/copilotkit`
16+
* endpoint with the shared Agno chat agent.
17+
*
18+
* Runtime: shared `/api/copilotkit` endpoint (no dedicated runtime). The
19+
* Agno backend is the same `agentic_chat` agent the agentic-chat cell
20+
* uses — the cosmetic layer (suggestions, theming, composer skin, side
21+
* canvas) lives entirely on the frontend.
22+
*/
23+
24+
import {
25+
CopilotKit,
26+
CopilotChat,
27+
useConfigureSuggestions,
28+
} from "@copilotkit/react-core/v2";
29+
import { BarChart } from "../byoc-json-render/charts/bar-chart";
30+
import { PieChart } from "../byoc-json-render/charts/pie-chart";
31+
32+
const AGENT_ID = "agentic_chat";
33+
34+
const BRAND_SUGGESTIONS = [
35+
{
36+
title: "Plan a 3-day Tokyo trip",
37+
message:
38+
"Plan a 3-day Tokyo trip for a solo traveler interested in food, art, and architecture. Keep it concise.",
39+
},
40+
{
41+
title: "Explain RAG like I'm 12",
42+
message:
43+
"Explain retrieval-augmented generation as if I were 12. Use a simple analogy.",
44+
},
45+
{
46+
title: "Draft a launch email",
47+
message:
48+
"Draft a short, upbeat launch email announcing a new AI-powered chat feature. 3 short paragraphs max.",
49+
},
50+
{
51+
title: "Summarize this dashboard",
52+
message:
53+
"Summarize the dashboard on the left. What stands out about the bar and pie charts?",
54+
},
55+
];
56+
57+
const SAMPLE_BAR_DATA = [
58+
{ label: "Mon", value: 32 },
59+
{ label: "Tue", value: 48 },
60+
{ label: "Wed", value: 51 },
61+
{ label: "Thu", value: 44 },
62+
{ label: "Fri", value: 67 },
63+
{ label: "Sat", value: 38 },
64+
{ label: "Sun", value: 29 },
65+
];
66+
67+
const SAMPLE_PIE_DATA = [
68+
{ label: "Chat", value: 42 },
69+
{ label: "Tools", value: 28 },
70+
{ label: "Gen UI", value: 18 },
71+
{ label: "Other", value: 12 },
72+
];
73+
74+
export default function BeautifulChatPage() {
75+
return (
76+
<CopilotKit runtimeUrl="/api/copilotkit" agent={AGENT_ID}>
77+
<div
78+
className="relative flex h-screen w-full overflow-hidden"
79+
style={{
80+
background:
81+
"radial-gradient(1200px 600px at 10% 10%, rgba(99,102,241,0.20), transparent 50%), radial-gradient(1000px 500px at 90% 90%, rgba(133,236,206,0.18), transparent 55%), linear-gradient(180deg, #FBFBFE 0%, #F4F4F8 100%)",
82+
}}
83+
>
84+
<div className="pointer-events-none absolute inset-0 [background:radial-gradient(circle_at_50%_0%,rgba(190,194,255,0.35),transparent_40%)]" />
85+
86+
{/* App surface (left) */}
87+
<div className="relative hidden flex-1 flex-col gap-4 overflow-y-auto px-8 py-10 lg:flex">
88+
<header className="space-y-1">
89+
<div className="text-[10px] font-medium uppercase tracking-[0.14em] text-[#57575B]">
90+
Beautiful chat
91+
</div>
92+
<h1 className="text-3xl font-semibold tracking-tight text-[#010507]">
93+
Polished Agno surface
94+
</h1>
95+
<p className="max-w-xl text-sm text-[#3A3A46]">
96+
A flagship-style chat shell over the shared Agno backend. Ask the
97+
assistant a question, pick a suggestion pill, or have it talk
98+
through the example dashboard.
99+
</p>
100+
</header>
101+
102+
<div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
103+
<BarChart
104+
title="Weekly active sessions"
105+
description="Sessions per day across the demo workspace."
106+
data={SAMPLE_BAR_DATA}
107+
/>
108+
<PieChart
109+
title="Surface mix"
110+
description="Where users are spending their time."
111+
data={SAMPLE_PIE_DATA}
112+
/>
113+
</div>
114+
</div>
115+
116+
{/* Chat (right) */}
117+
<div className="relative flex w-full max-w-xl flex-col gap-3 px-4 py-8 lg:px-6">
118+
<div className="flex-1 overflow-hidden rounded-2xl border border-[#E5E5ED] bg-white/70 shadow-[0_1px_0_0_rgba(0,0,0,0.02),0_10px_40px_-10px_rgba(99,102,241,0.18)] backdrop-blur-sm">
119+
<Chat />
120+
</div>
121+
</div>
122+
</div>
123+
</CopilotKit>
124+
);
125+
}
126+
127+
function Chat() {
128+
useConfigureSuggestions({
129+
suggestions: BRAND_SUGGESTIONS,
130+
available: "always",
131+
});
132+
133+
return <CopilotChat agentId={AGENT_ID} className="h-full rounded-2xl" />;
134+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Gen UI Interrupt — Not Supported on Agno
2+
3+
## Why this demo is stubbed
4+
5+
The canonical LangGraph version of `gen-ui-interrupt` uses LangGraph's
6+
graph-level `interrupt()` primitive together with the frontend
7+
`useInterrupt` hook:
8+
9+
1. Inside a node, the graph calls `interrupt({...payload})` and pauses.
10+
2. The frontend `useInterrupt` hook renders a card inside the chat from
11+
the surfaced payload.
12+
3. When the user picks a slot, the frontend resumes the run via
13+
`copilotkit.runAgent({ forwardedProps: { command: { resume } } })`,
14+
carrying the user-supplied value back into the paused node.
15+
16+
Agno has no equivalent graph-level interrupt primitive. An Agno agent
17+
runs to completion on each invocation, and there is no pause / resume API
18+
that can carry client-supplied state across a suspension. The demo is
19+
therefore documented and stubbed here rather than ported.
20+
21+
## What to use instead on Agno
22+
23+
For "agent blocks on user confirmation before proceeding", use Agno's
24+
`hitl-in-chat` demo (`useHumanInTheLoop`), which renders a card inside
25+
the chat and waits for the user to act. The user-visible UX is similar
26+
even though the underlying mechanism differs.
27+
28+
## Related
29+
30+
- Canonical implementation:
31+
`showcase/integrations/langgraph-python/src/app/demos/gen-ui-interrupt`
32+
- Closest Agno-supported pattern:
33+
`src/app/demos/hitl-in-chat` (in this integration)
34+
- Manifest entry: `not_supported_features` in `showcase/integrations/agno/manifest.yaml`
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"use client";
2+
3+
/**
4+
* Gen UI Interrupt — NOT SUPPORTED for Agno.
5+
*
6+
* The canonical LangGraph version of this demo uses LangGraph's native
7+
* `interrupt()` graph primitive plus the `useInterrupt` hook to pause a
8+
* graph run mid-execution and surface a payload that the frontend renders
9+
* inline in the chat. The user picks a slot, the frontend resumes the run
10+
* via `copilotkit.runAgent({ forwardedProps: { command: { resume } } })`,
11+
* and the agent continues with the user-supplied value.
12+
*
13+
* Agno has no equivalent graph-level interrupt primitive — an Agno agent
14+
* runs to completion on each invocation and does not expose a pause /
15+
* resume API that can carry client-supplied state across a suspension.
16+
* This demo is therefore stubbed rather than ported.
17+
*
18+
* See `manifest.yaml` → `not_supported_features` and the README for
19+
* details and pointers to the closest available patterns.
20+
*/
21+
22+
import Link from "next/link";
23+
24+
export default function GenUiInterruptUnsupportedPage() {
25+
return (
26+
<div
27+
data-testid="gen-ui-interrupt-unsupported"
28+
className="flex min-h-screen w-full items-center justify-center bg-[#FAFAFC] px-6 py-12"
29+
>
30+
<div className="w-full max-w-xl rounded-2xl border border-[#DBDBE5] bg-white p-8 shadow-[0_10px_40px_-20px_rgba(1,5,7,0.18)]">
31+
<div className="mb-3 inline-flex items-center gap-2 rounded-full border border-[#DBDBE5] bg-[#FAFAFC] px-3 py-1 text-[10px] font-medium uppercase tracking-[0.14em] text-[#57575B]">
32+
<span className="inline-flex h-1.5 w-1.5 rounded-full bg-[#F2A2A2]" />
33+
Not supported on Agno
34+
</div>
35+
<h1 className="mb-2 text-2xl font-semibold tracking-tight text-[#010507]">
36+
Gen UI Interrupt
37+
</h1>
38+
<p className="mb-4 text-sm leading-relaxed text-[#3A3A46]">
39+
This demo relies on a graph-level <code>interrupt()</code> primitive
40+
(LangGraph) that pauses a run mid-execution and resumes it with a
41+
client-supplied value. Agno does not currently expose an equivalent
42+
primitive, so the demo is documented but not runnable on this
43+
integration.
44+
</p>
45+
<p className="mb-6 text-sm leading-relaxed text-[#3A3A46]">
46+
The closest Agno-supported pattern for blocking on user input is{" "}
47+
<Link
48+
href="/demos/hitl-in-chat"
49+
className="font-medium text-[#6366F1] underline-offset-2 hover:underline"
50+
>
51+
in-chat human-in-the-loop
52+
</Link>
53+
{" "}via <code>useHumanInTheLoop</code>, which renders a card inside
54+
the chat and waits for the user to confirm before the agent
55+
proceeds.
56+
</p>
57+
<div className="text-xs text-[#57575B]">
58+
See the canonical implementation in{" "}
59+
<code>
60+
showcase/integrations/langgraph-python/src/app/demos/gen-ui-interrupt
61+
</code>
62+
.
63+
</div>
64+
</div>
65+
</div>
66+
);
67+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Headless Interrupt — Not Supported on Agno
2+
3+
## Why this demo is stubbed
4+
5+
The canonical LangGraph version of `interrupt-headless` drives a picker
6+
UI rendered OUTSIDE the chat (in the app surface) using a custom
7+
`useHeadlessInterrupt` hook on top of `useAgent` + `useCopilotKit`. The
8+
hook reads LangGraph's native `interrupt()` event from the AG-UI stream
9+
and resumes the run via
10+
`copilotkit.runAgent({ forwardedProps: { command: { resume, ... } } })`.
11+
12+
Agno has no equivalent graph-level interrupt primitive. An Agno agent
13+
runs to completion on each invocation, and there is no pause / resume
14+
API that can carry client-supplied state across a suspension. The demo
15+
is therefore documented and stubbed here rather than ported.
16+
17+
## What to use instead on Agno
18+
19+
For "agent blocks on user input rendered as a modal OUTSIDE the chat",
20+
use Agno's `hitl-in-app` demo. It registers an async `useFrontendTool`
21+
whose handler returns a Promise that only resolves once the user
22+
interacts with a host-rendered modal — equivalent UX, different
23+
underlying mechanism.
24+
25+
## Related
26+
27+
- Canonical implementation:
28+
`showcase/integrations/langgraph-python/src/app/demos/interrupt-headless`
29+
- Closest Agno-supported pattern:
30+
`src/app/demos/hitl-in-app` (in this integration)
31+
- Manifest entry: `not_supported_features` in `showcase/integrations/agno/manifest.yaml`

0 commit comments

Comments
 (0)