Skip to content

refactor(memory): complete TinyCortex engine migration#4794

Open
senamakel wants to merge 30 commits into
tinyhumansai:mainfrom
senamakel:feat/tinycortex-crate-ports
Open

refactor(memory): complete TinyCortex engine migration#4794
senamakel wants to merge 30 commits into
tinyhumansai:mainfrom
senamakel:feat/tinycortex-crate-ports

Conversation

@senamakel

@senamakel senamakel commented Jul 12, 2026

Copy link
Copy Markdown
Member

Summary

  • Complete the TinyCortex migration by moving reusable memory storage, queue, ingestion, sync, tree, scoring, graph, retrieval, source, and summarisation engines into the vendored crate.
  • Replace duplicate host implementations with narrow adapters for Config, providers, credentials, event publication, scheduling, RPC/tools, and product policy.
  • Port embedding providers into tinyagents and preserve one embedding trait identity across both Cargo worlds.
  • Preserve existing SQLite schemas, workspace paths, RPC payloads, source-scope access control, taint propagation, and on-disk Markdown artifacts.
  • Remove 56,100 lines of duplicate host engine/test code while retaining crate and host integration coverage.

Problem

  • OpenHuman still owned large duplicate memory-engine bodies despite TinyCortex being the intended reusable core. The duplication had already drifted in PII handling, source filtering, content hydration, queue settlement, and sealing behavior.
  • Storage and tree cutovers had to remain atomic across the shared SQLite connection; piecemeal delegation would risk dual connection semantics and inconsistent persisted types.

Solution

Submission Checklist

  • Tests added or updated (happy path + failure/edge cases): crate unit/integration coverage and host E2E fixtures were updated.
  • Diff coverage ≥ 80%: migrated engine lines are covered by the 1,118-test TinyCortex suite; CI remains authoritative for the merged diff gate.
  • N/A: Coverage matrix feature rows are unchanged; this is an implementation ownership migration with stable product behavior.
  • N/A: No affected feature IDs; user-facing feature inventory is unchanged.
  • No new production network behavior; sync tests use mocked Composio transport. The temporary git source pins reviewed dependency code only.
  • N/A: Release smoke surfaces and user workflows are unchanged.
  • N/A: No single tracking issue is being auto-closed; this executes the checked-in TinyCortex migration specification.

Impact

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: feat/tinycortex-crate-ports
  • Commit SHA: b3880460c0ccc42e68316ac08125845ff2cd2e4c

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: TinyCortex 1,118 passed; tinyagents embeddings 35 passed; source/retrieval/tree/queue/safety/goals focused suites passed.
  • Rust fmt/check: GGML_NATIVE=OFF cargo check --tests passed across all host targets; post-dependency cargo check --lib passed.
  • Tauri fmt/check: formatting passed; compile blocked by missing local glib-2.0.pc before project code compilation.

Validation Blocked

  • command: cargo check --manifest-path app/src-tauri/Cargo.toml
  • error: local system package glib-2.0 is absent from pkg-config search paths
  • impact: environment-only Linux desktop prerequisite; CI runners install the required GTK/GLib packages. The dependency graph resolves to one vendored tinyagents crate before this native build step.

Behavior Changes

  • Intended behavior change: engine ownership moves to reusable crates with parity fixes for hydration, source filtering, atomic sealing, and PII boundary handling.
  • User-visible effect: no intentional workflow or RPC change.

Parity Contract

  • Legacy behavior preserved: SQLite schema/table names, Markdown paths/frontmatter, embedding signatures, taint, source scopes, RPC payloads, and scheduler/event integration.
  • Guard/fallback/dispatch parity checks: golden workspace tests, mocked sync E2E, source-scope-before-limit tests, queue settlement tests, sealing atomicity tests, and full host test-target compilation.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): N/A
  • Canonical PR: this PR
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

  • New Features

    • Added unified synchronization and backfill flows for Gmail, Slack, and other connected sources, with clearer ingestion counts, status reporting, and audit tracking.
    • Added compatibility support for OpenAI, Cohere, Voyage, Ollama, and cloud embedding providers.
    • Expanded tree sealing, summarization, document ingestion, retrieval, and memory-source handling.
  • Bug Fixes

    • Improved embedding endpoint error detection for additional HTTP 404/405 response formats.
    • Improved Gmail ingestion validation and embedding behavior for empty inputs.
  • Refactor

    • Standardized memory, queue, ingestion, retrieval, and synchronization behavior across shared engine components.

@senamakel senamakel requested a review from a team July 12, 2026 11:34
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 31 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 700c0be6-4587-43bd-9a58-1fac6d8e4f61

📥 Commits

Reviewing files that changed from the base of the PR and between e797300 and 823142b.

📒 Files selected for processing (14)
  • src/openhuman/agent/harness/session/builder/factory.rs
  • src/openhuman/memory_sync/composio/providers/traits.rs
  • src/openhuman/memory_tree/retrieval/integration_tests.rs
  • src/openhuman/tinycortex/mod.rs
  • src/openhuman/tinycortex/sync.rs
  • tests/raw_coverage/embeddings_ollama_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_core_threads_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_sync_round23_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_sync_slack_bus_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_sync_tree_round21_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_threads_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rs
  • vendor/tinyagents
  • vendor/tinycortex
📝 Walkthrough

Walkthrough

This PR migrates OpenHuman memory, embeddings, ingestion, retrieval, queue, tree, and synchronization paths to TinyCortex and TinyAgents adapters. It also updates Cargo patching, provider backfill flows, session memory connections, endpoint detection, and related tests.

Changes

TinyCortex migration

Layer / File(s) Summary
Dependency and embedding adapters
Cargo.toml, app/src-tauri/Cargo.toml, src/openhuman/embeddings/*
TinyCortex features and vendored TinyAgents patches are configured; embedding providers delegate through TinyAgents models and compatibility wrappers.
Ingestion and memory contracts
src/openhuman/memory/*, src/openhuman/memory_store/*, src/openhuman/memory_queue/*
Memory contracts, ingestion, queue operations, storage, safety, and tree persistence are delegated to TinyCortex adapters.
Synchronization and source pipelines
src/openhuman/memory_sync/*, src/openhuman/tinycortex/*, src/bin/*backfill*.rs
Composio, Gmail, Slack, source readers, audit state, and backfill flows use TinyCortex orchestration and host adapters.
Retrieval and tree runtime
src/openhuman/memory_tree/*
Retrieval, scoring, graph traversal, sealing, summarization, and runtime storage delegate to TinyCortex implementations.
Tests and compatibility updates
src/openhuman/**tests*, tests/*
Tests update provider defaults, document ingestion, sync-state adapters, raw artifact setup, and embedding cardinality expectations.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: rust-core, memory

Suggested reviewers: codeghost21, m3ga-mind, sanil-23

Poem

I’m a rabbit watching crates align,
TinyCortex hops through every line.
Embeddings burrow, queues run neat,
Syncing carrots from source to seat.
Tests twitch bright in the moonlit glow.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 62.96% 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 summarizes the main change: completing the memory engine migration to TinyCortex.
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.

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3880460c0

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/openhuman/tinycortex/sync.rs Outdated
Comment thread src/openhuman/tinycortex/sync.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: db76303ba9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/openhuman/memory/ingest_pipeline.rs Outdated
Comment thread src/bin/gmail_backfill_3d.rs Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a8acb19e30

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/openhuman/memory_tree/retrieval/source.rs Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 12, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 67b1b84c55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/openhuman/memory_tree/retrieval/drill_down.rs Outdated
Comment thread src/openhuman/memory_sources/sync.rs

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e03b9f31fb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@@ -348,50 +348,38 @@ impl Memory for UnifiedMemory {
&self,
namespace: Option<&str>,
category: Option<&MemoryCategory>,
_session_id: Option<&str>,
session_id: Option<&str>,
) -> anyhow::Result<Vec<MemoryEntry>> {
let ns = normalize_namespace(namespace);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Sanitize namespaces before listing memory rows

When callers list a namespace containing characters that are sanitized on write (for example team alpha/#1, which upsert_document stores as team_alpha/_1), this new direct SQL path queries the unsanitized normalize_namespace value. The previous list_documents(Some(ns)) call sanitized internally, so Memory::list(Some(...)) now returns an empty list for valid namespaces with spaces, #, dots, etc.; apply UnifiedMemory::sanitize_namespace before binding the namespace, matching the write path.

Useful? React with 👍 / 👎.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4a42fa76dd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.tick(
&pipeline_id,
&memory_config,
&source_sync_context(memory, config, false),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route Gmail backfill through the memory-tree sink

When gmail-backfill-3d calls run_gmail_backfill, this local=false context supplies no LocalDocumentSink; the Gmail pipeline therefore stores via the SkillDocSink path (HostSyncAdapter::storestore_skill_sync) instead of the old ingest_page_into_memory_tree path. Operators running the backfill get records_ingested but chunks.db/content files remain empty, and the existing integrity check just verifies zero chunks. Use a memory-tree/local-document sink for this backfill or update the CLI semantics.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed988cd3d1

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.tick(
&pipeline_id,
&memory_config,
&source_sync_context(memory, config, source.kind != SourceKind::Composio),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route Composio source syncs through the tree sink

For Composio sources this passes local = false, so source_sync_context supplies no LocalDocumentSink or summariser; the TinyCortex Composio pipelines therefore can only call the SkillDocSink path (store_skill_sync) instead of the previous Gmail/Slack/Notion memory-tree ingest paths. In normal manual, periodic, and connection-created Composio syncs this can report records_ingested while leaving mem_tree_chunks/content files empty, so memory-tree retrieval will not see newly synced emails/messages/docs. Provide the tree/local-document sink for Composio pipelines or route those pipeline outputs through the equivalent memory-tree ingestion path.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dde408f03d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

log::warn!("[retrieval::drill_down] embed query failed — returning BFS order: {err}");
return Ok(hits);
}
build_embedder_from_config(config)?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Restore BFS fallback for semantic drill-down failures

When a drill-down includes a query, this ? makes an invalid or unavailable embedding provider fail the whole RPC before any traversal happens. The previous rerank_by_semantic_similarity path caught both embedder-build and embed errors and returned the BFS-ordered children specifically so local-AI/embedding outages did not surface to chat; with a bad custom/OpenAI-compatible embedding config, semantic drill-down now errors instead of returning usable children. Keep the fallback behavior around the crate-backed rerank path.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4abe9525b4

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

wipe_memory_tree_state(&config)?;
log::info!("[gmail_backfill_3d] clearing skill-gmail documents");
memory
.clear_namespace("skill-gmail")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reset Gmail sync state when wiping backfill docs

When --wipe is used after a prior Gmail sync, this only clears the skill-gmail documents; the persisted composio-sync-state cursor/synced_ids for that connection remains. The following run_gmail_backfill goes through the Gmail sync pipeline, so it can treat those messages as already synced and ingest zero records, while the verification still passes because documents_before was reset to 0. Clear the Gmail SyncState for the selected connection as part of the wipe.

Useful? React with 👍 / 👎.

sync_depth_days = ?source.sync_depth_days,
"[tinycortex:sync] dispatching Composio connection"
);
run_source_pipeline(&source, config).await

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Record successful Composio syncs for cadence

For Gmail manual/trigger syncs, the removed GmailProvider::sync path called periodic::record_sync_success, but this new direct wrapper returns after run_source_pipeline without updating the last-sync map. Since these non-periodic runs also don't write the periodic audit entry keyed by connection id, the periodic scheduler can consider the same Gmail connection due on its next tick and immediately repeat the sync, duplicating Composio calls/cost after a user-initiated or trigger-driven sync. Record success on the Ok path here or in each non-periodic caller.

Useful? React with 👍 / 👎.

@coderabbitai coderabbitai Bot added memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure. labels Jul 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e797300a74

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +17 to 19
pub(crate) fn tree_active_signature(config: &Config) -> String {
tinycortex::memory::chunks::tree_active_signature(&engine_config(config))
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve provider in tree embedding signatures

When users switch embedding providers without changing the model/dimension tuple (for example openai to custom with text-embedding-3-small), this now derives the tree sidecar key from TinyCortex's MemoryConfig, but memory_config_from only supplies model, dim, and strict, not memory.embedding_provider. The old tree_active_signature used active_embedding_signature(&config.memory, ...), whose contract includes provider=...; losing that component makes old vectors look covered under the new provider, so re-embed backfill can be skipped and retrieval can mix incompatible embedding spaces under the same sidecar key.

Useful? React with 👍 / 👎.

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

🧹 Nitpick comments (4)
src/openhuman/memory_sources/sync.rs (1)

102-119: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Collapse the three identical non-Composio match arms.

Conversation | Folder, GithubRepo, and RssFeed | WebPage now have byte-identical bodies. They can be merged into a single arm to reduce duplication.

♻️ Proposed consolidation
-                SourceKind::Conversation | SourceKind::Folder => {
-                    crate::openhuman::tinycortex::run_source_pipeline(&source, &config)
-                        .await
-                        .map(|outcome| outcome.records_ingested as usize)
-                        .map_err(|error| error.to_string())
-                }
-                SourceKind::GithubRepo => {
-                    crate::openhuman::tinycortex::run_source_pipeline(&source, &config)
-                        .await
-                        .map(|outcome| outcome.records_ingested as usize)
-                        .map_err(|error| error.to_string())
-                }
-                SourceKind::RssFeed | SourceKind::WebPage => {
+                SourceKind::Conversation
+                | SourceKind::Folder
+                | SourceKind::GithubRepo
+                | SourceKind::RssFeed
+                | SourceKind::WebPage => {
                     crate::openhuman::tinycortex::run_source_pipeline(&source, &config)
                         .await
                         .map(|outcome| outcome.records_ingested as usize)
                         .map_err(|error| error.to_string())
                 }
🤖 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/openhuman/memory_sources/sync.rs` around lines 102 - 119, Merge the
identical match arms for SourceKind::Conversation, Folder, GithubRepo, RssFeed,
and WebPage into one combined arm in the source-kind dispatch. Preserve the
existing run_source_pipeline call, records_ingested conversion, and error-string
mapping unchanged.
src/openhuman/memory_sync/composio/mod.rs (1)

154-176: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Drop the redundant caps lookup

run_composio_connection already pulls max_items and sync_depth_days from config.memory_sources (or falls back to defaults), so the list_enabled_by_kind read here and the let _ = (...) are dead work on every sync. I don’t see any in-repo code callers for run_connection_sync anymore, so this may be removable too.

🤖 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/openhuman/memory_sync/composio/mod.rs` around lines 154 - 176, The
redundant registry caps lookup and debug logging in run_connection_sync should
be removed, including src_max_items, src_sync_depth_days, and the trailing let _
assignment. Preserve the existing configuration-driven caps handling in
run_composio_connection; also remove run_connection_sync if it has no remaining
in-repository callers and is no longer needed.
src/openhuman/tinycortex/config.rs (1)

36-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a parity assertion for the newly-wired content_root.

The existing parity tests cover workspace, embedding, and tree defaults but not mc.content_root. Since this field now drives on-disk content read/write paths across the delegated wrappers, a small assertion guards it against silent drift.

💚 Suggested assertion
         assert_eq!(mc.workspace, workspace);
+        assert_eq!(mc.content_root, Some(config.memory_tree_content_root()));
         assert_eq!(mc.embedding.dim, 1024);
🤖 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/openhuman/tinycortex/config.rs` around lines 36 - 45, Extend the parity
test for memory_config_from to assert that the resulting
MemoryConfig.content_root matches config.memory_tree_content_root(). Keep the
existing workspace, embedding, and tree-default assertions unchanged and add
only this content-root parity check.
src/openhuman/memory_tree/retrieval/drill_down.rs (1)

30-45: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Capture current_source_scope() once to avoid the double call across the await.

current_source_scope() is invoked at Line 30 (to derive engine_limit) and again at Line 43 (for the retain filter), straddling the .await at Line 42. Binding it once — as source.rs already does with let scope = current_source_scope(); — avoids the repeated lookup/clone and guarantees the limit decision and the post-retrieval filter observe the same scope value.

♻️ Proposed refactor
     let bridge = EmbedderBridge(embedder.as_ref());
-    let engine_limit = current_source_scope()
-        .as_ref()
-        .map(|_| None)
-        .unwrap_or(limit);
+    let scope = current_source_scope();
+    let engine_limit = scope.as_ref().map(|_| None).unwrap_or(limit);
     let mut hits = tinycortex::memory::retrieval::drill_down(
         &engine_config(config),
         node_id,
         max_depth,
         query,
         &bridge,
         engine_limit,
     )
     .await?;
-    if let Some(set) = current_source_scope() {
+    if let Some(set) = scope {
         hits.retain(|hit| set.contains(&hit.tree_scope));
     }
🤖 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/openhuman/memory_tree/retrieval/drill_down.rs` around lines 30 - 45,
Capture current_source_scope() once in a local scope variable before deriving
engine_limit, then reuse that variable for the post-await hit filtering in the
drill_down flow. Preserve the existing limit and retain behavior while ensuring
both decisions use the same scope value.
🤖 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/openhuman/memory_store/memory_trait.rs`:
- Around line 353-357: Update the memory_docs namespace lookups in get and
forget to pass normalize_namespace(namespace) through
UnifiedMemory::sanitize_namespace, matching the existing list query and write
path. Keep all other query behavior unchanged so rewritten namespaces resolve
consistently for reads and deletes.

In `@src/openhuman/memory_sync/composio/periodic.rs`:
- Line 592: Update the success-recording call in the sync flow to pass the
normalized toolkit value returned by conn.normalized_toolkit() instead of
conn.toolkit. Keep the existing connection ID argument and record_sync_success
behavior unchanged.

In `@src/openhuman/memory_tree/score/extract/mod.rs`:
- Around line 17-66: Move the LlmEntityExtractor wrapper, its EntityExtractor
implementation, and build_summary_extractor factory from mod.rs into a sibling
implementation module such as ops.rs. Keep mod.rs limited to module declarations
and public re-exports, and re-export the moved public symbols so existing
callers retain the same API.

In `@src/openhuman/memory_tree/score/mod.rs`:
- Around line 17-42: Move the scoring_config_from function and its
provider/extractor construction logic from mod.rs into a sibling implementation
module such as ops.rs. Declare that module from mod.rs and re-export
scoring_config_from there, keeping the existing public API and fallback behavior
unchanged while leaving mod.rs export-only.

In `@src/openhuman/tinycortex/ingest.rs`:
- Around line 30-41: Update scoring_config to resolve and pass the configured
chat model into LlmExtractorConfig alongside the provider, reusing the
model-aware runtime builder used by scoring_config_from. Set
LlmExtractorConfig::model before constructing LlmEntityExtractor, while
preserving the existing regex-only fallback when provider resolution fails.

---

Nitpick comments:
In `@src/openhuman/memory_sources/sync.rs`:
- Around line 102-119: Merge the identical match arms for
SourceKind::Conversation, Folder, GithubRepo, RssFeed, and WebPage into one
combined arm in the source-kind dispatch. Preserve the existing
run_source_pipeline call, records_ingested conversion, and error-string mapping
unchanged.

In `@src/openhuman/memory_sync/composio/mod.rs`:
- Around line 154-176: The redundant registry caps lookup and debug logging in
run_connection_sync should be removed, including src_max_items,
src_sync_depth_days, and the trailing let _ assignment. Preserve the existing
configuration-driven caps handling in run_composio_connection; also remove
run_connection_sync if it has no remaining in-repository callers and is no
longer needed.

In `@src/openhuman/memory_tree/retrieval/drill_down.rs`:
- Around line 30-45: Capture current_source_scope() once in a local scope
variable before deriving engine_limit, then reuse that variable for the
post-await hit filtering in the drill_down flow. Preserve the existing limit and
retain behavior while ensuring both decisions use the same scope value.

In `@src/openhuman/tinycortex/config.rs`:
- Around line 36-45: Extend the parity test for memory_config_from to assert
that the resulting MemoryConfig.content_root matches
config.memory_tree_content_root(). Keep the existing workspace, embedding, and
tree-default assertions unchanged and add only this content-root parity check.
🪄 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: 1b043889-fd64-44fa-994d-ac9118ef645a

📥 Commits

Reviewing files that changed from the base of the PR and between a67d6a5 and e797300.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • app/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (197)
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • src/bin/gmail_backfill_3d.rs
  • src/bin/slack_backfill.rs
  • src/core/observability.rs
  • src/openhuman/agent/harness/session/builder/factory.rs
  • src/openhuman/agent/harness/session/builder/helpers.rs
  • src/openhuman/composio/identity.rs
  • src/openhuman/composio/ops/memory_cleanup.rs
  • src/openhuman/composio/ops/providers_ops.rs
  • src/openhuman/composio/ops_tests.rs
  • src/openhuman/composio/tools_tests.rs
  • src/openhuman/embeddings/cloud.rs
  • src/openhuman/embeddings/cloud_adapter.rs
  • src/openhuman/embeddings/cohere.rs
  • src/openhuman/embeddings/cohere_adapter.rs
  • src/openhuman/embeddings/factory.rs
  • src/openhuman/embeddings/mod.rs
  • src/openhuman/embeddings/ollama.rs
  • src/openhuman/embeddings/ollama_adapter.rs
  • src/openhuman/embeddings/ollama_tests.rs
  • src/openhuman/embeddings/openai.rs
  • src/openhuman/embeddings/openai_adapter.rs
  • src/openhuman/embeddings/openai_tests.rs
  • src/openhuman/embeddings/provider_trait.rs
  • src/openhuman/embeddings/rate_limit.rs
  • src/openhuman/embeddings/retry_after.rs
  • src/openhuman/embeddings/rpc.rs
  • src/openhuman/embeddings/voyage.rs
  • src/openhuman/embeddings/voyage_adapter.rs
  • src/openhuman/memory/ingest_pipeline.rs
  • src/openhuman/memory/ingestion/mod.rs
  • src/openhuman/memory/ingestion/parse.rs
  • src/openhuman/memory/ingestion/parse_tests.rs
  • src/openhuman/memory/ingestion/regex.rs
  • src/openhuman/memory/ingestion/rules.rs
  • src/openhuman/memory/ingestion/types.rs
  • src/openhuman/memory/ops/sync.rs
  • src/openhuman/memory/read_rpc/admin.rs
  • src/openhuman/memory/read_rpc_tests.rs
  • src/openhuman/memory/sync_pipeline_e2e_tests.rs
  • src/openhuman/memory/traits.rs
  • src/openhuman/memory_queue/mod.rs
  • src/openhuman/memory_queue/ops.rs
  • src/openhuman/memory_queue/redact.rs
  • src/openhuman/memory_queue/scheduler.rs
  • src/openhuman/memory_queue/store.rs
  • src/openhuman/memory_queue/types.rs
  • src/openhuman/memory_sources/readers/conversation.rs
  • src/openhuman/memory_sources/readers/folder.rs
  • src/openhuman/memory_sources/registry.rs
  • src/openhuman/memory_sources/sync.rs
  • src/openhuman/memory_sources/types.rs
  • src/openhuman/memory_store/chunks/connection.rs
  • src/openhuman/memory_store/chunks/embeddings.rs
  • src/openhuman/memory_store/chunks/migrations.rs
  • src/openhuman/memory_store/chunks/produce.rs
  • src/openhuman/memory_store/chunks/semantic.rs
  • src/openhuman/memory_store/chunks/store.rs
  • src/openhuman/memory_store/chunks/store_tests.rs
  • src/openhuman/memory_store/chunks/types.rs
  • src/openhuman/memory_store/content/README.md
  • src/openhuman/memory_store/content/atomic.rs
  • src/openhuman/memory_store/content/compose/chunk.rs
  • src/openhuman/memory_store/content/compose/mod.rs
  • src/openhuman/memory_store/content/compose/summary.rs
  • src/openhuman/memory_store/content/compose/tests.rs
  • src/openhuman/memory_store/content/compose/yaml.rs
  • src/openhuman/memory_store/content/mod.rs
  • src/openhuman/memory_store/content/paths.rs
  • src/openhuman/memory_store/content/raw.rs
  • src/openhuman/memory_store/content/read.rs
  • src/openhuman/memory_store/entities.rs
  • src/openhuman/memory_store/factories.rs
  • src/openhuman/memory_store/kv.rs
  • src/openhuman/memory_store/memory_trait.rs
  • src/openhuman/memory_store/safety/mod.rs
  • src/openhuman/memory_store/safety/pii.rs
  • src/openhuman/memory_store/trees/hotness.rs
  • src/openhuman/memory_store/trees/registry.rs
  • src/openhuman/memory_store/trees/store.rs
  • src/openhuman/memory_store/trees/types.rs
  • src/openhuman/memory_store/types.rs
  • src/openhuman/memory_store/vectors/mod.rs
  • src/openhuman/memory_store/vectors/store.rs
  • src/openhuman/memory_store/vectors/store_tests.rs
  • src/openhuman/memory_sync/canonicalize/README.md
  • src/openhuman/memory_sync/canonicalize/chat.rs
  • src/openhuman/memory_sync/canonicalize/document.rs
  • src/openhuman/memory_sync/canonicalize/email.rs
  • src/openhuman/memory_sync/canonicalize/email_clean.rs
  • src/openhuman/memory_sync/canonicalize/mod.rs
  • src/openhuman/memory_sync/composio/bus.rs
  • src/openhuman/memory_sync/composio/mod.rs
  • src/openhuman/memory_sync/composio/periodic.rs
  • src/openhuman/memory_sync/composio/providers/clickup/ingest.rs
  • src/openhuman/memory_sync/composio/providers/clickup/mod.rs
  • src/openhuman/memory_sync/composio/providers/clickup/provider.rs
  • src/openhuman/memory_sync/composio/providers/clickup/source.rs
  • src/openhuman/memory_sync/composio/providers/github/ingest.rs
  • src/openhuman/memory_sync/composio/providers/github/mod.rs
  • src/openhuman/memory_sync/composio/providers/github/provider.rs
  • src/openhuman/memory_sync/composio/providers/github/source.rs
  • src/openhuman/memory_sync/composio/providers/gmail/ingest.rs
  • src/openhuman/memory_sync/composio/providers/gmail/mod.rs
  • src/openhuman/memory_sync/composio/providers/gmail/provider.rs
  • src/openhuman/memory_sync/composio/providers/gmail/source.rs
  • src/openhuman/memory_sync/composio/providers/linear/ingest.rs
  • src/openhuman/memory_sync/composio/providers/linear/mod.rs
  • src/openhuman/memory_sync/composio/providers/linear/provider.rs
  • src/openhuman/memory_sync/composio/providers/linear/source.rs
  • src/openhuman/memory_sync/composio/providers/mod.rs
  • src/openhuman/memory_sync/composio/providers/notion/ingest.rs
  • src/openhuman/memory_sync/composio/providers/notion/mod.rs
  • src/openhuman/memory_sync/composio/providers/notion/provider.rs
  • src/openhuman/memory_sync/composio/providers/notion/source.rs
  • src/openhuman/memory_sync/composio/providers/orchestrator.rs
  • src/openhuman/memory_sync/composio/providers/registry.rs
  • src/openhuman/memory_sync/composio/providers/slack/ingest.rs
  • src/openhuman/memory_sync/composio/providers/slack/mod.rs
  • src/openhuman/memory_sync/composio/providers/slack/provider.rs
  • src/openhuman/memory_sync/composio/providers/slack/rpc.rs
  • src/openhuman/memory_sync/composio/providers/slack/source.rs
  • src/openhuman/memory_sync/composio/providers/slack/sync.rs
  • src/openhuman/memory_sync/composio/providers/slack/types.rs
  • src/openhuman/memory_sync/composio/providers/slack/users.rs
  • src/openhuman/memory_sync/composio/providers/sync_state.rs
  • src/openhuman/memory_sync/composio/providers/traits.rs
  • src/openhuman/memory_sync/sources/audit.rs
  • src/openhuman/memory_sync/sources/github.rs
  • src/openhuman/memory_sync/sources/mod.rs
  • src/openhuman/memory_sync/sources/rebuild.rs
  • src/openhuman/memory_sync/sync_status/rpc.rs
  • src/openhuman/memory_sync/sync_status/types.rs
  • src/openhuman/memory_tools/README.md
  • src/openhuman/memory_tools/store.rs
  • src/openhuman/memory_tools/tools/list.rs
  • src/openhuman/memory_tools/tools/put.rs
  • src/openhuman/memory_tree/graph/bfs.rs
  • src/openhuman/memory_tree/graph/store.rs
  • src/openhuman/memory_tree/ingest.rs
  • src/openhuman/memory_tree/io.rs
  • src/openhuman/memory_tree/retrieval/cover.rs
  • src/openhuman/memory_tree/retrieval/drill_down.rs
  • src/openhuman/memory_tree/retrieval/engine.rs
  • src/openhuman/memory_tree/retrieval/fast.rs
  • src/openhuman/memory_tree/retrieval/fetch.rs
  • src/openhuman/memory_tree/retrieval/mod.rs
  • src/openhuman/memory_tree/retrieval/search.rs
  • src/openhuman/memory_tree/retrieval/source.rs
  • src/openhuman/memory_tree/retrieval/types.rs
  • src/openhuman/memory_tree/score/extract/extractor.rs
  • src/openhuman/memory_tree/score/extract/llm.rs
  • src/openhuman/memory_tree/score/extract/llm_tests.rs
  • src/openhuman/memory_tree/score/extract/mod.rs
  • src/openhuman/memory_tree/score/extract/regex.rs
  • src/openhuman/memory_tree/score/extract/types.rs
  • src/openhuman/memory_tree/score/mod.rs
  • src/openhuman/memory_tree/score/resolver.rs
  • src/openhuman/memory_tree/score/signals/interaction.rs
  • src/openhuman/memory_tree/score/signals/metadata_weight.rs
  • src/openhuman/memory_tree/score/signals/mod.rs
  • src/openhuman/memory_tree/score/signals/ops.rs
  • src/openhuman/memory_tree/score/signals/source_weight.rs
  • src/openhuman/memory_tree/score/signals/token_count.rs
  • src/openhuman/memory_tree/score/signals/types.rs
  • src/openhuman/memory_tree/score/signals/unique_words.rs
  • src/openhuman/memory_tree/score/store.rs
  • src/openhuman/memory_tree/score/store_tests.rs
  • src/openhuman/memory_tree/summarise.rs
  • src/openhuman/memory_tree/tree/bucket_seal.rs
  • src/openhuman/memory_tree/tree/bucket_seal_tests.rs
  • src/openhuman/memory_tree/tree/factory.rs
  • src/openhuman/memory_tree/tree/flush.rs
  • src/openhuman/memory_tree/tree_runtime/engine.rs
  • src/openhuman/memory_tree/tree_runtime/engine_tests.rs
  • src/openhuman/memory_tree/tree_runtime/store.rs
  • src/openhuman/memory_tree/tree_runtime/store_tests.rs
  • src/openhuman/memory_tree/tree_runtime/types.rs
  • src/openhuman/task_sources/pipeline_tests.rs
  • src/openhuman/tinyagents/embeddings.rs
  • src/openhuman/tinycortex/config.rs
  • src/openhuman/tinycortex/ingest.rs
  • src/openhuman/tinycortex/mod.rs
  • src/openhuman/tinycortex/queue_driver.rs
  • src/openhuman/tinycortex/seal.rs
  • src/openhuman/tinycortex/summariser.rs
  • src/openhuman/tinycortex/sync.rs
  • tests/embeddings_rpc_e2e.rs
  • tests/json_rpc_e2e.rs
  • tests/memory_artifacts_e2e.rs
  • tests/raw_coverage/memory_sync_providers_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_sync_tree_round21_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_threads_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rs
  • vendor/tinyagents
  • vendor/tinycortex
💤 Files with no reviewable changes (26)
  • src/openhuman/memory_queue/redact.rs
  • src/openhuman/memory_sync/composio/providers/notion/mod.rs
  • src/openhuman/memory/ingestion/parse.rs
  • src/openhuman/memory_sync/composio/providers/linear/mod.rs
  • src/openhuman/memory_sync/composio/providers/clickup/mod.rs
  • src/openhuman/memory/ingestion/parse_tests.rs
  • src/openhuman/embeddings/retry_after.rs
  • src/openhuman/memory_sync/composio/providers/github/mod.rs
  • src/openhuman/memory_queue/mod.rs
  • src/openhuman/memory_sync/composio/providers/mod.rs
  • src/openhuman/memory_sync/composio/providers/gmail/mod.rs
  • src/openhuman/memory_store/chunks/migrations.rs
  • src/openhuman/embeddings/voyage.rs
  • src/openhuman/embeddings/rate_limit.rs
  • src/openhuman/memory/ingestion/rules.rs
  • src/openhuman/embeddings/ollama_tests.rs
  • src/openhuman/embeddings/openai_tests.rs
  • src/openhuman/embeddings/cohere.rs
  • src/openhuman/memory/ingestion/types.rs
  • src/openhuman/embeddings/cloud.rs
  • src/openhuman/memory/ingestion/regex.rs
  • src/openhuman/embeddings/ollama.rs
  • src/openhuman/embeddings/openai.rs
  • src/openhuman/composio/tools_tests.rs
  • tests/json_rpc_e2e.rs
  • tests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rs

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

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

🧹 Nitpick comments (4)
src/openhuman/memory_sources/sync.rs (1)

102-119: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Collapse the three identical non-Composio match arms.

Conversation | Folder, GithubRepo, and RssFeed | WebPage now have byte-identical bodies. They can be merged into a single arm to reduce duplication.

♻️ Proposed consolidation
-                SourceKind::Conversation | SourceKind::Folder => {
-                    crate::openhuman::tinycortex::run_source_pipeline(&source, &config)
-                        .await
-                        .map(|outcome| outcome.records_ingested as usize)
-                        .map_err(|error| error.to_string())
-                }
-                SourceKind::GithubRepo => {
-                    crate::openhuman::tinycortex::run_source_pipeline(&source, &config)
-                        .await
-                        .map(|outcome| outcome.records_ingested as usize)
-                        .map_err(|error| error.to_string())
-                }
-                SourceKind::RssFeed | SourceKind::WebPage => {
+                SourceKind::Conversation
+                | SourceKind::Folder
+                | SourceKind::GithubRepo
+                | SourceKind::RssFeed
+                | SourceKind::WebPage => {
                     crate::openhuman::tinycortex::run_source_pipeline(&source, &config)
                         .await
                         .map(|outcome| outcome.records_ingested as usize)
                         .map_err(|error| error.to_string())
                 }
🤖 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/openhuman/memory_sources/sync.rs` around lines 102 - 119, Merge the
identical match arms for SourceKind::Conversation, Folder, GithubRepo, RssFeed,
and WebPage into one combined arm in the source-kind dispatch. Preserve the
existing run_source_pipeline call, records_ingested conversion, and error-string
mapping unchanged.
src/openhuman/memory_sync/composio/mod.rs (1)

154-176: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Drop the redundant caps lookup

run_composio_connection already pulls max_items and sync_depth_days from config.memory_sources (or falls back to defaults), so the list_enabled_by_kind read here and the let _ = (...) are dead work on every sync. I don’t see any in-repo code callers for run_connection_sync anymore, so this may be removable too.

🤖 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/openhuman/memory_sync/composio/mod.rs` around lines 154 - 176, The
redundant registry caps lookup and debug logging in run_connection_sync should
be removed, including src_max_items, src_sync_depth_days, and the trailing let _
assignment. Preserve the existing configuration-driven caps handling in
run_composio_connection; also remove run_connection_sync if it has no remaining
in-repository callers and is no longer needed.
src/openhuman/tinycortex/config.rs (1)

36-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add a parity assertion for the newly-wired content_root.

The existing parity tests cover workspace, embedding, and tree defaults but not mc.content_root. Since this field now drives on-disk content read/write paths across the delegated wrappers, a small assertion guards it against silent drift.

💚 Suggested assertion
         assert_eq!(mc.workspace, workspace);
+        assert_eq!(mc.content_root, Some(config.memory_tree_content_root()));
         assert_eq!(mc.embedding.dim, 1024);
🤖 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/openhuman/tinycortex/config.rs` around lines 36 - 45, Extend the parity
test for memory_config_from to assert that the resulting
MemoryConfig.content_root matches config.memory_tree_content_root(). Keep the
existing workspace, embedding, and tree-default assertions unchanged and add
only this content-root parity check.
src/openhuman/memory_tree/retrieval/drill_down.rs (1)

30-45: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Capture current_source_scope() once to avoid the double call across the await.

current_source_scope() is invoked at Line 30 (to derive engine_limit) and again at Line 43 (for the retain filter), straddling the .await at Line 42. Binding it once — as source.rs already does with let scope = current_source_scope(); — avoids the repeated lookup/clone and guarantees the limit decision and the post-retrieval filter observe the same scope value.

♻️ Proposed refactor
     let bridge = EmbedderBridge(embedder.as_ref());
-    let engine_limit = current_source_scope()
-        .as_ref()
-        .map(|_| None)
-        .unwrap_or(limit);
+    let scope = current_source_scope();
+    let engine_limit = scope.as_ref().map(|_| None).unwrap_or(limit);
     let mut hits = tinycortex::memory::retrieval::drill_down(
         &engine_config(config),
         node_id,
         max_depth,
         query,
         &bridge,
         engine_limit,
     )
     .await?;
-    if let Some(set) = current_source_scope() {
+    if let Some(set) = scope {
         hits.retain(|hit| set.contains(&hit.tree_scope));
     }
🤖 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/openhuman/memory_tree/retrieval/drill_down.rs` around lines 30 - 45,
Capture current_source_scope() once in a local scope variable before deriving
engine_limit, then reuse that variable for the post-await hit filtering in the
drill_down flow. Preserve the existing limit and retain behavior while ensuring
both decisions use the same scope value.
🤖 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/openhuman/memory_store/memory_trait.rs`:
- Around line 353-357: Update the memory_docs namespace lookups in get and
forget to pass normalize_namespace(namespace) through
UnifiedMemory::sanitize_namespace, matching the existing list query and write
path. Keep all other query behavior unchanged so rewritten namespaces resolve
consistently for reads and deletes.

In `@src/openhuman/memory_sync/composio/periodic.rs`:
- Line 592: Update the success-recording call in the sync flow to pass the
normalized toolkit value returned by conn.normalized_toolkit() instead of
conn.toolkit. Keep the existing connection ID argument and record_sync_success
behavior unchanged.

In `@src/openhuman/memory_tree/score/extract/mod.rs`:
- Around line 17-66: Move the LlmEntityExtractor wrapper, its EntityExtractor
implementation, and build_summary_extractor factory from mod.rs into a sibling
implementation module such as ops.rs. Keep mod.rs limited to module declarations
and public re-exports, and re-export the moved public symbols so existing
callers retain the same API.

In `@src/openhuman/memory_tree/score/mod.rs`:
- Around line 17-42: Move the scoring_config_from function and its
provider/extractor construction logic from mod.rs into a sibling implementation
module such as ops.rs. Declare that module from mod.rs and re-export
scoring_config_from there, keeping the existing public API and fallback behavior
unchanged while leaving mod.rs export-only.

In `@src/openhuman/tinycortex/ingest.rs`:
- Around line 30-41: Update scoring_config to resolve and pass the configured
chat model into LlmExtractorConfig alongside the provider, reusing the
model-aware runtime builder used by scoring_config_from. Set
LlmExtractorConfig::model before constructing LlmEntityExtractor, while
preserving the existing regex-only fallback when provider resolution fails.

---

Nitpick comments:
In `@src/openhuman/memory_sources/sync.rs`:
- Around line 102-119: Merge the identical match arms for
SourceKind::Conversation, Folder, GithubRepo, RssFeed, and WebPage into one
combined arm in the source-kind dispatch. Preserve the existing
run_source_pipeline call, records_ingested conversion, and error-string mapping
unchanged.

In `@src/openhuman/memory_sync/composio/mod.rs`:
- Around line 154-176: The redundant registry caps lookup and debug logging in
run_connection_sync should be removed, including src_max_items,
src_sync_depth_days, and the trailing let _ assignment. Preserve the existing
configuration-driven caps handling in run_composio_connection; also remove
run_connection_sync if it has no remaining in-repository callers and is no
longer needed.

In `@src/openhuman/memory_tree/retrieval/drill_down.rs`:
- Around line 30-45: Capture current_source_scope() once in a local scope
variable before deriving engine_limit, then reuse that variable for the
post-await hit filtering in the drill_down flow. Preserve the existing limit and
retain behavior while ensuring both decisions use the same scope value.

In `@src/openhuman/tinycortex/config.rs`:
- Around line 36-45: Extend the parity test for memory_config_from to assert
that the resulting MemoryConfig.content_root matches
config.memory_tree_content_root(). Keep the existing workspace, embedding, and
tree-default assertions unchanged and add only this content-root parity check.
🪄 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: 1b043889-fd64-44fa-994d-ac9118ef645a

📥 Commits

Reviewing files that changed from the base of the PR and between a67d6a5 and e797300.

⛔ Files ignored due to path filters (2)
  • Cargo.lock is excluded by !**/*.lock
  • app/src-tauri/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (197)
  • Cargo.toml
  • app/src-tauri/Cargo.toml
  • src/bin/gmail_backfill_3d.rs
  • src/bin/slack_backfill.rs
  • src/core/observability.rs
  • src/openhuman/agent/harness/session/builder/factory.rs
  • src/openhuman/agent/harness/session/builder/helpers.rs
  • src/openhuman/composio/identity.rs
  • src/openhuman/composio/ops/memory_cleanup.rs
  • src/openhuman/composio/ops/providers_ops.rs
  • src/openhuman/composio/ops_tests.rs
  • src/openhuman/composio/tools_tests.rs
  • src/openhuman/embeddings/cloud.rs
  • src/openhuman/embeddings/cloud_adapter.rs
  • src/openhuman/embeddings/cohere.rs
  • src/openhuman/embeddings/cohere_adapter.rs
  • src/openhuman/embeddings/factory.rs
  • src/openhuman/embeddings/mod.rs
  • src/openhuman/embeddings/ollama.rs
  • src/openhuman/embeddings/ollama_adapter.rs
  • src/openhuman/embeddings/ollama_tests.rs
  • src/openhuman/embeddings/openai.rs
  • src/openhuman/embeddings/openai_adapter.rs
  • src/openhuman/embeddings/openai_tests.rs
  • src/openhuman/embeddings/provider_trait.rs
  • src/openhuman/embeddings/rate_limit.rs
  • src/openhuman/embeddings/retry_after.rs
  • src/openhuman/embeddings/rpc.rs
  • src/openhuman/embeddings/voyage.rs
  • src/openhuman/embeddings/voyage_adapter.rs
  • src/openhuman/memory/ingest_pipeline.rs
  • src/openhuman/memory/ingestion/mod.rs
  • src/openhuman/memory/ingestion/parse.rs
  • src/openhuman/memory/ingestion/parse_tests.rs
  • src/openhuman/memory/ingestion/regex.rs
  • src/openhuman/memory/ingestion/rules.rs
  • src/openhuman/memory/ingestion/types.rs
  • src/openhuman/memory/ops/sync.rs
  • src/openhuman/memory/read_rpc/admin.rs
  • src/openhuman/memory/read_rpc_tests.rs
  • src/openhuman/memory/sync_pipeline_e2e_tests.rs
  • src/openhuman/memory/traits.rs
  • src/openhuman/memory_queue/mod.rs
  • src/openhuman/memory_queue/ops.rs
  • src/openhuman/memory_queue/redact.rs
  • src/openhuman/memory_queue/scheduler.rs
  • src/openhuman/memory_queue/store.rs
  • src/openhuman/memory_queue/types.rs
  • src/openhuman/memory_sources/readers/conversation.rs
  • src/openhuman/memory_sources/readers/folder.rs
  • src/openhuman/memory_sources/registry.rs
  • src/openhuman/memory_sources/sync.rs
  • src/openhuman/memory_sources/types.rs
  • src/openhuman/memory_store/chunks/connection.rs
  • src/openhuman/memory_store/chunks/embeddings.rs
  • src/openhuman/memory_store/chunks/migrations.rs
  • src/openhuman/memory_store/chunks/produce.rs
  • src/openhuman/memory_store/chunks/semantic.rs
  • src/openhuman/memory_store/chunks/store.rs
  • src/openhuman/memory_store/chunks/store_tests.rs
  • src/openhuman/memory_store/chunks/types.rs
  • src/openhuman/memory_store/content/README.md
  • src/openhuman/memory_store/content/atomic.rs
  • src/openhuman/memory_store/content/compose/chunk.rs
  • src/openhuman/memory_store/content/compose/mod.rs
  • src/openhuman/memory_store/content/compose/summary.rs
  • src/openhuman/memory_store/content/compose/tests.rs
  • src/openhuman/memory_store/content/compose/yaml.rs
  • src/openhuman/memory_store/content/mod.rs
  • src/openhuman/memory_store/content/paths.rs
  • src/openhuman/memory_store/content/raw.rs
  • src/openhuman/memory_store/content/read.rs
  • src/openhuman/memory_store/entities.rs
  • src/openhuman/memory_store/factories.rs
  • src/openhuman/memory_store/kv.rs
  • src/openhuman/memory_store/memory_trait.rs
  • src/openhuman/memory_store/safety/mod.rs
  • src/openhuman/memory_store/safety/pii.rs
  • src/openhuman/memory_store/trees/hotness.rs
  • src/openhuman/memory_store/trees/registry.rs
  • src/openhuman/memory_store/trees/store.rs
  • src/openhuman/memory_store/trees/types.rs
  • src/openhuman/memory_store/types.rs
  • src/openhuman/memory_store/vectors/mod.rs
  • src/openhuman/memory_store/vectors/store.rs
  • src/openhuman/memory_store/vectors/store_tests.rs
  • src/openhuman/memory_sync/canonicalize/README.md
  • src/openhuman/memory_sync/canonicalize/chat.rs
  • src/openhuman/memory_sync/canonicalize/document.rs
  • src/openhuman/memory_sync/canonicalize/email.rs
  • src/openhuman/memory_sync/canonicalize/email_clean.rs
  • src/openhuman/memory_sync/canonicalize/mod.rs
  • src/openhuman/memory_sync/composio/bus.rs
  • src/openhuman/memory_sync/composio/mod.rs
  • src/openhuman/memory_sync/composio/periodic.rs
  • src/openhuman/memory_sync/composio/providers/clickup/ingest.rs
  • src/openhuman/memory_sync/composio/providers/clickup/mod.rs
  • src/openhuman/memory_sync/composio/providers/clickup/provider.rs
  • src/openhuman/memory_sync/composio/providers/clickup/source.rs
  • src/openhuman/memory_sync/composio/providers/github/ingest.rs
  • src/openhuman/memory_sync/composio/providers/github/mod.rs
  • src/openhuman/memory_sync/composio/providers/github/provider.rs
  • src/openhuman/memory_sync/composio/providers/github/source.rs
  • src/openhuman/memory_sync/composio/providers/gmail/ingest.rs
  • src/openhuman/memory_sync/composio/providers/gmail/mod.rs
  • src/openhuman/memory_sync/composio/providers/gmail/provider.rs
  • src/openhuman/memory_sync/composio/providers/gmail/source.rs
  • src/openhuman/memory_sync/composio/providers/linear/ingest.rs
  • src/openhuman/memory_sync/composio/providers/linear/mod.rs
  • src/openhuman/memory_sync/composio/providers/linear/provider.rs
  • src/openhuman/memory_sync/composio/providers/linear/source.rs
  • src/openhuman/memory_sync/composio/providers/mod.rs
  • src/openhuman/memory_sync/composio/providers/notion/ingest.rs
  • src/openhuman/memory_sync/composio/providers/notion/mod.rs
  • src/openhuman/memory_sync/composio/providers/notion/provider.rs
  • src/openhuman/memory_sync/composio/providers/notion/source.rs
  • src/openhuman/memory_sync/composio/providers/orchestrator.rs
  • src/openhuman/memory_sync/composio/providers/registry.rs
  • src/openhuman/memory_sync/composio/providers/slack/ingest.rs
  • src/openhuman/memory_sync/composio/providers/slack/mod.rs
  • src/openhuman/memory_sync/composio/providers/slack/provider.rs
  • src/openhuman/memory_sync/composio/providers/slack/rpc.rs
  • src/openhuman/memory_sync/composio/providers/slack/source.rs
  • src/openhuman/memory_sync/composio/providers/slack/sync.rs
  • src/openhuman/memory_sync/composio/providers/slack/types.rs
  • src/openhuman/memory_sync/composio/providers/slack/users.rs
  • src/openhuman/memory_sync/composio/providers/sync_state.rs
  • src/openhuman/memory_sync/composio/providers/traits.rs
  • src/openhuman/memory_sync/sources/audit.rs
  • src/openhuman/memory_sync/sources/github.rs
  • src/openhuman/memory_sync/sources/mod.rs
  • src/openhuman/memory_sync/sources/rebuild.rs
  • src/openhuman/memory_sync/sync_status/rpc.rs
  • src/openhuman/memory_sync/sync_status/types.rs
  • src/openhuman/memory_tools/README.md
  • src/openhuman/memory_tools/store.rs
  • src/openhuman/memory_tools/tools/list.rs
  • src/openhuman/memory_tools/tools/put.rs
  • src/openhuman/memory_tree/graph/bfs.rs
  • src/openhuman/memory_tree/graph/store.rs
  • src/openhuman/memory_tree/ingest.rs
  • src/openhuman/memory_tree/io.rs
  • src/openhuman/memory_tree/retrieval/cover.rs
  • src/openhuman/memory_tree/retrieval/drill_down.rs
  • src/openhuman/memory_tree/retrieval/engine.rs
  • src/openhuman/memory_tree/retrieval/fast.rs
  • src/openhuman/memory_tree/retrieval/fetch.rs
  • src/openhuman/memory_tree/retrieval/mod.rs
  • src/openhuman/memory_tree/retrieval/search.rs
  • src/openhuman/memory_tree/retrieval/source.rs
  • src/openhuman/memory_tree/retrieval/types.rs
  • src/openhuman/memory_tree/score/extract/extractor.rs
  • src/openhuman/memory_tree/score/extract/llm.rs
  • src/openhuman/memory_tree/score/extract/llm_tests.rs
  • src/openhuman/memory_tree/score/extract/mod.rs
  • src/openhuman/memory_tree/score/extract/regex.rs
  • src/openhuman/memory_tree/score/extract/types.rs
  • src/openhuman/memory_tree/score/mod.rs
  • src/openhuman/memory_tree/score/resolver.rs
  • src/openhuman/memory_tree/score/signals/interaction.rs
  • src/openhuman/memory_tree/score/signals/metadata_weight.rs
  • src/openhuman/memory_tree/score/signals/mod.rs
  • src/openhuman/memory_tree/score/signals/ops.rs
  • src/openhuman/memory_tree/score/signals/source_weight.rs
  • src/openhuman/memory_tree/score/signals/token_count.rs
  • src/openhuman/memory_tree/score/signals/types.rs
  • src/openhuman/memory_tree/score/signals/unique_words.rs
  • src/openhuman/memory_tree/score/store.rs
  • src/openhuman/memory_tree/score/store_tests.rs
  • src/openhuman/memory_tree/summarise.rs
  • src/openhuman/memory_tree/tree/bucket_seal.rs
  • src/openhuman/memory_tree/tree/bucket_seal_tests.rs
  • src/openhuman/memory_tree/tree/factory.rs
  • src/openhuman/memory_tree/tree/flush.rs
  • src/openhuman/memory_tree/tree_runtime/engine.rs
  • src/openhuman/memory_tree/tree_runtime/engine_tests.rs
  • src/openhuman/memory_tree/tree_runtime/store.rs
  • src/openhuman/memory_tree/tree_runtime/store_tests.rs
  • src/openhuman/memory_tree/tree_runtime/types.rs
  • src/openhuman/task_sources/pipeline_tests.rs
  • src/openhuman/tinyagents/embeddings.rs
  • src/openhuman/tinycortex/config.rs
  • src/openhuman/tinycortex/ingest.rs
  • src/openhuman/tinycortex/mod.rs
  • src/openhuman/tinycortex/queue_driver.rs
  • src/openhuman/tinycortex/seal.rs
  • src/openhuman/tinycortex/summariser.rs
  • src/openhuman/tinycortex/sync.rs
  • tests/embeddings_rpc_e2e.rs
  • tests/json_rpc_e2e.rs
  • tests/memory_artifacts_e2e.rs
  • tests/raw_coverage/memory_sync_providers_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_sync_tree_round21_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_threads_raw_coverage_e2e.rs
  • tests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rs
  • vendor/tinyagents
  • vendor/tinycortex
💤 Files with no reviewable changes (26)
  • src/openhuman/memory_queue/redact.rs
  • src/openhuman/memory_sync/composio/providers/notion/mod.rs
  • src/openhuman/memory/ingestion/parse.rs
  • src/openhuman/memory_sync/composio/providers/linear/mod.rs
  • src/openhuman/memory_sync/composio/providers/clickup/mod.rs
  • src/openhuman/memory/ingestion/parse_tests.rs
  • src/openhuman/embeddings/retry_after.rs
  • src/openhuman/memory_sync/composio/providers/github/mod.rs
  • src/openhuman/memory_queue/mod.rs
  • src/openhuman/memory_sync/composio/providers/mod.rs
  • src/openhuman/memory_sync/composio/providers/gmail/mod.rs
  • src/openhuman/memory_store/chunks/migrations.rs
  • src/openhuman/embeddings/voyage.rs
  • src/openhuman/embeddings/rate_limit.rs
  • src/openhuman/memory/ingestion/rules.rs
  • src/openhuman/embeddings/ollama_tests.rs
  • src/openhuman/embeddings/openai_tests.rs
  • src/openhuman/embeddings/cohere.rs
  • src/openhuman/memory/ingestion/types.rs
  • src/openhuman/embeddings/cloud.rs
  • src/openhuman/memory/ingestion/regex.rs
  • src/openhuman/embeddings/ollama.rs
  • src/openhuman/embeddings/openai.rs
  • src/openhuman/composio/tools_tests.rs
  • tests/json_rpc_e2e.rs
  • tests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rs
🛑 Comments failed to post (5)
src/openhuman/memory_store/memory_trait.rs (1)

353-357: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# How is the namespace stored on write, and does get/forget/list agree?
rg -nP 'fn sanitize_namespace' src/openhuman/memory_store
echo '--- upsert_document ---'
ast-grep run --pattern 'fn upsert_document($$$) { $$$ }' --lang rust src/openhuman/memory_store 2>/dev/null || \
  rg -nP -A60 '\bfn upsert_document\b' src/openhuman/memory_store
echo '--- sanitize call sites in memory_trait ---'
rg -nP 'sanitize_namespace|normalize_namespace' src/openhuman/memory_store/memory_trait.rs

Repository: tinyhumansai/openhuman

Length of output: 6561


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo '--- memory_trait get/forget/list slices ---'
sed -n '280,420p' src/openhuman/memory_store/memory_trait.rs | cat -n

echo '--- unified documents write path around insert ---'
sed -n '55,140p' src/openhuman/memory_store/unified/documents.rs | cat -n

echo '--- sanitize_namespace implementation ---'
sed -n '330,405p' src/openhuman/memory_store/unified/init.rs | cat -n

echo '--- all namespace-related call sites in memory store ---'
rg -n 'sanitize_namespace|normalize_namespace|namespace =' src/openhuman/memory_store

Repository: tinyhumansai/openhuman

Length of output: 21455


get and forget should sanitize namespaces too
Writes persist memory_docs.namespace through sanitize_namespace, and list now queries that same value. get/forget still use only normalize_namespace(...), so namespaces that get rewritten during sanitization will miss rows and fail deletes. Use the same helper on all memory_docs.namespace lookups.

🤖 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/openhuman/memory_store/memory_trait.rs` around lines 353 - 357, Update
the memory_docs namespace lookups in get and forget to pass
normalize_namespace(namespace) through UnifiedMemory::sanitize_namespace,
matching the existing list query and write path. Keep all other query behavior
unchanged so rewritten namespaces resolve consistently for reads and deletes.
src/openhuman/memory_sync/composio/periodic.rs (1)

592-592: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm normalized_toolkit() can differ from the raw `toolkit` field.
rg -nP -C4 'fn normalized_toolkit' src/openhuman
# Show how record_sync_success keys the map vs the due-check key.
rg -nP -C3 'fn record_sync_success|let key = \(' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 2404


🏁 Script executed:

#!/bin/bash
sed -n '490,605p' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 4940


🏁 Script executed:

#!/bin/bash
sed -n '470,520p' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 2246


🏁 Script executed:

#!/bin/bash
rg -n -C2 'record_sync_success\(' src/openhuman

Repository: tinyhumansai/openhuman

Length of output: 3620


🏁 Script executed:

#!/bin/bash
sed -n '1,180p' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 8555


🏁 Script executed:

#!/bin/bash
rg -n -C3 'persisted_since_last_sync|append_audit_entry|build_periodic_audit_entry' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 5595


🏁 Script executed:

#!/bin/bash
sed -n '1,160p' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 7944


🏁 Script executed:

#!/bin/bash
rg -n -C6 'persisted_since_last_sync|append_audit_entry|build_periodic_audit_entry' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 9036


🏁 Script executed:

#!/bin/bash
rg -n -C12 'fn persisted_since_last_sync|fn append_audit_entry|fn build_periodic_audit_entry' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 3490


🏁 Script executed:

#!/bin/bash
rg -n -C3 'let audit_index|index_last_success_by_connection|read_audit_log\(' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 1808


🏁 Script executed:

#!/bin/bash
sed -n '430,490p' src/openhuman/memory_sync/composio/periodic.rs

Repository: tinyhumansai/openhuman

Length of output: 3209


Record sync success with the normalized toolkit

record_sync_success stores the timestamp by (toolkit, connection_id), but the due-check uses conn.normalized_toolkit(). If the raw value differs in case or whitespace, the in-memory fast path misses and the scheduler falls back to the persisted path. Use toolkit here instead of conn.toolkit.

🤖 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/openhuman/memory_sync/composio/periodic.rs` at line 592, Update the
success-recording call in the sync flow to pass the normalized toolkit value
returned by conn.normalized_toolkit() instead of conn.toolkit. Keep the existing
connection ID argument and record_sync_success behavior unchanged.
src/openhuman/memory_tree/score/extract/mod.rs (1)

17-66: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Move extractor implementation out of mod.rs.

This wrapper and factory are business logic, but this mod.rs is reserved for module wiring and re-exports. Move them to a sibling such as ops.rs and re-export the public API.

Suggested module wiring
+mod ops;
+pub use ops::{build_summary_extractor, LlmEntityExtractor};
+
-pub struct LlmEntityExtractor(...);
-impl LlmEntityExtractor { ... }
-impl EntityExtractor for LlmEntityExtractor { ... }
-pub fn build_summary_extractor(...) -> ... { ... }

As per coding guidelines, src/openhuman/**/mod.rs files must be export-only: mod/pub mod, pub use, and controller schema wiring only; no business logic.

🤖 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/openhuman/memory_tree/score/extract/mod.rs` around lines 17 - 66, Move
the LlmEntityExtractor wrapper, its EntityExtractor implementation, and
build_summary_extractor factory from mod.rs into a sibling implementation module
such as ops.rs. Keep mod.rs limited to module declarations and public
re-exports, and re-export the moved public symbols so existing callers retain
the same API.

Source: Coding guidelines

src/openhuman/memory_tree/score/mod.rs (1)

17-42: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Move the scoring-policy builder out of mod.rs.

This function constructs providers, handles failures, and creates an extractor, violating the export-only module rule. Place it in a sibling such as ops.rs, then re-export it here.

As per coding guidelines, "src/openhuman/**/mod.rs: mod.rs files must be export-only ... no business logic."

🤖 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/openhuman/memory_tree/score/mod.rs` around lines 17 - 42, Move the
scoring_config_from function and its provider/extractor construction logic from
mod.rs into a sibling implementation module such as ops.rs. Declare that module
from mod.rs and re-export scoring_config_from there, keeping the existing public
API and fallback behavior unchanged while leaving mod.rs export-only.

Source: Coding guidelines

src/openhuman/tinycortex/ingest.rs (1)

30-41: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Static inspection only: compare model resolution and extractor configuration.
rg -n -C 4 --glob '*.rs' \
  'fn build_chat_runtime|fn build_chat_provider|struct LlmExtractorConfig|impl Default for LlmExtractorConfig' \
  src

rg -n -C 4 --glob '*.rs' \
  'scoring_config_from|fn scoring_config|LlmExtractorConfig \{' \
  src/openhuman/memory_tree/score src/openhuman/tinycortex

Repository: tinyhumansai/openhuman

Length of output: 7871


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the relevant scoring and extractor definitions.
sed -n '1,220p' src/openhuman/tinycortex/ingest.rs
printf '\n==== memory_tree score ====\n'
sed -n '1,220p' src/openhuman/memory_tree/score/mod.rs
printf '\n==== score extract ====\n'
sed -n '1,220p' src/openhuman/memory_tree/score/extract/mod.rs
printf '\n==== extractor config definition ====\n'
rg -n -C 3 --glob '*.rs' 'struct LlmExtractorConfig|model:|output_language:' src/openhuman

Repository: tinyhumansai/openhuman

Length of output: 50379


🏁 Script executed:

#!/bin/bash
set -euo pipefail

sed -n '1,180p' src/openhuman/memory_tree/score/extract/mod.rs
printf '\n==== tinycortex scoring path ====\n'
sed -n '1,120p' src/openhuman/tinycortex/ingest.rs
printf '\n==== LlmExtractorConfig definition ====\n'
rg -n -C 4 --glob '*.rs' 'pub struct LlmExtractorConfig|impl Default for LlmExtractorConfig|fn new\(.*LlmExtractorConfig' src/openhuman/memory_tree src/openhuman/tinycortex src/tinycortex

Repository: tinyhumansai/openhuman

Length of output: 4021


Pass the resolved model into LlmExtractorConfig here.

scoring_config() builds the extractor from build_chat_provider(), so model stays at its default. memory_tree::score::scoring_config_from() already threads the resolved chat model through, which can make ingestion and queue scoring pick different entity-extraction behavior for the same config. Reuse the model-aware runtime builder and set LlmExtractorConfig::model here too.

🤖 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/openhuman/tinycortex/ingest.rs` around lines 30 - 41, Update
scoring_config to resolve and pass the configured chat model into
LlmExtractorConfig alongside the provider, reusing the model-aware runtime
builder used by scoring_config_from. Set LlmExtractorConfig::model before
constructing LlmEntityExtractor, while preserving the existing regex-only
fallback when provider resolution fails.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 88c4bc84b3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

chunk_ids.len()
);
let permitted_ids = if let Some(set) = current_source_scope() {
let chunks = get_chunks_batch(config, chunk_ids)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Cap scoped leaf fetches before preloading chunks

When a profile source scope is active, this pre-filter loads every requested chunk before tinycortex::fetch_leaves can apply the MAX_BATCH cap. The previous path truncated to 20 IDs before any DB read, but now a scoped agent/tool call with hundreds or thousands of IDs can issue an unbounded get_chunks_batch query (or hit SQLite variable limits) just to discard most of the rows; cap the requested IDs before loading chunks for scope filtering.

Useful? React with 👍 / 👎.

let out = dedup_ids(["a".to_string(), "b".into(), "a".into(), "c".into()].into_iter());
assert_eq!(out, vec!["a", "b", "c"]);
}
let embedder = build_embedder_from_config(config)?;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Return empty fast retrieval before building embeddings

For an empty or whitespace-only query, the old fast_retrieve returned QueryResponse::empty() before touching embeddings, but this now constructs the configured embedder first. In environments with an invalid or unavailable embedding provider, a no-op smart_walk/benchmark request can fail instead of returning no hits; trim and short-circuit empty queries before build_embedder_from_config.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 751500ca69

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +381 to +383
.store_skill_sync(
&document.namespace_skill_id,
&document.connection_id,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Clear skill-sync documents when deleting connections

When a Gmail/Slack/etc. Composio sync stores through this SkillDocSink, it writes memory_docs rows in skill-* namespaces via store_skill_sync, but composio_delete_connection(clear_memory=true) only enumerates MemoryCleanupTargets that delete memory-tree chunks and never clears these namespace documents. In that delete-with-clear-memory scenario, newly synced emails/messages/docs can remain listed/searchable after the connection is removed; include the skill-* documents for the connection in the cleanup path as well.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9439b9487

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +222 to +223
source.max_items = max_items;
source.sync_depth_days = sync_depth_days;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve Composio sync caps when no override is passed

When run_composio_connection or the provider sync default calls this helper with max_items/sync_depth_days as None, these assignments overwrite any registered source caps (and even the fallback defaults created above) with None. That makes manual, trigger-driven, and connection-created Composio syncs run uncapped instead of honoring the user's per-source limits; only replace these fields when an override is actually present.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a64e623367

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

source_id,
source_kind,
scope,
usize::MAX,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Cap cover-window scans before querying

When memory_tree_cover_window is called for a broad window (for example the morning-brief path over a busy 24h period) with a small or default return limit, this now asks TinyCortex for usize::MAX hits and only truncates after the full response is materialized. The previous implementation bounded the DB scan to MAX_WINDOW_CHUNKS/per-source caps before building the cover, so large workspaces can now scan and allocate over every in-window chunk just to return the first 200 results; pass the caller/default cap (or restore an internal scan cap) into the engine instead of disabling the limit here.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e06a1d8473

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +164 to +170
let outcome = openhuman_core::openhuman::tinycortex::run_gmail_backfill(
&connection_id,
&query,
cli.max_pages as usize,
cli.page_size as usize,
&config,
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Honor --include-spam-trash in Gmail backfills

When gmail-backfill-3d --include-spam-trash is used, the new path only omits the -in:spam -in:trash query filter and then calls run_gmail_backfill, which has no way to pass the Gmail/Composio include_spam_trash flag. The previous implementation set args["include_spam_trash"] = true; without that boolean, Gmail fetches still use the default exclusion, so this CLI option no longer includes Spam/Trash despite reporting that it will.

Useful? React with 👍 / 👎.

.tick(
&pipeline_id,
&memory_config,
&source_sync_context(memory, config, false),

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Route Slack search backfill through the tree sink

When slack-backfill --use-search runs, this passes local=false, and source_sync_context therefore omits the LocalDocumentSink/summariser that feed memory-tree ingestion. The old run_backfill_via_search path grouped search results and called ingest_page_into_memory_tree, so operators using search backfill populated tree chunks; with only the skill-document sink available, the command can report records while memory-tree retrieval remains empty for those backfilled Slack messages.

Useful? React with 👍 / 👎.

@chatgpt-codex-connector chatgpt-codex-connector 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d944413508

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

.map_err(|e| format!("kv_set_global: {e}"))?;
Ok(())
pub async fn kv_set_global(&self, key: &str, value: &serde_json::Value) -> Result<(), String> {
self.tinycortex_kv()?.set_global(key, value)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Restore KV safety filtering before delegating writes

When openhuman.memory_kv_set or other KV callers persist user-provided keys/values, this direct delegation bypasses the host safety checks that previously rejected secret/PII-like keys/namespaces and sanitized JSON payloads before writing kv_global/kv_namespace (the unchanged kv_set_* tests still assert that contract). As a result, a value containing bearer tokens or a key like ssn-... can be stored and later recalled from memory instead of being redacted/rejected; keep the host safety gate here or make the crate call enforce the same contract before writing.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

memory Memory store, memory tree, recall, summarization, and embeddings in src/openhuman/memory/. rust-core Core Rust runtime in src/: CLI, core_server, shared infrastructure.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant