diff --git a/apps/agent/main.py b/apps/agent/main.py index 3e43367..4283880 100644 --- a/apps/agent/main.py +++ b/apps/agent/main.py @@ -18,13 +18,13 @@ from src.query import query_data from src.todos import AgentState, todo_tools from src.form import generate_form -from src.templates import template_tools +from src.plan import plan_visualization load_dotenv() agent = create_deep_agent( model=ChatOpenAI(model=os.environ.get("LLM_MODEL", "gpt-5.4-2026-03-05")), - tools=[query_data, *todo_tools, generate_form, *template_tools], + tools=[query_data, plan_visualization, *todo_tools, generate_form], middleware=[CopilotKitMiddleware()], context_schema=AgentState, skills=[str(Path(__file__).parent / "skills")], @@ -53,27 +53,36 @@ - Pre-styled form elements (buttons, inputs, sliders look native automatically) - Pre-built SVG CSS classes for color ramps (.c-purple, .c-teal, .c-blue, etc.) - ## UI Templates + ## Visualization Workflow (MANDATORY) - Users can save generated UIs as reusable templates and apply them later. - You have backend tools: `save_template`, `list_templates`, `apply_template`, `delete_template`. + When producing ANY visual response (widgetRenderer, pieChart, barChart), you MUST + follow this exact sequence: - **When a user asks to apply/recreate a template with new data:** - Check `pending_template` in state — the frontend sets this when the user picks a template. - If `pending_template` is present (has `id` and `name`): - 1. Call `apply_template(template_id=pending_template["id"])` to retrieve the HTML - 2. Take the returned HTML and COPY IT EXACTLY, only replacing the data values - (names, numbers, dates, labels, amounts) to match the user's message - 3. Render the modified HTML using `widgetRenderer` - 4. Call `clear_pending_template` to reset the pending state + 1. **Acknowledge** — Reply with 1-2 sentences of plain text acknowledging the + request and setting context for what the visualization will show. + 2. **Plan** — Call `plan_visualization` with your approach, technology choice, + and 2-4 key elements. Keep it concise. + 3. **Build** — Call the appropriate visualization tool (widgetRenderer, pieChart, + or barChart). + 4. **Narrate** — After the visualization, add 2-3 sentences walking through + what was built and offering to go deeper. - If no `pending_template` is set but the user mentions a template by name, use - `apply_template(name="...")` instead. + NEVER skip the plan_visualization step. NEVER call widgetRenderer, pieChart, or + barChart without calling plan_visualization first. - CRITICAL: Do NOT rewrite or generate HTML from scratch. Take the original HTML string, - find-and-replace ONLY the data values, and pass the result to widgetRenderer. - This preserves the exact layout and styling of the original template. - For bar/pie chart templates, use `barChart` or `pieChart` component instead. + ## Visualization Quality Standards + + The iframe has an import map with these ES module libraries — use `