refactor(memory): complete TinyCortex engine migration#4794
Conversation
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 31 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (14)
📝 WalkthroughWalkthroughThis 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. ChangesTinyCortex migration
Estimated code review effort: 5 (Critical) | ~120 minutes Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Comment |
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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".
There was a problem hiding this comment.
💡 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); | |||
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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), |
There was a problem hiding this comment.
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::store → store_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 👍 / 👎.
There was a problem hiding this comment.
💡 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), |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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)? |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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") |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| pub(crate) fn tree_active_signature(config: &Config) -> String { | ||
| tinycortex::memory::chunks::tree_active_signature(&engine_config(config)) | ||
| } |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
src/openhuman/memory_sources/sync.rs (1)
102-119: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueCollapse the three identical non-Composio match arms.
Conversation | Folder,GithubRepo, andRssFeed | WebPagenow 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 winDrop the redundant caps lookup
run_composio_connectionalready pullsmax_itemsandsync_depth_daysfromconfig.memory_sources(or falls back to defaults), so thelist_enabled_by_kindread here and thelet _ = (...)are dead work on every sync. I don’t see any in-repo code callers forrun_connection_syncanymore, 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 winAdd 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 winCapture
current_source_scope()once to avoid the double call across the await.
current_source_scope()is invoked at Line 30 (to deriveengine_limit) and again at Line 43 (for the retain filter), straddling the.awaitat Line 42. Binding it once — assource.rsalready does withlet 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
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockapp/src-tauri/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (197)
Cargo.tomlapp/src-tauri/Cargo.tomlsrc/bin/gmail_backfill_3d.rssrc/bin/slack_backfill.rssrc/core/observability.rssrc/openhuman/agent/harness/session/builder/factory.rssrc/openhuman/agent/harness/session/builder/helpers.rssrc/openhuman/composio/identity.rssrc/openhuman/composio/ops/memory_cleanup.rssrc/openhuman/composio/ops/providers_ops.rssrc/openhuman/composio/ops_tests.rssrc/openhuman/composio/tools_tests.rssrc/openhuman/embeddings/cloud.rssrc/openhuman/embeddings/cloud_adapter.rssrc/openhuman/embeddings/cohere.rssrc/openhuman/embeddings/cohere_adapter.rssrc/openhuman/embeddings/factory.rssrc/openhuman/embeddings/mod.rssrc/openhuman/embeddings/ollama.rssrc/openhuman/embeddings/ollama_adapter.rssrc/openhuman/embeddings/ollama_tests.rssrc/openhuman/embeddings/openai.rssrc/openhuman/embeddings/openai_adapter.rssrc/openhuman/embeddings/openai_tests.rssrc/openhuman/embeddings/provider_trait.rssrc/openhuman/embeddings/rate_limit.rssrc/openhuman/embeddings/retry_after.rssrc/openhuman/embeddings/rpc.rssrc/openhuman/embeddings/voyage.rssrc/openhuman/embeddings/voyage_adapter.rssrc/openhuman/memory/ingest_pipeline.rssrc/openhuman/memory/ingestion/mod.rssrc/openhuman/memory/ingestion/parse.rssrc/openhuman/memory/ingestion/parse_tests.rssrc/openhuman/memory/ingestion/regex.rssrc/openhuman/memory/ingestion/rules.rssrc/openhuman/memory/ingestion/types.rssrc/openhuman/memory/ops/sync.rssrc/openhuman/memory/read_rpc/admin.rssrc/openhuman/memory/read_rpc_tests.rssrc/openhuman/memory/sync_pipeline_e2e_tests.rssrc/openhuman/memory/traits.rssrc/openhuman/memory_queue/mod.rssrc/openhuman/memory_queue/ops.rssrc/openhuman/memory_queue/redact.rssrc/openhuman/memory_queue/scheduler.rssrc/openhuman/memory_queue/store.rssrc/openhuman/memory_queue/types.rssrc/openhuman/memory_sources/readers/conversation.rssrc/openhuman/memory_sources/readers/folder.rssrc/openhuman/memory_sources/registry.rssrc/openhuman/memory_sources/sync.rssrc/openhuman/memory_sources/types.rssrc/openhuman/memory_store/chunks/connection.rssrc/openhuman/memory_store/chunks/embeddings.rssrc/openhuman/memory_store/chunks/migrations.rssrc/openhuman/memory_store/chunks/produce.rssrc/openhuman/memory_store/chunks/semantic.rssrc/openhuman/memory_store/chunks/store.rssrc/openhuman/memory_store/chunks/store_tests.rssrc/openhuman/memory_store/chunks/types.rssrc/openhuman/memory_store/content/README.mdsrc/openhuman/memory_store/content/atomic.rssrc/openhuman/memory_store/content/compose/chunk.rssrc/openhuman/memory_store/content/compose/mod.rssrc/openhuman/memory_store/content/compose/summary.rssrc/openhuman/memory_store/content/compose/tests.rssrc/openhuman/memory_store/content/compose/yaml.rssrc/openhuman/memory_store/content/mod.rssrc/openhuman/memory_store/content/paths.rssrc/openhuman/memory_store/content/raw.rssrc/openhuman/memory_store/content/read.rssrc/openhuman/memory_store/entities.rssrc/openhuman/memory_store/factories.rssrc/openhuman/memory_store/kv.rssrc/openhuman/memory_store/memory_trait.rssrc/openhuman/memory_store/safety/mod.rssrc/openhuman/memory_store/safety/pii.rssrc/openhuman/memory_store/trees/hotness.rssrc/openhuman/memory_store/trees/registry.rssrc/openhuman/memory_store/trees/store.rssrc/openhuman/memory_store/trees/types.rssrc/openhuman/memory_store/types.rssrc/openhuman/memory_store/vectors/mod.rssrc/openhuman/memory_store/vectors/store.rssrc/openhuman/memory_store/vectors/store_tests.rssrc/openhuman/memory_sync/canonicalize/README.mdsrc/openhuman/memory_sync/canonicalize/chat.rssrc/openhuman/memory_sync/canonicalize/document.rssrc/openhuman/memory_sync/canonicalize/email.rssrc/openhuman/memory_sync/canonicalize/email_clean.rssrc/openhuman/memory_sync/canonicalize/mod.rssrc/openhuman/memory_sync/composio/bus.rssrc/openhuman/memory_sync/composio/mod.rssrc/openhuman/memory_sync/composio/periodic.rssrc/openhuman/memory_sync/composio/providers/clickup/ingest.rssrc/openhuman/memory_sync/composio/providers/clickup/mod.rssrc/openhuman/memory_sync/composio/providers/clickup/provider.rssrc/openhuman/memory_sync/composio/providers/clickup/source.rssrc/openhuman/memory_sync/composio/providers/github/ingest.rssrc/openhuman/memory_sync/composio/providers/github/mod.rssrc/openhuman/memory_sync/composio/providers/github/provider.rssrc/openhuman/memory_sync/composio/providers/github/source.rssrc/openhuman/memory_sync/composio/providers/gmail/ingest.rssrc/openhuman/memory_sync/composio/providers/gmail/mod.rssrc/openhuman/memory_sync/composio/providers/gmail/provider.rssrc/openhuman/memory_sync/composio/providers/gmail/source.rssrc/openhuman/memory_sync/composio/providers/linear/ingest.rssrc/openhuman/memory_sync/composio/providers/linear/mod.rssrc/openhuman/memory_sync/composio/providers/linear/provider.rssrc/openhuman/memory_sync/composio/providers/linear/source.rssrc/openhuman/memory_sync/composio/providers/mod.rssrc/openhuman/memory_sync/composio/providers/notion/ingest.rssrc/openhuman/memory_sync/composio/providers/notion/mod.rssrc/openhuman/memory_sync/composio/providers/notion/provider.rssrc/openhuman/memory_sync/composio/providers/notion/source.rssrc/openhuman/memory_sync/composio/providers/orchestrator.rssrc/openhuman/memory_sync/composio/providers/registry.rssrc/openhuman/memory_sync/composio/providers/slack/ingest.rssrc/openhuman/memory_sync/composio/providers/slack/mod.rssrc/openhuman/memory_sync/composio/providers/slack/provider.rssrc/openhuman/memory_sync/composio/providers/slack/rpc.rssrc/openhuman/memory_sync/composio/providers/slack/source.rssrc/openhuman/memory_sync/composio/providers/slack/sync.rssrc/openhuman/memory_sync/composio/providers/slack/types.rssrc/openhuman/memory_sync/composio/providers/slack/users.rssrc/openhuman/memory_sync/composio/providers/sync_state.rssrc/openhuman/memory_sync/composio/providers/traits.rssrc/openhuman/memory_sync/sources/audit.rssrc/openhuman/memory_sync/sources/github.rssrc/openhuman/memory_sync/sources/mod.rssrc/openhuman/memory_sync/sources/rebuild.rssrc/openhuman/memory_sync/sync_status/rpc.rssrc/openhuman/memory_sync/sync_status/types.rssrc/openhuman/memory_tools/README.mdsrc/openhuman/memory_tools/store.rssrc/openhuman/memory_tools/tools/list.rssrc/openhuman/memory_tools/tools/put.rssrc/openhuman/memory_tree/graph/bfs.rssrc/openhuman/memory_tree/graph/store.rssrc/openhuman/memory_tree/ingest.rssrc/openhuman/memory_tree/io.rssrc/openhuman/memory_tree/retrieval/cover.rssrc/openhuman/memory_tree/retrieval/drill_down.rssrc/openhuman/memory_tree/retrieval/engine.rssrc/openhuman/memory_tree/retrieval/fast.rssrc/openhuman/memory_tree/retrieval/fetch.rssrc/openhuman/memory_tree/retrieval/mod.rssrc/openhuman/memory_tree/retrieval/search.rssrc/openhuman/memory_tree/retrieval/source.rssrc/openhuman/memory_tree/retrieval/types.rssrc/openhuman/memory_tree/score/extract/extractor.rssrc/openhuman/memory_tree/score/extract/llm.rssrc/openhuman/memory_tree/score/extract/llm_tests.rssrc/openhuman/memory_tree/score/extract/mod.rssrc/openhuman/memory_tree/score/extract/regex.rssrc/openhuman/memory_tree/score/extract/types.rssrc/openhuman/memory_tree/score/mod.rssrc/openhuman/memory_tree/score/resolver.rssrc/openhuman/memory_tree/score/signals/interaction.rssrc/openhuman/memory_tree/score/signals/metadata_weight.rssrc/openhuman/memory_tree/score/signals/mod.rssrc/openhuman/memory_tree/score/signals/ops.rssrc/openhuman/memory_tree/score/signals/source_weight.rssrc/openhuman/memory_tree/score/signals/token_count.rssrc/openhuman/memory_tree/score/signals/types.rssrc/openhuman/memory_tree/score/signals/unique_words.rssrc/openhuman/memory_tree/score/store.rssrc/openhuman/memory_tree/score/store_tests.rssrc/openhuman/memory_tree/summarise.rssrc/openhuman/memory_tree/tree/bucket_seal.rssrc/openhuman/memory_tree/tree/bucket_seal_tests.rssrc/openhuman/memory_tree/tree/factory.rssrc/openhuman/memory_tree/tree/flush.rssrc/openhuman/memory_tree/tree_runtime/engine.rssrc/openhuman/memory_tree/tree_runtime/engine_tests.rssrc/openhuman/memory_tree/tree_runtime/store.rssrc/openhuman/memory_tree/tree_runtime/store_tests.rssrc/openhuman/memory_tree/tree_runtime/types.rssrc/openhuman/task_sources/pipeline_tests.rssrc/openhuman/tinyagents/embeddings.rssrc/openhuman/tinycortex/config.rssrc/openhuman/tinycortex/ingest.rssrc/openhuman/tinycortex/mod.rssrc/openhuman/tinycortex/queue_driver.rssrc/openhuman/tinycortex/seal.rssrc/openhuman/tinycortex/summariser.rssrc/openhuman/tinycortex/sync.rstests/embeddings_rpc_e2e.rstests/json_rpc_e2e.rstests/memory_artifacts_e2e.rstests/raw_coverage/memory_sync_providers_raw_coverage_e2e.rstests/raw_coverage/memory_sync_tree_round21_raw_coverage_e2e.rstests/raw_coverage/memory_threads_raw_coverage_e2e.rstests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rsvendor/tinyagentsvendor/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
There was a problem hiding this comment.
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 valueCollapse the three identical non-Composio match arms.
Conversation | Folder,GithubRepo, andRssFeed | WebPagenow 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 winDrop the redundant caps lookup
run_composio_connectionalready pullsmax_itemsandsync_depth_daysfromconfig.memory_sources(or falls back to defaults), so thelist_enabled_by_kindread here and thelet _ = (...)are dead work on every sync. I don’t see any in-repo code callers forrun_connection_syncanymore, 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 winAdd 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 winCapture
current_source_scope()once to avoid the double call across the await.
current_source_scope()is invoked at Line 30 (to deriveengine_limit) and again at Line 43 (for the retain filter), straddling the.awaitat Line 42. Binding it once — assource.rsalready does withlet 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
⛔ Files ignored due to path filters (2)
Cargo.lockis excluded by!**/*.lockapp/src-tauri/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (197)
Cargo.tomlapp/src-tauri/Cargo.tomlsrc/bin/gmail_backfill_3d.rssrc/bin/slack_backfill.rssrc/core/observability.rssrc/openhuman/agent/harness/session/builder/factory.rssrc/openhuman/agent/harness/session/builder/helpers.rssrc/openhuman/composio/identity.rssrc/openhuman/composio/ops/memory_cleanup.rssrc/openhuman/composio/ops/providers_ops.rssrc/openhuman/composio/ops_tests.rssrc/openhuman/composio/tools_tests.rssrc/openhuman/embeddings/cloud.rssrc/openhuman/embeddings/cloud_adapter.rssrc/openhuman/embeddings/cohere.rssrc/openhuman/embeddings/cohere_adapter.rssrc/openhuman/embeddings/factory.rssrc/openhuman/embeddings/mod.rssrc/openhuman/embeddings/ollama.rssrc/openhuman/embeddings/ollama_adapter.rssrc/openhuman/embeddings/ollama_tests.rssrc/openhuman/embeddings/openai.rssrc/openhuman/embeddings/openai_adapter.rssrc/openhuman/embeddings/openai_tests.rssrc/openhuman/embeddings/provider_trait.rssrc/openhuman/embeddings/rate_limit.rssrc/openhuman/embeddings/retry_after.rssrc/openhuman/embeddings/rpc.rssrc/openhuman/embeddings/voyage.rssrc/openhuman/embeddings/voyage_adapter.rssrc/openhuman/memory/ingest_pipeline.rssrc/openhuman/memory/ingestion/mod.rssrc/openhuman/memory/ingestion/parse.rssrc/openhuman/memory/ingestion/parse_tests.rssrc/openhuman/memory/ingestion/regex.rssrc/openhuman/memory/ingestion/rules.rssrc/openhuman/memory/ingestion/types.rssrc/openhuman/memory/ops/sync.rssrc/openhuman/memory/read_rpc/admin.rssrc/openhuman/memory/read_rpc_tests.rssrc/openhuman/memory/sync_pipeline_e2e_tests.rssrc/openhuman/memory/traits.rssrc/openhuman/memory_queue/mod.rssrc/openhuman/memory_queue/ops.rssrc/openhuman/memory_queue/redact.rssrc/openhuman/memory_queue/scheduler.rssrc/openhuman/memory_queue/store.rssrc/openhuman/memory_queue/types.rssrc/openhuman/memory_sources/readers/conversation.rssrc/openhuman/memory_sources/readers/folder.rssrc/openhuman/memory_sources/registry.rssrc/openhuman/memory_sources/sync.rssrc/openhuman/memory_sources/types.rssrc/openhuman/memory_store/chunks/connection.rssrc/openhuman/memory_store/chunks/embeddings.rssrc/openhuman/memory_store/chunks/migrations.rssrc/openhuman/memory_store/chunks/produce.rssrc/openhuman/memory_store/chunks/semantic.rssrc/openhuman/memory_store/chunks/store.rssrc/openhuman/memory_store/chunks/store_tests.rssrc/openhuman/memory_store/chunks/types.rssrc/openhuman/memory_store/content/README.mdsrc/openhuman/memory_store/content/atomic.rssrc/openhuman/memory_store/content/compose/chunk.rssrc/openhuman/memory_store/content/compose/mod.rssrc/openhuman/memory_store/content/compose/summary.rssrc/openhuman/memory_store/content/compose/tests.rssrc/openhuman/memory_store/content/compose/yaml.rssrc/openhuman/memory_store/content/mod.rssrc/openhuman/memory_store/content/paths.rssrc/openhuman/memory_store/content/raw.rssrc/openhuman/memory_store/content/read.rssrc/openhuman/memory_store/entities.rssrc/openhuman/memory_store/factories.rssrc/openhuman/memory_store/kv.rssrc/openhuman/memory_store/memory_trait.rssrc/openhuman/memory_store/safety/mod.rssrc/openhuman/memory_store/safety/pii.rssrc/openhuman/memory_store/trees/hotness.rssrc/openhuman/memory_store/trees/registry.rssrc/openhuman/memory_store/trees/store.rssrc/openhuman/memory_store/trees/types.rssrc/openhuman/memory_store/types.rssrc/openhuman/memory_store/vectors/mod.rssrc/openhuman/memory_store/vectors/store.rssrc/openhuman/memory_store/vectors/store_tests.rssrc/openhuman/memory_sync/canonicalize/README.mdsrc/openhuman/memory_sync/canonicalize/chat.rssrc/openhuman/memory_sync/canonicalize/document.rssrc/openhuman/memory_sync/canonicalize/email.rssrc/openhuman/memory_sync/canonicalize/email_clean.rssrc/openhuman/memory_sync/canonicalize/mod.rssrc/openhuman/memory_sync/composio/bus.rssrc/openhuman/memory_sync/composio/mod.rssrc/openhuman/memory_sync/composio/periodic.rssrc/openhuman/memory_sync/composio/providers/clickup/ingest.rssrc/openhuman/memory_sync/composio/providers/clickup/mod.rssrc/openhuman/memory_sync/composio/providers/clickup/provider.rssrc/openhuman/memory_sync/composio/providers/clickup/source.rssrc/openhuman/memory_sync/composio/providers/github/ingest.rssrc/openhuman/memory_sync/composio/providers/github/mod.rssrc/openhuman/memory_sync/composio/providers/github/provider.rssrc/openhuman/memory_sync/composio/providers/github/source.rssrc/openhuman/memory_sync/composio/providers/gmail/ingest.rssrc/openhuman/memory_sync/composio/providers/gmail/mod.rssrc/openhuman/memory_sync/composio/providers/gmail/provider.rssrc/openhuman/memory_sync/composio/providers/gmail/source.rssrc/openhuman/memory_sync/composio/providers/linear/ingest.rssrc/openhuman/memory_sync/composio/providers/linear/mod.rssrc/openhuman/memory_sync/composio/providers/linear/provider.rssrc/openhuman/memory_sync/composio/providers/linear/source.rssrc/openhuman/memory_sync/composio/providers/mod.rssrc/openhuman/memory_sync/composio/providers/notion/ingest.rssrc/openhuman/memory_sync/composio/providers/notion/mod.rssrc/openhuman/memory_sync/composio/providers/notion/provider.rssrc/openhuman/memory_sync/composio/providers/notion/source.rssrc/openhuman/memory_sync/composio/providers/orchestrator.rssrc/openhuman/memory_sync/composio/providers/registry.rssrc/openhuman/memory_sync/composio/providers/slack/ingest.rssrc/openhuman/memory_sync/composio/providers/slack/mod.rssrc/openhuman/memory_sync/composio/providers/slack/provider.rssrc/openhuman/memory_sync/composio/providers/slack/rpc.rssrc/openhuman/memory_sync/composio/providers/slack/source.rssrc/openhuman/memory_sync/composio/providers/slack/sync.rssrc/openhuman/memory_sync/composio/providers/slack/types.rssrc/openhuman/memory_sync/composio/providers/slack/users.rssrc/openhuman/memory_sync/composio/providers/sync_state.rssrc/openhuman/memory_sync/composio/providers/traits.rssrc/openhuman/memory_sync/sources/audit.rssrc/openhuman/memory_sync/sources/github.rssrc/openhuman/memory_sync/sources/mod.rssrc/openhuman/memory_sync/sources/rebuild.rssrc/openhuman/memory_sync/sync_status/rpc.rssrc/openhuman/memory_sync/sync_status/types.rssrc/openhuman/memory_tools/README.mdsrc/openhuman/memory_tools/store.rssrc/openhuman/memory_tools/tools/list.rssrc/openhuman/memory_tools/tools/put.rssrc/openhuman/memory_tree/graph/bfs.rssrc/openhuman/memory_tree/graph/store.rssrc/openhuman/memory_tree/ingest.rssrc/openhuman/memory_tree/io.rssrc/openhuman/memory_tree/retrieval/cover.rssrc/openhuman/memory_tree/retrieval/drill_down.rssrc/openhuman/memory_tree/retrieval/engine.rssrc/openhuman/memory_tree/retrieval/fast.rssrc/openhuman/memory_tree/retrieval/fetch.rssrc/openhuman/memory_tree/retrieval/mod.rssrc/openhuman/memory_tree/retrieval/search.rssrc/openhuman/memory_tree/retrieval/source.rssrc/openhuman/memory_tree/retrieval/types.rssrc/openhuman/memory_tree/score/extract/extractor.rssrc/openhuman/memory_tree/score/extract/llm.rssrc/openhuman/memory_tree/score/extract/llm_tests.rssrc/openhuman/memory_tree/score/extract/mod.rssrc/openhuman/memory_tree/score/extract/regex.rssrc/openhuman/memory_tree/score/extract/types.rssrc/openhuman/memory_tree/score/mod.rssrc/openhuman/memory_tree/score/resolver.rssrc/openhuman/memory_tree/score/signals/interaction.rssrc/openhuman/memory_tree/score/signals/metadata_weight.rssrc/openhuman/memory_tree/score/signals/mod.rssrc/openhuman/memory_tree/score/signals/ops.rssrc/openhuman/memory_tree/score/signals/source_weight.rssrc/openhuman/memory_tree/score/signals/token_count.rssrc/openhuman/memory_tree/score/signals/types.rssrc/openhuman/memory_tree/score/signals/unique_words.rssrc/openhuman/memory_tree/score/store.rssrc/openhuman/memory_tree/score/store_tests.rssrc/openhuman/memory_tree/summarise.rssrc/openhuman/memory_tree/tree/bucket_seal.rssrc/openhuman/memory_tree/tree/bucket_seal_tests.rssrc/openhuman/memory_tree/tree/factory.rssrc/openhuman/memory_tree/tree/flush.rssrc/openhuman/memory_tree/tree_runtime/engine.rssrc/openhuman/memory_tree/tree_runtime/engine_tests.rssrc/openhuman/memory_tree/tree_runtime/store.rssrc/openhuman/memory_tree/tree_runtime/store_tests.rssrc/openhuman/memory_tree/tree_runtime/types.rssrc/openhuman/task_sources/pipeline_tests.rssrc/openhuman/tinyagents/embeddings.rssrc/openhuman/tinycortex/config.rssrc/openhuman/tinycortex/ingest.rssrc/openhuman/tinycortex/mod.rssrc/openhuman/tinycortex/queue_driver.rssrc/openhuman/tinycortex/seal.rssrc/openhuman/tinycortex/summariser.rssrc/openhuman/tinycortex/sync.rstests/embeddings_rpc_e2e.rstests/json_rpc_e2e.rstests/memory_artifacts_e2e.rstests/raw_coverage/memory_sync_providers_raw_coverage_e2e.rstests/raw_coverage/memory_sync_tree_round21_raw_coverage_e2e.rstests/raw_coverage/memory_threads_raw_coverage_e2e.rstests/raw_coverage/memory_tree_sync_raw_coverage_e2e.rsvendor/tinyagentsvendor/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.rsRepository: 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_storeRepository: tinyhumansai/openhuman
Length of output: 21455
getandforgetshould sanitize namespaces too
Writes persistmemory_docs.namespacethroughsanitize_namespace, andlistnow queries that same value.get/forgetstill use onlynormalize_namespace(...), so namespaces that get rewritten during sanitization will miss rows and fail deletes. Use the same helper on allmemory_docs.namespacelookups.🤖 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.rsRepository: tinyhumansai/openhuman
Length of output: 2404
🏁 Script executed:
#!/bin/bash sed -n '490,605p' src/openhuman/memory_sync/composio/periodic.rsRepository: tinyhumansai/openhuman
Length of output: 4940
🏁 Script executed:
#!/bin/bash sed -n '470,520p' src/openhuman/memory_sync/composio/periodic.rsRepository: tinyhumansai/openhuman
Length of output: 2246
🏁 Script executed:
#!/bin/bash rg -n -C2 'record_sync_success\(' src/openhumanRepository: tinyhumansai/openhuman
Length of output: 3620
🏁 Script executed:
#!/bin/bash sed -n '1,180p' src/openhuman/memory_sync/composio/periodic.rsRepository: 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.rsRepository: tinyhumansai/openhuman
Length of output: 5595
🏁 Script executed:
#!/bin/bash sed -n '1,160p' src/openhuman/memory_sync/composio/periodic.rsRepository: 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.rsRepository: 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.rsRepository: 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.rsRepository: tinyhumansai/openhuman
Length of output: 1808
🏁 Script executed:
#!/bin/bash sed -n '430,490p' src/openhuman/memory_sync/composio/periodic.rsRepository: tinyhumansai/openhuman
Length of output: 3209
Record sync success with the normalized toolkit
record_sync_successstores the timestamp by(toolkit, connection_id), but the due-check usesconn.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. Usetoolkithere instead ofconn.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.rsis reserved for module wiring and re-exports. Move them to a sibling such asops.rsand 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.rsfiles 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.rsfiles 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/tinycortexRepository: 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/openhumanRepository: 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/tinycortexRepository: tinyhumansai/openhuman
Length of output: 4021
Pass the resolved model into
LlmExtractorConfighere.
scoring_config()builds the extractor frombuild_chat_provider(), somodelstays 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 setLlmExtractorConfig::modelhere 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.
There was a problem hiding this comment.
💡 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)?; |
There was a problem hiding this comment.
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)?; |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| .store_skill_sync( | ||
| &document.namespace_skill_id, | ||
| &document.connection_id, |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| source.max_items = max_items; | ||
| source.sync_depth_days = sync_depth_days; |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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, |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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".
| let outcome = openhuman_core::openhuman::tinycortex::run_gmail_backfill( | ||
| &connection_id, | ||
| &query, | ||
| cli.max_pages as usize, | ||
| cli.page_size as usize, | ||
| &config, | ||
| ) |
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
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 👍 / 👎.
There was a problem hiding this comment.
💡 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) |
There was a problem hiding this comment.
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 👍 / 👎.
…te-ports # Conflicts: # tests/raw_coverage/memory_threads_raw_coverage_e2e.rs # vendor/tinyagents
Summary
Config, providers, credentials, event publication, scheduling, RPC/tools, and product policy.Problem
Solution
UnifiedMemory, health diagnostics, NLP sidecar integration, and policy remain host-owned by design.Submission Checklist
Impact
Related
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
feat/tinycortex-crate-portsb3880460c0ccc42e68316ac08125845ff2cd2e4cValidation Run
pnpm --filter openhuman-app format:checkpnpm typecheckGGML_NATIVE=OFF cargo check --testspassed across all host targets; post-dependencycargo check --libpassed.glib-2.0.pcbefore project code compilation.Validation Blocked
command:cargo check --manifest-path app/src-tauri/Cargo.tomlerror:local system packageglib-2.0is absent from pkg-config search pathsimpact: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
Parity Contract
Duplicate / Superseded PR Handling
Summary by CodeRabbit
New Features
Bug Fixes
Refactor