From d47ef96916b437eb9bbd27e33f1dfe0f1bd11324 Mon Sep 17 00:00:00 2001 From: Rob Colbert Date: Tue, 19 May 2026 11:48:56 -0400 Subject: [PATCH] remove empty content continue; prettier then reformatted many things --- packages/ai/src/openai.ts | 197 ++++++++++++++++++++++---------------- 1 file changed, 113 insertions(+), 84 deletions(-) diff --git a/packages/ai/src/openai.ts b/packages/ai/src/openai.ts index 6ca947d..ee3e09f 100644 --- a/packages/ai/src/openai.ts +++ b/packages/ai/src/openai.ts @@ -199,30 +199,33 @@ export class OpenAiApi extends AiApi { } const startTime = Date.now(); - const response = await this.client.chat.completions.create({ - model: model.modelId, - messages: [ - ...(options.systemPrompt - ? [{ role: "system" as const, content: options.systemPrompt }] - : []), - { role: "user" as const, content: options.prompt }, - ], - stream: true, - stream_options: { include_usage: true }, - ...(model.params.maxCompletionTokens - ? { max_completion_tokens: model.params.maxCompletionTokens } - : {}), - temperature: model.params.temperature, - top_p: model.params.topP, - ...(typeof model.params.reasoning === "string" - ? { - reasoning_effort: model.params.reasoning as - | "low" - | "medium" - | "high", - } - : {}), - }, options.signal ? { signal: options.signal } : undefined); + const response = await this.client.chat.completions.create( + { + model: model.modelId, + messages: [ + ...(options.systemPrompt + ? [{ role: "system" as const, content: options.systemPrompt }] + : []), + { role: "user" as const, content: options.prompt }, + ], + stream: true, + stream_options: { include_usage: true }, + ...(model.params.maxCompletionTokens + ? { max_completion_tokens: model.params.maxCompletionTokens } + : {}), + temperature: model.params.temperature, + top_p: model.params.topP, + ...(typeof model.params.reasoning === "string" + ? { + reasoning_effort: model.params.reasoning as + | "low" + | "medium" + | "high", + } + : {}), + }, + options.signal ? { signal: options.signal } : undefined, + ); let accumulatedResponse = ""; let accumulatedThinking = ""; @@ -300,7 +303,12 @@ export class OpenAiApi extends AiApi { ); if (this.isEmptyIteration(iteration)) { - iteration = await this.readNonStreamingChatCompletion(model, messages, tools, options.signal); + iteration = await this.readNonStreamingChatCompletion( + model, + messages, + tools, + options.signal, + ); if (streamCallback && iteration.response) { await streamCallback({ type: "response", data: iteration.response }); } @@ -321,14 +329,19 @@ export class OpenAiApi extends AiApi { done: true, response: iteration.response, thinking: iteration.thinking, - toolCalls: iteration.toolCalls.length > 0 ? iteration.toolCalls : undefined, + toolCalls: + iteration.toolCalls.length > 0 ? iteration.toolCalls : undefined, stats: this.buildStats(startTime, iteration.usage), }; this.assertNonEmptyChatResponse(finalResponse); return finalResponse; } - private extractUsage(usage: { prompt_tokens: number; completion_tokens: number; completion_tokens_details?: { reasoning_tokens?: number } }): OpenAiUsage { + private extractUsage(usage: { + prompt_tokens: number; + completion_tokens: number; + completion_tokens_details?: { reasoning_tokens?: number }; + }): OpenAiUsage { return { promptTokens: usage.prompt_tokens, completionTokens: usage.completion_tokens, @@ -342,7 +355,6 @@ export class OpenAiApi extends AiApi { messages.push({ role: "system", content: options.systemPrompt }); } for (const msg of options.context || []) { - if (!msg.content?.trim()) continue; if (msg.role === "tool") { messages.push({ role: "tool", @@ -351,7 +363,11 @@ export class OpenAiApi extends AiApi { }); continue; } - if (msg.role === "assistant" && msg.toolCalls && msg.toolCalls.length > 0) { + if ( + msg.role === "assistant" && + msg.toolCalls && + msg.toolCalls.length > 0 + ) { messages.push({ role: "assistant", content: msg.content, @@ -371,14 +387,16 @@ export class OpenAiApi extends AiApi { } private buildTools(options: IAiChatOptions): ChatCompletionTool[] { - return (options.tools || []).map((tool): ChatCompletionFunctionTool => ({ - type: tool.definition.type, - function: { - name: tool.definition.function.name, - description: tool.definition.function.description, - parameters: tool.definition.function.parameters, - }, - })); + return (options.tools || []).map( + (tool): ChatCompletionFunctionTool => ({ + type: tool.definition.type, + function: { + name: tool.definition.function.name, + description: tool.definition.function.description, + parameters: tool.definition.function.parameters, + }, + }), + ); } private async readStreamingChatCompletion( @@ -392,26 +410,29 @@ export class OpenAiApi extends AiApi { throw new DOMException("The operation was aborted", "AbortError"); } - const response = await this.client.chat.completions.create({ - model: model.modelId, - messages, - tools, - stream: true, - stream_options: { include_usage: true }, - ...(model.params.maxCompletionTokens - ? { max_completion_tokens: model.params.maxCompletionTokens } - : {}), - temperature: model.params.temperature, - top_p: model.params.topP, - ...(typeof model.params.reasoning === "string" - ? { - reasoning_effort: model.params.reasoning as - | "low" - | "medium" - | "high", - } - : {}), - }, signal ? { signal } : undefined); + const response = await this.client.chat.completions.create( + { + model: model.modelId, + messages, + tools, + stream: true, + stream_options: { include_usage: true }, + ...(model.params.maxCompletionTokens + ? { max_completion_tokens: model.params.maxCompletionTokens } + : {}), + temperature: model.params.temperature, + top_p: model.params.topP, + ...(typeof model.params.reasoning === "string" + ? { + reasoning_effort: model.params.reasoning as + | "low" + | "medium" + | "high", + } + : {}), + }, + signal ? { signal } : undefined, + ); let content = ""; let thinking = ""; @@ -448,7 +469,10 @@ export class OpenAiApi extends AiApi { if ("reasoning" in delta && delta.reasoning) { thinking += delta.reasoning as string; if (streamCallback) { - await streamCallback({ type: "thinking", data: delta.reasoning as string }); + await streamCallback({ + type: "thinking", + data: delta.reasoning as string, + }); } } if (delta.tool_calls) { @@ -481,30 +505,35 @@ export class OpenAiApi extends AiApi { throw new DOMException("The operation was aborted", "AbortError"); } - const response = await this.client.chat.completions.create({ - model: model.modelId, - messages, - tools, - stream: false, - ...(model.params.maxCompletionTokens - ? { max_completion_tokens: model.params.maxCompletionTokens } - : {}), - temperature: model.params.temperature, - top_p: model.params.topP, - ...(typeof model.params.reasoning === "string" - ? { - reasoning_effort: model.params.reasoning as - | "low" - | "medium" - | "high", - } - : {}), - }, signal ? { signal } : undefined); + const response = await this.client.chat.completions.create( + { + model: model.modelId, + messages, + tools, + stream: false, + ...(model.params.maxCompletionTokens + ? { max_completion_tokens: model.params.maxCompletionTokens } + : {}), + temperature: model.params.temperature, + top_p: model.params.topP, + ...(typeof model.params.reasoning === "string" + ? { + reasoning_effort: model.params.reasoning as + | "low" + | "medium" + | "high", + } + : {}), + }, + signal ? { signal } : undefined, + ); const choice = response.choices[0]; const message = choice?.message; const content = typeof message?.content === "string" ? message.content : ""; - const usage = response.usage ? this.extractUsage(response.usage) : undefined; + const usage = response.usage + ? this.extractUsage(response.usage) + : undefined; const assistantToolCalls = (message?.tool_calls || []) .filter((tc) => tc.type === "function") .map((tc) => ({ @@ -516,12 +545,12 @@ export class OpenAiApi extends AiApi { }, })); const toolCalls: IToolCall[] = assistantToolCalls.map((tc) => ({ - callId: tc.id, - function: { - name: tc.function.name, - arguments: tc.function.arguments, - }, - })); + callId: tc.id, + function: { + name: tc.function.name, + arguments: tc.function.arguments, + }, + })); return { response: content,