From 09bc50d439679b6acfd2441e69ee5aa18c00e5d9 Mon Sep 17 00:00:00 2001 From: Jamon Holmgren Date: Thu, 13 Feb 2025 05:27:35 -0800 Subject: [PATCH 1/3] fix(realtime): call .toString() on WebSocket url (#1324) The [WebSocket spec at WHATWG](https://websockets.spec.whatwg.org/#ref-for-dom-websocket-websocket%E2%91%A0) indicates that the `url` parameter of the WebSocket constructor is a string. Some implementations (like Chrome) will accept a URL object, but calling .toString() should work for all cases. Fixes #1323. --- src/beta/realtime/websocket.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/beta/realtime/websocket.ts b/src/beta/realtime/websocket.ts index b10a2519d..e8900e809 100644 --- a/src/beta/realtime/websocket.ts +++ b/src/beta/realtime/websocket.ts @@ -53,7 +53,7 @@ export class OpenAIRealtimeWebSocket extends OpenAIRealtimeEmitter { props.onURL?.(this.url); // @ts-ignore - this.socket = new WebSocket(this.url, [ + this.socket = new WebSocket(this.url.toString(), [ 'realtime', ...(isAzure(client) ? [] : [`openai-insecure-api-key.${client.apiKey}`]), 'openai-beta.realtime-v1', From 8d77f8e3c4801b7fa1e7c6f50b48c1de1f43f3e6 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 19:41:49 +0000 Subject: [PATCH 2/3] feat(api): add support for storing chat completions (#1327) --- .stats.yml | 4 +- api.md | 72 ++++---- src/index.ts | 27 ++- src/lib/ChatCompletionStream.ts | 2 +- src/resources/chat/chat.ts | 19 +- .../chat/{ => completions}/completions.ts | 170 ++++++++++++++++-- src/resources/chat/completions/index.ts | 49 +++++ src/resources/chat/completions/messages.ts | 52 ++++++ src/resources/chat/index.ts | 10 +- src/resources/completions.ts | 4 +- src/resources/moderations.ts | 4 +- tests/api-resources/chat/completions.test.ts | 65 ------- .../chat/completions/completions.test.ts | 144 +++++++++++++++ .../chat/completions/messages.test.ts | 40 +++++ 14 files changed, 534 insertions(+), 128 deletions(-) rename src/resources/chat/{ => completions}/completions.ts (88%) create mode 100644 src/resources/chat/completions/index.ts create mode 100644 src/resources/chat/completions/messages.ts delete mode 100644 tests/api-resources/chat/completions.test.ts create mode 100644 tests/api-resources/chat/completions/completions.test.ts create mode 100644 tests/api-resources/chat/completions/messages.test.ts diff --git a/.stats.yml b/.stats.yml index d59a86d22..658877d3b 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,2 +1,2 @@ -configured_endpoints: 69 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-dfb00c627f58e5180af7a9b29ed2f2aa0764a3b9daa6a32a1cc45bc8e48dfe15.yml +configured_endpoints: 74 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-4aa6ee65ba9efc789e05e6a5ef0883b2cadf06def8efd863dbf75e9e233067e1.yml diff --git a/api.md b/api.md index 01854a8e0..63f239628 100644 --- a/api.md +++ b/api.md @@ -32,39 +32,51 @@ Types: Types: -- ChatCompletion -- ChatCompletionAssistantMessageParam -- ChatCompletionAudio -- ChatCompletionAudioParam -- ChatCompletionChunk -- ChatCompletionContentPart -- ChatCompletionContentPartImage -- ChatCompletionContentPartInputAudio -- ChatCompletionContentPartRefusal -- ChatCompletionContentPartText -- ChatCompletionDeveloperMessageParam -- ChatCompletionFunctionCallOption -- ChatCompletionFunctionMessageParam -- ChatCompletionMessage -- ChatCompletionMessageParam -- ChatCompletionMessageToolCall -- ChatCompletionModality -- ChatCompletionNamedToolChoice -- ChatCompletionPredictionContent -- ChatCompletionReasoningEffort -- ChatCompletionRole -- ChatCompletionStreamOptions -- ChatCompletionSystemMessageParam -- ChatCompletionTokenLogprob -- ChatCompletionTool -- ChatCompletionToolChoiceOption -- ChatCompletionToolMessageParam -- ChatCompletionUserMessageParam -- CreateChatCompletionRequestMessage +- ChatCompletion +- ChatCompletionAssistantMessageParam +- ChatCompletionAudio +- ChatCompletionAudioParam +- ChatCompletionChunk +- ChatCompletionContentPart +- ChatCompletionContentPartImage +- ChatCompletionContentPartInputAudio +- ChatCompletionContentPartRefusal +- ChatCompletionContentPartText +- ChatCompletionDeleted +- ChatCompletionDeveloperMessageParam +- ChatCompletionFunctionCallOption +- ChatCompletionFunctionMessageParam +- ChatCompletionMessage +- ChatCompletionMessageParam +- ChatCompletionMessageToolCall +- ChatCompletionModality +- ChatCompletionNamedToolChoice +- ChatCompletionPredictionContent +- ChatCompletionReasoningEffort +- ChatCompletionRole +- ChatCompletionStoreMessage +- ChatCompletionStreamOptions +- ChatCompletionSystemMessageParam +- ChatCompletionTokenLogprob +- ChatCompletionTool +- ChatCompletionToolChoiceOption +- ChatCompletionToolMessageParam +- ChatCompletionUserMessageParam +- CreateChatCompletionRequestMessage Methods: -- client.chat.completions.create({ ...params }) -> ChatCompletion +- client.chat.completions.create({ ...params }) -> ChatCompletion +- client.chat.completions.retrieve(completionId) -> ChatCompletion +- client.chat.completions.update(completionId, { ...params }) -> ChatCompletion +- client.chat.completions.list({ ...params }) -> ChatCompletionsPage +- client.chat.completions.del(completionId) -> ChatCompletionDeleted + +### Messages + +Methods: + +- client.chat.completions.messages.list(completionId, { ...params }) -> ChatCompletionStoreMessagesPage # Embeddings diff --git a/src/index.ts b/src/index.ts index f4e940af8..debefce8c 100644 --- a/src/index.ts +++ b/src/index.ts @@ -66,6 +66,13 @@ import { import { Audio, AudioModel, AudioResponseFormat } from './resources/audio/audio'; import { Beta } from './resources/beta/beta'; import { Chat, ChatModel } from './resources/chat/chat'; +import { FineTuning } from './resources/fine-tuning/fine-tuning'; +import { + Upload, + UploadCompleteParams, + UploadCreateParams, + Uploads as UploadsAPIUploads, +} from './resources/uploads/uploads'; import { ChatCompletion, ChatCompletionAssistantMessageParam, @@ -80,9 +87,11 @@ import { ChatCompletionCreateParams, ChatCompletionCreateParamsNonStreaming, ChatCompletionCreateParamsStreaming, + ChatCompletionDeleted, ChatCompletionDeveloperMessageParam, ChatCompletionFunctionCallOption, ChatCompletionFunctionMessageParam, + ChatCompletionListParams, ChatCompletionMessage, ChatCompletionMessageParam, ChatCompletionMessageToolCall, @@ -91,21 +100,17 @@ import { ChatCompletionPredictionContent, ChatCompletionReasoningEffort, ChatCompletionRole, + ChatCompletionStoreMessage, ChatCompletionStreamOptions, ChatCompletionSystemMessageParam, ChatCompletionTokenLogprob, ChatCompletionTool, ChatCompletionToolChoiceOption, ChatCompletionToolMessageParam, + ChatCompletionUpdateParams, ChatCompletionUserMessageParam, -} from './resources/chat/completions'; -import { FineTuning } from './resources/fine-tuning/fine-tuning'; -import { - Upload, - UploadCompleteParams, - UploadCreateParams, - Uploads as UploadsAPIUploads, -} from './resources/uploads/uploads'; + ChatCompletionsPage, +} from './resources/chat/completions/completions'; export interface ClientOptions { /** @@ -310,6 +315,7 @@ export class OpenAI extends Core.APIClient { OpenAI.Completions = Completions; OpenAI.Chat = Chat; +OpenAI.ChatCompletionsPage = ChatCompletionsPage; OpenAI.Embeddings = Embeddings; OpenAI.Files = Files; OpenAI.FileObjectsPage = FileObjectsPage; @@ -355,6 +361,7 @@ export declare namespace OpenAI { type ChatCompletionContentPartInputAudio as ChatCompletionContentPartInputAudio, type ChatCompletionContentPartRefusal as ChatCompletionContentPartRefusal, type ChatCompletionContentPartText as ChatCompletionContentPartText, + type ChatCompletionDeleted as ChatCompletionDeleted, type ChatCompletionDeveloperMessageParam as ChatCompletionDeveloperMessageParam, type ChatCompletionFunctionCallOption as ChatCompletionFunctionCallOption, type ChatCompletionFunctionMessageParam as ChatCompletionFunctionMessageParam, @@ -366,6 +373,7 @@ export declare namespace OpenAI { type ChatCompletionPredictionContent as ChatCompletionPredictionContent, type ChatCompletionReasoningEffort as ChatCompletionReasoningEffort, type ChatCompletionRole as ChatCompletionRole, + type ChatCompletionStoreMessage as ChatCompletionStoreMessage, type ChatCompletionStreamOptions as ChatCompletionStreamOptions, type ChatCompletionSystemMessageParam as ChatCompletionSystemMessageParam, type ChatCompletionTokenLogprob as ChatCompletionTokenLogprob, @@ -373,9 +381,12 @@ export declare namespace OpenAI { type ChatCompletionToolChoiceOption as ChatCompletionToolChoiceOption, type ChatCompletionToolMessageParam as ChatCompletionToolMessageParam, type ChatCompletionUserMessageParam as ChatCompletionUserMessageParam, + ChatCompletionsPage as ChatCompletionsPage, type ChatCompletionCreateParams as ChatCompletionCreateParams, type ChatCompletionCreateParamsNonStreaming as ChatCompletionCreateParamsNonStreaming, type ChatCompletionCreateParamsStreaming as ChatCompletionCreateParamsStreaming, + type ChatCompletionUpdateParams as ChatCompletionUpdateParams, + type ChatCompletionListParams as ChatCompletionListParams, }; export { diff --git a/src/lib/ChatCompletionStream.ts b/src/lib/ChatCompletionStream.ts index 6c846f70b..35648c27b 100644 --- a/src/lib/ChatCompletionStream.ts +++ b/src/lib/ChatCompletionStream.ts @@ -13,7 +13,7 @@ import { type ChatCompletionCreateParamsStreaming, type ChatCompletionCreateParamsBase, type ChatCompletionRole, -} from '../resources/chat/completions'; +} from '../resources/chat/completions/completions'; import { AbstractChatCompletionRunner, type AbstractChatCompletionRunnerEvents, diff --git a/src/resources/chat/chat.ts b/src/resources/chat/chat.ts index d4a18929c..5bceec45a 100644 --- a/src/resources/chat/chat.ts +++ b/src/resources/chat/chat.ts @@ -1,7 +1,7 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. import { APIResource } from '../../resource'; -import * as CompletionsAPI from './completions'; +import * as CompletionsAPI from './completions/completions'; import { ChatCompletion, ChatCompletionAssistantMessageParam, @@ -16,9 +16,11 @@ import { ChatCompletionCreateParams, ChatCompletionCreateParamsNonStreaming, ChatCompletionCreateParamsStreaming, + ChatCompletionDeleted, ChatCompletionDeveloperMessageParam, ChatCompletionFunctionCallOption, ChatCompletionFunctionMessageParam, + ChatCompletionListParams, ChatCompletionMessage, ChatCompletionMessageParam, ChatCompletionMessageToolCall, @@ -27,19 +29,24 @@ import { ChatCompletionPredictionContent, ChatCompletionReasoningEffort, ChatCompletionRole, + ChatCompletionStoreMessage, ChatCompletionStreamOptions, ChatCompletionSystemMessageParam, ChatCompletionTokenLogprob, ChatCompletionTool, ChatCompletionToolChoiceOption, ChatCompletionToolMessageParam, + ChatCompletionUpdateParams, ChatCompletionUserMessageParam, + ChatCompletionsPage, CompletionCreateParams, CompletionCreateParamsNonStreaming, CompletionCreateParamsStreaming, + CompletionListParams, + CompletionUpdateParams, Completions, CreateChatCompletionRequestMessage, -} from './completions'; +} from './completions/completions'; export class Chat extends APIResource { completions: CompletionsAPI.Completions = new CompletionsAPI.Completions(this._client); @@ -87,6 +94,7 @@ export type ChatModel = | 'gpt-3.5-turbo-16k-0613'; Chat.Completions = Completions; +Chat.ChatCompletionsPage = ChatCompletionsPage; export declare namespace Chat { export { type ChatModel as ChatModel }; @@ -103,6 +111,7 @@ export declare namespace Chat { type ChatCompletionContentPartInputAudio as ChatCompletionContentPartInputAudio, type ChatCompletionContentPartRefusal as ChatCompletionContentPartRefusal, type ChatCompletionContentPartText as ChatCompletionContentPartText, + type ChatCompletionDeleted as ChatCompletionDeleted, type ChatCompletionDeveloperMessageParam as ChatCompletionDeveloperMessageParam, type ChatCompletionFunctionCallOption as ChatCompletionFunctionCallOption, type ChatCompletionFunctionMessageParam as ChatCompletionFunctionMessageParam, @@ -114,6 +123,7 @@ export declare namespace Chat { type ChatCompletionPredictionContent as ChatCompletionPredictionContent, type ChatCompletionReasoningEffort as ChatCompletionReasoningEffort, type ChatCompletionRole as ChatCompletionRole, + type ChatCompletionStoreMessage as ChatCompletionStoreMessage, type ChatCompletionStreamOptions as ChatCompletionStreamOptions, type ChatCompletionSystemMessageParam as ChatCompletionSystemMessageParam, type ChatCompletionTokenLogprob as ChatCompletionTokenLogprob, @@ -122,11 +132,16 @@ export declare namespace Chat { type ChatCompletionToolMessageParam as ChatCompletionToolMessageParam, type ChatCompletionUserMessageParam as ChatCompletionUserMessageParam, type CreateChatCompletionRequestMessage as CreateChatCompletionRequestMessage, + ChatCompletionsPage as ChatCompletionsPage, type ChatCompletionCreateParams as ChatCompletionCreateParams, type CompletionCreateParams as CompletionCreateParams, type ChatCompletionCreateParamsNonStreaming as ChatCompletionCreateParamsNonStreaming, type CompletionCreateParamsNonStreaming as CompletionCreateParamsNonStreaming, type ChatCompletionCreateParamsStreaming as ChatCompletionCreateParamsStreaming, type CompletionCreateParamsStreaming as CompletionCreateParamsStreaming, + type ChatCompletionUpdateParams as ChatCompletionUpdateParams, + type CompletionUpdateParams as CompletionUpdateParams, + type ChatCompletionListParams as ChatCompletionListParams, + type CompletionListParams as CompletionListParams, }; } diff --git a/src/resources/chat/completions.ts b/src/resources/chat/completions/completions.ts similarity index 88% rename from src/resources/chat/completions.ts rename to src/resources/chat/completions/completions.ts index 2586845c3..3af4a3a1d 100644 --- a/src/resources/chat/completions.ts +++ b/src/resources/chat/completions/completions.ts @@ -1,15 +1,21 @@ // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. -import { APIResource } from '../../resource'; -import { APIPromise } from '../../core'; -import * as Core from '../../core'; -import * as ChatCompletionsAPI from './completions'; -import * as CompletionsAPI from '../completions'; -import * as Shared from '../shared'; -import * as ChatAPI from './chat'; -import { Stream } from '../../streaming'; +import { APIResource } from '../../../resource'; +import { isRequestOptions } from '../../../core'; +import { APIPromise } from '../../../core'; +import * as Core from '../../../core'; +import * as CompletionsCompletionsAPI from './completions'; +import * as CompletionsAPI from '../../completions'; +import * as Shared from '../../shared'; +import * as ChatAPI from '../chat'; +import * as MessagesAPI from './messages'; +import { MessageListParams, Messages } from './messages'; +import { CursorPage, type CursorPageParams } from '../../../pagination'; +import { Stream } from '../../../streaming'; export class Completions extends APIResource { + messages: MessagesAPI.Messages = new MessagesAPI.Messages(this._client); + /** * Creates a model response for the given chat conversation. Learn more in the * [text generation](https://platform.openai.com/docs/guides/text-generation), @@ -42,8 +48,60 @@ export class Completions extends APIResource { | APIPromise | APIPromise>; } + + /** + * Get a stored chat completion. Only chat completions that have been created with + * the `store` parameter set to `true` will be returned. + */ + retrieve(completionId: string, options?: Core.RequestOptions): Core.APIPromise { + return this._client.get(`/chat/completions/${completionId}`, options); + } + + /** + * Modify a stored chat completion. Only chat completions that have been created + * with the `store` parameter set to `true` can be modified. Currently, the only + * supported modification is to update the `metadata` field. + */ + update( + completionId: string, + body: ChatCompletionUpdateParams, + options?: Core.RequestOptions, + ): Core.APIPromise { + return this._client.post(`/chat/completions/${completionId}`, { body, ...options }); + } + + /** + * List stored chat completions. Only chat completions that have been stored with + * the `store` parameter set to `true` will be returned. + */ + list( + query?: ChatCompletionListParams, + options?: Core.RequestOptions, + ): Core.PagePromise; + list(options?: Core.RequestOptions): Core.PagePromise; + list( + query: ChatCompletionListParams | Core.RequestOptions = {}, + options?: Core.RequestOptions, + ): Core.PagePromise { + if (isRequestOptions(query)) { + return this.list({}, query); + } + return this._client.getAPIList('/chat/completions', ChatCompletionsPage, { query, ...options }); + } + + /** + * Delete a stored chat completion. Only chat completions that have been created + * with the `store` parameter set to `true` can be deleted. + */ + del(completionId: string, options?: Core.RequestOptions): Core.APIPromise { + return this._client.delete(`/chat/completions/${completionId}`, options); + } } +export class ChatCompletionsPage extends CursorPage {} + +export class ChatCompletionStoreMessagesPage extends CursorPage {} + /** * Represents a chat completion response returned by model, based on the provided * input. @@ -119,7 +177,7 @@ export namespace ChatCompletion { /** * A chat completion message generated by the model. */ - message: ChatCompletionsAPI.ChatCompletionMessage; + message: CompletionsCompletionsAPI.ChatCompletionMessage; } export namespace Choice { @@ -130,12 +188,12 @@ export namespace ChatCompletion { /** * A list of message content tokens with log probability information. */ - content: Array | null; + content: Array | null; /** * A list of message refusal tokens with log probability information. */ - refusal: Array | null; + refusal: Array | null; } } } @@ -437,12 +495,12 @@ export namespace ChatCompletionChunk { /** * A list of message content tokens with log probability information. */ - content: Array | null; + content: Array | null; /** * A list of message refusal tokens with log probability information. */ - refusal: Array | null; + refusal: Array | null; } } } @@ -537,6 +595,23 @@ export interface ChatCompletionContentPartText { type: 'text'; } +export interface ChatCompletionDeleted { + /** + * The ID of the chat completion that was deleted. + */ + id: string; + + /** + * Whether the chat completion was deleted. + */ + deleted: boolean; + + /** + * The type of object being deleted. + */ + object: 'chat.completion.deleted'; +} + /** * Developer-provided instructions that the model should follow, regardless of * messages sent by the user. With o1 models and newer, `developer` messages @@ -758,6 +833,16 @@ export type ChatCompletionReasoningEffort = 'low' | 'medium' | 'high' | null; */ export type ChatCompletionRole = 'developer' | 'system' | 'user' | 'assistant' | 'tool' | 'function'; +/** + * A chat completion message generated by the model. + */ +export interface ChatCompletionStoreMessage extends ChatCompletionMessage { + /** + * The identifier of the chat message. + */ + id: string; +} + /** * Options for streaming response. Only set this when you set `stream: true`. */ @@ -1229,8 +1314,9 @@ export namespace ChatCompletionCreateParams { } export type ChatCompletionCreateParamsNonStreaming = - ChatCompletionsAPI.ChatCompletionCreateParamsNonStreaming; - export type ChatCompletionCreateParamsStreaming = ChatCompletionsAPI.ChatCompletionCreateParamsStreaming; + CompletionsCompletionsAPI.ChatCompletionCreateParamsNonStreaming; + export type ChatCompletionCreateParamsStreaming = + CompletionsCompletionsAPI.ChatCompletionCreateParamsStreaming; } /** @@ -1272,6 +1358,51 @@ export interface ChatCompletionCreateParamsStreaming extends ChatCompletionCreat */ export type CompletionCreateParamsStreaming = ChatCompletionCreateParamsStreaming; +export interface ChatCompletionUpdateParams { + /** + * Set of 16 key-value pairs that can be attached to an object. This can be useful + * for storing additional information about the object in a structured format, and + * querying for objects via API or the dashboard. + * + * Keys are strings with a maximum length of 64 characters. Values are strings with + * a maximum length of 512 characters. + */ + metadata: Shared.Metadata | null; +} + +/** + * @deprecated Use ChatCompletionUpdateParams instead + */ +export type CompletionUpdateParams = ChatCompletionUpdateParams; + +export interface ChatCompletionListParams extends CursorPageParams { + /** + * A list of metadata keys to filter the chat completions by. Example: + * + * `metadata[key1]=value1&metadata[key2]=value2` + */ + metadata?: Shared.Metadata | null; + + /** + * The model used to generate the chat completions. + */ + model?: string; + + /** + * Sort order for chat completions by timestamp. Use `asc` for ascending order or + * `desc` for descending order. Defaults to `asc`. + */ + order?: 'asc' | 'desc'; +} + +/** + * @deprecated Use ChatCompletionListParams instead + */ +export type CompletionListParams = ChatCompletionListParams; + +Completions.ChatCompletionsPage = ChatCompletionsPage; +Completions.Messages = Messages; + export declare namespace Completions { export { type ChatCompletion as ChatCompletion, @@ -1284,6 +1415,7 @@ export declare namespace Completions { type ChatCompletionContentPartInputAudio as ChatCompletionContentPartInputAudio, type ChatCompletionContentPartRefusal as ChatCompletionContentPartRefusal, type ChatCompletionContentPartText as ChatCompletionContentPartText, + type ChatCompletionDeleted as ChatCompletionDeleted, type ChatCompletionDeveloperMessageParam as ChatCompletionDeveloperMessageParam, type ChatCompletionFunctionCallOption as ChatCompletionFunctionCallOption, type ChatCompletionFunctionMessageParam as ChatCompletionFunctionMessageParam, @@ -1295,6 +1427,7 @@ export declare namespace Completions { type ChatCompletionPredictionContent as ChatCompletionPredictionContent, type ChatCompletionReasoningEffort as ChatCompletionReasoningEffort, type ChatCompletionRole as ChatCompletionRole, + type ChatCompletionStoreMessage as ChatCompletionStoreMessage, type ChatCompletionStreamOptions as ChatCompletionStreamOptions, type ChatCompletionSystemMessageParam as ChatCompletionSystemMessageParam, type ChatCompletionTokenLogprob as ChatCompletionTokenLogprob, @@ -1303,11 +1436,18 @@ export declare namespace Completions { type ChatCompletionToolMessageParam as ChatCompletionToolMessageParam, type ChatCompletionUserMessageParam as ChatCompletionUserMessageParam, type CreateChatCompletionRequestMessage as CreateChatCompletionRequestMessage, + ChatCompletionsPage as ChatCompletionsPage, type ChatCompletionCreateParams as ChatCompletionCreateParams, type CompletionCreateParams as CompletionCreateParams, type ChatCompletionCreateParamsNonStreaming as ChatCompletionCreateParamsNonStreaming, type CompletionCreateParamsNonStreaming as CompletionCreateParamsNonStreaming, type ChatCompletionCreateParamsStreaming as ChatCompletionCreateParamsStreaming, type CompletionCreateParamsStreaming as CompletionCreateParamsStreaming, + type ChatCompletionUpdateParams as ChatCompletionUpdateParams, + type CompletionUpdateParams as CompletionUpdateParams, + type ChatCompletionListParams as ChatCompletionListParams, + type CompletionListParams as CompletionListParams, }; + + export { Messages as Messages, type MessageListParams as MessageListParams }; } diff --git a/src/resources/chat/completions/index.ts b/src/resources/chat/completions/index.ts new file mode 100644 index 000000000..3691f41d8 --- /dev/null +++ b/src/resources/chat/completions/index.ts @@ -0,0 +1,49 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +export { + ChatCompletionStoreMessagesPage, + ChatCompletionsPage, + Completions, + type ChatCompletion, + type ChatCompletionAssistantMessageParam, + type ChatCompletionAudio, + type ChatCompletionAudioParam, + type ChatCompletionChunk, + type ChatCompletionContentPart, + type ChatCompletionContentPartImage, + type ChatCompletionContentPartInputAudio, + type ChatCompletionContentPartRefusal, + type ChatCompletionContentPartText, + type ChatCompletionDeleted, + type ChatCompletionDeveloperMessageParam, + type ChatCompletionFunctionCallOption, + type ChatCompletionFunctionMessageParam, + type ChatCompletionMessage, + type ChatCompletionMessageParam, + type ChatCompletionMessageToolCall, + type ChatCompletionModality, + type ChatCompletionNamedToolChoice, + type ChatCompletionPredictionContent, + type ChatCompletionReasoningEffort, + type ChatCompletionRole, + type ChatCompletionStoreMessage, + type ChatCompletionStreamOptions, + type ChatCompletionSystemMessageParam, + type ChatCompletionTokenLogprob, + type ChatCompletionTool, + type ChatCompletionToolChoiceOption, + type ChatCompletionToolMessageParam, + type ChatCompletionUserMessageParam, + type CreateChatCompletionRequestMessage, + type ChatCompletionCreateParams, + type CompletionCreateParams, + type ChatCompletionCreateParamsNonStreaming, + type CompletionCreateParamsNonStreaming, + type ChatCompletionCreateParamsStreaming, + type CompletionCreateParamsStreaming, + type ChatCompletionUpdateParams, + type CompletionUpdateParams, + type ChatCompletionListParams, + type CompletionListParams, +} from './completions'; +export { Messages, type MessageListParams } from './messages'; diff --git a/src/resources/chat/completions/messages.ts b/src/resources/chat/completions/messages.ts new file mode 100644 index 000000000..fc1cc5d94 --- /dev/null +++ b/src/resources/chat/completions/messages.ts @@ -0,0 +1,52 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../../../resource'; +import { isRequestOptions } from '../../../core'; +import * as Core from '../../../core'; +import * as CompletionsAPI from './completions'; +import { ChatCompletionStoreMessagesPage } from './completions'; +import { type CursorPageParams } from '../../../pagination'; + +export class Messages extends APIResource { + /** + * Get the messages in a stored chat completion. Only chat completions that have + * been created with the `store` parameter set to `true` will be returned. + */ + list( + completionId: string, + query?: MessageListParams, + options?: Core.RequestOptions, + ): Core.PagePromise; + list( + completionId: string, + options?: Core.RequestOptions, + ): Core.PagePromise; + list( + completionId: string, + query: MessageListParams | Core.RequestOptions = {}, + options?: Core.RequestOptions, + ): Core.PagePromise { + if (isRequestOptions(query)) { + return this.list(completionId, {}, query); + } + return this._client.getAPIList( + `/chat/completions/${completionId}/messages`, + ChatCompletionStoreMessagesPage, + { query, ...options }, + ); + } +} + +export interface MessageListParams extends CursorPageParams { + /** + * Sort order for messages by timestamp. Use `asc` for ascending order or `desc` + * for descending order. Defaults to `asc`. + */ + order?: 'asc' | 'desc'; +} + +export declare namespace Messages { + export { type MessageListParams as MessageListParams }; +} + +export { ChatCompletionStoreMessagesPage }; diff --git a/src/resources/chat/index.ts b/src/resources/chat/index.ts index c3be19402..a9b5b46fb 100644 --- a/src/resources/chat/index.ts +++ b/src/resources/chat/index.ts @@ -2,6 +2,8 @@ export { Chat, type ChatModel } from './chat'; export { + ChatCompletionStoreMessagesPage, + ChatCompletionsPage, Completions, type ChatCompletion, type ChatCompletionAssistantMessageParam, @@ -13,6 +15,7 @@ export { type ChatCompletionContentPartInputAudio, type ChatCompletionContentPartRefusal, type ChatCompletionContentPartText, + type ChatCompletionDeleted, type ChatCompletionDeveloperMessageParam, type ChatCompletionFunctionCallOption, type ChatCompletionFunctionMessageParam, @@ -24,6 +27,7 @@ export { type ChatCompletionPredictionContent, type ChatCompletionReasoningEffort, type ChatCompletionRole, + type ChatCompletionStoreMessage, type ChatCompletionStreamOptions, type ChatCompletionSystemMessageParam, type ChatCompletionTokenLogprob, @@ -38,4 +42,8 @@ export { type CompletionCreateParamsNonStreaming, type ChatCompletionCreateParamsStreaming, type CompletionCreateParamsStreaming, -} from './completions'; + type ChatCompletionUpdateParams, + type CompletionUpdateParams, + type ChatCompletionListParams, + type CompletionListParams, +} from './completions/index'; diff --git a/src/resources/completions.ts b/src/resources/completions.ts index be75a46f0..664e39d9d 100644 --- a/src/resources/completions.ts +++ b/src/resources/completions.ts @@ -4,7 +4,7 @@ import { APIResource } from '../resource'; import { APIPromise } from '../core'; import * as Core from '../core'; import * as CompletionsAPI from './completions'; -import * as ChatCompletionsAPI from './chat/completions'; +import * as CompletionsCompletionsAPI from './chat/completions/completions'; import { Stream } from '../streaming'; export class Completions extends APIResource { @@ -311,7 +311,7 @@ export interface CompletionCreateParamsBase { /** * Options for streaming response. Only set this when you set `stream: true`. */ - stream_options?: ChatCompletionsAPI.ChatCompletionStreamOptions | null; + stream_options?: CompletionsCompletionsAPI.ChatCompletionStreamOptions | null; /** * The suffix that comes after a completion of inserted text. diff --git a/src/resources/moderations.ts b/src/resources/moderations.ts index f7b16166d..86e90376d 100644 --- a/src/resources/moderations.ts +++ b/src/resources/moderations.ts @@ -75,14 +75,14 @@ export namespace Moderation { * execution of wrongdoing, or that gives advice or instruction on how to commit * illicit acts. For example, "how to shoplift" would fit this category. */ - illicit: boolean; + illicit: boolean | null; /** * Content that includes instructions or advice that facilitate the planning or * execution of wrongdoing that also includes violence, or that gives advice or * instruction on the procurement of any weapon. */ - 'illicit/violent': boolean; + 'illicit/violent': boolean | null; /** * Content that promotes, encourages, or depicts acts of self-harm, such as diff --git a/tests/api-resources/chat/completions.test.ts b/tests/api-resources/chat/completions.test.ts deleted file mode 100644 index 8f1bc7d4c..000000000 --- a/tests/api-resources/chat/completions.test.ts +++ /dev/null @@ -1,65 +0,0 @@ -// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. - -import OpenAI from 'openai'; -import { Response } from 'node-fetch'; - -const client = new OpenAI({ - apiKey: 'My API Key', - baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', -}); - -describe('resource completions', () => { - test('create: only required params', async () => { - const responsePromise = client.chat.completions.create({ - messages: [{ content: 'string', role: 'developer' }], - model: 'gpt-4o', - }); - const rawResponse = await responsePromise.asResponse(); - expect(rawResponse).toBeInstanceOf(Response); - const response = await responsePromise; - expect(response).not.toBeInstanceOf(Response); - const dataAndResponse = await responsePromise.withResponse(); - expect(dataAndResponse.data).toBe(response); - expect(dataAndResponse.response).toBe(rawResponse); - }); - - test('create: required and optional params', async () => { - const response = await client.chat.completions.create({ - messages: [{ content: 'string', role: 'developer', name: 'name' }], - model: 'gpt-4o', - audio: { format: 'wav', voice: 'alloy' }, - frequency_penalty: -2, - function_call: 'none', - functions: [{ name: 'name', description: 'description', parameters: { foo: 'bar' } }], - logit_bias: { foo: 0 }, - logprobs: true, - max_completion_tokens: 0, - max_tokens: 0, - metadata: { foo: 'string' }, - modalities: ['text'], - n: 1, - parallel_tool_calls: true, - prediction: { content: 'string', type: 'content' }, - presence_penalty: -2, - reasoning_effort: 'low', - response_format: { type: 'text' }, - seed: 0, - service_tier: 'auto', - stop: 'string', - store: true, - stream: false, - stream_options: { include_usage: true }, - temperature: 1, - tool_choice: 'none', - tools: [ - { - function: { name: 'name', description: 'description', parameters: { foo: 'bar' }, strict: true }, - type: 'function', - }, - ], - top_logprobs: 0, - top_p: 1, - user: 'user-1234', - }); - }); -}); diff --git a/tests/api-resources/chat/completions/completions.test.ts b/tests/api-resources/chat/completions/completions.test.ts new file mode 100644 index 000000000..acdd631db --- /dev/null +++ b/tests/api-resources/chat/completions/completions.test.ts @@ -0,0 +1,144 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import OpenAI from 'openai'; +import { Response } from 'node-fetch'; + +const client = new OpenAI({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource completions', () => { + test('create: only required params', async () => { + const responsePromise = client.chat.completions.create({ + messages: [{ content: 'string', role: 'developer' }], + model: 'gpt-4o', + }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('create: required and optional params', async () => { + const response = await client.chat.completions.create({ + messages: [{ content: 'string', role: 'developer', name: 'name' }], + model: 'gpt-4o', + audio: { format: 'wav', voice: 'alloy' }, + frequency_penalty: -2, + function_call: 'none', + functions: [{ name: 'name', description: 'description', parameters: { foo: 'bar' } }], + logit_bias: { foo: 0 }, + logprobs: true, + max_completion_tokens: 0, + max_tokens: 0, + metadata: { foo: 'string' }, + modalities: ['text'], + n: 1, + parallel_tool_calls: true, + prediction: { content: 'string', type: 'content' }, + presence_penalty: -2, + reasoning_effort: 'low', + response_format: { type: 'text' }, + seed: 0, + service_tier: 'auto', + stop: 'string', + store: true, + stream: false, + stream_options: { include_usage: true }, + temperature: 1, + tool_choice: 'none', + tools: [ + { + function: { name: 'name', description: 'description', parameters: { foo: 'bar' }, strict: true }, + type: 'function', + }, + ], + top_logprobs: 0, + top_p: 1, + user: 'user-1234', + }); + }); + + test('retrieve', async () => { + const responsePromise = client.chat.completions.retrieve('completion_id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('retrieve: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.chat.completions.retrieve('completion_id', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(OpenAI.NotFoundError); + }); + + test('update: only required params', async () => { + const responsePromise = client.chat.completions.update('completion_id', { metadata: { foo: 'string' } }); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('update: required and optional params', async () => { + const response = await client.chat.completions.update('completion_id', { metadata: { foo: 'string' } }); + }); + + test('list', async () => { + const responsePromise = client.chat.completions.list(); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('list: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect(client.chat.completions.list({ path: '/_stainless_unknown_path' })).rejects.toThrow( + OpenAI.NotFoundError, + ); + }); + + test('list: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.chat.completions.list( + { after: 'after', limit: 0, metadata: { foo: 'string' }, model: 'model', order: 'asc' }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(OpenAI.NotFoundError); + }); + + test('del', async () => { + const responsePromise = client.chat.completions.del('completion_id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('del: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.chat.completions.del('completion_id', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(OpenAI.NotFoundError); + }); +}); diff --git a/tests/api-resources/chat/completions/messages.test.ts b/tests/api-resources/chat/completions/messages.test.ts new file mode 100644 index 000000000..664106cb9 --- /dev/null +++ b/tests/api-resources/chat/completions/messages.test.ts @@ -0,0 +1,40 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import OpenAI from 'openai'; +import { Response } from 'node-fetch'; + +const client = new OpenAI({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource messages', () => { + test('list', async () => { + const responsePromise = client.chat.completions.messages.list('completion_id'); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + test('list: request options instead of params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.chat.completions.messages.list('completion_id', { path: '/_stainless_unknown_path' }), + ).rejects.toThrow(OpenAI.NotFoundError); + }); + + test('list: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.chat.completions.messages.list( + 'completion_id', + { after: 'after', limit: 0, order: 'asc' }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(OpenAI.NotFoundError); + }); +}); From d9af85d58f2c915290e7220fab65b4d30e78e454 Mon Sep 17 00:00:00 2001 From: "stainless-app[bot]" <142633134+stainless-app[bot]@users.noreply.github.com> Date: Thu, 13 Feb 2025 19:53:06 +0000 Subject: [PATCH 3/3] release: 4.85.0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 13 +++++++++++++ jsr.json | 2 +- package.json | 2 +- src/version.ts | 2 +- 5 files changed, 17 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 023314f41..f48cc7f57 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "4.84.1" + ".": "4.85.0" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 444430307..290b2414d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 4.85.0 (2025-02-13) + +Full Changelog: [v4.84.1...v4.85.0](https://github.com/openai/openai-node/compare/v4.84.1...v4.85.0) + +### Features + +* **api:** add support for storing chat completions ([#1327](https://github.com/openai/openai-node/issues/1327)) ([8d77f8e](https://github.com/openai/openai-node/commit/8d77f8e3c4801b7fa1e7c6f50b48c1de1f43f3e6)) + + +### Bug Fixes + +* **realtime:** call .toString() on WebSocket url ([#1324](https://github.com/openai/openai-node/issues/1324)) ([09bc50d](https://github.com/openai/openai-node/commit/09bc50d439679b6acfd2441e69ee5aa18c00e5d9)) + ## 4.84.1 (2025-02-13) Full Changelog: [v4.84.0...v4.84.1](https://github.com/openai/openai-node/compare/v4.84.0...v4.84.1) diff --git a/jsr.json b/jsr.json index 3148d6fca..368f86c0b 100644 --- a/jsr.json +++ b/jsr.json @@ -1,6 +1,6 @@ { "name": "@openai/openai", - "version": "4.84.1", + "version": "4.85.0", "exports": { ".": "./index.ts", "./helpers/zod": "./helpers/zod.ts", diff --git a/package.json b/package.json index 4686e3a97..dc61af02c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openai", - "version": "4.84.1", + "version": "4.85.0", "description": "The official TypeScript library for the OpenAI API", "author": "OpenAI ", "types": "dist/index.d.ts", diff --git a/src/version.ts b/src/version.ts index 767424b0e..6483fa72b 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '4.84.1'; // x-release-please-version +export const VERSION = '4.85.0'; // x-release-please-version