How context flows
The context starts empty at the beginning of a run. As each stage completes, its outcome includes a set of context updates — key-value pairs that are merged into the shared context. Later stages see all updates from earlier stages.parallel.fan_in.* keys.
How agents access context
Agents do not have a tool to query the context store directly. Instead, context is made available through two mechanisms:- Preamble injection — When a node starts, Fabro assembles a preamble from the current context and prepends it to the node’s prompt. The fidelity setting controls how detailed this preamble is.
- Context updates — Agents can write to the context by including a
context_updatesobject in a JSON response. See Transitions for the response format.
Keys set by handlers
Each handler type writes specific keys into the context after execution:Agent and prompt nodes
Agents can also emit arbitrary context updates by including a JSON object with a
context_updates field in their response. See Transitions.
Command nodes
Human gates
Parallel fan-out and fan-in
Branch updates remain nested inside
parallel.results; they are not merged into top-level context. Prompted fan-in nodes can synthesize the complete result array, while promptless fan-in nodes act as barriers.
Engine-managed keys
The engine sets several keys automatically. These are prefixed withinternal. and are excluded from preambles:
Using context in conditions
Edge conditions can read context values to route execution:context. prefix is optional — tests_passed=true and context.tests_passed=true are equivalent.
Engine-managed keys like internal.node_visit_count work in conditions too. This is useful for fixed-count loops:
Fidelity: Controlling agent context
When a new agent or prompt node starts, Fabro assembles a preamble — a summary of what happened in prior stages. The fidelity setting controls how detailed this preamble is.Setting fidelity
Fidelity can be set at three levels. The first match wins:-
Edge attribute — Set
fidelityon an edge to control the transition into a specific node: -
Node attribute — Set
fidelityon a node to control all transitions into it: -
Graph default — Set
default_fidelityon the graph for a run-wide default:
compact.
Parallel branch fidelity
The first node in each parallel branch uses this precedence:fidelityon the fork-to-branch edgefidelityon the branch node- Otherwise, inherit the fork’s preamble unchanged
full degrades to summary:high because concurrent branches cannot share conversation sessions. thread_id on a branch node or fork-to-branch edge is inert.
Full fidelity and threads
full fidelity is typically used with thread_id to create a shared conversation across multiple nodes. Nodes with the same thread_id share a single LLM session, preserving full context continuity:
Fidelity on resume
When a run is resumed from a checkpoint, the first node after resume degradesfull fidelity to summary:high. This prevents the resumed node from expecting a conversation thread that no longer exists in memory.
Preamble construction
For non-full fidelity modes, Fabro builds a preamble from runtime data and prepends it to the node’s prompt.
Example compact preamble
Example compact preamble
Given a plan-test-implement workflow where the plan and test stages have completed, the running 42 tests … 41 passed, 1 failed
implement node would receive a preamble like this prepended to its prompt:- The workflow goal
- A summary of completed stages (format depends on fidelity level)
- Handler-specific details:
- Command nodes — the script that ran and the ordered output
- Agent/prompt nodes — the model used, token counts, and files touched
- Non-internal context values that weren’t already rendered inline
internal., current, graph., thread., response.) are excluded from preambles to avoid noise.
Artifact offloading
When a stage produces a large output (over 100KB of serialized JSON), Fabro stores the serialized bytes in a global content-addressed blob store and replaces the context value with a durable blob ref. Command output is always finalized into a blob ref after command completion, even when it is small or empty:blob:// refs, not host-specific file paths.
Before Fabro builds a preamble or starts the next stage, it resolves any blob refs into execution-local files so handlers and agents still see normal file:// references:
- Local execution materializes blobs under
{run_dir}/runtime/blobs/{blob_id}.json - Remote sandboxes materialize blobs under
{working_directory}/.fabro/blobs/{blob_id}.json
file:// paths are runtime-only. They are not written back into durable context snapshots.
This keeps the durable context lean and portable while still giving downstream stages a filesystem path they can read.
Context compaction
During long-running agent sessions, the conversation history can grow large enough to exceed the LLM’s context window. Context compaction automatically summarizes older turns and replaces them with a structured summary, keeping the session running without manual intervention. Compaction is always enabled and runs with hardcoded defaults — there are no user-facing configuration options.When it triggers
After every assistant turn, Fabro estimates the total token usage of the system prompt and conversation history (using a rough heuristic of 1 token per 4 characters). If the estimate exceeds 80% of the model’s context window, compaction runs.How it works
- Split history — The conversation is divided into older turns (to be summarized) and the most recent 6 turns (preserved verbatim).
- Render old turns — Older turns are serialized to a human-readable text format. Tool call arguments and tool results are truncated to 500 characters each.
- Summarize via LLM — Fabro makes a non-streaming LLM call (using the same model and provider as the agent session) with a structured summarization prompt. The summary uses these sections:
- Goal — what the user asked for
- Progress — what was accomplished, with file paths and key decisions
- Key Decisions — important choices and their rationale
- Failed Approaches — what was tried and didn’t work
- Open Issues — remaining bugs, edge cases, or TODOs
- Next Steps — what should happen next
- File Operations — if the agent has tracked file modifications, this section is copied verbatim into the summary
- Replace history — All old turns are removed and replaced with a single
[Context Summary]system message containing the structured summary. The preserved recent turns remain unchanged.
Failure behavior
Compaction failures are non-fatal. If the summarization LLM call fails, Fabro emits anAgent.Error event and the session continues with the original uncompacted history. The next assistant turn will trigger another compaction attempt.