microsoft / microsoft/amplifier

bug(streaming-ui): sub-agent orchestrator:complete fires parent cost handler mid-turn, showing wrong Turn/Session values

Open
#290 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
3.1k
Forks
261
Avg merge
3h 28m
Merged PRs (30d)
13

Description

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

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in amplifier_module_hooks_streaming_ui/init.py at _make_cost_handler() and its _on_orchestrator_complete handler. Review the session_id handling and compare with the fix described for feat/m0-cost-management. Done means sub-session completions no longer emit a mid-turn cost line or corrupt the final turn delta.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.