Repo: amplifier-module-hooks-streaming-ui
File: amplifier_module_hooks_streaming_ui/__init__.py β _make_cost_handler()
Evidence
From a real session, a π° line appears mid-turn immediately after a sub-agent finishes β before the parent turn is done:
β Input: 12,530 (64% cached) | Output: 145 | Total: 12,675 | Cost: $0.00711955
π° Turn: $0.05 | Session: $0.05 β spurious! sub-agent's orchestrator:complete
β
Tool result: delegate β parent turn still in progress here
...
β Input: 93,759 (93% cached) | Output: 114 | Total: 93,873 | Cost: $0.08
π° Turn: $0.38 | Session: $2.00 β actual end-of-turn line
Two π° lines appear per user turn when sub-agents are involved.
Root cause
Sub-agent orchestrator:complete events propagate up through the hook bus to the parent coordinator's hooks. The _on_orchestrator_complete handler registered by _make_cost_handler does not check whether the event came from a sub-session or the root session.
Secondary effect: The mid-turn firing updates state["prev_total"] to a wrong intermediate value (the parent's costs at that point, before bridge_child_cost has registered the sub-agent's costs). This corrupts the turn delta calculation for the real end-of-turn line.
The Turn: $0.05 shown mid-turn is actually the parent Opus LLM call cost (the initial call that decided to delegate) β not the sub-agent's haiku costs (~$0.027). This looks like cost doubling to the user.
Fix (already applied on feat/m0-cost-management)
Filter sub-session events at the top of the handler using the _ in session_id that marks sub-sessions (e.g. abc-def_foundation-file-ops):
async def _on_orchestrator_complete(event: str, data: dict):
session_id = data.get("session_id")
if session_id and "_" in session_id:
return HookResult(action="continue") # sub-session, skip
# ... rest of handler
Repo:
amplifier-module-hooks-streaming-uiFile:
amplifier_module_hooks_streaming_ui/__init__.pyβ_make_cost_handler()Evidence
From a real session, a
π°line appears mid-turn immediately after a sub-agent finishes β before the parent turn is done:Two
π°lines appear per user turn when sub-agents are involved.Root cause
Sub-agent
orchestrator:completeevents propagate up through the hook bus to the parent coordinator's hooks. The_on_orchestrator_completehandler registered by_make_cost_handlerdoes not check whether the event came from a sub-session or the root session.Secondary effect: The mid-turn firing updates
state["prev_total"]to a wrong intermediate value (the parent's costs at that point, beforebridge_child_costhas registered the sub-agent's costs). This corrupts the turn delta calculation for the real end-of-turn line.The
Turn: $0.05shown mid-turn is actually the parent Opus LLM call cost (the initial call that decided to delegate) β not the sub-agent's haiku costs (~$0.027). This looks like cost doubling to the user.Fix (already applied on
feat/m0-cost-management)Filter sub-session events at the top of the handler using the
_in session_id that marks sub-sessions (e.g.abc-def_foundation-file-ops):