Skip to content

Intelligent Context Synthesis

Intelligent Context Synthesis (ICS) runs after each thinking step (iteration ≥ 1) when the shared ReAct-style kernel is active. It produces a compact message list for the next LLM call instead of replaying the full raw transcript.

ModeBehavior
autoHeuristic: e.g. fast templates on capable tiers; may skip deep synthesis on small local models without a dedicated synthesis model
fastDeterministic template synthesis (no extra LLM)
deepLLM-driven synthesis via ContextSynthesizerService
customSupply synthesisStrategy on .withReasoning()
offDisable synthesis; kernel uses the standard message window

Top-level fields apply to every strategy unless overridden:

.withReasoning({
synthesis: "auto",
synthesisModel: "claude-3-5-haiku-20241022",
synthesisProvider: "anthropic",
synthesisTemperature: 0,
})

Per-strategy overrides apply only when that strategy is the effective execution strategy (after tier routing). Keys match the internal bundles: reactive, planExecute, treeOfThought, reflexion. The adaptive meta-strategy does not have its own bundle — only the global/top-level ICS fields apply until a concrete strategy runs (each inner run then uses its own resolved config).

.withReasoning({
synthesis: "fast",
strategies: {
reactive: { synthesis: "deep", synthesisModel: "gpt-4o-mini" },
planExecute: { synthesis: "off" },
},
})

Resolution order: per-strategy ICS fields → top-level .withReasoning() synthesis fields → default { mode: "auto" }. Advanced layouts can call resolveSynthesisConfigForStrategy() from @reactive-agents/runtime when building custom configs.

Fast-mode synthesis reconstructs a multi-turn conversation from the kernel transcript rather than flattening everything into a single user message. This is critical for native function-calling models (especially local models like Ollama) that rely on the proper userassistant (with tool_use blocks) → tool (result) → user (nudge) message structure.

The synthesizer applies a sliding window to keep only the most recent N turns as full multi-turn messages. Older turns are compacted into a single summary message ([Prior work: called web-search → result preview | ...]). The window size varies by model tier:

TierFull Turns KeptArg Budget (chars)
local2100
mid3200
large5400
frontier8600

Tool-call arguments (e.g. large file-write content) are truncated per tier budget so they don’t bloat the synthesized context. The actual deliverables live in the tool results, not in the repeated argument replay.

Each synthesis pass classifies the current task phase based on tool usage and iteration progress:

PhaseMeaningSteering
gatherRequired tools not yet calledNudges the model to call missing tools
produceData gathered, output not yet createdDirects the model to produce the deliverable
synthesizeAll required tools satisfiedEncourages a final summary
verifyOutput exists, confirmation stepAsks the model to confirm/summarize results

When synthesis runs, the framework publishes a ContextSynthesized event on the EventBus (payload includes a snapshot of signals such as tier, iteration, and last errors). Subscribe with agent.subscribe("ContextSynthesized", …) when .withEvents() is enabled.