Real clinic data. Live LLM. The model never sees a row.
The model below is a librarian who has never read any of the books. It sees a menu of 21 named queries and a handful of chart components — descriptions only, no schema, no rows, no patient data of any kind. When you ask a question, it picks an entry and a chart by name, then writes a small JSON plan. The runner executes the plan against D1, the renderer draws the result. The model is never in the loop with the data.
how it works in 30 seconds ▸
1. The carte is 21 typed queries. Each one declares a name, a description, typed parameters, a typed return shape, an optional RBAC predicate, and a query function. The LLM's prompt contains the descriptions and shapes — never the data behind them.
2. You type a question. The LLM picks one query id, fills in parameters, picks a chart component, and writes a JSON plan. That's all it can do.
3. The plan is validated (does the entry exist? does the user's role allow it? do the bound fields exist on the return shape?), then executed. Rows go from D1 to the chart component. The LLM never sees them — not in this turn, not in retry, not in errors.
Switch the role dropdown to watch entries appear and disappear from what the LLM is allowed to ask. The role gate is enforced twice: at prompt-time (entry stripped from the menu) and at validation-time (forged plans rejected even if a model emits one).
appointments + demographics only
plan▸
(none yet)
results▸
(none yet)