Repository navigation
feat(agent): short replies, questions only when they matter - #12506
Merged
Merged
Conversation
Owner decision of 2026-11-01 after the user test: replies are short and to the point, and a follow-up question comes only when it really matters. - root.md: a "Replies" section. The reply leads with the result in two or three sentences; the notices the data rules require stay (the loader's reads, keeps-time and converts lines, data changes with their counts, requested_not_found, refusals and limits). A question only when the turn cannot go on without it or the answer changes the data or the plot materially; no closing offer; an "offer" elsewhere in the instruction is said as a statement; a user's answer is acted on in the same turn. The step-1 summary no longer asks by default. - adapter.md and the self-review line: the "what changed" notes are in the plot language, in plain words without the code's names, without what stayed the same, and a fix lists only itself. - prep eval: every reply is measured (words, questions, a closing question); a closing question the turn was not blocked for, or a reply over 100 words, is a reply miss, gated at 10 %. A case can send the summarize_data action; four summary cases added. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
- root.md: a statement of what is possible may close a reply; only an invitation may not (Gemini Flash pre-check). - prep eval: a turn that leaves a required role of the spec without a column is blocked, the case root.md names for a question. - test_policy covers all seven loader prefixes. - changelog fragment. 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
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
An import-blocking NameError in PrepCase plus an incorrect even-count median calculation and stale golden-test documentation leave active correctness and maintainability issues.
3 open issues
What changed in this PR
This pull request makes agent replies shorter and more purposeful, asks follow-up questions only when necessary, and acts on user answers in the same turn. It also extends prep evaluation with summary actions, reply metrics, blocked-turn handling, and a reply-miss gate.
Changes:
- Adds concise reply and meaningful-question guidance.
- Updates adapter notes to use plain, plot-language descriptions without code-specific names.
- Adds summary-action fixtures and reply behavior measurements.
- Updates tests, documentation, README guidance, and the changelog.
This pull request requires changes.
| File | Description |
|---|---|
tests/unit/agents/runtime/test_policy.py |
Tests the updated reply and adapter-note prompt rules. |
tests/unit/agents/evals/test_prep.py |
Tests summary fixtures, reply measurement, blocked turns, and reply gating. |
docs/reference/api.md |
Documents the updated summary behavior and current bindings. |
docs/concepts/agent-network.md |
Describes concise replies, required notices, and current bindings. |
changelog.d/agent-replies-short.md |
Records the reply-policy and prep-evaluation changes. |
agents/README.md |
Documents prep evaluation cases, actions, and reply metrics. |
agents/evals/prep.py |
Adds summary actions, reply measurement, blocked-turn detection, reporting, and gating. |
agents/evals/fixtures/prep/en-summary-daily-readings.json |
Adds an English daily-readings summary case. |
agents/evals/fixtures/prep/en-summary-ambiguous-dates.json |
Adds an English ambiguous-date summary case. |
agents/evals/fixtures/prep/de-summary-haustiere.json |
Adds a German pet-count summary case. |
agents/evals/fixtures/prep/de-summary-ausgaben-breit.json |
Adds a German wide-table summary case. |
agents/anyplot/prompts/root.md |
Defines concise replies, meaningful questions, protected notices, and same-turn handling. |
agents/anyplot/prompts/adapter.md |
Requires concise plot-language notes without code-specific wording. |
agents/anyplot/pipeline.py |
Prevents self-review notes from repeating prior adapter changes. |
Review effort: Lite
Copilot review of #12506: an even number of replies took the upper middle value as the median; the pinned adapter-prompt test no longer claims the prompt from before the split. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Brings in #12505 and #12503. The one conflict, the messages row of docs/reference/api.md, takes main's `?theme=` wording and keeps this branch's summary clause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
Brings in #12504; merged without conflicts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
The notes explain the plot to the user, so they belong in the language the user chats in (lead, 2026-11-01). Since #12504 the plot language can differ from the session language: AdaptRequest gains `reply_language`, set only when the two differ and fenced as `<reply_language>` after the plot language, and adapter.md writes `changes` in it while the plot text stays in the plot language. Without the field the notes follow the plot language, which then is the reply language too. The design doc's two lines that said the notes stay English now say which language they take. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8
MarkusNeusinger
added a commit
that referenced
this pull request
Nov 1, 2026
## Summary - Cuts v3.6.0 "All fifteen": `tools.changelog release` folds the 95 fragments of the window into `## [3.6.0] — 2026-11-01 — All fifteen` (170 entries: Added 63, Changed 57, Removed 2, Fixed 42, Security 6), repoints the compare links and bumps `pyproject.toml`, `uv.lock` and `app/package.json` to 3.6.0. - The window is 253 squash-merged PRs since v3.5.0 (#12160 to #12506). The milestone: the agent chat ("Use with my data") serves all 15 libraries for admins, plus today's user-test fixes #12502 to #12506. #12507 and the open sample-data, combo-request, date-convert and data-grid work are not on main and not in this release. - Hand-written aggregate lines: the `**Dependencies:**` bullet (14 Dependabot PRs; four security updates close 60 advisories, four critical and 32 high) and the italic `*Catalog:*` line (no new implementations or specs; 138 regenerations, 127 of them the MUI X 9 migration, 11 daily-regen improvements; 3 stored re-scores; coverage unchanged at 315 of 325 specs). Routine decisions, documented here: - Ten fragment bullets had no PR reference (`/pull_request` step 7 never ran for #12404, #12408, #12409, #12235, #12458, #12461, #12462). Before the cut, their real numbers were appended (found with `git log --diff-filter=A` on each fragment), and the two Jules fragments (#12408, #12409) were wrapped to the file's line width without changing their wording. - Completeness: every non-bot commit in `v3.5.0..origin/main` has an entry except #12469, #12471 and #12472 (`skip-changelog`; a temporary DEBUG diagnosis and its revert, net zero) and #12298 (`plots/`-only metadata attribution, exempt). No fragment was added. - Catalog count: implementation-file changes in the window, classified by whether the file existed at `v3.5.0` (all did, so no new implementations), cross-checked against the merged pipeline PRs' labels on GitHub (127 `regen:forced`, 11 `regen:improved`, 3 `review-writeback`); the MUI X split comes from `library_version` and `generated_by` in `plots/*/metadata/javascript/muix.yaml`. Advisory counts are unique GHSA ids of the Dependabot alerts fixed after the v3.5.0 tag; the nanoid and `@vitest/mocker` alerts closed by #12235 and #12249 belong to those PRs' own entries and are not counted. ## Plan `agentic/commands/release.md`, steps 1 to 5. The tag and the GitHub release (steps 6 and 7) follow after the merge. ## Test plan - [x] `uv run python -m tools.changelog release 3.6.0 --title "All fifteen" --dry-run`, then the real run - [x] The diff touches only `CHANGELOG.md`, `pyproject.toml`, `uv.lock`, `app/package.json` and the 95 deleted fragments - [x] `uv lock --check` passes; the lock changes only the project's own version line - [x] `uv run pytest tests/unit/test_version_sync.py` passes (2 tests) - [x] `uv run python -m tools.changelog check --base origin/main` passes - [ ] CI green https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Summary
root.mdgets a "Replies" section. A reply leads with the result in two or three sentences, asks a question only when the turn cannot go on without the answer or the answer changes the data or the plot materially, closes with no invitation, and acts on the user's answer in the same turn. Brevity never drops a notice the data rules require: the loader's "reads", "keeps time" and "converts" lines, data changes with their counts,requested_not_found, binding warnings, tool errors and limits. The step-1 summary no longer asks a question by default and lists nothing the data does not have.load_user_data(), without what stayed as it was, and a fix lists only itself (adapter.md, and the self-review line inpipeline.py).--max-reply-misses). A turn is blocked when the case is taggedask_back, a data call failed, or a required role is left without a column. A case can send the page'ssummarize_dataaction, and four summary cases join the set.Decided and documented here:
root.md: the information stays, said as one short statement, through one rule in "Replies" rather than an edit of every passage. This keeps the diff away from the lines fix(agent): read the drawn texts of every library for the reply #12503 and fix(agent): a follow-up message keeps the plot's language #12504 change. Onlyneeds_attentiondrops its "offer to fix one" outright: the user asks when they want a fix.AdaptRequest.reply_languagecarries the session language only when it differs from the plot language, fenced as<reply_language>after the plot language. The adapter then writeschangesin it and keeps the plot text in the plot language. Without the field the two languages are the same.root.mdallows at most.Measurements
Claude Haiku 5.5 on Vertex AI
eu, $0.985 in all.Seven scripted chats rebuilt from the user test (A1, A3, B1, B4 and three summaries, two of them run twice), through
/v1in process with the deployed renderer, 20 replies per arm. The baseline arm ran on theorigin/mainprompts.plot_pipelinewith "Set the value axis to run from 0 to 100 ...", and the axis runs from 0 to 100.loadUserData(). On this branch they are German, with no code names.The prep eval (55 cases) ran with the same eval code on both arms:
The main arm ran before the open-role rule joined the blocked definition, so its reply-miss count is not comparable one to one. The closing-question and question counts are.
Pre-PR Gemini 3.8 Flash check ($0.21, three findings):
Copilot review (one round, three findings):
NameErroronPrepCase's return annotation. The module hasfrom __future__ import annotationsand runs on Python 3.14, and its tests pass.Plan
N/A (brief from the lead session; owner decision of 2026-11-01)
Test plan
ruff check .,ruff format --check .,mypy api core agentspytest tests/unit tests/integration -n 6: 25,857 passed. New tests cover the "Replies" rules and every protected notice, the action-or-message case model, the reply measurement (closing question, long reply, and blocked byask_back, by a failed call or by an open role), the reply gate, and a scripted summary run.origin/main(feat(agent): the plot follows the site theme #12505, fix(agent): read the drawn texts of every library for the reply #12503, fix(agent): a follow-up message keeps the plot's language #12504) and the reply-language commit:ruff,mypy api core agents, andpytest tests/unit tests/integration -n 6with 25,934 passed. Two flow tests through/v1pin that a German plot under English replies gets its notes in English and the reverse, and that no<reply_language>block appears while the two languages agree.Open points
matrix.pywould collide with fix(agent): read the drawn texts of every library for the reply #12503.https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8