Skip to content

feat(api): add POST /agentmemory/reindex-vectors to re-embed after a model swap#956

Open
shgew wants to merge 2 commits into
rohitg00:mainfrom
shgew:feat/api-reindex-vectors
Open

feat(api): add POST /agentmemory/reindex-vectors to re-embed after a model swap#956
shgew wants to merge 2 commits into
rohitg00:mainfrom
shgew:feat/api-reindex-vectors

Conversation

@shgew

@shgew shgew commented Jun 20, 2026

Copy link
Copy Markdown

What

Add a new REST endpoint POST /agentmemory/reindex-vectors and the backing mem::reindex-vectors iii function. Re-embeds every observation and memory in place. The live index keeps serving during the rebuild; the fresh index is built off to the side, validated (failed === 0), then atomically swapped in via IndexPersistence.restoreFrom and persisted synchronously.

Why

Switching the embedding model or dimensions invalidates the persisted vectors. Today the only paths are full-restart rebuild or AGENTMEMORY_DROP_STALE_INDEX, neither of which re-embeds history on demand without a restart.

How

Builds on the existing migrateVectorIndex helper, which already constructed a fresh index but discarded it. The new reindexVectors() keeps the fresh index and atomically swaps it.

Tests

  • test/reindex-vectors.test.ts (new file, 9 cases) - full coverage of the new function + REST handler.
  • test/vector-index-dimensions.test.ts extended.
  • Targeted suite: 11/11 pass.

Compatibility

Additive endpoint. No existing endpoint changed. REST endpoint count bumps 128 → 129.

How to verify

# swap embedding provider in ~/.agentmemory/.env, restart, then:
curl -X POST http://localhost:3111/agentmemory/reindex-vectors | jq
# returns { success: true, reindexed: <N>, failed: 0 }

Summary by CodeRabbit

  • New Features
    • Added a new authenticated REST API endpoint to rebuild/reindex the vector index using the currently configured embedding provider.
    • The rebuild now supports swapping the rebuilt index into service and returns detailed rebuild/swap results.
  • Documentation
    • Updated the README API documentation to reflect the increased total to 129 REST endpoints on port 3111.
  • Tests
    • Added and extended test coverage for vector index rebuild behavior, including dimension/size consistency and failure cases.

…model swap

Switching the embedding model or dimensions invalidates the persisted
vectors. Today the only paths are full-restart rebuild or
AGENTMEMORY_DROP_STALE_INDEX, neither of which re-embeds history on
demand without a restart.

This adds a new REST endpoint (and the backing mem::reindex-vectors
iii function) that re-embeds every observation and memory in place.
The live index keeps serving during the rebuild; the fresh index is
built off to the side, validated (failed === 0), then atomically
swapped in via IndexPersistence.restoreFrom and persisted
synchronously.

Builds on the existing migrateVectorIndex helper, which already
constructed a fresh index but discarded it. The new reindexVectors()
keeps the fresh index and atomically swaps it.

Tests:
  - test/reindex-vectors.test.ts (full coverage of the new function +
    REST handler).
  - test/vector-index-dimensions.test.ts extended.

REST endpoint count bumps 128 -> 129. No MCP tool added.

Signed-off-by: Hleb Shauchenka <me@marleb.org>
@vercel

vercel Bot commented Jun 20, 2026

Copy link
Copy Markdown

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

coderabbitai Bot commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: cffba102-4331-4c7f-9d5d-46ff1324533d

📥 Commits

Reviewing files that changed from the base of the PR and between d9e8be8 and d22ef0e.

📒 Files selected for processing (2)
  • src/functions/search.ts
  • src/types.ts
✅ Files skipped from review due to trivial changes (1)
  • src/types.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/functions/search.ts

📝 Walkthrough

Walkthrough

Adds a reindexVectors function that rebuilds the live vector index by calling migrateVectorIndex, swaps the result into the running index, and persists it. Extends MigrateVectorIndexResult with the rebuilt VectorIndex. Registers the function as SDK entry mem::reindex-vectors and exposes it as HTTP POST /agentmemory/reindex-vectors. Updates endpoint counts to 129.

Changes

reindex-vectors feature

Layer / File(s) Summary
Vector index result and audit event contracts
src/functions/migrate-vector-index.ts, src/types.ts
Adds index: VectorIndex property to MigrateVectorIndexResult and populates it in both return sites (failure and success). Extends AuditEntry.operation union to include "vector_index_swap" for index swap audit events.
reindexVectors implementation and SDK registration
src/functions/search.ts
Imports migrateVectorIndex. Implements reindexVectors(kv) that validates embedding provider and live vector index, calls migrateVectorIndex to rebuild an index off to the side, conditionally swaps via restoreFrom on success, persists via flushIndexSave, and records vector_index_swap audit event. Registers mem::reindex-vectors as a new SDK entry point.
HTTP endpoint POST /agentmemory/reindex-vectors
src/triggers/api.ts
Registers api::reindex-vectors as an authenticated handler that invokes mem::reindex-vectors with {} and returns status 200 with the result body.
Tests and endpoint count updates
test/reindex-vectors.test.ts, test/vector-index-dimensions.test.ts, README.md, src/index.ts
Adds vitest suite covering successful reindex with swap, missing embedding provider (failure/no swap), and missing vector index (failure/no swap) cases. Adds a migrateVectorIndex test asserting the returned index is a VectorIndex with size matching vectorSize. Updates endpoint counts from 128 to 129 in README and boot log.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • rohitg00/agentmemory#636: Introduces flushIndexSave() and index-mutation helpers that the new reindexVectors() function calls to persist the rebuilt vector index.

Suggested reviewers

  • rohitg00

Poem

🐇 Hop, hop, the index grows stale no more,
A reindex command knocks on the REST door.
Vectors rebuilt, swapped in with care,
129 endpoints now fill the air.
The rabbit cheers: "Fresh embeddings, hooray!" 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.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 title accurately describes the main change: adding a REST endpoint to re-embed data after embedding model changes.
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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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/search.ts`:
- Around line 375-380: The code performs a state-changing operation when
swapping the vector index (within the if block where stats.success is true and
swapped is set to true) but fails to record an audit entry as required by coding
guidelines. After the swapped variable is set to true and flushIndexSave() is
awaited, add a call to recordAudit() to log this state-changing operation,
including relevant details such as the operation type (index swap) and any
pertinent context like the endpoint name (ep.name) and dimensions
(ep.dimensions) to maintain a complete audit trail.
- Around line 375-378: The code mutates live state via vi.restoreFrom(index) on
line 376 before persisting the change via flushIndexSave() on line 377. If the
persistence call throws an error, the swap has already happened in live state
but callers perceive a failure and may retry the operation unnecessarily.
Reorder these operations so that flushIndexSave() is called before
vi.restoreFrom(index), or alternatively wrap the flushIndexSave() call in a
try-catch block and return a structured partial-failure response (indicating the
swap succeeded but persistence failed) when an error is caught after the state
mutation has already occurred. This ensures callers can distinguish between a
swap that never happened versus a swap that succeeded but failed to persist.
🪄 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: 6f97e1f2-986c-4978-9fc6-ef67ac95770b

📥 Commits

Reviewing files that changed from the base of the PR and between f6f9e3c and d9e8be8.

📒 Files selected for processing (7)
  • README.md
  • src/functions/migrate-vector-index.ts
  • src/functions/search.ts
  • src/index.ts
  • src/triggers/api.ts
  • test/reindex-vectors.test.ts
  • test/vector-index-dimensions.test.ts

Comment thread src/functions/search.ts
Comment thread src/functions/search.ts
The previous flow mutated the live vector index via vi.restoreFrom() and
then awaited flushIndexSave() with no guard. If the persistence call
threw, callers saw the failure but the in-memory swap had already
happened, so retries would have operated on a half-applied state.

Move flushIndexSave() into a try/catch after the live swap. On failure,
return a structured response with success:false, swapped:true, and the
error message so operators can distinguish 'swap never happened' from
'swap applied but persistence failed'.

Also record a vector_index_swap audit entry on the successful path, per
the project rule that state-changing operations carry an audit trail.
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