Repository navigation
fix(memory): store completed BidiAgent transcripts - #722
Open
abhiramshaji-cyber wants to merge 1 commit into
Open
abhiramshaji-cyber wants to merge 1 commit into
abhiramshaji-cyber wants to merge 1 commit into
Conversation
BidiAgent adds each spoken turn to history as an empty placeholder (MessageAddedEvent, bidi status "pending") and later replaces it with the finished text through MessageUpdatedEvent (status "complete"). The session manager only persisted on MessageAddedEvent, so the placeholder was dropped as empty and the finished text was never written. Voice agents therefore stored no user or assistant turns and long term memory strategies had nothing to extract. Persist MessageUpdatedEvent messages whose bidi status is "complete" through append_message, the same path text messages use, in both sync and async mode. Pending placeholders are skipped explicitly so a custom converter cannot store them, and "incomplete" updates are ignored. Each transcript completes once, so it is written exactly once. The hook is only registered when the installed strands-agents provides MessageUpdatedEvent. Closes aws#716
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
abhiramshaji-cyber
requested a deployment
to
manual-approval
October 28, 2026 00:48 — with
GitHub Actions
Waiting
This branch is waiting to be deployed
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.
Voice agents built with
BidiAgentnow save what the caller and the assistant said into AgentCore Memory, so long term memory has something to learn from.What this code is for
AgentCoreMemorySessionManagerlistens to Strands agent events and writes each conversation turn to AgentCore Memory as aUSERorASSISTANTevent. Memory strategies (summary, preferences, facts) read those events to build long term memory.Before
BidiAgentadds an empty placeholder message to its history and firesMessageAddedEventwith bidi status"pending".BidiAgentreplaces the placeholder with the finished text and firesMessageUpdatedEventwith status"complete".MessageUpdatedEvent, so the finished text is never written.After
"pending"placeholder is skipped on purpose.BidiAgentfiresMessageUpdatedEventwith status"complete".MessageUpdatedEventand saves the finished text throughappend_message, the same path text messages use."incomplete"(a turn cut off when the session ends) are not saved, and empty text is still dropped by the converter.USERorASSISTANT.flowchart LR subgraph Before direction TB A1[Turn starts: placeholder added] --> A2[MessageAddedEvent: empty, nothing saved] A2 --> A3[Turn ends: placeholder replaced] A3 --> A4[MessageUpdatedEvent: not handled] A4 --> A5[Memory has no turns] end subgraph After direction TB B1[Turn starts: placeholder added] --> B2[MessageAddedEvent: pending, skipped] B2 --> B3[Turn ends: placeholder replaced] B3 --> B4[MessageUpdatedEvent: complete, saved once] B4 --> B5[Memory has USER and ASSISTANT turns] endThe change
In
session_manager.py:_bidi_statushelper readsmetadata.custom.bidi.statusfrom a message. It returnsNonefor normal messages, including ones whose metadata is missing orNone.append_messagereturns early for"pending"messages, so a custom converter can never store an empty placeholder._append_completed_messagecallback saves aMessageUpdatedEventmessage only when its status is"complete". It is registered in sync mode and, through the existingasyncio.to_threadwrapper, in async mode.MessageUpdatedEventis looked up withgetattr, and the callback is only registered when the installedstrands-agentsprovides it. The minimum supported version (1.56.0) does not have it, and nothing changes there.Tests in
test_agentcore_memory_session_manager.pycover: pending placeholders are not saved, complete user and assistant transcripts are saved exactly once with the right role, incomplete, empty and whitespace transcripts are not saved, updates without a bidi status are not saved, and normal messages with missing orNonemetadata are still saved. Each runs in sync and async mode. The update tests are skipped whenstrands-agentshas noMessageUpdatedEvent.I also ran the reproduction script from the issue against
strands-agents1.62.0. Before this change memory held only the greeting. After it, memory holds the greeting, the user turn and the assistant turn, each once, in both sync and async mode.What changes for users
Voice agents that use
BidiAgentwithAgentCoreMemorySessionManagernow keep a record of each conversation, and long term memory strategies can summarize it and remember the caller in later sessions. RegularAgentusers see no change.This PR does not change the write latency in the receive loop or the error handling that the issue also mentions; those can be handled separately.
Closes #716