Skip to content

feat(graph): auto-trigger mem::graph-extract on mem::remember#568

Open
efenex wants to merge 1 commit into
rohitg00:mainfrom
efenex:feat/v3-d-graph-extract-on-remember
Open

feat(graph): auto-trigger mem::graph-extract on mem::remember#568
efenex wants to merge 1 commit into
rohitg00:mainfrom
efenex:feat/v3-d-graph-extract-on-remember

Conversation

@efenex
Copy link
Copy Markdown
Contributor

@efenex efenex commented May 20, 2026

Summary

mem::remember (the explicit memory-save path used by memory_save MCP calls, plugin Stop hooks, JSONL imports, etc.) does NOT auto-trigger mem::graph-extract. Observations do auto-trigger extraction when GRAPH_EXTRACTION_ENABLED=true, but memories don't — so the knowledge graph grows from observation traffic only, leaving curated memories invisible to graph queries.

This wires the same auto-trigger pattern on the memory write path: after a successful mem::remember, fire mem::graph-extract against the newly-saved memory id when GRAPH_EXTRACTION_ENABLED=true. Best-effort; failure is logged-and-continued so a slow/down LLM provider can't block the save.

Impact

Closes the gap between observation-driven and memory-driven graph growth. After this:

  • mem::lineage (with includeGraph: true) sees the same node set whether a concept was extracted from observation traffic or written as a memory.
  • mem::smart-search graph-score component lights up for curated memories.
  • agentmemory graph-build (feat(graph): backfill graph from stored memories #538, if/when it lands) becomes a backfill tool for old data, not the only path for new data.

Related

Test plan

  • Existing tests pass (`npm test`)
  • `GRAPH_EXTRACTION_ENABLED=true mem::remember` produces graph nodes within the configured concurrency window
  • `GRAPH_EXTRACTION_ENABLED=false` (default) no-ops the trigger

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Memory saves can now optionally trigger background knowledge-graph extraction when the feature flag is enabled. Extraction runs asynchronously after a save so the save remains fast; extraction errors are logged as warnings and do not block or revert the original save.

@vercel
Copy link
Copy Markdown

vercel Bot commented May 20, 2026

@efenex is attempting to deploy a commit to the rohitg00's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 20, 2026

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e04b3db5-721b-45db-aa22-7ddb9f9b77c6

📥 Commits

Reviewing files that changed from the base of the PR and between ee8d844 and bdd25ca.

📒 Files selected for processing (2)
  • node_modules
  • src/functions/remember.ts
💤 Files with no reviewable changes (1)
  • src/functions/remember.ts
✅ Files skipped from review due to trivial changes (1)
  • node_modules

📝 Walkthrough

Walkthrough

The mem::remember flow now imports isGraphExtractionEnabled and, after persisting and indexing a memory, conditionally enqueues a fire-and-forget mem::graph-extract trigger with the saved memory converted to an observation; enqueue errors are logged and do not block the response.

Changes

Graph Extraction Triggering

Layer / File(s) Summary
Conditional graph extraction triggering
src/functions/remember.ts
Import of isGraphExtractionEnabled and gated fire-and-forget sdk.trigger call to mem::graph-extract after saving/indexing a memory; synchronous enqueue errors are caught and logged.
Repository metadata symlink
node_modules
node_modules now represented as a symbolic link to an external path (metadata change).

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • rohitg00/agentmemory#698: Also updates how mem::graph-extract is enqueued and wires triggers related to extraction flows.

Poem

🐇 I tucked a thought inside my den,
I nudged a whisper out again,
A gentle call—no wait, no bind,
It hops away, leave logs behind,
If hiccups happen, we'll just grin.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and specifically describes the main change: adding auto-triggering of mem::graph-extract when mem::remember is called, which directly matches the changeset's primary modification to src/functions/remember.ts.
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

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
Contributor

@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: 1

🧹 Nitpick comments (1)
src/functions/remember.ts (1)

123-133: ⚡ Quick win

Reduce the large WHAT-comment block.

Please trim this to a short intent note and rely on naming/function structure for behavior details.

As per coding guidelines, "Avoid code comments explaining WHAT — use clear naming instead".

🤖 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/functions/remember.ts` around lines 123 - 133, Replace the large
explanatory comment in src/functions/remember.ts with a concise intent note:
state that saved memories are enqueued for graph extraction (same behavior as
observation writes) when GRAPH_EXTRACTION_ENABLED is true and that extraction is
fire-and-forget to avoid blocking the remember response; keep references to the
existing helpers/paths (the observation event path event::session::compressed,
mem::reflect, graph-extract, and KV.graphNodes/Edges) only if needed for
clarity, and rely on function/variable names to convey the detailed behavior
instead of a long WHAT block.
🤖 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/functions/remember.ts`:
- Around line 135-144: The call to sdk.triggerVoid("mem::graph-extract", {
observations: [memoryToObservation(memory)] }) returns a Promise<void> so the
current try/catch around it won't catch async rejections; update the call in the
remember handler to either await the Promise (ensuring the enclosing function is
async) or append .catch(...) to the Promise and log via logger.warn including
memId: memory.id and the error message (err instanceof Error ? err.message :
String(err)) to mirror existing logging; ensure you reference sdk.triggerVoid,
memoryToObservation, and logger.warn when making the change.

---

Nitpick comments:
In `@src/functions/remember.ts`:
- Around line 123-133: Replace the large explanatory comment in
src/functions/remember.ts with a concise intent note: state that saved memories
are enqueued for graph extraction (same behavior as observation writes) when
GRAPH_EXTRACTION_ENABLED is true and that extraction is fire-and-forget to avoid
blocking the remember response; keep references to the existing helpers/paths
(the observation event path event::session::compressed, mem::reflect,
graph-extract, and KV.graphNodes/Edges) only if needed for clarity, and rely on
function/variable names to convey the detailed behavior instead of a long WHAT
block.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 928583d5-3cec-4f23-83e7-b2f7ae0aa802

📥 Commits

Reviewing files that changed from the base of the PR and between e371be9 and 545e97f.

📒 Files selected for processing (1)
  • src/functions/remember.ts

Comment thread src/functions/remember.ts
efenex added a commit to efenex/agentmemory that referenced this pull request May 20, 2026
`sdk.triggerVoid()` returns `Promise<void>`, so the previous sync
try/catch only caught synchronous throws (argument validation, etc.).
Async rejections — provider timeout, engine queue full, downstream
extraction failure — escaped as unhandledRejection. CodeRabbit caught
this on rohitg00#568.

Keep the sync guard (defense in depth) and add a Promise.catch() so
either failure mode is logged-and-continued. Defensive type-narrow
the return value before attaching .catch in case a future iii-sdk
release changes triggerVoid's exact return shape.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
src/functions/remember.ts (1)

135-140: ⚡ Quick win

Remove the WHAT-style inline explanation block.

These lines restate control flow behavior; keep intent-focused comments only where naming cannot express why.

As per coding guidelines, "Avoid code comments explaining WHAT — use clear naming instead".

🤖 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/functions/remember.ts` around lines 135 - 140, Remove the WHAT-style
explanatory block comment that restates control flow (the multi-line comment
above the triggerVoid call) and replace it with an intent-focused one-liner (or
no comment) clarifying why we attach .catch() to the promise — e.g., "Ensure
fire-and-forget handles both sync throws and async rejections" — near the
triggerVoid invocation; update references around triggerVoid and the surrounding
try/catch so naming and the concise note communicate the why without restating
how the language works.
🤖 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.

Nitpick comments:
In `@src/functions/remember.ts`:
- Around line 135-140: Remove the WHAT-style explanatory block comment that
restates control flow (the multi-line comment above the triggerVoid call) and
replace it with an intent-focused one-liner (or no comment) clarifying why we
attach .catch() to the promise — e.g., "Ensure fire-and-forget handles both sync
throws and async rejections" — near the triggerVoid invocation; update
references around triggerVoid and the surrounding try/catch so naming and the
concise note communicate the why without restating how the language works.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: ba3bf5d5-e18b-4827-87ec-9ed3e7d13a80

📥 Commits

Reviewing files that changed from the base of the PR and between 545e97f and e7489ed.

📒 Files selected for processing (1)
  • src/functions/remember.ts

efenex added a commit to efenex/agentmemory that referenced this pull request May 20, 2026
CodeRabbit nitpick on rohitg00#568. The block explained what triggerVoid does
in detail; the WHY (handle sync throw + async rejection) is captured
in a single line. Naming + structure already convey the rest.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Contributor

@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.

🧹 Nitpick comments (1)
src/functions/remember.ts (1)

135-135: ⚡ Quick win

Remove WHAT-style inline comment and let code carry intent.

Line 135 adds a behavior-explaining comment that conflicts with the repo style rule; please remove it (or rewrite as intent-focused naming only).

Suggested minimal diff
-          // triggerVoid can throw synchronously or reject async — handle both.
           try {

As per coding guidelines, "Avoid code comments explaining WHAT — use clear naming instead".

🤖 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/functions/remember.ts` at line 135, Remove the WHAT-style inline comment
next to triggerVoid in remember.ts: either delete the comment entirely or
replace it with an intent-focused element (e.g., rename the surrounding
helper/variable to convey error-handling intent or extract the call into a
clearly named function like handleTriggerVoidErrors/ensureTriggerVoidHandled) so
the code self-documents that triggerVoid may throw synchronously or reject
asynchronously without an explanatory inline comment.
🤖 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.

Nitpick comments:
In `@src/functions/remember.ts`:
- Line 135: Remove the WHAT-style inline comment next to triggerVoid in
remember.ts: either delete the comment entirely or replace it with an
intent-focused element (e.g., rename the surrounding helper/variable to convey
error-handling intent or extract the call into a clearly named function like
handleTriggerVoidErrors/ensureTriggerVoidHandled) so the code self-documents
that triggerVoid may throw synchronously or reject asynchronously without an
explanatory inline comment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a822be70-1ea2-4394-bf67-30f81d4b0793

📥 Commits

Reviewing files that changed from the base of the PR and between e7489ed and 0fed195.

📒 Files selected for processing (1)
  • src/functions/remember.ts

efenex added a commit to efenex/agentmemory that referenced this pull request May 21, 2026
CodeRabbit re-flagged the one-line note that survived rohitg00#568's earlier
trim. The surrounding sync try/catch + async .catch() already make
the intent self-evident.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Owner

@rohitg00 rohitg00 left a comment

Choose a reason for hiding this comment

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

Audited locally: build clean, tests pass. Closes #600 (knowledge graph never auto-fires). Gated on existing GRAPH_EXTRACTION_ENABLED flag, fire-and-forget so it never blocks mem::remember, logger-only on failure. Ready to merge.

mem::remember already feeds observations into the graph; saved memories
skipped it, so mem::reflect's graph-clustering path never saw them. Trigger
graph extraction (fire-and-forget, Void action) on remember too, gated on
GRAPH_EXTRACTION_ENABLED. Rebased on current main; uses sdk.trigger +
TriggerAction.Void() (sdk.triggerVoid was removed in rohitg00#773).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@efenex efenex force-pushed the feat/v3-d-graph-extract-on-remember branch from ee8d844 to bdd25ca Compare June 5, 2026 00:51
@efenex
Copy link
Copy Markdown
Contributor Author

efenex commented Jun 5, 2026

Rebased on current main. sdk.triggerVoid was removed in #773, so the graph-extract enqueue now uses sdk.trigger + TriggerAction.Void(). Tests green; only the Vercel deploy-preview is red (it fails on every fork PR). Ready when you are.

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.

2 participants