feat(a2a): inject conversation history on context resume (multi-turn) - #77526
feat(a2a): inject conversation history on context resume (multi-turn)#77526kuangmi-bit wants to merge 1 commit into
Conversation
SummaryTwo PRs address A2A multi-turn continuity. #64982 introduced a broad pre-#77109 A2A implementation including persistence and history replay, while #77526 applies the remaining history-injection change directly to the A2A implementation now on main, with bounded replay and original-only persistence/auditing. Related pull requests
Duplicates#64982 and #77526 overlap on persisted-history injection, but #77526 is the focused successor implementing that live remainder against the current A2A code; #64982 contains substantial superseded platform work beyond that overlap. Suggested consolidationKeep #77526 open with a salvage path centered on its bounded history formatter, resume-time injection, original-only persistence/auditing, and focused tests. Keep #64982 closed as superseded by #77526; this does not disregard its earlier keep_open review, because the later contributor assessment explicitly narrowed the wanted work to history injection after #77109 landed, and #77526's diff implements that requested scope. Cross-PR triage: Reviewed 2 pull requests and 0 issues in this complex. Each diff was read against this issue; Assessment working set: 80 kB of PR diffs, 4 kB of issue/PR text, 6 kB of discussion (9 comments), 0 verify verdicts. verdicts reflect diff content, not PR titles. Part of an automated triage batch. |
When a caller reuses a contextId, prepend the persisted conversation so the agent sees the full thread instead of only the latest message. - protocol.format_history(): render prior messages as 'role: text' lines, bounded by A2A_HISTORY_INJECTION_LIMIT (default 20, max 200, 0 disables) - adapter._prepare_task(): inject history before dispatch; audit and on-disk persistence keep the original (un-augmented) message so injected prefixes never accumulate in the log - tests: 9 new cases covering empty history, role rendering, limit/env, injection on resume, original-only persistence, no-duplication over three turns Closes NousResearch#64982 (superseded by this rebased implementation).
c0e4143 to
7001260
Compare
|
Rebased onto current main (per the ask in #64982) — the PR now sits on top of the merged A2A v1.0 plugin with the scope narrowed exactly to the history-injection half: guard markers in @teknium1 — you mentioned you'd be happy to review this scoped-down version; it's ready whenever you have a moment. |
|
@teknium1 — gentle ping on this one. The branch is rebased on current main and scoped exactly to the history-injection half you flagged in #64982 (guard markers in |
|
Hi @kuangmi-bit — while validating conversation persistence on current |
|
@honor2030 — thank you for the reproduction and for preserving attribution on the SHA-256 idea. To your question: I'd prefer the focused follow-up PR (#83706) over folding the collision fix into this one — keeping this PR scoped to history injection makes both easier to review, and your fix (SHA-256 filenames + v2 namespace + persisted One sequencing note: this PR should land on top of #83706 rather than before it — otherwise the injection path inherits the |
Summary
Multi-turn support for the A2A plugin that landed in #77109: when a caller reuses a
contextId, the persisted conversation is prepended to the inbound message so the agent sees the full thread — not just the latest message.Built on top of the merged official plugin (
plugins/platforms/a2a/), which already persists every exchange to disk (persist_message/load_conversation). This PR adds the missing read-back half of multi-turn.Changes
protocol.format_history(context_id, limit=None)— renders prior messages asrole: textlines (user:/assistant:). Empty string when the context has no history. Bounded byA2A_HISTORY_INJECTION_LIMITenv (default 20, max 200,0disables injection entirely).adapter._prepare_task()— on inboundmessage/send, if history exists for the context, prepend it to the text that goes to the agent. The original message is what gets audited and persisted, so injected prefixes never accumulate in the on-disk log (verified across 3+ turns).tests/plugins/test_a2a_multiturn.py— 9 tests: empty history, role rendering, limit + env override, injection on resume, original-only persistence/audit, no duplicate-prefix growth.Why it matters
A2A peers that hold a
contextIdopen across multiplemessage/sendcalls (the standard multi-turn pattern) currently get a stateless agent — the agent answers each message as if it were the first. With this, a resumed context behaves like a conversation thread.Non-goals (unchanged from #64982)
Verification
tests/plugins/test_a2a_multiturn.py: 9 passedtest_a2a_plugin.py+test_a2a_phase23.py: 151 passed, 0 regressionsruff checkclean on all touched filesSupersedes #64982 (multi-turn conversation support) — same intent, rebased onto the merged official plugin.