fix: record workflow tool parts in audit metadata
Workflow audit records currently report zero tool parts because the main workflow never supplies the count to the existing audit writer. Count top-level static/dynamic tool UI parts in the accumulated assistant message and forward that optional metadata through handleChatCredits.
This is a bounded successor to #649. The count includes pending/failed parts and preexisting parts in a resumed message; it is not successful executions, incremental resume work, or nested subagent usage. Credit calculations, amounts, account/model attribution, charge conditions and workflow boundaries remain unchanged. No migration or historical backfill.
Validation:
- Six regression tests failed before wiring; 213 focused tests across 36 files now pass.
- Full lint and diff checks pass.
- Whole-project local typecheck retains the same 211 baseline diagnostics by path/code/message; one existing test diagnostic moved two lines.
- Independent Spec and Standards review clear at
9364e765d5b38b51fed75dd2801c396cdccc5616(tree19add370db831f2cf80528180c73358cee21b7dc, base5c0e585d0e12277abc57160129f35b02c9e7cacf). - Tests mock external workflow/credit/provider leaves. No live workflow, database write, credit deduction, customer job or credential inspection performed. CI and preview compilation tracked separately.
Summary by cubic
Fixes workflow audit records reporting zero tool calls because the main workflow never supplied the count to the existing audit writer. Counts tool UI parts in the accumulated assistant message and passes the optional count through handleChatCredits into audit metadata, without changing credit calculations, amounts, charge conditions, or workflow boundaries.
Tool call counting
- Counts top-level static and dynamic tool UI parts, including pending and failed parts, and preexisting parts in resumed messages.
- Excludes successful-execution counts, incremental resume work, and nested subagent output.
- Omitted when the count is undefined, preserving the writer's existing zero default.