Skip to content

refactor(rag): de-fork graph retrieval — one neighbour contract, one graph blend, shared config (#18139, #18141) - #18421

Merged
mrveiss merged 3 commits into
mainfrom
issue-18139-rag-graph-defork
Oct 13, 2026
Merged

mrveiss merged 3 commits into
mainfrom
issue-18139-rag-graph-defork

Conversation

@mrveiss

@mrveiss mrveiss commented Oct 12, 2026 •

Copy link
Copy Markdown
Owner

Thinking Path

Two issues share the RAG graph-retrieval files, so one branch and one PR. #18139: the get_neighbors contract was forked across PPR (to_node dicts, min_weight kwarg), the PostgreSQL adapter (tuples, no min_weight), staleness BFS and edge sync, so PPR wired with the adapter raised TypeError on first use. #18141: graph-RAG and the Neural Mesh retriever blended graph signals with different formulas, weights, config and rerank weights, and the mesh branch skipped the stale-chunk filter. Fix each at its root with one definition per concept.

What Changed

#18139

  • services/mesh_brain/neighbor_store.py: the one NeighborStore Protocol, get_neighbors(node_id, min_weight=0.0) -> list[tuple[str, float]], and decode_neighbors.
  • PPR, MeshDBAdapter, the Redis staleness adapter and MeshEdgeSync all conform; the duplicate MeshGraph and PPR NeighborStore Protocols are gone. The raw dict-row query on MeshDB is renamed fetch_neighbor_rows (it is not a neighbour-contract implementation).
  • New test runs PPR over the real MeshDBAdapter. Before: MeshDBAdapter.get_neighbors(node_id) took no min_weight, so PPR's get_neighbors(node_id, min_weight=...) raised TypeError.

#18141

  • knowledge/search_components/graph_blend.py: blend_graph_score, the one pre-rerank blend; compute_blended_score stays the one post-rerank blend.
  • RAGConfig.graph_weight (env AUTOBOT_RAG_GRAPH_WEIGHT, registered) and graph_traversal_depth; defaults in constants/rag_graph_constants.py.
  • Graph-RAG reads the shared config; lifespan no longer builds a private RAGConfig(timeout_seconds=10.0) or restates 0.3. The graph path keeps its 10 s default as the env-backed RAGConfig.graph_timeout_seconds field.
  • NeuralMeshRetriever takes config, blends with blend_graph_score and passes config.rerank_weights (incl. MMR) on every rerank; rag_service passes its config. The mesh branch now runs _filter_stale_chunks, on RankedResult objects (reranker dicts are converted by MeshRetrievalResult.ranked_chunks).
  • Traversal depth default declared once for graph-RAG search, TraverseRequest, and the multi-source graph request; PersonalizedPageRank.rank(max_hops=...) takes its default from the same module.

Behavioural differences resolved

Place Before Kept Why
Graph-RAG blend (1-w)*base + w*base*strength, w=0.3 same, now blend_graph_score(base, base*strength, w) proven equal on a 4x11x11 grid
Mesh blend score + ppr_boost (unweighted, unbounded) convex blend_graph_score(score, ppr, w) stays in 0-1, which the cross-encoder blend assumes; behaviour CHANGE, test updated
Mesh-only nodes raw PPR score w * ppr same blend with base 0
Graph-RAG timeout 10 s via a private RAGConfig 10 s via RAGConfig.graph_timeout_seconds (AUTOBOT_RAG_GRAPH_TIMEOUT_SECONDS) unchanged latency; the private config object was the fork, not the value. The general RAG budget stays at the shared 120 s
Mesh rerank RerankWeights() default, no MMR RAGConfig.rerank_weights recurrence of #2103
Mesh stale filter skipped applied recurrence of #4721
PPR moderate tier docstring "1-hop", loads 3 behaviour kept (3), docstring corrected changing hop count is a retrieval-quality change, not a de-fork

Not changed, on purpose: the depth fields defaulting to 1 and 6 (path length) in schemas_knowledge.py are different concepts; mesh SIMPLE tier returns un-reranked chunks by design; symbol_fork_baseline.json has no cluster for the removed duplicate Protocols (they were different names), so no row to lower. Ceilings lowered for schemas_knowledge.py (5155), lifespan.py (2338), graph_rag_service.py (738) in both records.

Verification

  • pytest services/ tests/test_rag_rerank_weights.py tests/test_session_adaptive_reranker.py tests/test_mmr_diversity.py tests/memory_graph knowledge/search_components advanced_rag_optimizer_test.py: 3508 passed.
  • services/mesh_brain: 181 passed before the blend commit; new rag_graph_blend_18141_test.py: 12 passed.
  • repo_tests: symbol_fork_ratchet_17312, python_file_size_ratchet, ceiling_record_parity_17872, guard_reach_meta: pass; reach_scope_claim_17844 alone: 10 passed.
  • A wider knowledge/ run showed egress_vendor_behaviour_test.py failures only under ordering ("Event loop is closed"); in isolation it passes (105 passed with the graph-RAG and memory-graph tests). knowledge/chat_knowledge_system_e2e_test.py needs live services and was not run.
  • Pre-push passed its pytest selection with no override.

Closes #18139
Refs #18141 (blend, config, rerank weights, stale filter and depth done; KAG has no retrieval branch to test, only the dispatcher routes it)

Model Used

Claude Sonnet 5.5

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Oct 12, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 47 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration
  • Configuration used: Repository: mrveiss/AutoBot-AI/.coderabbit.yaml
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: a30184dd-57f1-4a4f-8004-c15771cb506e

📥 Commits

Reviewing files that changed from the base of the PR and between df211d3 and 3b120cf.


⛔ Files ignored due to path filters (2)
  • repo_tests/python_file_size_ratchet_baseline.py is excluded by !repo_tests/python_file_size_ratchet_baseline.py
  • scripts/python_file_size_known_large.py is excluded by !scripts/python_file_size_known_large.py

📒 Files selected for processing (26)
  • autobot-backend/api/graph_rag.py
  • autobot-backend/api/schemas_knowledge.py
  • autobot-backend/constants/rag_graph_constants.py
  • autobot-backend/initialization/lifespan.py
  • autobot-backend/knowledge/search_components/graph_blend.py
  • autobot-backend/services/graph_rag_service.py
  • autobot-backend/services/graph_rag_service_test.py
  • autobot-backend/services/mesh_brain/edge_sync.py
  • autobot-backend/services/mesh_brain/edge_sync_test.py
  • autobot-backend/services/mesh_brain/mesh_db.py
  • autobot-backend/services/mesh_brain/mesh_db_adapter.py
  • autobot-backend/services/mesh_brain/mesh_db_adapter_test.py
  • autobot-backend/services/mesh_brain/mesh_db_test.py
  • autobot-backend/services/mesh_brain/neighbor_store.py
  • autobot-backend/services/mesh_brain/ppr.py
  • autobot-backend/services/mesh_brain/ppr_test.py
  • autobot-backend/services/mesh_brain/staleness_propagator.py
  • autobot-backend/services/neural_mesh_retriever.py
  • autobot-backend/services/neural_mesh_retriever_test.py
  • autobot-backend/services/rag_config.py
  • autobot-backend/services/rag_graph_blend_18141_test.py
  • autobot-backend/services/rag_mesh_results.py
  • autobot-backend/services/rag_service.py
  • autobot_shared/env_registry_ai.py
  • autobot_shared/env_registry_rag.py
  • docs/developer/ENV_VARS.md

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@github-actions

Copy link
Copy Markdown
Contributor

Notice: 29 open PRs — past the runaway threshold (25)

This is not a request to defer this PR. The actual limit is the open-PR cap (AUTOBOT_OPEN_PR_CAP, default 40), enforced at pre-push against NEW branches only -- pushing more commits to this PR's own branch is never blocked by it.

This notice only means the count is high enough to be worth a glance for a runaway — something opening PRs in a loop, or a merge pipeline that has stalled so nothing is draining.

Currently open:

If the queue is draining normally, ignore this. Otherwise:

  1. Check whether CI is dispatching at all — see the ci-dispatch-watchdog status on these PRs
  2. Merge the ones whose CI has finished and review has passed: gh pr merge <number> --squash --delete-branch
  3. Look for a loop opening near-identical PRs

Warn-only runaway detector — .github/workflows/pr-queue-gate.yml. It never blocks a merge.

@github-actions

Copy link
Copy Markdown
Contributor

✅ SSOT Configuration Compliance: Passing

🎉 No new hardcoded values of either class — ssot and other both block.

Known backlog in pipeline-scripts/hardcoded_values_baseline.txt is suppressed and tracked in #14371.

@mrveiss

mrveiss commented Oct 12, 2026

Copy link
Copy Markdown
Owner Author

Review (Sonnet) at 8522b85: changes requested (one Medium). Every AC of #18139 is met:

  • one NeighborStore.get_neighbors(node_id, min_weight) contract (mesh_brain/neighbor_store.py);
  • PPR (ppr.py:155), staleness (staleness_propagator.py:129), MeshDBAdapter (mesh_db_adapter.py:75) and edge sync (edge_sync.py:74) all conform;
  • the duplicate Protocol is gone;
  • PPR runs against the real adapter in ppr_test.py:188-198;
  • the rename to fetch_neighbor_rows leaves no stale caller.

For #18141: one blend_graph_score, plus AUTOBOT_RAG_GRAPH_WEIGHT, registered with range 0–1. Behaviour changes (a), (b) and (d) are intended and tested, and the size baselines only shrink.

Severity Location Finding Fix
Medium lifespan.py:~1159 Removing RAGConfig(timeout_seconds=10.0) moves the graph-RAG timeout from 10s to the shared timeout_seconds. rag_service.py:767 uses timeout or config.timeout_seconds, and graph_rag_service.py:493 passes timeout=None by default. Both the /search handler (api/graph_rag.py:188, request timeout defaults to None) and retrieval_dispatcher.get_context (via knowledge_rag.py:~570, which sends no timeout) await it inline. So a default user request can now wait up to the shared ceiling instead of 10s. No issue or owner decision covers that. Give graph-aware search its own env-backed default (keeping 10s), registered, read by both paths. Otherwise state the 10s → shared change in the body as an owner decision.
Low api/graph_rag.py:352 The metrics payload still hardcodes "timeout_seconds": 10.0, so it reports a value that no longer applies. Read it from get_rag_config().
Low rag_graph_blend_18141_test.py:76 The r.metadata-on-dict crash fix is covered only indirectly. Assert that metadata and chunk_id survive coerce_ranked_results.

@mrveiss

mrveiss commented Oct 12, 2026

Copy link
Copy Markdown
Owner Author

Delta review at 3b120cf: approve. The timeout Medium is resolved.

  • Default restored: graph search defaults to RAGConfig.graph_timeout_seconds, built from AUTOBOT_RAG_GRAPH_TIMEOUT_SECONDS (10.0) and validated > 0 (rag_config.py:68,195). graph_rag_service.py:246 applies timeout or config.graph_timeout_seconds, so /search and the dispatcher are back to 10s and an explicit caller timeout still wins.
  • Registry: the new autobot_shared/env_registry_rag.py is loaded through env_registry_ai.py:33, so its vars are registered, and ENV_VARS.md is updated.
  • Metrics: get_metrics reports the real value (graph_rag_service.py:730). The old hardcoded 10.0 is now a placeholder in a docstring example.
  • Tests: default, env override, and the caller-timeout precedence. The graph_rag_service ceiling went 738 → 734.

Queued for the next merge train.

This was referenced Oct 12, 2026
@mrveiss
mrveiss merged commit 50faeaf into main Oct 13, 2026
28 of 73 checks passed
@mrveiss
mrveiss deleted the issue-18139-rag-graph-defork branch October 13, 2026 04:02
mrveiss added a commit that referenced this pull request Oct 13, 2026
chore(train): merge train #9c — eleven approved PRs (de-fork batch, #18418 #18421 #18471 #18472 #18467 #18371)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug(rag): PPR is wired with the mesh adapter whose get_neighbors signature differs — mesh retrieval raises TypeError on first use

1 participant