Skip to content

feat(enh-005): directional GraphRAG expansion (in/out/any)#122

Merged
kjoshi07 merged 1 commit into
mainfrom
enh/005-directional-graph-expansion
Jun 22, 2026
Merged

feat(enh-005): directional GraphRAG expansion (in/out/any)#122
kjoshi07 merged 1 commit into
mainfrom
enh/005-directional-graph-expansion

Conversation

@kjoshi07

Copy link
Copy Markdown
Contributor

Summary

First implementation on the 0.4 graph train. Adds a direction knob to GraphRAG expansion so it follows asymmetric edges the right way:

  • in — callers / who-cites-X / dependents
  • out — callees / what-X-cites / dependencies
  • any (default) — today's undirected traverse behaviour, byte-for-byte unchanged

How

  • direction: Literal["out","in","any"] = "any" on GraphExpansion (agentforge_core.values.retrieval) + GraphExpansionConfig (agentforge_core.config.schema); threaded by build_retriever_from_config.
  • Retriever._expand_via_graph branches: any keeps the native traverse() path verbatim; in/out run a BFS over the already-locked GraphStore.get_edges(direction=...) primitive (_reach_via_get_edges) — collecting edge.dst (out) / edge.src (in), fetching each neighbour via get_node. The merge/decay/dedup pipeline is reused unchanged.
  • No ABC change, no major bump, no new package. Improves feat-023.

The reference traverse() is out-directed, so direction=in is what surfaces the predecessors (callers) the undirected path can't reach — test_direction_in_surfaces_what_traverse_cannot asserts exactly that.

Tests

out=successors · in=predecessors · in-surfaces-what-traverse-cannot · multi-hop caller chain · edge-type filtering · no-predecessor tolerance · value + config defaults / bad-value rejection. The existing feat-023 suite is unchanged (backward-compat for any). Directional logic at 100% coverage, fully offline. Pre-commit green (mypy --strict, coverage, drift hook).

Spec: docs/enhancements/enh-005-directional-graph-expansion.md (status → in-progress; implementation section filled in).

🤖 Generated with Claude Code

First implementation on the 0.4 graph train. Adds a `direction` knob to
GraphRAG expansion so it follows asymmetric edges the right way — `in`
(callers / who-cites-X / dependents), `out` (callees / what-X-cites /
dependencies), `any` (default = today's undirected `traverse`).

- `direction: Literal["out","in","any"] = "any"` on `GraphExpansion`
  (agentforge_core.values.retrieval) + `GraphExpansionConfig`
  (agentforge_core.config.schema); threaded by build_retriever_from_config.
- `Retriever._expand_via_graph` branches: `any` keeps the native traverse()
  path verbatim (byte-for-byte backward compatible); `in`/`out` run a BFS
  over the already-locked `GraphStore.get_edges(direction=...)` primitive
  (`_reach_via_get_edges`) — collecting edge.dst (out) / edge.src (in),
  fetching neighbours via get_node. Merge/decay/dedup pipeline reused.
- NO ABC change, no major bump, no new package. Improves feat-023.

The reference `traverse()` is out-directed, so `direction=in` is what
surfaces predecessors (callers) that the undirected path can't reach —
the headline test asserts exactly that.

Tests: out=successors, in=predecessors, in-surfaces-what-traverse-cannot,
multi-hop caller chain, edge-type filtering, no-predecessor tolerance,
value + config defaults / rejection; existing feat-023 suite unchanged
(backward-compat). Directional logic at 100% coverage; fully offline.

Refs enh-005 · docs/enhancements/enh-005-directional-graph-expansion.md

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kjoshi07 kjoshi07 merged commit 19335da into main Jun 22, 2026
4 checks passed
@kjoshi07 kjoshi07 deleted the enh/005-directional-graph-expansion branch June 22, 2026 08:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant