Skip to content

feat(agent): example data on request in the data field and the chat - #12509

Merged
MarkusNeusinger merged 7 commits into
mainfrom
feat/agent-example-data
Nov 2, 2026
Merged

MarkusNeusinger merged 7 commits into
mainfrom
feat/agent-example-data

Conversation

@MarkusNeusinger

Copy link
Copy Markdown
Owner

Summary

  • Detection, no new model call. "Beispieldaten", "generiere Zufallszahlen mit Kategorien" or "random numbers with 3 categories" in the data field now answer 422 data_request instead of "no table found". Fixed phrases in eight languages catch the common cases before any model (classify.looks_like_data_request: one line, at most 30 words, fewer than three values of its own). The transcriber that already reads every other free text gets an asks_for_data field for the rest ("monthly sales for 4 regions", other languages). The server honours that field only for text the chat takes, when the answer holds no table or the text no values of its own, and drops any table that came with it, so no model-written row reaches the user. The BFF passes the code through. The page sends the text to the chat as the user's message at once (no extra click) and empties the box.
  • Generation by code the root writes. The root reads the spec's roles (get_spec_brief) and calls run_data_code with the new source_language example: one column per role, realistic labels and ranges, the user's counts, and np.random.default_rng(42). The sandbox computes the table; the validator's literal-data rule still applies. The change line reads generated example data: <rows> rows, <columns> columns, the source line for the adapter and reviewer names it, and .undo(), confirmation and a new paste work as before. The same path answers a request typed into the chat. The scope rubric calls made-up example data in_scope; real figures (a named company, "the official numbers") stay needs_data.
  • Telemetry and docs. Closed enums gain data_input.format/outcome data_request (cause transcribed_data_request from the transcriber) and chat_turn.kind example; Plausible's agent_data_parsed gains status data_request. Docs: design doc, API reference, telemetry reference (with a "shifts" note), Plausible, agents README.

Decisions (decide-and-document)

  • Detection: both halves. The rules cost nothing and cover the owner's own words; the transcriber covers other wording and languages without an extra call. A request that names three sizes ("3 Kategorien, 4 Regionen und 12 Monaten") is left to the transcriber by the rules (three numbers) and goes on its no-table answer.
  • Hand-off: automatic. The page sends the text as the user's message, as the lead suggested.
  • Generation: run_data_code, not a server-side generator. A spec's data needs structure that no list of role kinds states (a value for every category and group pair, a trend over dates, a relation between x and y, high above low). The root reads that from the spec's description, and the code it ran is shown under the data. Cost: one data run per request, counted toward AGENT_DAILY_DATA_RUNS (30), and the run queue's start window. At the default of one start a minute, the first .create_plot() can wait up to a minute behind it.
  • Marking: source_language example instead of a new tool, so ToolSafety, the result caps and the run queue stay as they are.

Live check (Claude Haiku 5.5, eu, the deployed renderer)

Each case ran from the data field (or the chat) through a confirmed table to a shipped plot:

Input Spec, library Generated table Plot
"Beispieldaten" (rules) bar-grouped, matplotlib 16 rows: Quartal, Region, Umsatz ok
"generiere Zufallszahlen mit Kategorien" (rules) scatter-basic, plotly 200 rows: Kategorie, x, y ok
"example data: 36 months of daily-average temperatures between -5 and 25 degrees" (rules) line-timeseries, ggplot2 1,096 rows: date, temperature ok
"monthly sales for 4 regions over 6 months" (transcriber) bar-grouped, seaborn 24 rows: month, region, sales ok
"Can you make up some example data for this plot? 24 weekly values." (chat) line-timeseries, Chart.js 24 rows: week, value ok

Cost: $0.15 for the six runs (one case twice), about $0.03 for a request with its plot. Prep eval --tags example_data: 3 of 3, $0.010, replies of 39 words at the median. Scope eval on the seven new cases: 7 of 7, $0.004. The two English cases in the first live round got German column names from the prompt's German example; the prompt now gives both and names the plot language.

Review before opening

Gemini 3.8 Flash ($0.15, Flex): 4 findings. Applied: a request with three sizes ended in "no table found" (the transcriber gate now takes the model's no-table answer); the data field's hint now quotes the words to type. Skipped: "get_spec_brief and set_bindings do not exist" (both are root tools in SESSION_TOOLS), and the "leak" of a transcribed table when the text holds values (that is the transcriber's ordinary, user-confirmed path).

Deploy order

The BFF must know data_request before the agents service sends it; both deploy from main on merge. A gap answers the page with a generic error for such text, where it said "no table found" before.

Plan

N/A (owner request of 2026-11-01, relayed by the lead)

Test plan

  • uv run pytest tests/unit tests/integration -n 6: 25,939 passed before the merge of origin/main; the agents and BFF suites (19,889) after it
  • New tests: tests/unit/agents/data/test_classify.py (German, English and six more languages, true negatives: tables, a list under a request word, JSON, prose with values, a formula, code; linear-time pattern), tests/unit/agents/runtime/test_example_data.py (both detection paths, paste counting, telemetry lines, the gate on the transcriber's flag, the change and source lines, a full turn with chat_turn.kind example), BFF passthrough, the hook and the data panel
  • ruff check, ruff format --check, mypy api core agents
  • cd app && yarn lint && yarn fm:check && yarn type-check && yarn test && yarn build
  • Headless playwright-core against the mock BFF, desktop light and mobile dark: the hint and placeholder, "Beispieldaten" answered 422 data_request becomes the user's message in the thread, the box empties, no error shows (only the local font CORS console noise)
  • Live check on Haiku in eu (table above), prep and scope evals on the new cases

https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8

MarkusNeusinger and others added 4 commits November 1, 2026 23:51
"Beispieldaten" or "generiere Zufallszahlen mit Kategorien" in the data
field ended in "no table found". The dataset route now answers
`422 data_request` for text that asks for data instead of holding it:
fixed phrases in eight languages before any model
(`classify.looks_like_data_request`), and the transcriber's new
`asks_for_data` for data described in words, honoured only for text the
chat takes that holds no values of its own. The page sends the text to
the chat as the user's message at once and empties the box.

The root reads the spec's roles and writes seeded Python for
`run_data_code` with `source_language` `example`; the sandbox computes
the table, so no model writes a row. The change line says
`generated example data`, the source line for the adapter and reviewer
names it, and `chat_turn.kind` is `example`. The scope rubric calls
made-up example data in scope and keeps real figures `needs_data`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
The transcriber's asks_for_data now counts when its answer holds no table, whatever numbers the text names, so "Beispieldaten mit 3 Kategorien, 4 Regionen und 12 Monaten" no longer ends in "no table found". The data field's hint quotes the words to type. Found by the Gemini Flash pre-PR check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
Copilot AI lite review requested due to automatic review settings November 1, 2026 23:11
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
@codecov

codecov Bot commented Nov 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The changelog fragment contains a bare (#12509) placeholder that the changelog check rejects and must be removed.

1 open issue
What changed in this PR

This pull request adds multilingual support for requesting generated example data from the data panel or agent chat. Requests are routed through the existing sandboxed data-generation flow, with provenance labeling, telemetry, scope rules, frontend handoff behavior, documentation, and test coverage.

Changes:

  • Detects example-data requests before parsing or through the transcriber, then forwards them to chat.
  • Generates deterministic example tables through run_data_code using source_language: "example".
  • Adds API, telemetry, Plausible, prompt, scope-evaluation, documentation, and UI updates.
  • Adds regression tests and evaluation fixtures across the agent and frontend flows.
File Description
tests/​unit/​api/​test_agent_router.py Tests BFF passthrough of data_request.
tests/​unit/​agents/​runtime/​test_policy.py Tests example-data scope classification.
tests/​unit/​agents/​runtime/​test_models.py Verifies the transcriber schema includes asks_for_data.
tests/​unit/​agents/​runtime/​test_example_data.py Covers detection, generation, provenance, telemetry, and full-turn behavior.
tests/​unit/​agents/​evals/​test_scope.py Tests made-up versus real-world data scope cases.
tests/​unit/​agents/​evals/​test_prep.py Includes example-data preparation fixtures.
tests/​unit/​agents/​data/​test_classify.py Tests multilingual request detection and false positives.
docs/​reference/​plausible.md Documents the new Plausible parse status.
docs/​reference/​api.md Documents the data_request response and workflow.
docs/​reference/​agent-telemetry.md Documents telemetry enum additions and reporting shifts.
docs/​concepts/​agent-network.md Describes detection and generated-data architecture.
changelog.d/​agent-example-data.md Adds the release-note fragment. Nit: remove the (#12509) placeholder.
app/​src/​sections/​agent-chat/​DataPanel.tsx Clears the data field after chat handoff and updates hints. Moderate: preserve edits entered while the request is in flight instead of unconditionally clearing them after the delayed response.
app/​src/​sections/​agent-chat/​DataPanel.test.tsx Tests data-field clearing behavior.
app/​src/​pages/​AgentChatPage.tsx Updates chat guidance and placeholders.
app/​src/​pages/​AgentChatPage.test.tsx Tests updated UI copy.
app/​src/​lib/​agent.ts Documents the new dataset response behavior.
app/​src/​hooks/​useAgentSession.ts Handles data_request responses and starts the chat turn.
app/​src/​hooks/​useAgentSession.test.ts Tests automatic chat handoff and generated-data state.
api/​routers/​agent.py Allows and documents the new upstream error code.
agents/​README.md Records new evaluation coverage and results.
agents/​main.py Detects transcriber requests and returns data_request.
agents/​evals/​scope.evalset.json Adds example-data scope cases.
agents/​evals/​fixtures/​prep/​en-example-data-monthly.json Adds a monthly example-data preparation case.
agents/​evals/​fixtures/​prep/​en-example-data-50-points.json Adds a scatter example-data preparation case.
agents/​evals/​fixtures/​prep/​de-beispieldaten-regionen-jahre.json Adds a German example-data preparation case.
agents/​anyplot/​tools/​session.py Adds example-data source labeling and change lines.
agents/​anyplot/​telemetry.py Adds data-request and example-turn telemetry enums.
agents/​anyplot/​prompts/​transcriber.md Teaches the transcriber to flag data requests.
agents/​anyplot/​prompts/​scope_judge.md Defines example data as in scope and real figures as requiring data.
agents/​anyplot/​prompts/​root.md Adds the example-data generation workflow and constraints.
agents/​anyplot/​plugins/​tool_safety.py Allows example as a data-code source.
agents/​anyplot/​plugins/​ledger.py Tracks example-data generation per turn.
agents/​anyplot/​dataset_context.py Labels generated example data in dataset source metadata.
agents/​anyplot/​data/​transcribe.py Adds the transcriber’s asks_for_data field.
agents/​anyplot/​data/​generate.py Adds shared stated-value counting for request detection.
agents/​anyplot/​data/​classify.py Implements fixed-phrase and transcriber-based request classification.

Review effort: Lite

Comment thread changelog.d/agent-example-data.md Resolved
The data box is editable while the parse runs; the hand-off to the chat now empties it only while it still holds the text that went. Copilot review of #12509.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
@MarkusNeusinger

Copy link
Copy Markdown
Owner Author

Review triage: applied the overview's moderate note on DataPanel.tsx (an edit made while the request was in flight is now kept: the box empties only while it still holds the text that went to the chat, with a test). Skipped the fragment finding: (#12509) is the real PR number, which /pull_request step 7 appends; the checker refuses only the literal letter placeholder, and tools.changelog check passes.

@MarkusNeusinger
MarkusNeusinger merged commit a55a5c7 into main Nov 2, 2026
16 checks passed
@MarkusNeusinger
MarkusNeusinger deleted the feat/agent-example-data branch November 2, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants