|
18 | 18 | from src.query import query_data |
19 | 19 | from src.todos import AgentState, todo_tools |
20 | 20 | from src.form import generate_form |
21 | | -from src.templates import template_tools |
| 21 | +from src.plan import plan_visualization |
22 | 22 |
|
23 | 23 | load_dotenv() |
24 | 24 |
|
25 | 25 | agent = create_deep_agent( |
26 | 26 | model=ChatOpenAI(model=os.environ.get("LLM_MODEL", "gpt-5.4-2026-03-05")), |
27 | | - tools=[query_data, *todo_tools, generate_form, *template_tools], |
| 27 | + tools=[query_data, plan_visualization, *todo_tools, generate_form], |
28 | 28 | middleware=[CopilotKitMiddleware()], |
29 | 29 | context_schema=AgentState, |
30 | 30 | skills=[str(Path(__file__).parent / "skills")], |
|
53 | 53 | - Pre-styled form elements (buttons, inputs, sliders look native automatically) |
54 | 54 | - Pre-built SVG CSS classes for color ramps (.c-purple, .c-teal, .c-blue, etc.) |
55 | 55 |
|
56 | | - ## UI Templates |
| 56 | + ## Visualization Workflow (MANDATORY) |
57 | 57 |
|
58 | | - Users can save generated UIs as reusable templates and apply them later. |
59 | | - You have backend tools: `save_template`, `list_templates`, `apply_template`, `delete_template`. |
| 58 | + When producing ANY visual response (widgetRenderer, pieChart, barChart), you MUST |
| 59 | + follow this exact sequence: |
60 | 60 |
|
61 | | - **When a user asks to apply/recreate a template with new data:** |
62 | | - Check `pending_template` in state — the frontend sets this when the user picks a template. |
63 | | - If `pending_template` is present (has `id` and `name`): |
64 | | - 1. Call `apply_template(template_id=pending_template["id"])` to retrieve the HTML |
65 | | - 2. Take the returned HTML and COPY IT EXACTLY, only replacing the data values |
66 | | - (names, numbers, dates, labels, amounts) to match the user's message |
67 | | - 3. Render the modified HTML using `widgetRenderer` |
68 | | - 4. Call `clear_pending_template` to reset the pending state |
| 61 | + 1. **Acknowledge** — Reply with 1-2 sentences of plain text acknowledging the |
| 62 | + request and setting context for what the visualization will show. |
| 63 | + 2. **Plan** — Call `plan_visualization` with your approach, technology choice, |
| 64 | + and 2-4 key elements. Keep it concise. |
| 65 | + 3. **Build** — Call the appropriate visualization tool (widgetRenderer, pieChart, |
| 66 | + or barChart). |
| 67 | + 4. **Narrate** — After the visualization, add 2-3 sentences walking through |
| 68 | + what was built and offering to go deeper. |
69 | 69 |
|
70 | | - If no `pending_template` is set but the user mentions a template by name, use |
71 | | - `apply_template(name="...")` instead. |
| 70 | + NEVER skip the plan_visualization step. NEVER call widgetRenderer, pieChart, or |
| 71 | + barChart without calling plan_visualization first. |
72 | 72 |
|
73 | | - CRITICAL: Do NOT rewrite or generate HTML from scratch. Take the original HTML string, |
74 | | - find-and-replace ONLY the data values, and pass the result to widgetRenderer. |
75 | | - This preserves the exact layout and styling of the original template. |
76 | | - For bar/pie chart templates, use `barChart` or `pieChart` component instead. |
| 73 | + ## Visualization Quality Standards |
| 74 | +
|
| 75 | + The iframe has an import map with these ES module libraries — use `<script type="module">` and bare import specifiers: |
| 76 | + - `three` — 3D graphics. `import * as THREE from "three"`. Also `three/examples/jsm/controls/OrbitControls.js` for camera controls. |
| 77 | + - `gsap` — animation. `import gsap from "gsap"`. |
| 78 | + - `d3` — data visualization and force layouts. `import * as d3 from "d3"`. |
| 79 | + - `chart.js/auto` — charts (but prefer the built-in `barChart`/`pieChart` components for simple charts). |
| 80 | +
|
| 81 | + **3D content**: ALWAYS use Three.js with proper WebGL rendering. Use real geometry, PBR materials (MeshStandardMaterial/MeshPhysicalMaterial), multiple light sources, and OrbitControls for interactivity. NEVER fake 3D with CSS transforms, CSS perspective, or Canvas 2D manual projection — these look broken and unprofessional. |
| 82 | +
|
| 83 | + **Quality bar**: Every visualization should look polished and portfolio-ready. Use smooth animations, proper lighting (ambient + directional at minimum), responsive canvas sizing (`window.addEventListener('resize', ...)`), and antialiasing (`antialias: true`). No proof-of-concept quality. |
| 84 | +
|
| 85 | + **Critical**: `<script type="module">` is REQUIRED when using import map libraries. Regular `<script>` tags cannot use `import` statements. |
77 | 86 | """, |
78 | 87 | ) |
79 | 88 |
|
|
0 commit comments