/** * Shared utilities for OpenAI-compatible API paths. * * Both the OpenAI path (queryModelOpenAI) and Grok path (queryModelGrok) use * the same adapters (openaiStreamAdapter, openaiConvertMessages), so the event * processing logic should be shared rather than duplicated. */ /** * Merge a delta usage into the accumulated usage, preserving cache-related * fields from previous values when the delta carries explicit zeroes or * undefined values. * * Mirrors updateUsage() in claude.ts: a future adapter change that omits * cache fields from certain streaming events should not silently zero the * accumulated counters. */ export function updateOpenAIUsage( current: { input_tokens: number output_tokens: number cache_creation_input_tokens: number cache_read_input_tokens: number }, delta: { input_tokens?: number output_tokens?: number cache_creation_input_tokens?: number cache_read_input_tokens?: number }, ): typeof current { return { input_tokens: delta.input_tokens ?? current.input_tokens, output_tokens: delta.output_tokens ?? current.output_tokens, cache_creation_input_tokens: delta.cache_creation_input_tokens !== undefined && delta.cache_creation_input_tokens > 0 ? delta.cache_creation_input_tokens : current.cache_creation_input_tokens, cache_read_input_tokens: delta.cache_read_input_tokens !== undefined && delta.cache_read_input_tokens > 0 ? delta.cache_read_input_tokens : current.cache_read_input_tokens, } }