Skip to content

feat(agents): conversation / short-term memory on DynamoDB (#290) - #349

Open
codeforstartups wants to merge 1 commit into
feat/hitl-interruptsfrom
feat/conversation-memory
Open

codeforstartups wants to merge 1 commit into
feat/hitl-interruptsfrom
feat/conversation-memory

Conversation

@codeforstartups

Copy link
Copy Markdown
Owner

Closes #290. Supersedes #336 by @shivamm-gupta (credited as co-author). #336 was written against the agent loop before #328/#345, so it conflicts in react.py and drops the shared-state context. This ports it onto the current loop.

Stacked on #348 (HITL interrupts) — both change react.py. Review/merge #348 first; GitHub will retarget this PR to development automatically when #348's branch is deleted.

What it does

from dynavec.agents import ReActAgent, DynamoDBMemoryStore, WindowMemoryPolicy

memory = DynamoDBMemoryStore(table, namespace="app", policy=WindowMemoryPolicy(k=20))
agent = ReActAgent(model, memory=memory, system_prompt="Helpful assistant.")
agent.run("My name is Alice.", thread_id="u-42")
agent.run("What is my name?", thread_id="u-42")   # sees the earlier turn

From #336, unchanged: InMemoryMemoryStore, DynamoDBMemoryStore, window / token-budget / summary policies, scratchpad, and its tests.

Fixes made while porting

  • Scratchpad could be overwritten: DynamoDBMemoryStore.append read the item twice and rewrote it with put_item, so a set_scratchpad in between was lost. It now uses update_item on the message attributes only.
  • 400 KB item limit: each thread is one item; documented, with a pointer to the trimming policies.
  • Shared state kept: the user turn still carries the Issue 289 supervisor v2 #345 AgentState context.
  • Memory + checkpointer on one thread_id: the second run() used to reload the finished checkpoint instead of starting a new turn. A finished checkpoint now starts a new turn; unfinished ones (e.g. max_steps_reached) still resume as before — the existing resumption test is unchanged.
  • Works with interrupts: a paused turn records the user message once, and the final answer is recorded after resume().

Tests

#336's 7 tests kept, plus 6 new: scratchpad survives append, item metadata, shared-state context in the stored turn, memory + checkpointer multi-turn, finished checkpoint starts fresh, memory with interrupt/resume. Local: ruff clean, strict mypy clean, 1137 passed.

🤖 Generated with Claude Code

InMemoryMemoryStore and DynamoDBMemoryStore with window, token-budget and
summary policies and a per-thread scratchpad. ReActAgent(memory=...) loads
earlier turns for a thread_id, stores the system prompt once, keeps the #345
shared-state context in the user turn, and records each final answer
(including runs finished via resume()).

Ported onto the current agent loop from Shivam Gupta's #336, with fixes:
- DynamoDBMemoryStore.append uses update_item on the message attributes, so a
  scratchpad written concurrently is not overwritten (was read + put_item)
- documents the 400 KB item limit and recommends a trimming policy
- a run on a thread whose checkpoint is finished starts a new turn, so memory
  and the checkpointer can share a thread_id

Co-authored-by: shivamm-gupta <72978868+shivamm-gupta@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

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.

1 participant