Skip to content

Commit 2a6b316

Browse files
bloveclaude
andauthored
fix(c-generative-ui): three demo-polish followups (#440)
1. render_spec(elements, root) instead of render_spec(spec) — matches what gpt-5 reasoning='minimal' naturally emits; eliminates the visible Pydantic 'spec: Field required' retry artifact in the chat. 2. Tighten prompt: explicit 'if render_spec and the data tools have already been called this turn, you are DONE' — stops the double-loop where gpt-5 re-runs all tools on the second iteration. 3. Welcome chip text now matches the aviation backend ('Airline operations dashboard' / 'Filter to cancelled flights' instead of the off-theme 'Q3 sales dashboard' / 'contact form'). Mirrors to umbrella graph + prompt per the full-copy policy. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ae87167 commit 2a6b316

4 files changed

Lines changed: 17 additions & 17 deletions

File tree

cockpit/chat/generative-ui/angular/src/app/generative-ui.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const dashboardViews = views({
2222
});
2323

2424
const WELCOME_SUGGESTIONS = [
25-
{ label: 'Render a dashboard', value: 'Show me a Q3 sales dashboard with three metrics.' },
26-
{ label: 'Render a form', value: 'Create a contact form with name, email, and message.' },
25+
{ label: 'Airline operations dashboard', value: 'Show me a dashboard of airline operations.' },
26+
{ label: 'Filter to cancelled flights', value: 'Filter to only the cancelled flights.' },
2727
] as const;
2828

2929
@Component({

cockpit/chat/generative-ui/python/prompts/dashboard.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
You are a dashboard agent that builds interactive airline-operations KPI dashboards. You have five tools:
44

5-
- `render_spec(spec)` — Author or update the dashboard layout. The spec is a JSON object describing component types, props, children, and state bindings. See the schema below.
5+
- `render_spec(elements, root)` — Author or update the dashboard layout. `elements` is a dict keyed by component id (each value has `type`, optional `props`, optional `children`); `root` is the id of the top-level component. See the schema below.
66
- `query_airline_kpis()` — Snapshot of operational KPIs: on-time %, flights today, avg delay, load factor.
77
- `query_on_time_trend(months=12)` — On-time performance per month, for the line chart.
88
- `query_flights_by_airline(airlines=None)` — Daily flight counts per airline, for the bar chart.
@@ -14,7 +14,7 @@ You are a dashboard agent that builds interactive airline-operations KPI dashboa
1414

1515
1. Call `render_spec` ONCE with a complete dashboard layout — stat cards, charts, table — using `$state` bindings to the slots the data tools populate (see "State Path Conventions" below).
1616
2. In the SAME turn (same tool_calls array), call EACH data tool that backs a component in your spec. Do NOT call tools whose data your spec doesn't reference.
17-
3. After the tools return, return WITHOUT any further tool calls. A separate node will write a brief conversational summary.
17+
3. After the tools return, return WITHOUT any further tool calls. A separate node will write a brief conversational summary. **Critical: if `render_spec` and the data tools have already been called this turn, you are DONE. Return with no tool_calls. Do NOT call `render_spec` again. Do NOT re-call the data tools.**
1818

1919
### When the dashboard exists (follow-up turn)
2020

cockpit/chat/generative-ui/python/src/graph.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,27 +38,27 @@ class DashboardState(MessagesState):
3838

3939

4040
@tool
41-
async def render_spec(spec: dict) -> str:
42-
"""Render an interactive dashboard layout from a JSON spec.
41+
async def render_spec(elements: dict, root: str) -> str:
42+
"""Render an interactive dashboard layout.
4343
44-
Use this tool to author or update the dashboard layout. The spec is a
45-
JSON object with `elements` (a dict keyed by component id) and `root`
46-
(the id of the top-level component). See the system prompt for the full
47-
schema and component catalog.
44+
Use this tool to author or update the dashboard layout. See the system
45+
prompt for the full component catalog and state binding conventions.
4846
49-
Call this tool FIRST on any turn where the layout needs to be created
50-
or restructured. After calling render_spec, call the data tools needed
51-
to populate the components you authored.
47+
Call this tool AT MOST ONCE per turn — only when the layout needs to
48+
be created (first turn) or restructured (follow-up structural change).
49+
Do NOT call it again to refresh data; the data tools handle that.
5250
5351
Args:
54-
spec: The dashboard JSON render spec.
52+
elements: Dict keyed by component id. Each value has `type`, optional
53+
`props`, and optional `children` (list of component ids).
54+
root: The id of the top-level component (must be a key in `elements`).
5555
5656
Returns:
5757
The spec serialized as JSON. A post-process node (wrap_spec_into_ai)
5858
wraps this payload into the AI message content where the
5959
chat-lib's content-classifier picks it up.
6060
"""
61-
return json.dumps(spec)
61+
return json.dumps({"elements": elements, "root": root})
6262

6363

6464
_ALL_TOOLS = [render_spec, *_DATA_TOOLS]

cockpit/langgraph/streaming/python/prompts/dashboard.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
You are a dashboard agent that builds interactive airline-operations KPI dashboards. You have five tools:
44

5-
- `render_spec(spec)` — Author or update the dashboard layout. The spec is a JSON object describing component types, props, children, and state bindings. See the schema below.
5+
- `render_spec(elements, root)` — Author or update the dashboard layout. `elements` is a dict keyed by component id (each value has `type`, optional `props`, optional `children`); `root` is the id of the top-level component. See the schema below.
66
- `query_airline_kpis()` — Snapshot of operational KPIs: on-time %, flights today, avg delay, load factor.
77
- `query_on_time_trend(months=12)` — On-time performance per month, for the line chart.
88
- `query_flights_by_airline(airlines=None)` — Daily flight counts per airline, for the bar chart.
@@ -14,7 +14,7 @@ You are a dashboard agent that builds interactive airline-operations KPI dashboa
1414

1515
1. Call `render_spec` ONCE with a complete dashboard layout — stat cards, charts, table — using `$state` bindings to the slots the data tools populate (see "State Path Conventions" below).
1616
2. In the SAME turn (same tool_calls array), call EACH data tool that backs a component in your spec. Do NOT call tools whose data your spec doesn't reference.
17-
3. After the tools return, return WITHOUT any further tool calls. A separate node will write a brief conversational summary.
17+
3. After the tools return, return WITHOUT any further tool calls. A separate node will write a brief conversational summary. **Critical: if `render_spec` and the data tools have already been called this turn, you are DONE. Return with no tool_calls. Do NOT call `render_spec` again. Do NOT re-call the data tools.**
1818

1919
### When the dashboard exists (follow-up turn)
2020

0 commit comments

Comments
 (0)