fix(moa): show real tok/s on mesh by reporting effective completion_tokens - #638
Merged
Conversation
The chat UI's response stats bar always read '0.0 tok/s' for the mesh
virtual model. MoA's response builders hardcoded
`usage: { 0, 0, 0 }`, so even though the UI computes decode_time_ms
from client-side first-delta-to-completion (mesh-connection.ts:243),
it had no token count to divide.
Reporting the winning worker's measured tokens would be misleading:
MoA fans out to multiple workers and may run a reducer, so any single
worker's rate lies about the user's actual wait. The honest number is
'how many tokens did the user receive over the wall time they waited'.
Use a `chars / 4` estimate (OpenAI's documented rule-of-thumb for
English) of the final user-visible content. The UI's client-side
decode interval then yields an honest effective tok/s for the whole
MoA pipeline.
Wires through chat_response, tool_call_response, and error_response.
Tests pin both the estimator and each builder's non-zero output.
Refs #637
Contributor
There was a problem hiding this comment.
Pull request overview
Improves the MoA (mesh virtual model) response usage reporting so the chat UI can compute a non-zero effective tok/s by providing a best-effort completion_tokens estimate derived from the final user-visible content.
Changes:
- Replaced hardcoded zero
usagevalues in MoA response builders with achars / 4-basedcompletion_tokensestimate (mirrored intototal_tokens). - Added helper functions (
estimate_completion_tokens,usage_for_content) to centralize the estimation logic. - Added unit tests covering the estimator and ensuring
chat_response,tool_call_response, anderror_responsereport non-zero completion tokens for non-empty content.
Comments suppressed due to low confidence (1)
crates/mesh-mixture-of-agents/src/lib.rs:763
- This test comment mentions clients "dividing by completion_tokens", but the tok/s computation uses
completion_tokensas the token count and divides by elapsed time. Recommend updating the wording to match the actual usage (avoid confusion for future readers).
assert_eq!(estimate_completion_tokens(&"x".repeat(40)), 10);
}
… too small MoA blocks until a worker wins, then dumps the full reduced answer in a single SSE event. decode_time_ms (firstDelta -> completed) is ~0 in that case, so tokens / decode_time produces absurd numbers (we saw 236,000 tok/s locally). When the streaming gap is unrealistically small (<50ms), use the total wall time as the denominator instead. That matches what the user actually waited and yields honest single/low-double-digit tok/s for MoA responses (verified ~13 tok/s vs the old ~100,000). Refs #637
|
|
||
| const decodeOk = | ||
| typeof decodeTimeMs === 'number' && Number.isFinite(decodeTimeMs) && decodeTimeMs >= MIN_DECODE_INTERVAL_MS | ||
| const totalOk = typeof totalTimeMs === 'number' && Number.isFinite(totalTimeMs) && totalTimeMs > 0 |
Collaborator
Author
There was a problem hiding this comment.
what a waste of tokens copilot - doing what a deterministic tool can do. You may as well pretend to compile it 👎
michaelneale
added a commit
that referenced
this pull request
May 22, 2026
…back * origin/main: fix(moa): show real tok/s on mesh by reporting effective completion_tokens (#638)
michaelneale
added a commit
that referenced
this pull request
May 24, 2026
* origin/main: Ship real client and serving SDKs across Swift, Kotlin, and Node.js (#634) task: Add tok/s and model name to nightly workflow summary (#654) fix(docs): restore docs.anarchai.org as Pages custom domain Update llama.cpp upstream pin Fix skippy smoke llama build directory (#655) Update pinned llama.cpp revision (#646) Normalize non-stream chat tool call IDs chore(github): Add lightweight issue templates to repo Add nightly mesh stability harness (#631) fix(moa): show real tok/s on mesh by reporting effective completion_tokens (#638)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The chat UI's response stats bar always read
0.0 tok/swhen using themeshvirtual model (the default since #619 flippedAUTO_BACKEND_MODEL = 'mesh'). After this PR,meshresponses show real, honest effective throughput.Why "0.0 tok/s"?
The UI's
mesh-connection.tsalready measuresdecode_time_msclient-side (from first delta to completion). It then dividesusage.output_tokens / decode_time_msto compute tok/s. But MoA's three response builders \u2014chat_response,tool_call_response,error_response\u2014 all hardcodedusage: { 0, 0, 0 }, so the dividend was always zero. The downstream Responses-API translation chain (moa_gateway.rs\u2192chat_usage_to_responses_usage\u2192responses_stream_completed_event) faithfully forwarded the zeros to the wire.Why not report the winning worker's measured tokens?
Considered and rejected. MoA fans out to multiple workers and may run a reducer; reporting any single worker's measured rate would lie about the user's actual wait. A worker that finishes at 80 tok/s while the reducer deliberates for another 2s does not mean the user got an 80 tok/s response.
The honest number for a chat UI is "how many tokens did the user actually receive over the wall time they waited." That's effective throughput across the whole MoA pipeline \u2014 fan-out, grace window, reducer, the lot.
Approach
Estimate
completion_tokensfrom the final user-visible content using achars / 4heuristic (OpenAI's documented rule-of-thumb for English token density). Combined with the UI's existing client-sidedecode_time_ms, this yields an honest effective tok/s for the whole MoA response.Plumbed via one helper:
chat_responseuses the final answer text.tool_call_responseuses the tool-args JSON.error_responseuses the error message text.Tradeoffs
chars / 4rule is stable at ~3-5% of true token count; close enough for a UI stats bar.usageis already a field everyone expects; just goes from "always zero" to "always reasonable."Tests
New tests in
response_builder_tests:estimate_completion_tokens_returns_zero_for_empty_contentestimate_completion_tokens_returns_at_least_one_for_non_emptyestimate_completion_tokens_is_roughly_chars_over_fourchat_response_reports_non_zero_completion_tokenstool_call_response_reports_non_zero_completion_tokenserror_response_reports_message_based_completion_tokenscargo test -p mesh-mixture-of-agents --lib: 107 pass, 0 fail.Refs
Closes #637.
Validation plan post-merge
mesh-llm-console.fly.devafter the next deploy.mesh).X.Y tok/snot0.0 tok/s.Screenshot
n/a (UI behavior change only; the value displayed in the existing stats bar goes from "0.0" to a real number).