Add resolved YAML render output format
Problem
The existing render formats serve different audiences: HTML/SVG for humans, JSON for programmatic access, text for compact AI summaries. But none produce output that is both human-readable AND re-renderable as valid dataface input. AI agents work in YAML — they write it, edit it, iterate on it. A "resolved YAML" format would let agents see exactly what the system decided (chart types, fields, data) in the same language they author dashboards in, and that output could be fed back in as input.
Context
dataface/core/render/json_format.py—_face_to_dict()already walks the layout, executes queries, resolves charts, returns structured dicts. The YAML format reuses this.dataface/core/render/renderer.py— format dispatch +RENDER_FORMATStuple- The dataface YAML schema supports
values:as an inline data source (alternative tosql:). The resolved YAML replaces queries with their executed results asvalues:. dataface/core/compile/— normalizer/compiler that the output must be compatible with as input- Related:
format="json"(PR #623),format="text"(PR #624), playground fixes (PR #625)
Possible Solutions
-
Recommended — Map resolved dict back to dataface YAML schema. Call
_face_to_dict(), then transform the result into valid dataface YAML: top-leveltitle,source,queries(withvalues:instead ofsql:),charts(with resolved types/fields),rows/cols/gridlayout. Output viayaml.dump(). The result is a valid.ymlfile that can be re-compiled and rendered without a database. -
Dump
_face_to_dict()directly as YAML. Simpler but the output wouldn't be valid dataface input — it uses the internal JSON structure (nested items, chart objects) rather than the user-facing YAML schema (flat charts dict, layout references).
Plan
Files to create:
- dataface/core/render/yaml_format.py — render_face_yaml() that transforms resolved data into dataface YAML schema
Files to modify:
- dataface/core/render/renderer.py — add elif format == "yaml" + add to RENDER_FORMATS
- dataface/cli/commands/render.py — yaml prints to stdout like json/text
- dataface/cli/main.py — update --format help
- dataface/ai/tool_schemas.py — add "yaml" to format enum
- apps/playground/routes.py — add yaml format case (same as json/text — HTML-wrapped pre block)
- apps/playground/static/index.html — add YAML option to dropdown
- apps/playground/websocket.py — already handled generically
- tests/core/test_yaml_format.py — tests
Key design decisions:
- Queries become values: with the executed data rows inline
- Auto chart types resolved to concrete types
- Auto-detected x/y/color fields filled in explicitly
- The output must round-trip: render --format yaml | compile should succeed
- Layout preserved as rows/cols/grid references
Steps:
1. Write failing test: render a face with format="yaml", assert output is valid YAML, contains resolved chart type, has values instead of sql
2. Implement render_face_yaml() — reuse _face_to_dict, map to dataface schema
3. Write round-trip test: render to yaml, re-compile, verify success
4. Wire into renderer, CLI, MCP schema, playground
5. Run just ci
Implementation Progress
Approach: Solution 1 — Map resolved dict back to dataface YAML schema
render_face_yaml() reuses _face_to_dict() from json_format.py (shared with text format), then transforms the internal JSON structure into valid dataface YAML schema:
- Queries: SQL/CSV/HTTP queries become
type: valueswithrows:containing the executed data inline - Charts: Auto chart types resolved to concrete types (bar, line, etc.), auto-detected fields (x, y, color) filled in explicitly, referencing their query by name
- Layout: Preserved as
rows:with chart name references - Nested faces: Recursively converted and inlined in layout
- Type coercion:
Decimal→ int/float,datetime→ ISO string,DotDict→ dict for clean YAML output
Files created
dataface/core/render/yaml_format.py—render_face_yaml()+_face_to_yaml_dict()+_chart_to_yaml_dict()+_clean_value()tests/core/test_yaml_format.py— 9 tests: basic output, resolved fields, values-not-sql, auto-type resolution, layout preservation, KPI charts, round-trip compile, nested faces, multiple charts with distinct queries
Files modified
dataface/core/render/renderer.py— addedformat == "yaml"dispatch (lazy import)dataface/cli/commands/render.py— added"yaml"to stdout format listdataface/cli/main.py— updated--formathelp textdataface/ai/tool_schemas.py— added"yaml"to MCP tool format enum with descriptionapps/playground/routes.py— added"yaml"to json/text format handling branchapps/playground/static/index.html— added YAML option to format dropdown
Validation
- 9/9 YAML format tests pass
- All 2855+ tests pass (1 pre-existing flaky test in
test_ai_service.py) - Ruff, Black, Mypy all clean
QA Exploration
N/A — non-UI-rendering task. The playground dropdown was updated but the core feature is a text output format consumed by CLI and MCP.
- [x] QA exploration completed (or N/A for non-UI tasks)
Review Feedback
- [ ] Review cleared