Context Packing
An agent's context window is finite. When it asks for context around a node, CGraph has to choose which of the surrounding graph to include — enough to be useful, few enough to fit. That is gather-and-pack.
Gather: fixed vs adaptive
fixed: [ whole k-hop neighborhood ] (query-independent)
adaptive: [ full 2-hop core ]
+ third hop, only along query-relevant nodesgather: "fixed"packs the whole k-hop neighborhood — simple and query-independent.gather: "adaptive"keeps the full 2-hop core but expands the third hop only along nodes relevant to the query. It needs aquery/q— without one the relevance gate is a no-op and it behaves like a fixed gather.
Pack: knapsack
The gathered candidates are packed to a token budget with a knapsack strategy
(packing: "knapsack") — fit the most relevant nodes into the budget rather than
truncating arbitrarily.
cgraph-client context '{"q":"Parser","budget":5000}'Reach: an inspectable result
The response reports how the neighborhood was selected, so retrieval is auditable rather than a black box:
| Counter | Meaning |
|---|---|
candidates | Total potential nodes considered. |
expanded_past_core | Nodes expanded beyond the 2-hop core. |
gated_at_core | Nodes filtered out at the core boundary. |
Alongside these, the response carries the gather and packing mode it used.
Why adaptive
Expanding every third hop is expensive; expanding none loses relevant context. Adaptive gather targets the middle: it spends tokens only where the query points. The measured tradeoff — recall lift versus token cost — is documented on the Benchmarks page with methodology, not asserted here.