diff --git a/backend/src/adapters/upstream/openai.ts b/backend/src/adapters/upstream/openai.ts index 817652a..64c935c 100644 --- a/backend/src/adapters/upstream/openai.ts +++ b/backend/src/adapters/upstream/openai.ts @@ -11,8 +11,7 @@ import type { InternalResponse, InternalStreamChunk, InternalToolDefinition, - InternalUsage, - ProviderConfig, +ProviderConfig, StopReason, TextContentBlock, ThinkingContentBlock, @@ -387,7 +386,7 @@ export const openaiUpstreamAdapter: UpstreamAdapter = { buildRequest( request: InternalRequest, - provider: ProviderConfig, + provider: ProviderConfig, ): { url: string; init: RequestInit } { // Build messages array with system prompt const messages: OpenAIMessage[] = []; @@ -510,6 +509,17 @@ export const openaiUpstreamAdapter: UpstreamAdapter = { const choice = data.choices[0]; if (!choice) { + // Usage-only chunk (choices=[]) — some providers send usage separately + // after the finish_reason chunk when stream_options.include_usage=true + if (data.usage) { + yield { + type: "message_delta", + usage: { + inputTokens: data.usage.prompt_tokens, + outputTokens: data.usage.completion_tokens, + }, + }; + } continue; } @@ -581,18 +591,20 @@ export const openaiUpstreamAdapter: UpstreamAdapter = { // Handle finish reason if (choice.finish_reason) { yield { type: "content_block_stop", index: blockIndex }; - const usage: InternalUsage = data.usage - ? { - inputTokens: data.usage.prompt_tokens, - outputTokens: data.usage.completion_tokens, - } - : { inputTokens: -1, outputTokens: -1 }; + // Include usage only if upstream provided it in this chunk. + // Some providers bundle usage with finish_reason; others send a + // separate usage-only chunk (choices=[]) immediately after. yield { type: "message_delta", messageDelta: { stopReason: convertFinishReason(choice.finish_reason), }, - usage, + ...(data.usage && { + usage: { + inputTokens: data.usage.prompt_tokens, + outputTokens: data.usage.completion_tokens, + }, + }), }; } } diff --git a/backend/src/db/index.ts b/backend/src/db/index.ts index 1db6744..c433623 100644 --- a/backend/src/db/index.ts +++ b/backend/src/db/index.ts @@ -955,9 +955,14 @@ export async function listUniqueSystemNames( const r = await db .selectDistinct({ systemName: schema.ModelsTable.systemName }) .from(schema.ModelsTable) + .innerJoin( + schema.ProvidersTable, + eq(schema.ModelsTable.providerId, schema.ProvidersTable.id), + ) .where( and( not(schema.ModelsTable.deleted), + not(schema.ProvidersTable.deleted), modelType ? eq(schema.ModelsTable.modelType, modelType) : undefined, ), )