Files
multica/server/internal/daemon
joyanup 4c1fd60215 fix(daemon): report task usage before cancel check (#1180)
handleTask had two early-return paths that ran before ReportTaskUsage:
the cancelledByPoll select and the post-run GetTaskStatus check. Both
silently discarded any usage accumulated by the agent — and both
claude.go and codex.go populate Result.Usage even when runCtx is
cancelled mid-run, so cancelled tasks consistently under-reported tokens.

Hoist ReportTaskUsage to run immediately after the runner returns,
before any early-return path. Add a taskRunner interface seam and a
cancelPollInterval field so tests can inject a fake runner and trigger
the poll-cancellation path on a 10ms ticker without spawning real agents.

Two regression tests cover both leak windows:
- TestHandleTask_ReportsUsageBeforeCancel: post-run /status returns
  "cancelled"; usage must be reported before the status check.
- TestHandleTask_ReportsUsageWhenCancelledByPoll: poll goroutine fires
  first and cancels runCtx; runner returns usage on Done; assert
  poll-status precedes usage (proving the cancelledByPoll branch was
  the one exercised, not the post-run path).

Sanity-checked: reverting only the ReportTaskUsage hoist fails both
tests with the original "tokens lost" message.

MUL-2258

Co-authored-by: Jiang Bohan <bhjiang@outlook.com>
Co-authored-by: multica-agent <github@multica.ai>
2026-05-15 13:33:17 +08:00
..