From 51c1f3d9ae0df4aa2ae0b7615bc4c36be7968834 Mon Sep 17 00:00:00 2001 From: Em Date: Thu, 27 Mar 2025 17:04:57 -0400 Subject: [PATCH] chore(client): fully remove deprecated function call types from tool runner --- src/lib/AbstractChatCompletionRunner.ts | 50 ++++++++------------ src/lib/chatCompletionUtils.ts | 7 --- tests/lib/ChatCompletionRunFunctions.test.ts | 8 ++-- tests/lib/azure.test.ts | 2 +- 4 files changed, 24 insertions(+), 43 deletions(-) diff --git a/src/lib/AbstractChatCompletionRunner.ts b/src/lib/AbstractChatCompletionRunner.ts index 9f31ac119..2e879bfec 100644 --- a/src/lib/AbstractChatCompletionRunner.ts +++ b/src/lib/AbstractChatCompletionRunner.ts @@ -1,10 +1,11 @@ -import { type CompletionUsage } from '../resources/completions'; -import { - type ChatCompletion, - type ChatCompletionMessage, - type ChatCompletionMessageParam, - type ChatCompletionCreateParams, - type ChatCompletionTool, +import type { CompletionUsage } from '../resources/completions'; +import type { + ChatCompletion, + ChatCompletionMessage, + ChatCompletionMessageParam, + ChatCompletionCreateParams, + ChatCompletionTool, + ChatCompletionMessageToolCall, } from '../resources/chat/completions'; import { OpenAIError } from '../error'; import { @@ -13,14 +14,14 @@ import { type BaseFunctionsArgs, RunnableToolFunction, } from './RunnableFunction'; -import { ChatCompletionToolRunnerParams } from './ChatCompletionRunner'; -import { ChatCompletionStreamingToolRunnerParams } from './ChatCompletionStreamingRunner'; -import { isAssistantMessage, isFunctionMessage, isToolMessage } from './chatCompletionUtils'; +import type { ChatCompletionToolRunnerParams } from './ChatCompletionRunner'; +import type { ChatCompletionStreamingToolRunnerParams } from './ChatCompletionStreamingRunner'; +import { isAssistantMessage, isToolMessage } from './chatCompletionUtils'; import { BaseEvents, EventStream } from './EventStream'; -import { ParsedChatCompletion } from '../resources/beta/chat/completions'; +import type { ParsedChatCompletion } from '../resources/beta/chat/completions'; import OpenAI from '../index'; import { isAutoParsableTool, parseChatCompletion } from '../lib/parser'; -import { RequestOptions } from '../internal/request-options'; +import type { RequestOptions } from '../internal/request-options'; const DEFAULT_MAX_CHAT_COMPLETIONS = 10; export interface RunnerOptions extends RequestOptions { @@ -57,11 +58,9 @@ export class AbstractChatCompletionRunner< if (emit) { this._emit('message', message); - if ((isFunctionMessage(message) || isToolMessage(message)) && message.content) { + if (isToolMessage(message) && message.content) { // Note, this assumes that {role: 'tool', content: …} is always the result of a call of tool of type=function. this._emit('functionCallResult', message.content as string); - } else if (isAssistantMessage(message) && message.function_call) { - this._emit('functionCall', message.function_call); } else if (isAssistantMessage(message) && message.tool_calls) { for (const tool_call of message.tool_calls) { if (tool_call.type === 'function') { @@ -101,17 +100,12 @@ export class AbstractChatCompletionRunner< while (i-- > 0) { const message = this.messages[i]; if (isAssistantMessage(message)) { - const { function_call, ...rest } = message; - // TODO: support audio here const ret: Omit = { - ...rest, + ...message, content: (message as ChatCompletionMessage).content ?? null, refusal: (message as ChatCompletionMessage).refusal ?? null, }; - if (function_call) { - ret.function_call = function_call; - } return ret; } } @@ -127,12 +121,9 @@ export class AbstractChatCompletionRunner< return this.#getFinalMessage(); } - #getFinalFunctionCall(): ChatCompletionMessage.FunctionCall | undefined { + #getFinalFunctionCall(): ChatCompletionMessageToolCall.Function | undefined { for (let i = this.messages.length - 1; i >= 0; i--) { const message = this.messages[i]; - if (isAssistantMessage(message) && message?.function_call) { - return message.function_call; - } if (isAssistantMessage(message) && message?.tool_calls?.length) { return message.tool_calls.at(-1)?.function; } @@ -145,7 +136,7 @@ export class AbstractChatCompletionRunner< * @returns a promise that resolves with the content of the final FunctionCall, or rejects * if an error occurred or the stream ended prematurely without producing a ChatCompletionMessage. */ - async finalFunctionCall(): Promise { + async finalFunctionCall(): Promise { await this.done(); return this.#getFinalFunctionCall(); } @@ -153,9 +144,6 @@ export class AbstractChatCompletionRunner< #getFinalFunctionCallResult(): string | undefined { for (let i = this.messages.length - 1; i >= 0; i--) { const message = this.messages[i]; - if (isFunctionMessage(message) && message.content != null) { - return message.content; - } if ( isToolMessage(message) && message.content != null && @@ -402,13 +390,13 @@ export class AbstractChatCompletionRunner< } export interface AbstractChatCompletionRunnerEvents extends BaseEvents { - functionCall: (functionCall: ChatCompletionMessage.FunctionCall) => void; + functionCall: (functionCall: ChatCompletionMessageToolCall.Function) => void; message: (message: ChatCompletionMessageParam) => void; chatCompletion: (completion: ChatCompletion) => void; finalContent: (contentSnapshot: string) => void; finalMessage: (message: ChatCompletionMessageParam) => void; finalChatCompletion: (completion: ChatCompletion) => void; - finalFunctionCall: (functionCall: ChatCompletionMessage.FunctionCall) => void; + finalFunctionCall: (functionCall: ChatCompletionMessageToolCall.Function) => void; functionCallResult: (content: string) => void; finalFunctionCallResult: (content: string) => void; totalUsage: (usage: CompletionUsage) => void; diff --git a/src/lib/chatCompletionUtils.ts b/src/lib/chatCompletionUtils.ts index 7e9f8a093..2bf0d5b47 100644 --- a/src/lib/chatCompletionUtils.ts +++ b/src/lib/chatCompletionUtils.ts @@ -1,6 +1,5 @@ import { type ChatCompletionAssistantMessageParam, - type ChatCompletionFunctionMessageParam, type ChatCompletionMessageParam, type ChatCompletionToolMessageParam, } from '../resources'; @@ -11,12 +10,6 @@ export const isAssistantMessage = ( return message?.role === 'assistant'; }; -export const isFunctionMessage = ( - message: ChatCompletionMessageParam | null | undefined, -): message is ChatCompletionFunctionMessageParam => { - return message?.role === 'function'; -}; - export const isToolMessage = ( message: ChatCompletionMessageParam | null | undefined, ): message is ChatCompletionToolMessageParam => { diff --git a/tests/lib/ChatCompletionRunFunctions.test.ts b/tests/lib/ChatCompletionRunFunctions.test.ts index f2ce1c029..51f648f55 100644 --- a/tests/lib/ChatCompletionRunFunctions.test.ts +++ b/tests/lib/ChatCompletionRunFunctions.test.ts @@ -130,12 +130,12 @@ class RunnerListener { readonly contents: string[] = []; readonly messages: ChatCompletionMessageParam[] = []; readonly chatCompletions: OpenAI.Chat.ChatCompletion[] = []; - readonly functionCalls: OpenAI.Chat.ChatCompletionMessage.FunctionCall[] = []; + readonly functionCalls: OpenAI.Chat.ChatCompletionMessageToolCall.Function[] = []; readonly functionCallResults: string[] = []; finalContent: string | null = null; finalMessage: ChatCompletionMessageParam | undefined; finalChatCompletion: OpenAI.Chat.ChatCompletion | undefined; - finalFunctionCall: OpenAI.Chat.ChatCompletionMessage.FunctionCall | undefined; + finalFunctionCall: OpenAI.Chat.ChatCompletionMessageToolCall.Function | undefined; finalFunctionCallResult: string | undefined; totalUsage: OpenAI.CompletionUsage | undefined; error: OpenAIError | undefined; @@ -247,13 +247,13 @@ class StreamingRunnerListener { readonly eventContents: [string, string][] = []; readonly eventMessages: ChatCompletionMessageParam[] = []; readonly eventChatCompletions: OpenAI.Chat.ChatCompletion[] = []; - readonly eventFunctionCalls: OpenAI.Chat.ChatCompletionMessage.FunctionCall[] = []; + readonly eventFunctionCalls: OpenAI.Chat.ChatCompletionMessageToolCall.Function[] = []; readonly eventFunctionCallResults: string[] = []; finalContent: string | null = null; finalMessage: ChatCompletionMessageParam | undefined; finalChatCompletion: OpenAI.Chat.ChatCompletion | undefined; - finalFunctionCall: OpenAI.Chat.ChatCompletionMessage.FunctionCall | undefined; + finalFunctionCall: OpenAI.Chat.ChatCompletionMessageToolCall.Function | undefined; finalFunctionCallResult: string | undefined; error: OpenAIError | undefined; gotConnect = false; diff --git a/tests/lib/azure.test.ts b/tests/lib/azure.test.ts index 1b9b2546c..87c2de171 100644 --- a/tests/lib/azure.test.ts +++ b/tests/lib/azure.test.ts @@ -134,7 +134,7 @@ describe('instantiate azure client', () => { const spy = jest.spyOn(client, 'request'); - await expect(client.get('/foo', { signal: controller.signal })).rejects.toThrowError(APIUserAbortError); + await expect(client.get('/foo', { signal: controller.signal })).rejects.toThrow(APIUserAbortError); expect(spy).toHaveBeenCalledTimes(1); });