From ff97a693b33151baf85cf4a1fef8fcdb424a6056 Mon Sep 17 00:00:00 2001
From: Max Stepanov
Date: Fri, 24 Apr 2026 15:11:15 +0300
Subject: [PATCH 01/11] update prompt for html generation
---
anton/core/llm/prompt_builder.py | 29 ++-
anton/core/llm/prompts.py | 423 ++++++++++++++++++++++---------
anton/core/tools/recall_skill.py | 18 ++
3 files changed, 349 insertions(+), 121 deletions(-)
diff --git a/anton/core/llm/prompt_builder.py b/anton/core/llm/prompt_builder.py
index d7340fe6..734bcc55 100644
--- a/anton/core/llm/prompt_builder.py
+++ b/anton/core/llm/prompt_builder.py
@@ -61,6 +61,18 @@ def _build_tool_prompts_section(self, tool_defs: list["ToolDef"] | None) -> str:
return "\n\n".join(chunks)
+ # Built-in skills that are always available regardless of ~/.anton/skills/.
+ # Each entry must have "label" and "when_to_use".
+ _BUILTIN_SKILL_SUMMARIES: list[dict] = [
+ {
+ "label": "generate_dashboard_html",
+ "when_to_use": (
+ "when the user asks to build a dashboard, chart, report, "
+ "presentation, or any data visualization as a standalone HTML page"
+ ),
+ },
+ ]
+
def _build_procedural_memory_section(
self, skill_store: "SkillStore | None"
) -> str:
@@ -71,12 +83,17 @@ def _build_procedural_memory_section(
the full procedure. Returns an empty string if no store is wired
or no skills are saved — the caller skips the section entirely.
"""
- if skill_store is None:
- return ""
- try:
- summaries = skill_store.list_summaries()
- except Exception:
- return ""
+ summaries: list[dict] = list(self._BUILTIN_SKILL_SUMMARIES)
+ if skill_store is not None:
+ try:
+ user_summaries = skill_store.list_summaries()
+ except Exception:
+ user_summaries = []
+ # User skills override builtins with the same label.
+ builtin_labels = {s["label"] for s in summaries}
+ for s in user_summaries:
+ if s.get("label") not in builtin_labels:
+ summaries.append(s)
if not summaries:
return ""
diff --git a/anton/core/llm/prompts.py b/anton/core/llm/prompts.py
index 73f57da6..3de22211 100644
--- a/anton/core/llm/prompts.py
+++ b/anton/core/llm/prompts.py
@@ -236,124 +236,317 @@
VISUALIZATIONS_HTML_OUTPUT_FORMAT_PROMPT = """\
-LIST THE INSIGHTS (terse — one line each, not an essay):
-Before coding, list the insights you want to present/convey/highlight as `1 - : ..`
-Example: `1 - Line chart of weekly signups: shows growth inflection after the March launch, flags whether momentum is sustained.`
-This is a checklist, not a brief — no narrative prose, no design discussion.
-
-BUILD THE DASHBOARD — use multiple scratchpad cells, but produce ONE single self-contained HTML file:
-
- CRITICAL: The final dashboard MUST be a single .html file with ALL data, CSS, and JS inlined. \
-Do NOT reference external local files (like data.js) — browsers block local file:// cross-references \
-for security reasons and the dashboard will silently fail to load data.
-
- SECURITY (critical): Dashboards may be published to the web. NEVER embed API keys, tokens, \
-passwords, connection strings, or any credentials in the HTML, JS, or inline data. Fetch data \
-in scratchpad cells using credentials from environment variables, then serialize only the \
-resulting data into the dashboard. If the user explicitly asks to embed a credential \
-(e.g. for a live-updating dashboard), warn them that publishing will expose it and get \
-confirmation before proceeding.
-
- Build the parts in separate cells, then assemble at the end:
-
- CELL 1 — Serialize data to a JS string variable (programmatic, no HTML):
- Serialize all computed data (dataframes, metrics, KPIs) into a Python string. Build a \
-Python dict with keys like "kpis", "tables", "charts" — each containing the relevant data. \
-Convert DataFrames with df.to_dict(orient='records'). Use json.dumps(data, default=str) to \
-handle dates, Decimal, numpy types. Store as a Python variable: \
-`data_js = 'const D = ' + json_string + ';'` — do NOT write to a separate file.
-
- CELL 2 — Build CSS + HTML structure as a Python string variable:
- Write the HTML head (styles, CDN script tags) and body structure (header, KPIs, chart divs, \
-tabs, tables) as a Python string variable `html_body`. This cell builds the template.
-
- CELL 3+ — Build JS chart rendering logic as Python string variables:
- Write the JavaScript that initializes charts, populates tables, handles tabs, etc. \
-Split across multiple cells if needed to avoid token limits. Store as `js_charts` etc.
-
- FINAL CELL — Assemble and write the HTML file:
- Combine: `html = html_body.replace('
+
+
+
+
+
+
+
+