Skip to content

feat(memory): Add pluggable memory provider support with fallback - #1068

Draft
tautvydasLiekis wants to merge 2 commits into
masterfrom
feat-Add-pluggable-memory-provider-registry-with-file-fallback
Draft

feat(memory): Add pluggable memory provider support with fallback#1068
tautvydasLiekis wants to merge 2 commits into
masterfrom
feat-Add-pluggable-memory-provider-registry-with-file-fallback

Conversation

@tautvydasLiekis

@tautvydasLiekis tautvydasLiekis commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Linked issue

Why

Subagent system prompts are built inside agent-runner.ts, so external extensions have no hook to supply agent memory — previously every subagent got a hardwired per-agent MEMORY.md block, which is flat, unranked (the full index is injected relevant or not), and can't be supplied by semantic memory backends (OpenViking, mem0, etc.). To let any memory DB provide subagent memory without growing harness-side integration code per backend, the resolution point had to become generic. This is the harness-side foundation that the kimchi-openviking package (and its generic HTTP adapter presets for mem0/Supermemory/Letta/Zep) plugs into.

What

  • Generic AgentMemoryProvider contract in memory.ts ({ name, buildBlock(agentName, cwd): Promise<string | null> }) with an ordered registry: first non-null block wins, then file memory.
  • Config-driven loading: on first use, modules listed in <agent-dir>/memory-providers.json ([{"name", "module"}]) are dynamic-imported and shape-validated before registration — the harness keeps zero provider-specific code; adding a backend is a config edit, not a code change.
  • Fail-open resolution (resolveMemoryBlock): malformed manifests, unloadable modules, throwing providers, and all-null results are skipped silently, falling back to the existing file-based buildMemoryBlock / buildReadOnlyMemoryBlock — behavior is byte-identical for an empty registry.
  • agent-runner.ts now builds the memory block via resolveMemoryBlock instead of calling the file builders directly.
  • README.md documenting the contract, scopes, registration paths, and resolution semantics.

Testing: npx vitest run src/extensions/agents — 506 tests across 46 files; new memory.test.ts covers registry ordering, exception containment, missing/malformed manifests, invalid entries, shape mismatches, unloadable modules, and file fallback in write and read-only modes.

Checklist

  • I have read CONTRIBUTING.md and agree to the CLA
  • This PR links to an open issue above
  • Tests pass locally (pnpm run test)
  • Lint passes (pnpm run check)
  • Documentation updated if behavior changed

@kimchi-review

kimchi-review Bot commented Aug 20, 2026

Copy link
Copy Markdown

Kimchi Code Review

Property Value
Commit 3e83275
Author @tautvydasLiekis
Files changed 0
Review status Completed
Comments 6 (2 info, 4 warning)
Duration 89s

Summary

📊 Review Score: 76/100 (overall code quality — 0 lowest, 100 highest)
⏱️ Estimated effort to review: 3/5 (1 = trivial, 5 = very complex)

🧪 Tests: yes — Tests were added in src/extensions/agents/memory/memory.test.ts covering config-driven loading, missing/invalid config, malformed JSON, provider ordering, exception containment, and file fallback. The mock in src/extensions/agents/manager/agent-runner.test.ts was updated for the new async resolveMemoryBlock export.

🔒 Security concerns found: loadConfiguredProviders() dynamically imports arbitrary module paths read from <agent-dir>/memory-providers.json without validating that the path is absolute, under a trusted directory, or not a symlink. If an attacker can write to that config file, they can achieve code execution on the next agent spawn. This is intentional as a plugin mechanism, but the expanded attack surface should be documented and ideally sandboxed.

📝 Found 6 issue(s). See inline comments for details.

What to expect

Kimchi will analyze the changes in this pull request and post:

  • A summary of the overall changes
  • Inline comments on specific lines with findings categorized by issue type

The review typically completes within a few minutes. This comment will be updated once the review is ready.

Interact with Kimchi
  • @getkimchi review — re-trigger a full review on the latest commit
  • @getkimchi summary — regenerate the PR summary
  • @getkimchi ignore — skip this PR (no review will be posted)
  • Reply to any inline comment to ask follow-up questions or request clarification
Configuration

Reviews are configured by your organization admin.
Review instructions, excluded directories, and severity thresholds can be adjusted per repository in the Kimchi dashboard.


Powered by Kimchi — AI-powered code review by CAST AI

@kimchi-review kimchi-review Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📊 Review Score: 76/100 (overall code quality — 0 lowest, 100 highest)
⏱️ Estimated effort to review: 3/5 (1 = trivial, 5 = very complex)

🧪 Tests: yes — Tests were added in src/extensions/agents/memory/memory.test.ts covering config-driven loading, missing/invalid config, malformed JSON, provider ordering, exception containment, and file fallback. The mock in src/extensions/agents/manager/agent-runner.test.ts was updated for the new async resolveMemoryBlock export.

🔒 Security concerns found: loadConfiguredProviders() dynamically imports arbitrary module paths read from <agent-dir>/memory-providers.json without validating that the path is absolute, under a trusted directory, or not a symlink. If an attacker can write to that config file, they can achieve code execution on the next agent spawn. This is intentional as a plugin mechanism, but the expanded attack surface should be documented and ideally sandboxed.

📝 Found 6 issue(s). See inline comments for details.

Comment thread src/extensions/agents/memory/memory.ts Outdated
Comment thread src/extensions/agents/memory/memory.ts
Comment thread src/extensions/agents/memory/memory.ts Outdated
Comment thread src/extensions/agents/memory/memory.ts
Comment thread src/extensions/agents/memory/memory.ts
Comment thread src/extensions/agents/memory/memory.ts
- Validate module paths before dynamic import: absolute, existing,
  non-symlink only; import via pathToFileURL() for platform-correct
  ESM resolution on all OSes
- Accept only non-empty string blocks from providers so a provider
  returning undefined cannot leak into the Promise<string> contract
- Contain load failures: the lazy load promise resets on unexpected
  errors instead of wedging as rejected forever
- Extend the provider contract with an optional context carrying the
  memory scope and read-only mode, so providers can tailor output;
  two-argument implementations stay compatible

Co-Authored-By: Kimchi <noreply@kimchi.dev>
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

This PR has been marked as stale because it has not had recent activity. It will be closed tomorrow if no further activity occurs.

@github-actions github-actions Bot added the stale No recent activity label Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale No recent activity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant