mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 08:07:15 +00:00
fix(ai-chat): accumulate output tokens across tool-use steps in a turn
Fold each finished round-trip's streamed total into a base so the thinking indicator's token count stays monotonic across a multi-step turn instead of dropping back to near-zero when the next step's message begins. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
02f3a2927d
commit
ecb406d1ef
@@ -273,9 +273,15 @@ export class AIChatManager {
|
||||
currentReply = $state<string>('')
|
||||
currentReasoning = $state<string>('')
|
||||
currentReasoningActive = $state<boolean>(false)
|
||||
// Live output-token count for the in-flight assistant message; drives the typing
|
||||
// indicator's progress readout. Only populated by providers that stream usage.
|
||||
// Live output-token count for the current turn; drives the typing indicator's
|
||||
// progress readout. Only populated by providers that stream usage.
|
||||
currentOutputTokens = $state<number>(0)
|
||||
// A turn can span several API round-trips (one per tool-use step). Each round-trip's
|
||||
// streamed usage.output_tokens is a running total scoped to that one message, so it
|
||||
// restarts from near-zero every step. To keep the readout monotonic across the whole
|
||||
// turn, fold each finished step's total into a base and add the in-flight step on top.
|
||||
#outputTokensBase = 0
|
||||
#outputTokensStep = 0
|
||||
displayMessages = $state<DisplayMessage[]>([])
|
||||
messages = $state<ChatCompletionMessageParam[]>([])
|
||||
/** Provider-reported context size of the last committed turn (prompt +
|
||||
@@ -1641,6 +1647,8 @@ export class AIChatManager {
|
||||
this.currentReasoning = ''
|
||||
this.currentReasoningActive = false
|
||||
this.currentOutputTokens = 0
|
||||
this.#outputTokensBase = 0
|
||||
this.#outputTokensStep = 0
|
||||
|
||||
// Compaction trigger. Without a known context window there is no limit
|
||||
// to enforce, so compaction stays off rather than guessing one.
|
||||
@@ -1696,7 +1704,14 @@ export class AIChatManager {
|
||||
onNewToken: (token) => (this.currentReply += token),
|
||||
onReasoningDelta: (token) => (this.currentReasoning += token),
|
||||
onReasoningStart: () => (this.currentReasoningActive = true),
|
||||
onOutputTokens: (n) => (this.currentOutputTokens = n),
|
||||
onOutputTokens: (n) => {
|
||||
// A drop means a new step's message started; bank the prior step's total.
|
||||
if (n < this.#outputTokensStep) {
|
||||
this.#outputTokensBase += this.#outputTokensStep
|
||||
}
|
||||
this.#outputTokensStep = n
|
||||
this.currentOutputTokens = this.#outputTokensBase + n
|
||||
},
|
||||
onMessageEnd: () => {
|
||||
// Keep the streamed text for the abort/error paths. Non-empty only:
|
||||
// parsers flush (and reset) when a tool call starts after text, and
|
||||
|
||||
Reference in New Issue
Block a user