Skip to content

fix(ingest): embed project-scoped writes (#216) - #217

Merged
nullure merged 1 commit into
CaviraOSS:mainfrom
RockinPaul:fix/project-ingest-embeddings
Oct 17, 2026
Merged

nullure merged 1 commit into
CaviraOSS:mainfrom
RockinPaul:fix/project-ingest-embeddings

Conversation

@RockinPaul

Copy link
Copy Markdown
Contributor

📋 Description

Fixes #216. applyImportPlan ingests inside a synchronous import_transaction().run(...) and never called the embedder, so every node it created was stored with vectors.semantic: null. Project ingest (longmemory_ingest with project_id), every longmemory_remember_decision, and connector imports go through it, so those memories never received a vector score in recall and could only match lexically.

This embeds each planned node before entering the transaction, the same way ingest() does (embed(cfg.embedding_provider, multilingual_embeddings, embedding_cache, text, language, 'document')), and passes it to engine.ingest as vector. Nodes are embedded sequentially, as ingest() does, so a large connector import doesn't fan out into concurrent provider requests.

🔄 Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)

Verification

  • New check in benchmarks/src/check.ts: a project-scoped ingestProjectEvent with a configured embedding provider must store a semantic vector. It failed on main (undefined !== 4) and passes with the fix.

  • pnpm typecheck, pnpm bench:check, pnpm bench:ci and pnpm build pass.

  • pnpm branding:check and pnpm integration:check fail identically on unmodified main: tools/ is not in the repository (Cannot find module tools/branding.mjs), and the n8n lint step reports Command "eslint" not found. No files were added, so the header requirement is unaffected.

  • pnpm release:check passes locally (blocked by the missing tools/ directory above)

  • New files pass pnpm branding:check (no new files)

  • User-visible behavior has been exercised manually when applicable (the reproduction in [BUG] Project-scoped writes (ingest with project_id, remember_decision) are stored without embeddings #216 was run against a deployed server)

🔍 Code Review Checklist

  • Code follows the project's coding standards
  • Self-review of the code has been performed

📚 Related Issues

🚀 Deployment Notes

Memories already written through this path keep their null vectors; there is no re-embed step, so they stay lexical-only until re-ingested.

🤖 Generated with Claude Code

applyImportPlan ingests inside a synchronous transaction and never called
the embedder, so every node it created was stored with vectors.semantic
null. Project ingest, remember_decision and connector imports all go
through it, so those memories never received a vector score in recall.

Embed each planned node before entering the transaction, the same way
ingest() does, and pass the vector to engine.ingest.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@nullure nullure left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM

@nullure
nullure merged commit 95d8559 into CaviraOSS:main Oct 17, 2026
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.

[BUG] Project-scoped writes (ingest with project_id, remember_decision) are stored without embeddings

2 participants