Summary
ContextEngine.assemble should fire per LLM call, not per user prompt
Current behavior
User prompt
→ assembleAttemptContextEngine() ← fires ONCE
→ activeSession.prompt() ← agentic loop
LLM call 1 ← ✅ assemble ran before this
→ tool result
→ LLM call 2 ← ❌ no assemble before this
→ tool result
→ LLM call 3 ← ❌ no assemble before this
→ final response
In attempt.ts:1904, assembleAttemptContextEngine() is called before activeSession.prompt(), which contains the agentic loop. Once the loop starts executing multiple LLM calls, assemble is never invoked again.
Why installContextEngineLoopHook is insufficient
transformContext's call frequency does not guarantee invocation before every LLM call — it fires at specific internal transition points.
Related
Problem to solve
ContextEngine.assemble() currently fires once per user prompt (per attempt), not per LLM call within the agentic loop. Context engines — especially those doing context compression — cannot make informed decisions about the message array before subsequent LLM calls in a multi-turn tool loop.
Proposed solution
Add a transform_context hook that fires before each LLM call within the agentic loop. Two approaches:
- New
transform_context hook type — conservative, doesn't change existing assemble semantics
- Make
assemble fire at each LLM call boundary — simpler but may have backward-compatibility implications
Option 1 is recommended as the safer path.
Alternatives considered
No response
Impact
Context overflow on long agentic loops, stale context in subsequent LLM calls, inability to implement smart trimming strategies.
Evidence/examples
No response
Additional information
No response
Summary
ContextEngine.assembleshould fire per LLM call, not per user promptCurrent behavior
User prompt
→ assembleAttemptContextEngine() ← fires ONCE
→ activeSession.prompt() ← agentic loop
LLM call 1 ← ✅ assemble ran before this
→ tool result
→ LLM call 2 ← ❌ no assemble before this
→ tool result
→ LLM call 3 ← ❌ no assemble before this
→ final response
In
attempt.ts:1904,assembleAttemptContextEngine()is called beforeactiveSession.prompt(), which contains the agentic loop. Once the loop starts executing multiple LLM calls,assembleis never invoked again.Why
installContextEngineLoopHookis insufficienttransformContext's call frequency does not guarantee invocation before every LLM call — it fires at specific internal transition points.Related
Problem to solve
ContextEngine.assemble()currently fires once per user prompt (per attempt), not per LLM call within the agentic loop. Context engines — especially those doing context compression — cannot make informed decisions about the message array before subsequent LLM calls in a multi-turn tool loop.Proposed solution
Add a
transform_contexthook that fires before each LLM call within the agentic loop. Two approaches:transform_contexthook type — conservative, doesn't change existingassemblesemanticsassemblefire at each LLM call boundary — simpler but may have backward-compatibility implicationsOption 1 is recommended as the safer path.
Alternatives considered
No response
Impact
Context overflow on long agentic loops, stale context in subsequent LLM calls, inability to implement smart trimming strategies.
Evidence/examples
No response
Additional information
No response