Skip to content

feat: introduce pluggable memory providers for agent workflows#29

Merged
frisbeeman merged 2 commits into
mainfrom
feat/memory
May 18, 2026
Merged

feat: introduce pluggable memory providers for agent workflows#29
frisbeeman merged 2 commits into
mainfrom
feat/memory

Conversation

@frisbeeman
Copy link
Copy Markdown
Contributor

@frisbeeman frisbeeman commented May 17, 2026

  • Added MemoryProvider trait to allow customizable state compaction strategies.
  • Implemented default SlidingWindowMemory provider to maintain legacy behavior.
  • Updated AgentWorkerBuilder to support configurable memory providers.
  • Removed hardcoded compaction logic from workflow.rs and state.rs, and moved to memory.rs.

Summary by CodeRabbit

  • New Features
    • Introduced pluggable memory provider system for workflow history management
    • Added sliding-window memory strategy with automatic history compaction capabilities
    • Enabled memory customization via agent worker builder for tailored behavior
    • Exposed memory-related APIs in public modules for advanced configuration

Review Change Stack

- Added `MemoryProvider` trait to allow customizable state compaction strategies.
- Implemented default `SlidingWindowMemory` provider to maintain legacy behavior.
- Updated `AgentWorkerBuilder` to support configurable memory providers.
- Removed hardcoded compaction logic from `workflow.rs` and `state.rs`, and moved to `memory.rs`.
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Warning

Rate limit exceeded

@frisbeeman has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 19 minutes and 45 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6278ecce-b993-4834-8642-08deaa9e2f39

📥 Commits

Reviewing files that changed from the base of the PR and between 504b488 and a48c036.

📒 Files selected for processing (6)
  • AGENTS.md
  • Cargo.toml
  • README.md
  • examples/tunable_memory_agent/main.rs
  • src/builder.rs
  • src/state.rs

Walkthrough

The PR refactors history compaction in AgentWorkflow from hardcoded logic to a pluggable MemoryProvider trait. It adds a new src/memory.rs module with a SlidingWindowMemory default implementation, wires it into the builder via WORKER_MEMORY, integrates provider dispatch into the workflow loop, and removes the legacy compaction function from state.rs.

Changes

Pluggable Memory Provider System

Layer / File(s) Summary
Memory Provider Contract & Sliding-Window Implementation
src/memory.rs
Defines the MemoryProvider trait with should_compact and compact methods, implements SlidingWindowMemory as a FIFO sliding-window strategy configurable by threshold and recent-message count, provides the compact_sliding_window kernel that synthesizes prior conversation summaries while preserving system prompts and metadata, and includes comprehensive unit tests.
Worker Builder Memory Configuration
src/builder.rs
Adds optional memory field to AgentWorkerBuilder, introduces process-wide WORKER_MEMORY: OnceCell<Arc<dyn MemoryProvider>> for workflow access, implements fluent builder method, and initializes the static during build_worker.
Workflow Memory Provider Dispatch
src/workflow.rs
Imports MemoryProvider and SlidingWindowMemory, replaces hardcoded history-length compaction checks with dynamic provider lookup from WORKER_MEMORY, and calls should_compact/compact per iteration to decide continue-as-new.
Public API Exports & Verification
src/lib.rs, src/prelude.rs, tests/prelude_memory_exports.rs
Exposes memory module and core types at crate level and via prelude; compile-time test verifies re-exports are usable as both concrete and trait-object types.
Removal of Legacy Compaction Code
src/state.rs
Removes pub fn compact, truncate helper, and related unit tests, consolidating history-compaction logic entirely into the new memory module.

Possibly related issues

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

A rabbit hops through history's hall,
With memory compacted—never too tall!
Pluggable, configurable, tests keeping score,
Legacy code swept right out the door. 🐰✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: introducing pluggable memory providers as a new feature for agent workflows, which is reflected across all modified files.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/memory

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 and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/builder.rs (1)

115-123: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Do not ignore OnceCell::set failures for workflow globals.

Silently discarding failed sets can bind a worker to stale WORKER_TOOL_CATALOG / WORKER_MEMORY values from a previous initialization in the same process. build_worker should fail fast (or validate exact equality) when initialization is not accepted.

As per coding guidelines, "Set WORKER_TOOL_CATALOG (process-global OnceCell) once at worker init in build_worker; it must be set before the worker starts and never mutated after."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/builder.rs` around lines 115 - 123, The current code ignores failures
from WORKER_TOOL_CATALOG.set(...) and WORKER_MEMORY.set(...), which can leave a
worker bound to stale globals; in build_worker handle the Result returned by
OnceCell::set: if set succeeds continue, if it fails retrieve the existing value
with WORKER_TOOL_CATALOG.get()/WORKER_MEMORY.get() and either validate it is
exactly equal to the value being set (and continue) or return an error / abort
initialization (fail fast). Update build_worker to propagate an Err (or panic)
when the existing global differs from the new value so initialization cannot
silently proceed with stale state.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/workflow.rs`:
- Around line 97-99: The workflow currently defers compaction entirely to
MemoryProvider::should_compact, allowing providers to bypass the mandated
continue-as-new behavior when AgentState::history.len() >
CONTINUE_AS_NEW_THRESHOLD (200); modify the workflow around ctx.state(|s| ...)
so it always enforces the invariant: if s.state.history.len() >
CONTINUE_AS_NEW_THRESHOLD then perform continue_as_new with a compacted state
(call memory.compact to produce a summary, prepend that summary to the system
prompt, and retain only the last 20 messages from s.state.history) and only
otherwise allow MemoryProvider::should_compact to influence additional
compaction strategy. Ensure you update the logic that currently uses
ctx.state(|s| memory.should_compact(&s.state)) and ctx.state(|s|
memory.compact(&s.state)) to implement this enforced path before delegating to
providers.

---

Outside diff comments:
In `@src/builder.rs`:
- Around line 115-123: The current code ignores failures from
WORKER_TOOL_CATALOG.set(...) and WORKER_MEMORY.set(...), which can leave a
worker bound to stale globals; in build_worker handle the Result returned by
OnceCell::set: if set succeeds continue, if it fails retrieve the existing value
with WORKER_TOOL_CATALOG.get()/WORKER_MEMORY.get() and either validate it is
exactly equal to the value being set (and continue) or return an error / abort
initialization (fail fast). Update build_worker to propagate an Err (or panic)
when the existing global differs from the new value so initialization cannot
silently proceed with stale state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c969f53d-d46c-417e-b1c4-14a8948078e4

📥 Commits

Reviewing files that changed from the base of the PR and between 93f02f3 and 504b488.

📒 Files selected for processing (7)
  • src/builder.rs
  • src/lib.rs
  • src/memory.rs
  • src/prelude.rs
  • src/state.rs
  • src/workflow.rs
  • tests/prelude_memory_exports.rs
💤 Files with no reviewable changes (1)
  • src/state.rs

Comment thread src/memory.rs
Comment thread src/workflow.rs
…r memory providers

- Introduced the `tunable_memory_agent` example to demonstrate custom and aggressive `SlidingWindowMemory` configurations.
- Expanded README with a "Pluggable memory backends" section describing memory provider traits and usage.
- Added documentation for `MemoryProvider` determinism requirements in `AGENTS.md`.
- Enforced consistency checks for `MemoryProvider` across workers in multi-worker setups.
@frisbeeman frisbeeman merged commit ed88d6b into main May 18, 2026
10 checks passed
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