Skip to content

Return real communication history from LongTermMemory - #339

Open
Lokkhita wants to merge 1 commit into
mesa:mainfrom
Lokkhita:fix/lt-memory-communication-history
Open

Lokkhita wants to merge 1 commit into
mesa:mainfrom
Lokkhita:fix/lt-memory-communication-history

Conversation

@Lokkhita

Copy link
Copy Markdown

Pre-PR Checklist

  • This PR is a bug fix, not a new feature or enhancement.

Summary

LongTermMemory.get_communication_history() returned a constant placeholder. Because the string is always truthy, ReActReasoning injected it into every prompt as "last communication", so agents using LongTermMemory never saw the messages they received. This PR returns the real, recent messages, and "" when there are none.

Bug / Issue

Fixes #327.

react.py only adds the section when the history is truthy. The other backends return "" when there are no messages. LongTermMemory returned "communication history is in memory of the agent", which filled that slot on every step, while messages delivered via send_message were never shown.

Implementation

Consolidation rewrites each step into an LLM summary, so exact wording and senders cannot be recovered from long_term_memory. The fix keeps recent messages verbatim:

  • Bounded (step, message) log (communication_history_capacity, default 50, validated as a positive int, bool rejected). The history is injected into every ReAct prompt, so it must not grow without limit.
  • Recorded in add_to_memory after super(), so base validation runs first. aadd_to_memory delegates to it, which covers async delivery.
  • Recorded at add time, not at consolidation. The message is visible when the agent plans its next step, and a failed-then-retried summarization cannot drop or duplicate it.
  • Rendered with the shared _format_message_entry(), matching the output of the other backends.
  • Log created lazily, following Memory._step_event_order. Instances pickled before this change have no log attribute and would otherwise raise AttributeError on the first delivered message.

Alternatives rejected:

  • Returning "": hides the placeholder but still shows no messages.
  • Returning the summary: lossy, and duplicates get_prompt_ready().
  • Reading only unconsolidated entries: each message would be visible for a single step.
  • Recording at consolidation: delays visibility by a step and needs rollback handling.

Testing

12 new tests in tests/test_memory/test_lt_memory.py: all fail on main, all pass here.

  • Empty history is "".
  • Rendering and order match the other backends; non-message events are excluded.
  • A message is visible while planning, before consolidation.
  • Exactly once across a failed plus retried consolidation.
  • Async delivery.
  • Capacity bound; invalid capacities (0, -1, 1.5, True).
  • An instance without the log attribute (older pickle).
  • The ReActReasoning.get_react_prompt output contains the real message and not the placeholder.

End-to-end with two LLMAgents (LLM mocked): after send_message("I offer 20 sugar for 5 spice", [b]), b's ReAct prompt contains Step 0: Agent 1 says: I offer 20 sugar for 5 spice. Same with asend_message.

Full suite: 1564 passed. pre-commit run passes.

Additional Notes

get_communication_history() returned the constant "communication history
is in memory of the agent". Being always truthy, ReActReasoning injected
it into every prompt as "last communication", in place of the messages
the agent had actually received.

Consolidation folds each step into an LLM-written summary, so exact
wording (offers, quantities, who said what) cannot be recovered from
long_term_memory. Keep the most recent messages verbatim in a bounded
log, recorded at add time (async delivery goes through add_to_memory),
and render them with the shared _format_message_entry() formatter used
by the other backends. With no messages the result is "", so ReAct adds
no section.

Recording at add time keeps the log independent of consolidation: a
message is visible while the agent plans its next step, and a failed and
retried summarization neither drops nor duplicates it. The log is
created lazily so instances unpickled from older versions keep working.

Fixes mesa#327
@coderabbitai

coderabbitai Bot commented Sep 21, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Advanced

Run ID: 0858b4ed-05d8-4a85-a7e5-fbd954b573f5

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Lokkhita

Lokkhita commented Oct 6, 2026

Copy link
Copy Markdown
Author

#328 (opened in August) takes the same approach. This PR adds legacy-instance safety and stricter capacity validation; I've offered on #328 to fold those in.

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.

bug: LongTermMemory.get_communication_history() returns a hardcoded placeholder instead of real message history

1 participant