Skip to content

Commit 6191e2a

Browse files
committed
fix(openai): emit streaming token usage from usage-only SSE chunks
1 parent 18f1960 commit 6191e2a

2 files changed

Lines changed: 13 additions & 4 deletions

File tree

Sources/AgentRunKit/LLM/OpenAIClientStreaming.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ extension OpenAIClient {
110110

111111
func extractDeltas(from chunk: StreamingChunk) throws -> [StreamDelta] {
112112
var deltas: [StreamDelta] = []
113+
var emittedFinished = false
113114
for choice in chunk.choices ?? [] {
114115
if let reasoning = choice.delta.reasoning ?? choice.delta.reasoningContent, !reasoning.isEmpty {
115116
deltas.append(.reasoning(reasoning))
@@ -121,8 +122,12 @@ extension OpenAIClient {
121122
try extractAudioDeltas(from: choice.delta, into: &deltas)
122123
if choice.finishReason != nil {
123124
deltas.append(.finished(usage: chunk.usage.map(\.tokenUsage)))
125+
emittedFinished = true
124126
}
125127
}
128+
if !emittedFinished, let usage = chunk.usage {
129+
deltas.append(.finished(usage: usage.tokenUsage))
130+
}
126131
return deltas
127132
}
128133

Tests/AgentRunKitTests/OpenAIClientResponseTests.swift

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ struct StreamingChunkParsingTests {
406406
}
407407

408408
@Test
409-
func streamingChunkWithoutChoicesDecodesCleanly() throws {
409+
func streamingChunkWithUsageOnlyEmitsFinished() throws {
410410
let json = """
411411
{
412412
"usage": {
@@ -419,9 +419,13 @@ struct StreamingChunkParsingTests {
419419
let chunk = try client.parseStreamingChunk(Data(json.utf8))
420420
let deltas = try client.extractDeltas(from: chunk)
421421

422-
#expect(deltas.isEmpty)
423-
#expect(chunk.usage?.promptTokens == 100)
424-
#expect(chunk.usage?.completionTokens == 50)
422+
#expect(deltas.count == 1)
423+
if case let .finished(usage) = deltas.first {
424+
#expect(usage?.input == 100)
425+
#expect(usage?.output == 50)
426+
} else {
427+
Issue.record("Expected .finished delta with usage")
428+
}
425429
}
426430

427431
@Test

0 commit comments

Comments
 (0)