Skip to content

fix(agent): every part of a combined follow-up reaches the plot - #12510

Open
MarkusNeusinger wants to merge 5 commits into
mainfrom
fix/agent-combined-requests
Open

MarkusNeusinger wants to merge 5 commits into
mainfrom
fix/agent-combined-requests

Conversation

@MarkusNeusinger

Copy link
Copy Markdown
Owner

Summary

  • The server owns the language rewrite. In the user test of 2026-11-01, "make the title German and use a log scale" reached the plot with the German title only. root.md told the root to call set_language "alone, before any other tool" and then plot_pipeline with a fixed request that ends "change nothing else" (agents/anyplot/prompts/root.md:24 on main), so the root had to merge the user's other change into a sentence that forbade it. No code path dropped the request: the adapter already rewrites the plot's text whenever the base version is in another language (language_changed). Now pipeline.rewrite_request supplies the rewrite request only when the root sent no change of its own. The root's change_request carries only the message's other changes. plot_outdated: false no longer means "call no plot_pipeline" when the message asks for more, and a language request before the first plot passes its other changes to the first plot.
  • A theme goes only into theme. The live baseline found a second defect: for "make it dark and add vertical grid lines", the root wrote "dark background" into the change request as well as theme="dark". In 1 of 3 runs, the adapter then replaced PAGE_BG and INK with fixed dark colours, which breaks the light and dark switch. root.md now sends a theme only as theme, puts every part of a combined message into the one call, names each part in the reply, and gives one sentence for an in-scope part that cannot be done.
  • Follow-up checks in the eval harness. case.json has an optional checks block (cases.FollowUpChecks) that matrix.follow_up_checks measures on the version the follow-up shipped: the plot language, the theme, code_added patterns (match the shipped code, not the first version's), code_kept patterns (match both), texts_changed roles in PlotShows.texts, and an empty requested_not_found. A failed check fails the run, and the report lists it under check_failures. There are four new cases: language with a log scale, theme with a grid, language with a colour, and a log scale alone as the control.

Decided without escalation and documented here:

  • The language-only path keeps the old rewrite sentence as the server's LANGUAGE_REWRITE_REQUEST, so it behaves as before.
  • The colour case uses English region names, because the first baseline run's German-sounding names made the paste set the session to German.
  • I reproduced the drop zero times in 8 baseline runs on Haiku: the root merged both parts into its change request each time. The mechanism is the prompt text above. The theme defect did reproduce.

Gemini 3.8 Flash pre-PR check: 6 findings, all addressed.

  • I fixed the multi-line call finding with patterns that handle nested parentheses rather than re.DOTALL, which would let .* reach a later savefig(facecolor=PAGE_BG).
  • set_yscale(value=...), more blue spellings, and a positional y-only grid are now covered.
  • "Cannot be done" now applies only to in-scope parts, and a theme with only a language leaves change_request out.

Plan

N/A (brief from the lead session; the owner approved the fix on 2026-11-01)

Test plan

  • ruff check, ruff format --check, and mypy agents pass.
  • pytest tests/unit/agents: 19,471 passed. The one failure was an old root.md assertion, since updated; afterwards I reran the touched suites (979 passed).
  • New unit tests: rewrite_request, plus a service flow test in which set_language and the other change reach the adapter together with language_changed and are stored in the version's requests. The language-only flow now gets the server's request. The new tests also cover the policy wording, FollowUpChecks loading and validation, each case's patterns against real and near-miss code, follow_up_checks for each failure, and a scripted matrix run that passes with the log scale and fails without it.
  • Live matrix, Haiku 5.5 on Vertex eu, remote renderer, $0.67 in all:
Case Before (main root.md) After
Language and log scale 6/6 both parts 3/3, change request "Use a logarithmic scale on the y axis."
Language and colour 2/2 both parts 3/3
Theme and grid 3/3 grid; theme words in the change request 3/3; theme tokens overwritten 1/3 3/3, theme only as theme; every code_kept check held
Log scale alone (control) 3/3 3/3

Every after reply names each change. The "before" arm ran the branch's harness with main's root.md swapped in. The new pipeline step is a no-op there, because that prompt always sends a change request.

https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8

MarkusNeusinger and others added 3 commits November 1, 2026 23:58
A follow-up such as "make the title German and use a log scale" could reach
the plot with the language part only: root.md had the root follow
`set_language` with a fixed rewrite request ending "change nothing else".
The rewrite is the server's now (`pipeline.rewrite_request`): the adapter
rewrites the text on `language_changed` anyway, the root's change request
carries only the user's other changes, and a run with none gets the
server's own rewrite request. A theme goes only into `theme`: written into
the change request, "a dark background" made the adapter hardcode the dark
colours over the theme tokens.

The matrix harness gets follow-up `checks` in case.json (language, theme,
code patterns added or kept, changed drawn texts, an empty
requested_not_found) and four combined-request cases.

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
… review)

The eval patterns read multi-line calls (one level of nested parentheses,
never across calls), `set_yscale(value="log")`, more blues and a positional
y-only grid; root.md limits "a part that cannot be done" to in-scope parts
and says a theme with only a language leaves `change_request` out.

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:18
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H7HSkGyea1k2v293XiAMo8

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

A moderate validation bug allows empty or null follow-up checks to pass despite the documented requirement for a substantive check, and the changelog fragment also contains hardcoded PR references.

2 open issues
What changed in this PR

This pull request fixes combined agent follow-ups so language, theme, and additional plot changes reach the plotting pipeline together. It also adds evaluation fixtures and regression coverage to verify that requested changes are present in the shipped version.

Changes:

  • Moves language-only rewrite behavior into pipeline.rewrite_request.
  • Updates root-agent guidance to preserve combined changes and pass themes through theme.
  • Adds four evaluation cases, follow-up validation, reporting, documentation, and runtime tests.

Review findings remain unresolved:

  • Moderate, 1 vote: agents/anyplot/prompts/root.md:43 should distinguish plot changes from data changes, leaving data mutations on the prepare_data path.
  • Moderate, 2 votes: agents/evals/cases.py:179 should reject checks whose fields are all empty or null.
  • Moderate, 1 vote: the theme-and-grid fixture should require an enabling grid argument rather than accepting ax.grid(False).
  • Moderate, 1 vote: agents/evals/matrix.py:1086 should preserve missing PlotShows state and require actual evidence for requested_found.
  • Nit, 2 votes: changelog.d/agent-combined-requests.md should omit the hardcoded PR number, including the reference on line 25.
File Reviewed change
tests/​unit/​agents/​runtime/​test_service_flow.py Tests server rewrite behavior and combined requests reaching the adapter.
tests/​unit/​agents/​runtime/​test_policy.py Verifies updated root-agent policy wording.
tests/​unit/​agents/​runtime/​test_pipeline.py Tests server-owned language rewrite construction.
tests/​unit/​agents/​evals/​test_matrix.py Tests follow-up checks, failure reporting, and matrix behavior.
tests/​unit/​agents/​evals/​test_cases.py Tests fixture loading, validation, and combined-request patterns.
docs/​concepts/​agent-network.md Documents server-side language rewriting and combined requests.
changelog.d/​agent-combined-requests.md Records the combined-request fix and evaluation coverage.
agents/​README.md Updates the evaluation fixture inventory.
agents/​evals/​report.py Reports follow-up check failures and incorporates them into results.
agents/​evals/​matrix.py Evaluates shipped-version facts and applies follow-up checks.
agents/​evals/​fixtures/​README.md Documents the expanded fixture format and checks.
agents/​evals/​fixtures/​cases/​scatter-basic-matplotlib-combined-theme-grid/​data.csv Provides synthetic scatter-plot data.
agents/​evals/​fixtures/​cases/​scatter-basic-matplotlib-combined-theme-grid/​change_request.txt Defines the combined theme and vertical-grid request.
agents/​evals/​fixtures/​cases/​scatter-basic-matplotlib-combined-theme-grid/​case.json Defines theme, grid, and code-preservation checks.
agents/​evals/​fixtures/​cases/​line-basic-matplotlib-combined-language-log/​data.csv Provides synthetic line-plot data.
agents/​evals/​fixtures/​cases/​line-basic-matplotlib-combined-language-log/​change_request.txt Defines the combined language and log-scale request.
agents/​evals/​fixtures/​cases/​line-basic-matplotlib-combined-language-log/​case.json Defines language, title, and log-scale checks.
agents/​evals/​fixtures/​cases/​line-basic-matplotlib-combined-control-log/​data.csv Provides control-case data.
agents/​evals/​fixtures/​cases/​line-basic-matplotlib-combined-control-log/​change_request.txt Defines the log-scale-only control request.
agents/​evals/​fixtures/​cases/​line-basic-matplotlib-combined-control-log/​case.json Defines the control fixture checks.
agents/​evals/​fixtures/​cases/​bar-basic-seaborn-combined-language-colour/​data.csv Provides synthetic bar-plot data.
agents/​evals/​fixtures/​cases/​bar-basic-seaborn-combined-language-colour/​change_request.txt Defines the combined language and colour request.
agents/​evals/​fixtures/​cases/​bar-basic-seaborn-combined-language-colour/​case.json Defines language, title, and colour checks.
agents/​evals/​cases.py Defines and validates follow-up check configuration.
agents/​anyplot/​prompts/​root.md Updates instructions for combined language, theme, and plot changes.
agents/​anyplot/​pipeline.py Adds server-owned language rewrite request handling.

Review effort: Lite

Comment thread agents/evals/cases.py Resolved
Comment thread changelog.d/agent-combined-requests.md Resolved
…quested_found

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

❌ Patch coverage is 97.80220% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
agents/evals/matrix.py 94.73% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

This branch has not been deployed

No deployments
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