diff --git a/.stats.yml b/.stats.yml index f21eb8fef0..03b0268ffa 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1 +1 @@ -configured_endpoints: 28 +configured_endpoints: 57 diff --git a/api.md b/api.md index 915a05479a..818ae73b31 100644 --- a/api.md +++ b/api.md @@ -19,10 +19,23 @@ Types: ```python from openai.types.chat import ( ChatCompletion, + ChatCompletionAssistantMessageParam, ChatCompletionChunk, + ChatCompletionContentPart, + ChatCompletionContentPartImage, + ChatCompletionContentPartText, + ChatCompletionFunctionCallOption, + ChatCompletionFunctionMessageParam, ChatCompletionMessage, ChatCompletionMessageParam, + ChatCompletionMessageToolCall, + ChatCompletionNamedToolChoice, ChatCompletionRole, + ChatCompletionSystemMessageParam, + ChatCompletionTool, + ChatCompletionToolChoiceOption, + ChatCompletionToolMessageParam, + ChatCompletionUserMessageParam, ) ``` @@ -66,7 +79,7 @@ Methods: - client.files.create(\*\*params) -> FileObject - client.files.retrieve(file_id) -> FileObject -- client.files.list() -> SyncPage[FileObject] +- client.files.list(\*\*params) -> SyncPage[FileObject] - client.files.delete(file_id) -> FileDeleted - client.files.retrieve_content(file_id) -> str - client.files.wait_for_processing(\*args) -> FileObject @@ -111,6 +124,12 @@ Methods: - client.audio.translations.create(\*\*params) -> Translation +## Speech + +Methods: + +- client.audio.speech.create(\*\*params) -> HttpxBinaryResponseContent + # Moderations Types: @@ -170,3 +189,122 @@ Methods: - client.fine_tunes.list() -> SyncPage[FineTune] - client.fine_tunes.cancel(fine_tune_id) -> FineTune - client.fine_tunes.list_events(fine_tune_id, \*\*params) -> FineTuneEventsListResponse + +# Beta + +## Assistants + +Types: + +```python +from openai.types.beta import Assistant, AsssitantDeleted +``` + +Methods: + +- client.beta.assistants.create(\*\*params) -> Assistant +- client.beta.assistants.retrieve(assistant_id) -> Assistant +- client.beta.assistants.update(assistant_id, \*\*params) -> Assistant +- client.beta.assistants.list(\*\*params) -> SyncCursorPage[Assistant] +- client.beta.assistants.delete(assistant_id) -> AsssitantDeleted + +### Files + +Types: + +```python +from openai.types.beta.assistants import AssistantFile, FileDeleteResponse +``` + +Methods: + +- client.beta.assistants.files.create(assistant_id, \*\*params) -> AssistantFile +- client.beta.assistants.files.retrieve(file_id, \*, assistant_id) -> AssistantFile +- client.beta.assistants.files.list(assistant_id, \*\*params) -> SyncCursorPage[AssistantFile] +- client.beta.assistants.files.delete(file_id, \*, assistant_id) -> FileDeleteResponse + +## Threads + +Types: + +```python +from openai.types.beta import Thread, ThreadDeleted +``` + +Methods: + +- client.beta.threads.create(\*\*params) -> Thread +- client.beta.threads.retrieve(thread_id) -> Thread +- client.beta.threads.update(thread_id, \*\*params) -> Thread +- client.beta.threads.delete(thread_id) -> ThreadDeleted +- client.beta.threads.create_and_run(\*\*params) -> Run + +### Runs + +Types: + +```python +from openai.types.beta.threads import RequiredActionFunctionToolCall, Run +``` + +Methods: + +- client.beta.threads.runs.create(thread_id, \*\*params) -> Run +- client.beta.threads.runs.retrieve(run_id, \*, thread_id) -> Run +- client.beta.threads.runs.update(run_id, \*, thread_id, \*\*params) -> Run +- client.beta.threads.runs.list(thread_id, \*\*params) -> SyncCursorPage[Run] +- client.beta.threads.runs.cancel(run_id, \*, thread_id) -> Run +- client.beta.threads.runs.submit_tool_outputs(run_id, \*, thread_id, \*\*params) -> Run + +#### Steps + +Types: + +```python +from openai.types.beta.threads.runs import ( + CodeToolCall, + FunctionToolCall, + MessageCreationStepDetails, + RetrievalToolCall, + RunStep, + ToolCallsStepDetails, +) +``` + +Methods: + +- client.beta.threads.runs.steps.retrieve(step_id, \*, thread_id, run_id) -> RunStep +- client.beta.threads.runs.steps.list(run_id, \*, thread_id, \*\*params) -> SyncCursorPage[RunStep] + +### Messages + +Types: + +```python +from openai.types.beta.threads import ( + MessageContentImageFile, + MessageContentText, + ThreadMessage, + ThreadMessageDeleted, +) +``` + +Methods: + +- client.beta.threads.messages.create(thread_id, \*\*params) -> ThreadMessage +- client.beta.threads.messages.retrieve(message_id, \*, thread_id) -> ThreadMessage +- client.beta.threads.messages.update(message_id, \*, thread_id, \*\*params) -> ThreadMessage +- client.beta.threads.messages.list(thread_id, \*\*params) -> SyncCursorPage[ThreadMessage] + +#### Files + +Types: + +```python +from openai.types.beta.threads.messages import MessageFile +``` + +Methods: + +- client.beta.threads.messages.files.retrieve(file_id, \*, thread_id, message_id) -> MessageFile +- client.beta.threads.messages.files.list(message_id, \*, thread_id, \*\*params) -> SyncCursorPage[MessageFile] diff --git a/examples/async_demo.py b/examples/async_demo.py old mode 100644 new mode 100755 diff --git a/examples/azure.py b/examples/azure.py old mode 100644 new mode 100755 diff --git a/examples/azure_ad.py b/examples/azure_ad.py old mode 100644 new mode 100755 diff --git a/examples/demo.py b/examples/demo.py old mode 100644 new mode 100755 diff --git a/examples/module_client.py b/examples/module_client.py old mode 100644 new mode 100755 diff --git a/pyproject.toml b/pyproject.toml index 8c83f4260d..9ab62e23fc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openai" -version = "1.0.1" +version = "1.1.0" description = "Client library for the openai API" readme = "README.md" license = "Apache-2.0" diff --git a/src/openai/__init__.py b/src/openai/__init__.py index f033d8f26c..da1157a767 100644 --- a/src/openai/__init__.py +++ b/src/openai/__init__.py @@ -329,6 +329,7 @@ def _reset_client() -> None: # type: ignore[reportUnusedFunction] _client = None +from ._module_client import beta as beta from ._module_client import chat as chat from ._module_client import audio as audio from ._module_client import edits as edits diff --git a/src/openai/_client.py b/src/openai/_client.py index 9df7eabf9a..6476d2b1a8 100644 --- a/src/openai/_client.py +++ b/src/openai/_client.py @@ -52,6 +52,7 @@ class OpenAI(SyncAPIClient): models: resources.Models fine_tuning: resources.FineTuning fine_tunes: resources.FineTunes + beta: resources.Beta with_raw_response: OpenAIWithRawResponse # client options @@ -125,6 +126,7 @@ def __init__( self.models = resources.Models(self) self.fine_tuning = resources.FineTuning(self) self.fine_tunes = resources.FineTunes(self) + self.beta = resources.Beta(self) self.with_raw_response = OpenAIWithRawResponse(self) @property @@ -257,6 +259,7 @@ class AsyncOpenAI(AsyncAPIClient): models: resources.AsyncModels fine_tuning: resources.AsyncFineTuning fine_tunes: resources.AsyncFineTunes + beta: resources.AsyncBeta with_raw_response: AsyncOpenAIWithRawResponse # client options @@ -330,6 +333,7 @@ def __init__( self.models = resources.AsyncModels(self) self.fine_tuning = resources.AsyncFineTuning(self) self.fine_tunes = resources.AsyncFineTunes(self) + self.beta = resources.AsyncBeta(self) self.with_raw_response = AsyncOpenAIWithRawResponse(self) @property @@ -466,6 +470,7 @@ def __init__(self, client: OpenAI) -> None: self.models = resources.ModelsWithRawResponse(client.models) self.fine_tuning = resources.FineTuningWithRawResponse(client.fine_tuning) self.fine_tunes = resources.FineTunesWithRawResponse(client.fine_tunes) + self.beta = resources.BetaWithRawResponse(client.beta) class AsyncOpenAIWithRawResponse: @@ -481,6 +486,7 @@ def __init__(self, client: AsyncOpenAI) -> None: self.models = resources.AsyncModelsWithRawResponse(client.models) self.fine_tuning = resources.AsyncFineTuningWithRawResponse(client.fine_tuning) self.fine_tunes = resources.AsyncFineTunesWithRawResponse(client.fine_tunes) + self.beta = resources.AsyncBetaWithRawResponse(client.beta) Client = OpenAI diff --git a/src/openai/_module_client.py b/src/openai/_module_client.py index ca80468e88..fe8e0a2139 100644 --- a/src/openai/_module_client.py +++ b/src/openai/_module_client.py @@ -12,6 +12,12 @@ def __load__(self) -> resources.Chat: return _load_client().chat +class BetaProxy(LazyProxy[resources.Beta]): + @override + def __load__(self) -> resources.Beta: + return _load_client().beta + + class EditsProxy(LazyProxy[resources.Edits]): @override def __load__(self) -> resources.Edits: @@ -73,6 +79,7 @@ def __load__(self) -> resources.FineTuning: chat: resources.Chat = ChatProxy().__as_proxied__() +beta: resources.Beta = BetaProxy().__as_proxied__() edits: resources.Edits = EditsProxy().__as_proxied__() files: resources.Files = FilesProxy().__as_proxied__() audio: resources.Audio = AudioProxy().__as_proxied__() diff --git a/src/openai/_version.py b/src/openai/_version.py index f6f3a35c07..57548ed376 100644 --- a/src/openai/_version.py +++ b/src/openai/_version.py @@ -1,4 +1,4 @@ # File generated from our OpenAPI spec by Stainless. __title__ = "openai" -__version__ = "1.0.1" +__version__ = "1.1.0" diff --git a/src/openai/cli/_api/chat/completions.py b/src/openai/cli/_api/chat/completions.py index e7566b143d..c299741fe0 100644 --- a/src/openai/cli/_api/chat/completions.py +++ b/src/openai/cli/_api/chat/completions.py @@ -3,7 +3,7 @@ import sys from typing import TYPE_CHECKING, List, Optional, cast from argparse import ArgumentParser -from typing_extensions import NamedTuple +from typing_extensions import Literal, NamedTuple from ..._utils import get_client from ..._models import BaseModel @@ -97,7 +97,9 @@ class CLIChatCompletion: def create(args: CLIChatCompletionCreateArgs) -> None: params: CompletionCreateParams = { "model": args.model, - "messages": [{"role": message.role, "content": message.content} for message in args.message], + "messages": [ + {"role": cast(Literal["user"], message.role), "content": message.content} for message in args.message + ], "n": args.n, "temperature": args.temperature, "top_p": args.top_p, diff --git a/src/openai/cli/_api/files.py b/src/openai/cli/_api/files.py index ae6dadf0f1..5f3631b284 100644 --- a/src/openai/cli/_api/files.py +++ b/src/openai/cli/_api/files.py @@ -1,6 +1,6 @@ from __future__ import annotations -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, Any, cast from argparse import ArgumentParser from .._utils import get_client, print_model @@ -55,7 +55,12 @@ def create(args: CLIFileCreateArgs) -> None: with open(args.file, "rb") as file_reader: buffer_reader = BufferReader(file_reader.read(), desc="Upload progress") - file = get_client().files.create(file=(args.file, buffer_reader), purpose=args.purpose) + file = get_client().files.create( + file=(args.file, buffer_reader), + # casts required because the API is typed for enums + # but we don't want to validate that here for forwards-compat + purpose=cast(Any, args.purpose), + ) print_model(file) @staticmethod diff --git a/src/openai/pagination.py b/src/openai/pagination.py index ff45f39517..4ec300f2d1 100644 --- a/src/openai/pagination.py +++ b/src/openai/pagination.py @@ -1,7 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import Any, List, Generic, TypeVar, Optional, cast -from typing_extensions import Protocol, override, runtime_checkable +from typing_extensions import Literal, Protocol, override, runtime_checkable from ._types import ModelT from ._models import BaseModel @@ -21,7 +21,7 @@ class SyncPage(BaseSyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): """Note: no pagination actually occurs yet, this is for forwards-compatibility.""" data: List[ModelT] - object: str + object: Literal["list"] @override def _get_page_items(self) -> List[ModelT]: @@ -40,7 +40,7 @@ class AsyncPage(BaseAsyncPage[ModelT], BasePage[ModelT], Generic[ModelT]): """Note: no pagination actually occurs yet, this is for forwards-compatibility.""" data: List[ModelT] - object: str + object: Literal["list"] @override def _get_page_items(self) -> List[ModelT]: diff --git a/src/openai/resources/__init__.py b/src/openai/resources/__init__.py index e0a26c72d2..e0f4f08d5c 100644 --- a/src/openai/resources/__init__.py +++ b/src/openai/resources/__init__.py @@ -1,5 +1,6 @@ # File generated from our OpenAPI spec by Stainless. +from .beta import Beta, AsyncBeta, BetaWithRawResponse, AsyncBetaWithRawResponse from .chat import Chat, AsyncChat, ChatWithRawResponse, AsyncChatWithRawResponse from .audio import Audio, AsyncAudio, AudioWithRawResponse, AsyncAudioWithRawResponse from .edits import Edits, AsyncEdits, EditsWithRawResponse, AsyncEditsWithRawResponse @@ -92,4 +93,8 @@ "AsyncFineTunes", "FineTunesWithRawResponse", "AsyncFineTunesWithRawResponse", + "Beta", + "AsyncBeta", + "BetaWithRawResponse", + "AsyncBetaWithRawResponse", ] diff --git a/src/openai/resources/audio/__init__.py b/src/openai/resources/audio/__init__.py index 771bfe9da2..76547b5f34 100644 --- a/src/openai/resources/audio/__init__.py +++ b/src/openai/resources/audio/__init__.py @@ -1,6 +1,12 @@ # File generated from our OpenAPI spec by Stainless. from .audio import Audio, AsyncAudio, AudioWithRawResponse, AsyncAudioWithRawResponse +from .speech import ( + Speech, + AsyncSpeech, + SpeechWithRawResponse, + AsyncSpeechWithRawResponse, +) from .translations import ( Translations, AsyncTranslations, @@ -23,6 +29,10 @@ "AsyncTranslations", "TranslationsWithRawResponse", "AsyncTranslationsWithRawResponse", + "Speech", + "AsyncSpeech", + "SpeechWithRawResponse", + "AsyncSpeechWithRawResponse", "Audio", "AsyncAudio", "AudioWithRawResponse", diff --git a/src/openai/resources/audio/audio.py b/src/openai/resources/audio/audio.py index 8e8872c5b5..6f7226ee59 100644 --- a/src/openai/resources/audio/audio.py +++ b/src/openai/resources/audio/audio.py @@ -4,6 +4,12 @@ from typing import TYPE_CHECKING +from .speech import ( + Speech, + AsyncSpeech, + SpeechWithRawResponse, + AsyncSpeechWithRawResponse, +) from ..._resource import SyncAPIResource, AsyncAPIResource from .translations import ( Translations, @@ -27,24 +33,28 @@ class Audio(SyncAPIResource): transcriptions: Transcriptions translations: Translations + speech: Speech with_raw_response: AudioWithRawResponse def __init__(self, client: OpenAI) -> None: super().__init__(client) self.transcriptions = Transcriptions(client) self.translations = Translations(client) + self.speech = Speech(client) self.with_raw_response = AudioWithRawResponse(self) class AsyncAudio(AsyncAPIResource): transcriptions: AsyncTranscriptions translations: AsyncTranslations + speech: AsyncSpeech with_raw_response: AsyncAudioWithRawResponse def __init__(self, client: AsyncOpenAI) -> None: super().__init__(client) self.transcriptions = AsyncTranscriptions(client) self.translations = AsyncTranslations(client) + self.speech = AsyncSpeech(client) self.with_raw_response = AsyncAudioWithRawResponse(self) @@ -52,9 +62,11 @@ class AudioWithRawResponse: def __init__(self, audio: Audio) -> None: self.transcriptions = TranscriptionsWithRawResponse(audio.transcriptions) self.translations = TranslationsWithRawResponse(audio.translations) + self.speech = SpeechWithRawResponse(audio.speech) class AsyncAudioWithRawResponse: def __init__(self, audio: AsyncAudio) -> None: self.transcriptions = AsyncTranscriptionsWithRawResponse(audio.transcriptions) self.translations = AsyncTranslationsWithRawResponse(audio.translations) + self.speech = AsyncSpeechWithRawResponse(audio.speech) diff --git a/src/openai/resources/audio/speech.py b/src/openai/resources/audio/speech.py new file mode 100644 index 0000000000..7318e3a2e4 --- /dev/null +++ b/src/openai/resources/audio/speech.py @@ -0,0 +1,166 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING, Union +from typing_extensions import Literal + +from ..._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ..._utils import maybe_transform +from ..._resource import SyncAPIResource, AsyncAPIResource +from ..._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from ...types.audio import speech_create_params +from ..._base_client import HttpxBinaryResponseContent, make_request_options + +if TYPE_CHECKING: + from ..._client import OpenAI, AsyncOpenAI + +__all__ = ["Speech", "AsyncSpeech"] + + +class Speech(SyncAPIResource): + with_raw_response: SpeechWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.with_raw_response = SpeechWithRawResponse(self) + + def create( + self, + *, + input: str, + model: Union[str, Literal["tts-1", "tts-1-hd"]], + voice: Literal["alloy", "echo", "fable", "onyx", "nova", "shimmer"], + response_format: Literal["mp3", "opus", "aac", "flac"] | NotGiven = NOT_GIVEN, + speed: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> HttpxBinaryResponseContent: + """ + Generates audio from the input text. + + Args: + input: The text to generate audio for. The maximum length is 4096 characters. + + model: + One of the available [TTS models](https://platform.openai.com/docs/models/tts): + `tts-1` or `tts-1-hd` + + voice: The voice to use when generating the audio. Supported voices are `alloy`, + `echo`, `fable`, `onyx`, `nova`, and `shimmer`. + + response_format: The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`. + + speed: The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is + the default. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return self._post( + "/audio/speech", + body=maybe_transform( + { + "input": input, + "model": model, + "voice": voice, + "response_format": response_format, + "speed": speed, + }, + speech_create_params.SpeechCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=HttpxBinaryResponseContent, + ) + + +class AsyncSpeech(AsyncAPIResource): + with_raw_response: AsyncSpeechWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.with_raw_response = AsyncSpeechWithRawResponse(self) + + async def create( + self, + *, + input: str, + model: Union[str, Literal["tts-1", "tts-1-hd"]], + voice: Literal["alloy", "echo", "fable", "onyx", "nova", "shimmer"], + response_format: Literal["mp3", "opus", "aac", "flac"] | NotGiven = NOT_GIVEN, + speed: float | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> HttpxBinaryResponseContent: + """ + Generates audio from the input text. + + Args: + input: The text to generate audio for. The maximum length is 4096 characters. + + model: + One of the available [TTS models](https://platform.openai.com/docs/models/tts): + `tts-1` or `tts-1-hd` + + voice: The voice to use when generating the audio. Supported voices are `alloy`, + `echo`, `fable`, `onyx`, `nova`, and `shimmer`. + + response_format: The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`. + + speed: The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is + the default. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + return await self._post( + "/audio/speech", + body=maybe_transform( + { + "input": input, + "model": model, + "voice": voice, + "response_format": response_format, + "speed": speed, + }, + speech_create_params.SpeechCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=HttpxBinaryResponseContent, + ) + + +class SpeechWithRawResponse: + def __init__(self, speech: Speech) -> None: + self.create = to_raw_response_wrapper( + speech.create, + ) + + +class AsyncSpeechWithRawResponse: + def __init__(self, speech: AsyncSpeech) -> None: + self.create = async_to_raw_response_wrapper( + speech.create, + ) diff --git a/src/openai/resources/audio/transcriptions.py b/src/openai/resources/audio/transcriptions.py index ca61f8bd42..44d973d0af 100644 --- a/src/openai/resources/audio/transcriptions.py +++ b/src/openai/resources/audio/transcriptions.py @@ -60,8 +60,8 @@ def create( [prompt](https://platform.openai.com/docs/guides/speech-to-text/prompting) should match the audio language. - response_format: The format of the transcript output, in one of these options: json, text, srt, - verbose_json, or vtt. + response_format: The format of the transcript output, in one of these options: `json`, `text`, + `srt`, `verbose_json`, or `vtt`. temperature: The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and @@ -147,8 +147,8 @@ async def create( [prompt](https://platform.openai.com/docs/guides/speech-to-text/prompting) should match the audio language. - response_format: The format of the transcript output, in one of these options: json, text, srt, - verbose_json, or vtt. + response_format: The format of the transcript output, in one of these options: `json`, `text`, + `srt`, `verbose_json`, or `vtt`. temperature: The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and diff --git a/src/openai/resources/audio/translations.py b/src/openai/resources/audio/translations.py index 0b499b9865..bb37c691fc 100644 --- a/src/openai/resources/audio/translations.py +++ b/src/openai/resources/audio/translations.py @@ -54,8 +54,8 @@ def create( [prompt](https://platform.openai.com/docs/guides/speech-to-text/prompting) should be in English. - response_format: The format of the transcript output, in one of these options: json, text, srt, - verbose_json, or vtt. + response_format: The format of the transcript output, in one of these options: `json`, `text`, + `srt`, `verbose_json`, or `vtt`. temperature: The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and @@ -134,8 +134,8 @@ async def create( [prompt](https://platform.openai.com/docs/guides/speech-to-text/prompting) should be in English. - response_format: The format of the transcript output, in one of these options: json, text, srt, - verbose_json, or vtt. + response_format: The format of the transcript output, in one of these options: `json`, `text`, + `srt`, `verbose_json`, or `vtt`. temperature: The sampling temperature, between 0 and 1. Higher values like 0.8 will make the output more random, while lower values like 0.2 will make it more focused and diff --git a/src/openai/resources/beta/__init__.py b/src/openai/resources/beta/__init__.py new file mode 100644 index 0000000000..55ad243cca --- /dev/null +++ b/src/openai/resources/beta/__init__.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. + +from .beta import Beta, AsyncBeta, BetaWithRawResponse, AsyncBetaWithRawResponse +from .threads import ( + Threads, + AsyncThreads, + ThreadsWithRawResponse, + AsyncThreadsWithRawResponse, +) +from .assistants import ( + Assistants, + AsyncAssistants, + AssistantsWithRawResponse, + AsyncAssistantsWithRawResponse, +) + +__all__ = [ + "Assistants", + "AsyncAssistants", + "AssistantsWithRawResponse", + "AsyncAssistantsWithRawResponse", + "Threads", + "AsyncThreads", + "ThreadsWithRawResponse", + "AsyncThreadsWithRawResponse", + "Beta", + "AsyncBeta", + "BetaWithRawResponse", + "AsyncBetaWithRawResponse", +] diff --git a/src/openai/resources/beta/assistants/__init__.py b/src/openai/resources/beta/assistants/__init__.py new file mode 100644 index 0000000000..6efb0b21ec --- /dev/null +++ b/src/openai/resources/beta/assistants/__init__.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. + +from .files import Files, AsyncFiles, FilesWithRawResponse, AsyncFilesWithRawResponse +from .assistants import ( + Assistants, + AsyncAssistants, + AssistantsWithRawResponse, + AsyncAssistantsWithRawResponse, +) + +__all__ = [ + "Files", + "AsyncFiles", + "FilesWithRawResponse", + "AsyncFilesWithRawResponse", + "Assistants", + "AsyncAssistants", + "AssistantsWithRawResponse", + "AsyncAssistantsWithRawResponse", +] diff --git a/src/openai/resources/beta/assistants/assistants.py b/src/openai/resources/beta/assistants/assistants.py new file mode 100644 index 0000000000..03f2759fc2 --- /dev/null +++ b/src/openai/resources/beta/assistants/assistants.py @@ -0,0 +1,654 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING, List, Optional +from typing_extensions import Literal + +from .files import Files, AsyncFiles, FilesWithRawResponse, AsyncFilesWithRawResponse +from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ...._utils import maybe_transform +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from ....pagination import SyncCursorPage, AsyncCursorPage +from ....types.beta import ( + Assistant, + AsssitantDeleted, + assistant_list_params, + assistant_create_params, + assistant_update_params, +) +from ...._base_client import AsyncPaginator, make_request_options + +if TYPE_CHECKING: + from ...._client import OpenAI, AsyncOpenAI + +__all__ = ["Assistants", "AsyncAssistants"] + + +class Assistants(SyncAPIResource): + files: Files + with_raw_response: AssistantsWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.files = Files(client) + self.with_raw_response = AssistantsWithRawResponse(self) + + def create( + self, + *, + model: str, + description: Optional[str] | NotGiven = NOT_GIVEN, + file_ids: List[str] | NotGiven = NOT_GIVEN, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + tools: List[assistant_create_params.Tool] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Assistant: + """ + Create an assistant with a model and instructions. + + Args: + model: ID of the model to use. You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + + description: The description of the assistant. The maximum length is 512 characters. + + file_ids: A list of [file](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. + + instructions: The system instructions that the assistant uses. The maximum length is 32768 + characters. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + name: The name of the assistant. The maximum length is 256 characters. + + tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per + assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + "/assistants", + body=maybe_transform( + { + "model": model, + "description": description, + "file_ids": file_ids, + "instructions": instructions, + "metadata": metadata, + "name": name, + "tools": tools, + }, + assistant_create_params.AssistantCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Assistant, + ) + + def retrieve( + self, + assistant_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Assistant: + """ + Retrieves an assistant. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/assistants/{assistant_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Assistant, + ) + + def update( + self, + assistant_id: str, + *, + description: Optional[str] | NotGiven = NOT_GIVEN, + file_ids: List[str] | NotGiven = NOT_GIVEN, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + model: str | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + tools: List[assistant_update_params.Tool] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Assistant: + """Modifies an assistant. + + Args: + description: The description of the assistant. + + The maximum length is 512 characters. + + file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. If a + file was previosuly attached to the list but does not show up in the list, it + will be deleted from the assistant. + + instructions: The system instructions that the assistant uses. The maximum length is 32768 + characters. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + model: ID of the model to use. You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + + name: The name of the assistant. The maximum length is 256 characters. + + tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per + assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/assistants/{assistant_id}", + body=maybe_transform( + { + "description": description, + "file_ids": file_ids, + "instructions": instructions, + "metadata": metadata, + "model": model, + "name": name, + "tools": tools, + }, + assistant_update_params.AssistantUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Assistant, + ) + + def list( + self, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> SyncCursorPage[Assistant]: + """Returns a list of assistants. + + Args: + after: A cursor for use in pagination. + + `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + "/assistants", + page=SyncCursorPage[Assistant], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + assistant_list_params.AssistantListParams, + ), + ), + model=Assistant, + ) + + def delete( + self, + assistant_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsssitantDeleted: + """ + Delete an assistant. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._delete( + f"/assistants/{assistant_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AsssitantDeleted, + ) + + +class AsyncAssistants(AsyncAPIResource): + files: AsyncFiles + with_raw_response: AsyncAssistantsWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.files = AsyncFiles(client) + self.with_raw_response = AsyncAssistantsWithRawResponse(self) + + async def create( + self, + *, + model: str, + description: Optional[str] | NotGiven = NOT_GIVEN, + file_ids: List[str] | NotGiven = NOT_GIVEN, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + tools: List[assistant_create_params.Tool] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Assistant: + """ + Create an assistant with a model and instructions. + + Args: + model: ID of the model to use. You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + + description: The description of the assistant. The maximum length is 512 characters. + + file_ids: A list of [file](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. + + instructions: The system instructions that the assistant uses. The maximum length is 32768 + characters. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + name: The name of the assistant. The maximum length is 256 characters. + + tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per + assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + "/assistants", + body=maybe_transform( + { + "model": model, + "description": description, + "file_ids": file_ids, + "instructions": instructions, + "metadata": metadata, + "name": name, + "tools": tools, + }, + assistant_create_params.AssistantCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Assistant, + ) + + async def retrieve( + self, + assistant_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Assistant: + """ + Retrieves an assistant. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/assistants/{assistant_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Assistant, + ) + + async def update( + self, + assistant_id: str, + *, + description: Optional[str] | NotGiven = NOT_GIVEN, + file_ids: List[str] | NotGiven = NOT_GIVEN, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + model: str | NotGiven = NOT_GIVEN, + name: Optional[str] | NotGiven = NOT_GIVEN, + tools: List[assistant_update_params.Tool] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Assistant: + """Modifies an assistant. + + Args: + description: The description of the assistant. + + The maximum length is 512 characters. + + file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. If a + file was previosuly attached to the list but does not show up in the list, it + will be deleted from the assistant. + + instructions: The system instructions that the assistant uses. The maximum length is 32768 + characters. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + model: ID of the model to use. You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + + name: The name of the assistant. The maximum length is 256 characters. + + tools: A list of tool enabled on the assistant. There can be a maximum of 128 tools per + assistant. Tools can be of types `code_interpreter`, `retrieval`, or `function`. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/assistants/{assistant_id}", + body=maybe_transform( + { + "description": description, + "file_ids": file_ids, + "instructions": instructions, + "metadata": metadata, + "model": model, + "name": name, + "tools": tools, + }, + assistant_update_params.AssistantUpdateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Assistant, + ) + + def list( + self, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[Assistant, AsyncCursorPage[Assistant]]: + """Returns a list of assistants. + + Args: + after: A cursor for use in pagination. + + `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + "/assistants", + page=AsyncCursorPage[Assistant], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + assistant_list_params.AssistantListParams, + ), + ), + model=Assistant, + ) + + async def delete( + self, + assistant_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsssitantDeleted: + """ + Delete an assistant. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._delete( + f"/assistants/{assistant_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AsssitantDeleted, + ) + + +class AssistantsWithRawResponse: + def __init__(self, assistants: Assistants) -> None: + self.files = FilesWithRawResponse(assistants.files) + + self.create = to_raw_response_wrapper( + assistants.create, + ) + self.retrieve = to_raw_response_wrapper( + assistants.retrieve, + ) + self.update = to_raw_response_wrapper( + assistants.update, + ) + self.list = to_raw_response_wrapper( + assistants.list, + ) + self.delete = to_raw_response_wrapper( + assistants.delete, + ) + + +class AsyncAssistantsWithRawResponse: + def __init__(self, assistants: AsyncAssistants) -> None: + self.files = AsyncFilesWithRawResponse(assistants.files) + + self.create = async_to_raw_response_wrapper( + assistants.create, + ) + self.retrieve = async_to_raw_response_wrapper( + assistants.retrieve, + ) + self.update = async_to_raw_response_wrapper( + assistants.update, + ) + self.list = async_to_raw_response_wrapper( + assistants.list, + ) + self.delete = async_to_raw_response_wrapper( + assistants.delete, + ) diff --git a/src/openai/resources/beta/assistants/files.py b/src/openai/resources/beta/assistants/files.py new file mode 100644 index 0000000000..b1953525e8 --- /dev/null +++ b/src/openai/resources/beta/assistants/files.py @@ -0,0 +1,414 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING +from typing_extensions import Literal + +from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ...._utils import maybe_transform +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from ....pagination import SyncCursorPage, AsyncCursorPage +from ...._base_client import AsyncPaginator, make_request_options +from ....types.beta.assistants import ( + AssistantFile, + FileDeleteResponse, + file_list_params, + file_create_params, +) + +if TYPE_CHECKING: + from ...._client import OpenAI, AsyncOpenAI + +__all__ = ["Files", "AsyncFiles"] + + +class Files(SyncAPIResource): + with_raw_response: FilesWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.with_raw_response = FilesWithRawResponse(self) + + def create( + self, + assistant_id: str, + *, + file_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AssistantFile: + """ + Create an assistant file by attaching a + [File](https://platform.openai.com/docs/api-reference/files) to an + [assistant](https://platform.openai.com/docs/api-reference/assistants). + + Args: + file_id: A [File](https://platform.openai.com/docs/api-reference/files) ID (with + `purpose="assistants"`) that the assistant should use. Useful for tools like + `retrieval` and `code_interpreter` that can access files. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/assistants/{assistant_id}/files", + body=maybe_transform({"file_id": file_id}, file_create_params.FileCreateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AssistantFile, + ) + + def retrieve( + self, + file_id: str, + *, + assistant_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AssistantFile: + """ + Retrieves an AssistantFile. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/assistants/{assistant_id}/files/{file_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AssistantFile, + ) + + def list( + self, + assistant_id: str, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> SyncCursorPage[AssistantFile]: + """ + Returns a list of assistant files. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/assistants/{assistant_id}/files", + page=SyncCursorPage[AssistantFile], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + file_list_params.FileListParams, + ), + ), + model=AssistantFile, + ) + + def delete( + self, + file_id: str, + *, + assistant_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> FileDeleteResponse: + """ + Delete an assistant file. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._delete( + f"/assistants/{assistant_id}/files/{file_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileDeleteResponse, + ) + + +class AsyncFiles(AsyncAPIResource): + with_raw_response: AsyncFilesWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.with_raw_response = AsyncFilesWithRawResponse(self) + + async def create( + self, + assistant_id: str, + *, + file_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AssistantFile: + """ + Create an assistant file by attaching a + [File](https://platform.openai.com/docs/api-reference/files) to an + [assistant](https://platform.openai.com/docs/api-reference/assistants). + + Args: + file_id: A [File](https://platform.openai.com/docs/api-reference/files) ID (with + `purpose="assistants"`) that the assistant should use. Useful for tools like + `retrieval` and `code_interpreter` that can access files. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/assistants/{assistant_id}/files", + body=maybe_transform({"file_id": file_id}, file_create_params.FileCreateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AssistantFile, + ) + + async def retrieve( + self, + file_id: str, + *, + assistant_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AssistantFile: + """ + Retrieves an AssistantFile. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/assistants/{assistant_id}/files/{file_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=AssistantFile, + ) + + def list( + self, + assistant_id: str, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[AssistantFile, AsyncCursorPage[AssistantFile]]: + """ + Returns a list of assistant files. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/assistants/{assistant_id}/files", + page=AsyncCursorPage[AssistantFile], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + file_list_params.FileListParams, + ), + ), + model=AssistantFile, + ) + + async def delete( + self, + file_id: str, + *, + assistant_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> FileDeleteResponse: + """ + Delete an assistant file. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._delete( + f"/assistants/{assistant_id}/files/{file_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=FileDeleteResponse, + ) + + +class FilesWithRawResponse: + def __init__(self, files: Files) -> None: + self.create = to_raw_response_wrapper( + files.create, + ) + self.retrieve = to_raw_response_wrapper( + files.retrieve, + ) + self.list = to_raw_response_wrapper( + files.list, + ) + self.delete = to_raw_response_wrapper( + files.delete, + ) + + +class AsyncFilesWithRawResponse: + def __init__(self, files: AsyncFiles) -> None: + self.create = async_to_raw_response_wrapper( + files.create, + ) + self.retrieve = async_to_raw_response_wrapper( + files.retrieve, + ) + self.list = async_to_raw_response_wrapper( + files.list, + ) + self.delete = async_to_raw_response_wrapper( + files.delete, + ) diff --git a/src/openai/resources/beta/beta.py b/src/openai/resources/beta/beta.py new file mode 100644 index 0000000000..b552561763 --- /dev/null +++ b/src/openai/resources/beta/beta.py @@ -0,0 +1,60 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from .threads import ( + Threads, + AsyncThreads, + ThreadsWithRawResponse, + AsyncThreadsWithRawResponse, +) +from .assistants import ( + Assistants, + AsyncAssistants, + AssistantsWithRawResponse, + AsyncAssistantsWithRawResponse, +) +from ..._resource import SyncAPIResource, AsyncAPIResource + +if TYPE_CHECKING: + from ..._client import OpenAI, AsyncOpenAI + +__all__ = ["Beta", "AsyncBeta"] + + +class Beta(SyncAPIResource): + assistants: Assistants + threads: Threads + with_raw_response: BetaWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.assistants = Assistants(client) + self.threads = Threads(client) + self.with_raw_response = BetaWithRawResponse(self) + + +class AsyncBeta(AsyncAPIResource): + assistants: AsyncAssistants + threads: AsyncThreads + with_raw_response: AsyncBetaWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.assistants = AsyncAssistants(client) + self.threads = AsyncThreads(client) + self.with_raw_response = AsyncBetaWithRawResponse(self) + + +class BetaWithRawResponse: + def __init__(self, beta: Beta) -> None: + self.assistants = AssistantsWithRawResponse(beta.assistants) + self.threads = ThreadsWithRawResponse(beta.threads) + + +class AsyncBetaWithRawResponse: + def __init__(self, beta: AsyncBeta) -> None: + self.assistants = AsyncAssistantsWithRawResponse(beta.assistants) + self.threads = AsyncThreadsWithRawResponse(beta.threads) diff --git a/src/openai/resources/beta/threads/__init__.py b/src/openai/resources/beta/threads/__init__.py new file mode 100644 index 0000000000..b9aaada465 --- /dev/null +++ b/src/openai/resources/beta/threads/__init__.py @@ -0,0 +1,30 @@ +# File generated from our OpenAPI spec by Stainless. + +from .runs import Runs, AsyncRuns, RunsWithRawResponse, AsyncRunsWithRawResponse +from .threads import ( + Threads, + AsyncThreads, + ThreadsWithRawResponse, + AsyncThreadsWithRawResponse, +) +from .messages import ( + Messages, + AsyncMessages, + MessagesWithRawResponse, + AsyncMessagesWithRawResponse, +) + +__all__ = [ + "Runs", + "AsyncRuns", + "RunsWithRawResponse", + "AsyncRunsWithRawResponse", + "Messages", + "AsyncMessages", + "MessagesWithRawResponse", + "AsyncMessagesWithRawResponse", + "Threads", + "AsyncThreads", + "ThreadsWithRawResponse", + "AsyncThreadsWithRawResponse", +] diff --git a/src/openai/resources/beta/threads/messages/__init__.py b/src/openai/resources/beta/threads/messages/__init__.py new file mode 100644 index 0000000000..d8d4ce448c --- /dev/null +++ b/src/openai/resources/beta/threads/messages/__init__.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. + +from .files import Files, AsyncFiles, FilesWithRawResponse, AsyncFilesWithRawResponse +from .messages import ( + Messages, + AsyncMessages, + MessagesWithRawResponse, + AsyncMessagesWithRawResponse, +) + +__all__ = [ + "Files", + "AsyncFiles", + "FilesWithRawResponse", + "AsyncFilesWithRawResponse", + "Messages", + "AsyncMessages", + "MessagesWithRawResponse", + "AsyncMessagesWithRawResponse", +] diff --git a/src/openai/resources/beta/threads/messages/files.py b/src/openai/resources/beta/threads/messages/files.py new file mode 100644 index 0000000000..70166eb7b2 --- /dev/null +++ b/src/openai/resources/beta/threads/messages/files.py @@ -0,0 +1,257 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING +from typing_extensions import Literal + +from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ....._utils import maybe_transform +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from .....pagination import SyncCursorPage, AsyncCursorPage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.beta.threads.messages import MessageFile, file_list_params + +if TYPE_CHECKING: + from ....._client import OpenAI, AsyncOpenAI + +__all__ = ["Files", "AsyncFiles"] + + +class Files(SyncAPIResource): + with_raw_response: FilesWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.with_raw_response = FilesWithRawResponse(self) + + def retrieve( + self, + file_id: str, + *, + thread_id: str, + message_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> MessageFile: + """ + Retrieves a message file. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/threads/{thread_id}/messages/{message_id}/files/{file_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=MessageFile, + ) + + def list( + self, + message_id: str, + *, + thread_id: str, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> SyncCursorPage[MessageFile]: + """Returns a list of message files. + + Args: + after: A cursor for use in pagination. + + `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/messages/{message_id}/files", + page=SyncCursorPage[MessageFile], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + file_list_params.FileListParams, + ), + ), + model=MessageFile, + ) + + +class AsyncFiles(AsyncAPIResource): + with_raw_response: AsyncFilesWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.with_raw_response = AsyncFilesWithRawResponse(self) + + async def retrieve( + self, + file_id: str, + *, + thread_id: str, + message_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> MessageFile: + """ + Retrieves a message file. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/threads/{thread_id}/messages/{message_id}/files/{file_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=MessageFile, + ) + + def list( + self, + message_id: str, + *, + thread_id: str, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[MessageFile, AsyncCursorPage[MessageFile]]: + """Returns a list of message files. + + Args: + after: A cursor for use in pagination. + + `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/messages/{message_id}/files", + page=AsyncCursorPage[MessageFile], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + file_list_params.FileListParams, + ), + ), + model=MessageFile, + ) + + +class FilesWithRawResponse: + def __init__(self, files: Files) -> None: + self.retrieve = to_raw_response_wrapper( + files.retrieve, + ) + self.list = to_raw_response_wrapper( + files.list, + ) + + +class AsyncFilesWithRawResponse: + def __init__(self, files: AsyncFiles) -> None: + self.retrieve = async_to_raw_response_wrapper( + files.retrieve, + ) + self.list = async_to_raw_response_wrapper( + files.list, + ) diff --git a/src/openai/resources/beta/threads/messages/messages.py b/src/openai/resources/beta/threads/messages/messages.py new file mode 100644 index 0000000000..caec03f484 --- /dev/null +++ b/src/openai/resources/beta/threads/messages/messages.py @@ -0,0 +1,477 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING, List, Optional +from typing_extensions import Literal + +from .files import Files, AsyncFiles, FilesWithRawResponse, AsyncFilesWithRawResponse +from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ....._utils import maybe_transform +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from .....pagination import SyncCursorPage, AsyncCursorPage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.beta.threads import ( + ThreadMessage, + message_list_params, + message_create_params, + message_update_params, +) + +if TYPE_CHECKING: + from ....._client import OpenAI, AsyncOpenAI + +__all__ = ["Messages", "AsyncMessages"] + + +class Messages(SyncAPIResource): + files: Files + with_raw_response: MessagesWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.files = Files(client) + self.with_raw_response = MessagesWithRawResponse(self) + + def create( + self, + thread_id: str, + *, + content: str, + role: Literal["user"], + file_ids: List[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadMessage: + """ + Create a message. + + Args: + content: The content of the message. + + role: The role of the entity that is creating the message. Currently only `user` is + supported. + + file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that + the message should use. There can be a maximum of 10 files attached to a + message. Useful for tools like `retrieval` and `code_interpreter` that can + access and use files. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}/messages", + body=maybe_transform( + { + "content": content, + "role": role, + "file_ids": file_ids, + "metadata": metadata, + }, + message_create_params.MessageCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadMessage, + ) + + def retrieve( + self, + message_id: str, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadMessage: + """ + Retrieve a message. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/threads/{thread_id}/messages/{message_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadMessage, + ) + + def update( + self, + message_id: str, + *, + thread_id: str, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadMessage: + """ + Modifies a message. + + Args: + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}/messages/{message_id}", + body=maybe_transform({"metadata": metadata}, message_update_params.MessageUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadMessage, + ) + + def list( + self, + thread_id: str, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> SyncCursorPage[ThreadMessage]: + """ + Returns a list of messages for a given thread. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/messages", + page=SyncCursorPage[ThreadMessage], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + message_list_params.MessageListParams, + ), + ), + model=ThreadMessage, + ) + + +class AsyncMessages(AsyncAPIResource): + files: AsyncFiles + with_raw_response: AsyncMessagesWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.files = AsyncFiles(client) + self.with_raw_response = AsyncMessagesWithRawResponse(self) + + async def create( + self, + thread_id: str, + *, + content: str, + role: Literal["user"], + file_ids: List[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadMessage: + """ + Create a message. + + Args: + content: The content of the message. + + role: The role of the entity that is creating the message. Currently only `user` is + supported. + + file_ids: A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that + the message should use. There can be a maximum of 10 files attached to a + message. Useful for tools like `retrieval` and `code_interpreter` that can + access and use files. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}/messages", + body=maybe_transform( + { + "content": content, + "role": role, + "file_ids": file_ids, + "metadata": metadata, + }, + message_create_params.MessageCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadMessage, + ) + + async def retrieve( + self, + message_id: str, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadMessage: + """ + Retrieve a message. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/threads/{thread_id}/messages/{message_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadMessage, + ) + + async def update( + self, + message_id: str, + *, + thread_id: str, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadMessage: + """ + Modifies a message. + + Args: + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}/messages/{message_id}", + body=maybe_transform({"metadata": metadata}, message_update_params.MessageUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadMessage, + ) + + def list( + self, + thread_id: str, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[ThreadMessage, AsyncCursorPage[ThreadMessage]]: + """ + Returns a list of messages for a given thread. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/messages", + page=AsyncCursorPage[ThreadMessage], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + message_list_params.MessageListParams, + ), + ), + model=ThreadMessage, + ) + + +class MessagesWithRawResponse: + def __init__(self, messages: Messages) -> None: + self.files = FilesWithRawResponse(messages.files) + + self.create = to_raw_response_wrapper( + messages.create, + ) + self.retrieve = to_raw_response_wrapper( + messages.retrieve, + ) + self.update = to_raw_response_wrapper( + messages.update, + ) + self.list = to_raw_response_wrapper( + messages.list, + ) + + +class AsyncMessagesWithRawResponse: + def __init__(self, messages: AsyncMessages) -> None: + self.files = AsyncFilesWithRawResponse(messages.files) + + self.create = async_to_raw_response_wrapper( + messages.create, + ) + self.retrieve = async_to_raw_response_wrapper( + messages.retrieve, + ) + self.update = async_to_raw_response_wrapper( + messages.update, + ) + self.list = async_to_raw_response_wrapper( + messages.list, + ) diff --git a/src/openai/resources/beta/threads/runs/__init__.py b/src/openai/resources/beta/threads/runs/__init__.py new file mode 100644 index 0000000000..6b61813974 --- /dev/null +++ b/src/openai/resources/beta/threads/runs/__init__.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. + +from .runs import Runs, AsyncRuns, RunsWithRawResponse, AsyncRunsWithRawResponse +from .steps import Steps, AsyncSteps, StepsWithRawResponse, AsyncStepsWithRawResponse + +__all__ = [ + "Steps", + "AsyncSteps", + "StepsWithRawResponse", + "AsyncStepsWithRawResponse", + "Runs", + "AsyncRuns", + "RunsWithRawResponse", + "AsyncRunsWithRawResponse", +] diff --git a/src/openai/resources/beta/threads/runs/runs.py b/src/openai/resources/beta/threads/runs/runs.py new file mode 100644 index 0000000000..370056cbf4 --- /dev/null +++ b/src/openai/resources/beta/threads/runs/runs.py @@ -0,0 +1,654 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING, List, Optional +from typing_extensions import Literal + +from .steps import Steps, AsyncSteps, StepsWithRawResponse, AsyncStepsWithRawResponse +from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ....._utils import maybe_transform +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from .....pagination import SyncCursorPage, AsyncCursorPage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.beta.threads import ( + Run, + run_list_params, + run_create_params, + run_update_params, + run_submit_tool_outputs_params, +) + +if TYPE_CHECKING: + from ....._client import OpenAI, AsyncOpenAI + +__all__ = ["Runs", "AsyncRuns"] + + +class Runs(SyncAPIResource): + steps: Steps + with_raw_response: RunsWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.steps = Steps(client) + self.with_raw_response = RunsWithRawResponse(self) + + def create( + self, + thread_id: str, + *, + assistant_id: str, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + model: Optional[str] | NotGiven = NOT_GIVEN, + tools: Optional[List[run_create_params.Tool]] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Create a run. + + Args: + assistant_id: The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to + execute this run. + + instructions: Override the default system message of the assistant. This is useful for + modifying the behavior on a per-run basis. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + model: The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to + be used to execute this run. If a value is provided here, it will override the + model associated with the assistant. If not, the model associated with the + assistant will be used. + + tools: Override the tools the assistant can use for this run. This is useful for + modifying the behavior on a per-run basis. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}/runs", + body=maybe_transform( + { + "assistant_id": assistant_id, + "instructions": instructions, + "metadata": metadata, + "model": model, + "tools": tools, + }, + run_create_params.RunCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + def retrieve( + self, + run_id: str, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Retrieves a run. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/threads/{thread_id}/runs/{run_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + def update( + self, + run_id: str, + *, + thread_id: str, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Modifies a run. + + Args: + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}/runs/{run_id}", + body=maybe_transform({"metadata": metadata}, run_update_params.RunUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + def list( + self, + thread_id: str, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> SyncCursorPage[Run]: + """ + Returns a list of runs belonging to a thread. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/runs", + page=SyncCursorPage[Run], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + run_list_params.RunListParams, + ), + ), + model=Run, + ) + + def cancel( + self, + run_id: str, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Cancels a run that is `in_progress`. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}/runs/{run_id}/cancel", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + def submit_tool_outputs( + self, + run_id: str, + *, + thread_id: str, + tool_outputs: List[run_submit_tool_outputs_params.ToolOutput], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + When a run has the `status: "requires_action"` and `required_action.type` is + `submit_tool_outputs`, this endpoint can be used to submit the outputs from the + tool calls once they're all completed. All outputs must be submitted in a single + request. + + Args: + tool_outputs: A list of tools for which the outputs are being submitted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}/runs/{run_id}/submit_tool_outputs", + body=maybe_transform( + {"tool_outputs": tool_outputs}, run_submit_tool_outputs_params.RunSubmitToolOutputsParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + +class AsyncRuns(AsyncAPIResource): + steps: AsyncSteps + with_raw_response: AsyncRunsWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.steps = AsyncSteps(client) + self.with_raw_response = AsyncRunsWithRawResponse(self) + + async def create( + self, + thread_id: str, + *, + assistant_id: str, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + model: Optional[str] | NotGiven = NOT_GIVEN, + tools: Optional[List[run_create_params.Tool]] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Create a run. + + Args: + assistant_id: The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to + execute this run. + + instructions: Override the default system message of the assistant. This is useful for + modifying the behavior on a per-run basis. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + model: The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to + be used to execute this run. If a value is provided here, it will override the + model associated with the assistant. If not, the model associated with the + assistant will be used. + + tools: Override the tools the assistant can use for this run. This is useful for + modifying the behavior on a per-run basis. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}/runs", + body=maybe_transform( + { + "assistant_id": assistant_id, + "instructions": instructions, + "metadata": metadata, + "model": model, + "tools": tools, + }, + run_create_params.RunCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + async def retrieve( + self, + run_id: str, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Retrieves a run. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/threads/{thread_id}/runs/{run_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + async def update( + self, + run_id: str, + *, + thread_id: str, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Modifies a run. + + Args: + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}/runs/{run_id}", + body=maybe_transform({"metadata": metadata}, run_update_params.RunUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + def list( + self, + thread_id: str, + *, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[Run, AsyncCursorPage[Run]]: + """ + Returns a list of runs belonging to a thread. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/runs", + page=AsyncCursorPage[Run], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + run_list_params.RunListParams, + ), + ), + model=Run, + ) + + async def cancel( + self, + run_id: str, + *, + thread_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Cancels a run that is `in_progress`. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}/runs/{run_id}/cancel", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + async def submit_tool_outputs( + self, + run_id: str, + *, + thread_id: str, + tool_outputs: List[run_submit_tool_outputs_params.ToolOutput], + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + When a run has the `status: "requires_action"` and `required_action.type` is + `submit_tool_outputs`, this endpoint can be used to submit the outputs from the + tool calls once they're all completed. All outputs must be submitted in a single + request. + + Args: + tool_outputs: A list of tools for which the outputs are being submitted. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}/runs/{run_id}/submit_tool_outputs", + body=maybe_transform( + {"tool_outputs": tool_outputs}, run_submit_tool_outputs_params.RunSubmitToolOutputsParams + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + +class RunsWithRawResponse: + def __init__(self, runs: Runs) -> None: + self.steps = StepsWithRawResponse(runs.steps) + + self.create = to_raw_response_wrapper( + runs.create, + ) + self.retrieve = to_raw_response_wrapper( + runs.retrieve, + ) + self.update = to_raw_response_wrapper( + runs.update, + ) + self.list = to_raw_response_wrapper( + runs.list, + ) + self.cancel = to_raw_response_wrapper( + runs.cancel, + ) + self.submit_tool_outputs = to_raw_response_wrapper( + runs.submit_tool_outputs, + ) + + +class AsyncRunsWithRawResponse: + def __init__(self, runs: AsyncRuns) -> None: + self.steps = AsyncStepsWithRawResponse(runs.steps) + + self.create = async_to_raw_response_wrapper( + runs.create, + ) + self.retrieve = async_to_raw_response_wrapper( + runs.retrieve, + ) + self.update = async_to_raw_response_wrapper( + runs.update, + ) + self.list = async_to_raw_response_wrapper( + runs.list, + ) + self.cancel = async_to_raw_response_wrapper( + runs.cancel, + ) + self.submit_tool_outputs = async_to_raw_response_wrapper( + runs.submit_tool_outputs, + ) diff --git a/src/openai/resources/beta/threads/runs/steps.py b/src/openai/resources/beta/threads/runs/steps.py new file mode 100644 index 0000000000..bc6fd7fdc9 --- /dev/null +++ b/src/openai/resources/beta/threads/runs/steps.py @@ -0,0 +1,255 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING +from typing_extensions import Literal + +from ....._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ....._utils import maybe_transform +from ....._resource import SyncAPIResource, AsyncAPIResource +from ....._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from .....pagination import SyncCursorPage, AsyncCursorPage +from ....._base_client import AsyncPaginator, make_request_options +from .....types.beta.threads.runs import RunStep, step_list_params + +if TYPE_CHECKING: + from ....._client import OpenAI, AsyncOpenAI + +__all__ = ["Steps", "AsyncSteps"] + + +class Steps(SyncAPIResource): + with_raw_response: StepsWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.with_raw_response = StepsWithRawResponse(self) + + def retrieve( + self, + step_id: str, + *, + thread_id: str, + run_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> RunStep: + """ + Retrieves a run step. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/threads/{thread_id}/runs/{run_id}/steps/{step_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RunStep, + ) + + def list( + self, + run_id: str, + *, + thread_id: str, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> SyncCursorPage[RunStep]: + """ + Returns a list of run steps belonging to a run. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/runs/{run_id}/steps", + page=SyncCursorPage[RunStep], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + step_list_params.StepListParams, + ), + ), + model=RunStep, + ) + + +class AsyncSteps(AsyncAPIResource): + with_raw_response: AsyncStepsWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.with_raw_response = AsyncStepsWithRawResponse(self) + + async def retrieve( + self, + step_id: str, + *, + thread_id: str, + run_id: str, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> RunStep: + """ + Retrieves a run step. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/threads/{thread_id}/runs/{run_id}/steps/{step_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=RunStep, + ) + + def list( + self, + run_id: str, + *, + thread_id: str, + after: str | NotGiven = NOT_GIVEN, + before: str | NotGiven = NOT_GIVEN, + limit: int | NotGiven = NOT_GIVEN, + order: Literal["asc", "desc"] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> AsyncPaginator[RunStep, AsyncCursorPage[RunStep]]: + """ + Returns a list of run steps belonging to a run. + + Args: + after: A cursor for use in pagination. `after` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include after=obj_foo in order to + fetch the next page of the list. + + before: A cursor for use in pagination. `before` is an object ID that defines your place + in the list. For instance, if you make a list request and receive 100 objects, + ending with obj_foo, your subsequent call can include before=obj_foo in order to + fetch the previous page of the list. + + limit: A limit on the number of objects to be returned. Limit can range between 1 and + 100, and the default is 20. + + order: Sort order by the `created_at` timestamp of the objects. `asc` for ascending + order and `desc` for descending order. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get_api_list( + f"/threads/{thread_id}/runs/{run_id}/steps", + page=AsyncCursorPage[RunStep], + options=make_request_options( + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform( + { + "after": after, + "before": before, + "limit": limit, + "order": order, + }, + step_list_params.StepListParams, + ), + ), + model=RunStep, + ) + + +class StepsWithRawResponse: + def __init__(self, steps: Steps) -> None: + self.retrieve = to_raw_response_wrapper( + steps.retrieve, + ) + self.list = to_raw_response_wrapper( + steps.list, + ) + + +class AsyncStepsWithRawResponse: + def __init__(self, steps: AsyncSteps) -> None: + self.retrieve = async_to_raw_response_wrapper( + steps.retrieve, + ) + self.list = async_to_raw_response_wrapper( + steps.list, + ) diff --git a/src/openai/resources/beta/threads/threads.py b/src/openai/resources/beta/threads/threads.py new file mode 100644 index 0000000000..286630d81c --- /dev/null +++ b/src/openai/resources/beta/threads/threads.py @@ -0,0 +1,541 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import TYPE_CHECKING, List, Optional + +from .runs import Runs, AsyncRuns, RunsWithRawResponse, AsyncRunsWithRawResponse +from .messages import ( + Messages, + AsyncMessages, + MessagesWithRawResponse, + AsyncMessagesWithRawResponse, +) +from ...._types import NOT_GIVEN, Body, Query, Headers, NotGiven +from ...._utils import maybe_transform +from ...._resource import SyncAPIResource, AsyncAPIResource +from ...._response import to_raw_response_wrapper, async_to_raw_response_wrapper +from ....types.beta import ( + Thread, + ThreadDeleted, + thread_create_params, + thread_update_params, + thread_create_and_run_params, +) +from ...._base_client import make_request_options +from ....types.beta.threads import Run + +if TYPE_CHECKING: + from ...._client import OpenAI, AsyncOpenAI + +__all__ = ["Threads", "AsyncThreads"] + + +class Threads(SyncAPIResource): + runs: Runs + messages: Messages + with_raw_response: ThreadsWithRawResponse + + def __init__(self, client: OpenAI) -> None: + super().__init__(client) + self.runs = Runs(client) + self.messages = Messages(client) + self.with_raw_response = ThreadsWithRawResponse(self) + + def create( + self, + *, + messages: List[thread_create_params.Message] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Thread: + """ + Create a thread. + + Args: + messages: A list of [messages](https://platform.openai.com/docs/api-reference/messages) to + start the thread with. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + "/threads", + body=maybe_transform( + { + "messages": messages, + "metadata": metadata, + }, + thread_create_params.ThreadCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Thread, + ) + + def retrieve( + self, + thread_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Thread: + """ + Retrieves a thread. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._get( + f"/threads/{thread_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Thread, + ) + + def update( + self, + thread_id: str, + *, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Thread: + """ + Modifies a thread. + + Args: + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + f"/threads/{thread_id}", + body=maybe_transform({"metadata": metadata}, thread_update_params.ThreadUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Thread, + ) + + def delete( + self, + thread_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadDeleted: + """ + Delete a thread. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._delete( + f"/threads/{thread_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadDeleted, + ) + + def create_and_run( + self, + *, + assistant_id: str, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + model: Optional[str] | NotGiven = NOT_GIVEN, + thread: thread_create_and_run_params.Thread | NotGiven = NOT_GIVEN, + tools: Optional[List[thread_create_and_run_params.Tool]] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Create a thread and run it in one request. + + Args: + assistant_id: The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to + execute this run. + + instructions: Override the default system message of the assistant. This is useful for + modifying the behavior on a per-run basis. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + model: The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to + be used to execute this run. If a value is provided here, it will override the + model associated with the assistant. If not, the model associated with the + assistant will be used. + + thread: If no thread is provided, an empty thread will be created. + + tools: Override the tools the assistant can use for this run. This is useful for + modifying the behavior on a per-run basis. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return self._post( + "/threads/runs", + body=maybe_transform( + { + "assistant_id": assistant_id, + "instructions": instructions, + "metadata": metadata, + "model": model, + "thread": thread, + "tools": tools, + }, + thread_create_and_run_params.ThreadCreateAndRunParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + +class AsyncThreads(AsyncAPIResource): + runs: AsyncRuns + messages: AsyncMessages + with_raw_response: AsyncThreadsWithRawResponse + + def __init__(self, client: AsyncOpenAI) -> None: + super().__init__(client) + self.runs = AsyncRuns(client) + self.messages = AsyncMessages(client) + self.with_raw_response = AsyncThreadsWithRawResponse(self) + + async def create( + self, + *, + messages: List[thread_create_params.Message] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Thread: + """ + Create a thread. + + Args: + messages: A list of [messages](https://platform.openai.com/docs/api-reference/messages) to + start the thread with. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + "/threads", + body=maybe_transform( + { + "messages": messages, + "metadata": metadata, + }, + thread_create_params.ThreadCreateParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Thread, + ) + + async def retrieve( + self, + thread_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Thread: + """ + Retrieves a thread. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._get( + f"/threads/{thread_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Thread, + ) + + async def update( + self, + thread_id: str, + *, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Thread: + """ + Modifies a thread. + + Args: + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + f"/threads/{thread_id}", + body=maybe_transform({"metadata": metadata}, thread_update_params.ThreadUpdateParams), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Thread, + ) + + async def delete( + self, + thread_id: str, + *, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> ThreadDeleted: + """ + Delete a thread. + + Args: + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._delete( + f"/threads/{thread_id}", + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=ThreadDeleted, + ) + + async def create_and_run( + self, + *, + assistant_id: str, + instructions: Optional[str] | NotGiven = NOT_GIVEN, + metadata: Optional[object] | NotGiven = NOT_GIVEN, + model: Optional[str] | NotGiven = NOT_GIVEN, + thread: thread_create_and_run_params.Thread | NotGiven = NOT_GIVEN, + tools: Optional[List[thread_create_and_run_params.Tool]] | NotGiven = NOT_GIVEN, + # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. + # The extra values given here take precedence over values defined on the client or passed to this method. + extra_headers: Headers | None = None, + extra_query: Query | None = None, + extra_body: Body | None = None, + timeout: float | None | NotGiven = NOT_GIVEN, + ) -> Run: + """ + Create a thread and run it in one request. + + Args: + assistant_id: The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to + execute this run. + + instructions: Override the default system message of the assistant. This is useful for + modifying the behavior on a per-run basis. + + metadata: 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. Keys + can be a maximum of 64 characters long and values can be a maxium of 512 + characters long. + + model: The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to + be used to execute this run. If a value is provided here, it will override the + model associated with the assistant. If not, the model associated with the + assistant will be used. + + thread: If no thread is provided, an empty thread will be created. + + tools: Override the tools the assistant can use for this run. This is useful for + modifying the behavior on a per-run basis. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ + extra_headers = {"OpenAI-Beta": "assistants=v1", **(extra_headers or {})} + return await self._post( + "/threads/runs", + body=maybe_transform( + { + "assistant_id": assistant_id, + "instructions": instructions, + "metadata": metadata, + "model": model, + "thread": thread, + "tools": tools, + }, + thread_create_and_run_params.ThreadCreateAndRunParams, + ), + options=make_request_options( + extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + ), + cast_to=Run, + ) + + +class ThreadsWithRawResponse: + def __init__(self, threads: Threads) -> None: + self.runs = RunsWithRawResponse(threads.runs) + self.messages = MessagesWithRawResponse(threads.messages) + + self.create = to_raw_response_wrapper( + threads.create, + ) + self.retrieve = to_raw_response_wrapper( + threads.retrieve, + ) + self.update = to_raw_response_wrapper( + threads.update, + ) + self.delete = to_raw_response_wrapper( + threads.delete, + ) + self.create_and_run = to_raw_response_wrapper( + threads.create_and_run, + ) + + +class AsyncThreadsWithRawResponse: + def __init__(self, threads: AsyncThreads) -> None: + self.runs = AsyncRunsWithRawResponse(threads.runs) + self.messages = AsyncMessagesWithRawResponse(threads.messages) + + self.create = async_to_raw_response_wrapper( + threads.create, + ) + self.retrieve = async_to_raw_response_wrapper( + threads.retrieve, + ) + self.update = async_to_raw_response_wrapper( + threads.update, + ) + self.delete = async_to_raw_response_wrapper( + threads.delete, + ) + self.create_and_run = async_to_raw_response_wrapper( + threads.create_and_run, + ) diff --git a/src/openai/resources/chat/completions.py b/src/openai/resources/chat/completions.py index e6e6ce52b8..2ecde23ce1 100644 --- a/src/openai/resources/chat/completions.py +++ b/src/openai/resources/chat/completions.py @@ -13,7 +13,9 @@ from ...types.chat import ( ChatCompletion, ChatCompletionChunk, + ChatCompletionToolParam, ChatCompletionMessageParam, + ChatCompletionToolChoiceOptionParam, completion_create_params, ) from ..._base_client import make_request_options @@ -59,9 +61,13 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -88,18 +94,24 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) - function_call: Controls how the model calls functions. "none" means the model will not call a - function and instead generates a message. "auto" means the model can pick - between generating a message or calling a function. Specifying a particular - function via `{"name": "my_function"}` forces the model to call that function. - "none" is the default when no functions are present. "auto" is the default if + function_call: Deprecated in favor of `tool_choice`. + + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if functions are present. - functions: A list of functions the model may generate JSON inputs for. + functions: Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -121,6 +133,15 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + response_format: An object specifying the format that the model must output. Used to enable JSON + mode. + + seed: This feature is in Beta. If specified, our system will make a best effort to + sample deterministically, such that repeated requests with the same `seed` and + parameters should return the same result. Determinism is not guaranteed, and you + should refer to the `system_fingerprint` response parameter to monitor changes + in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. stream: If set, partial message deltas will be sent, like in ChatGPT. Tokens will be @@ -136,6 +157,20 @@ def create( We generally recommend altering this or `top_p` but not both. + tool_choice: Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + + tools: A list of tools the model may call. Currently, only functions are supported as a + tool. Use this to provide a list of functions the model may generate JSON inputs + for. + top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. @@ -185,8 +220,12 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -220,18 +259,24 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) - function_call: Controls how the model calls functions. "none" means the model will not call a - function and instead generates a message. "auto" means the model can pick - between generating a message or calling a function. Specifying a particular - function via `{"name": "my_function"}` forces the model to call that function. - "none" is the default when no functions are present. "auto" is the default if + function_call: Deprecated in favor of `tool_choice`. + + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if functions are present. - functions: A list of functions the model may generate JSON inputs for. + functions: Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -253,6 +298,15 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + response_format: An object specifying the format that the model must output. Used to enable JSON + mode. + + seed: This feature is in Beta. If specified, our system will make a best effort to + sample deterministically, such that repeated requests with the same `seed` and + parameters should return the same result. Determinism is not guaranteed, and you + should refer to the `system_fingerprint` response parameter to monitor changes + in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will @@ -261,6 +315,20 @@ def create( We generally recommend altering this or `top_p` but not both. + tool_choice: Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + + tools: A list of tools the model may call. Currently, only functions are supported as a + tool. Use this to provide a list of functions the model may generate JSON inputs + for. + top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. @@ -310,8 +378,12 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -345,18 +417,24 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) - function_call: Controls how the model calls functions. "none" means the model will not call a - function and instead generates a message. "auto" means the model can pick - between generating a message or calling a function. Specifying a particular - function via `{"name": "my_function"}` forces the model to call that function. - "none" is the default when no functions are present. "auto" is the default if + function_call: Deprecated in favor of `tool_choice`. + + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if functions are present. - functions: A list of functions the model may generate JSON inputs for. + functions: Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -378,6 +456,15 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + response_format: An object specifying the format that the model must output. Used to enable JSON + mode. + + seed: This feature is in Beta. If specified, our system will make a best effort to + sample deterministically, such that repeated requests with the same `seed` and + parameters should return the same result. Determinism is not guaranteed, and you + should refer to the `system_fingerprint` response parameter to monitor changes + in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will @@ -386,6 +473,20 @@ def create( We generally recommend altering this or `top_p` but not both. + tool_choice: Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + + tools: A list of tools the model may call. Currently, only functions are supported as a + tool. Use this to provide a list of functions the model may generate JSON inputs + for. + top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. @@ -434,9 +535,13 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -459,9 +564,13 @@ def create( "max_tokens": max_tokens, "n": n, "presence_penalty": presence_penalty, + "response_format": response_format, + "seed": seed, "stop": stop, "stream": stream, "temperature": temperature, + "tool_choice": tool_choice, + "tools": tools, "top_p": top_p, "user": user, }, @@ -511,9 +620,13 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -540,18 +653,24 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) - function_call: Controls how the model calls functions. "none" means the model will not call a - function and instead generates a message. "auto" means the model can pick - between generating a message or calling a function. Specifying a particular - function via `{"name": "my_function"}` forces the model to call that function. - "none" is the default when no functions are present. "auto" is the default if + function_call: Deprecated in favor of `tool_choice`. + + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if functions are present. - functions: A list of functions the model may generate JSON inputs for. + functions: Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -573,6 +692,15 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + response_format: An object specifying the format that the model must output. Used to enable JSON + mode. + + seed: This feature is in Beta. If specified, our system will make a best effort to + sample deterministically, such that repeated requests with the same `seed` and + parameters should return the same result. Determinism is not guaranteed, and you + should refer to the `system_fingerprint` response parameter to monitor changes + in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. stream: If set, partial message deltas will be sent, like in ChatGPT. Tokens will be @@ -588,6 +716,20 @@ async def create( We generally recommend altering this or `top_p` but not both. + tool_choice: Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + + tools: A list of tools the model may call. Currently, only functions are supported as a + tool. Use this to provide a list of functions the model may generate JSON inputs + for. + top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. @@ -637,8 +779,12 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -672,18 +818,24 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) - function_call: Controls how the model calls functions. "none" means the model will not call a - function and instead generates a message. "auto" means the model can pick - between generating a message or calling a function. Specifying a particular - function via `{"name": "my_function"}` forces the model to call that function. - "none" is the default when no functions are present. "auto" is the default if + function_call: Deprecated in favor of `tool_choice`. + + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if functions are present. - functions: A list of functions the model may generate JSON inputs for. + functions: Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -705,6 +857,15 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + response_format: An object specifying the format that the model must output. Used to enable JSON + mode. + + seed: This feature is in Beta. If specified, our system will make a best effort to + sample deterministically, such that repeated requests with the same `seed` and + parameters should return the same result. Determinism is not guaranteed, and you + should refer to the `system_fingerprint` response parameter to monitor changes + in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will @@ -713,6 +874,20 @@ async def create( We generally recommend altering this or `top_p` but not both. + tool_choice: Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + + tools: A list of tools the model may call. Currently, only functions are supported as a + tool. Use this to provide a list of functions the model may generate JSON inputs + for. + top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. @@ -762,8 +937,12 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -797,18 +976,24 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) - function_call: Controls how the model calls functions. "none" means the model will not call a - function and instead generates a message. "auto" means the model can pick - between generating a message or calling a function. Specifying a particular - function via `{"name": "my_function"}` forces the model to call that function. - "none" is the default when no functions are present. "auto" is the default if + function_call: Deprecated in favor of `tool_choice`. + + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if functions are present. - functions: A list of functions the model may generate JSON inputs for. + functions: Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -830,6 +1015,15 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + response_format: An object specifying the format that the model must output. Used to enable JSON + mode. + + seed: This feature is in Beta. If specified, our system will make a best effort to + sample deterministically, such that repeated requests with the same `seed` and + parameters should return the same result. Determinism is not guaranteed, and you + should refer to the `system_fingerprint` response parameter to monitor changes + in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will @@ -838,6 +1032,20 @@ async def create( We generally recommend altering this or `top_p` but not both. + tool_choice: Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + + tools: A list of tools the model may call. Currently, only functions are supported as a + tool. Use this to provide a list of functions the model may generate JSON inputs + for. + top_p: An alternative to sampling with temperature, called nucleus sampling, where the model considers the results of the tokens with top_p probability mass. So 0.1 means only the tokens comprising the top 10% probability mass are considered. @@ -886,9 +1094,13 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, + tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN, + tools: List[ChatCompletionToolParam] | NotGiven = NOT_GIVEN, top_p: Optional[float] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. @@ -911,9 +1123,13 @@ async def create( "max_tokens": max_tokens, "n": n, "presence_penalty": presence_penalty, + "response_format": response_format, + "seed": seed, "stop": stop, "stream": stream, "temperature": temperature, + "tool_choice": tool_choice, + "tools": tools, "top_p": top_p, "user": user, }, diff --git a/src/openai/resources/completions.py b/src/openai/resources/completions.py index 26a34524c6..f1a938ba9a 100644 --- a/src/openai/resources/completions.py +++ b/src/openai/resources/completions.py @@ -54,6 +54,7 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, @@ -104,7 +105,7 @@ def create( logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -142,6 +143,13 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + seed: If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. @@ -209,6 +217,7 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, @@ -265,7 +274,7 @@ def create( logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -303,6 +312,13 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + seed: If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. @@ -363,6 +379,7 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, @@ -419,7 +436,7 @@ def create( logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -457,6 +474,13 @@ def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + seed: If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. @@ -516,6 +540,7 @@ def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, @@ -543,6 +568,7 @@ def create( "max_tokens": max_tokens, "n": n, "presence_penalty": presence_penalty, + "seed": seed, "stop": stop, "stream": stream, "suffix": suffix, @@ -596,6 +622,7 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, @@ -646,7 +673,7 @@ async def create( logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -684,6 +711,13 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + seed: If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. @@ -751,6 +785,7 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, @@ -807,7 +842,7 @@ async def create( logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -845,6 +880,13 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + seed: If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. @@ -905,6 +947,7 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, temperature: Optional[float] | NotGiven = NOT_GIVEN, @@ -961,7 +1004,7 @@ async def create( logit_bias: Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -999,6 +1042,13 @@ async def create( [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) + seed: If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + stop: Up to 4 sequences where the API will stop generating further tokens. The returned text will not contain the stop sequence. @@ -1058,6 +1108,7 @@ async def create( max_tokens: Optional[int] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, presence_penalty: Optional[float] | NotGiven = NOT_GIVEN, + seed: Optional[int] | NotGiven = NOT_GIVEN, stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN, stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN, suffix: Optional[str] | NotGiven = NOT_GIVEN, @@ -1085,6 +1136,7 @@ async def create( "max_tokens": max_tokens, "n": n, "presence_penalty": presence_penalty, + "seed": seed, "stop": stop, "stream": stream, "suffix": suffix, diff --git a/src/openai/resources/files.py b/src/openai/resources/files.py index d2e674c942..16d3944a12 100644 --- a/src/openai/resources/files.py +++ b/src/openai/resources/files.py @@ -4,8 +4,9 @@ import time from typing import TYPE_CHECKING, Mapping, cast +from typing_extensions import Literal -from ..types import FileObject, FileDeleted, file_create_params +from ..types import FileObject, FileDeleted, file_list_params, file_create_params from .._types import NOT_GIVEN, Body, Query, Headers, NotGiven, FileTypes from .._utils import extract_files, maybe_transform, deepcopy_minimal from .._resource import SyncAPIResource, AsyncAPIResource @@ -30,7 +31,7 @@ def create( self, *, file: FileTypes, - purpose: str, + purpose: Literal["fine-tune", "assistants"], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -40,22 +41,28 @@ def create( ) -> FileObject: """Upload a file that can be used across various endpoints/features. - Currently, the - size of all the files uploaded by one organization can be up to 1 GB. Please - [contact us](https://help.openai.com/) if you need to increase the storage - limit. + The size of + all the files uploaded by one organization can be up to 100 GB. - Args: - file: The file object (not file name) to be uploaded. + The size of individual files for can be a maximum of 512MB. See the + [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) to + learn more about the types of files supported. The Fine-tuning API only supports + `.jsonl` files. + + Please [contact us](https://help.openai.com/) if you need to increase these + storage limits. - If the `purpose` is set to "fine-tune", the file will be used for fine-tuning. + Args: + file: The File object (not file name) to be uploaded. purpose: The intended purpose of the uploaded file. Use "fine-tune" for - [fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning). This - allows us to validate the format of the uploaded file is correct for - fine-tuning. + [Fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning) and + "assistants" for + [Assistants](https://platform.openai.com/docs/api-reference/assistants) and + [Messages](https://platform.openai.com/docs/api-reference/messages). This allows + us to validate the format of the uploaded file is correct for fine-tuning. extra_headers: Send extra headers @@ -122,6 +129,7 @@ def retrieve( def list( self, *, + purpose: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -129,12 +137,29 @@ def list( extra_body: Body | None = None, timeout: float | None | NotGiven = NOT_GIVEN, ) -> SyncPage[FileObject]: - """Returns a list of files that belong to the user's organization.""" + """ + Returns a list of files that belong to the user's organization. + + Args: + purpose: Only return files with the given purpose. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ return self._get_api_list( "/files", page=SyncPage[FileObject], options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"purpose": purpose}, file_list_params.FileListParams), ), model=FileObject, ) @@ -237,7 +262,7 @@ async def create( self, *, file: FileTypes, - purpose: str, + purpose: Literal["fine-tune", "assistants"], # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -247,22 +272,28 @@ async def create( ) -> FileObject: """Upload a file that can be used across various endpoints/features. - Currently, the - size of all the files uploaded by one organization can be up to 1 GB. Please - [contact us](https://help.openai.com/) if you need to increase the storage - limit. + The size of + all the files uploaded by one organization can be up to 100 GB. - Args: - file: The file object (not file name) to be uploaded. + The size of individual files for can be a maximum of 512MB. See the + [Assistants Tools guide](https://platform.openai.com/docs/assistants/tools) to + learn more about the types of files supported. The Fine-tuning API only supports + `.jsonl` files. + + Please [contact us](https://help.openai.com/) if you need to increase these + storage limits. - If the `purpose` is set to "fine-tune", the file will be used for fine-tuning. + Args: + file: The File object (not file name) to be uploaded. purpose: The intended purpose of the uploaded file. Use "fine-tune" for - [fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning). This - allows us to validate the format of the uploaded file is correct for - fine-tuning. + [Fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning) and + "assistants" for + [Assistants](https://platform.openai.com/docs/api-reference/assistants) and + [Messages](https://platform.openai.com/docs/api-reference/messages). This allows + us to validate the format of the uploaded file is correct for fine-tuning. extra_headers: Send extra headers @@ -329,6 +360,7 @@ async def retrieve( def list( self, *, + purpose: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. extra_headers: Headers | None = None, @@ -336,12 +368,29 @@ def list( extra_body: Body | None = None, timeout: float | None | NotGiven = NOT_GIVEN, ) -> AsyncPaginator[FileObject, AsyncPage[FileObject]]: - """Returns a list of files that belong to the user's organization.""" + """ + Returns a list of files that belong to the user's organization. + + Args: + purpose: Only return files with the given purpose. + + extra_headers: Send extra headers + + extra_query: Add additional query parameters to the request + + extra_body: Add additional JSON properties to the request + + timeout: Override the client-level default timeout for this request, in seconds + """ return self._get_api_list( "/files", page=AsyncPage[FileObject], options=make_request_options( - extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout + extra_headers=extra_headers, + extra_query=extra_query, + extra_body=extra_body, + timeout=timeout, + query=maybe_transform({"purpose": purpose}, file_list_params.FileListParams), ), model=FileObject, ) diff --git a/src/openai/resources/images.py b/src/openai/resources/images.py index 1fd39b43a6..9d4ae9936a 100644 --- a/src/openai/resources/images.py +++ b/src/openai/resources/images.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Mapping, Optional, cast +from typing import TYPE_CHECKING, Union, Mapping, Optional, cast from typing_extensions import Literal from ..types import ( @@ -34,6 +34,7 @@ def create_variation( self, *, image: FileTypes, + model: Union[str, Literal["dall-e-2"], None] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, response_format: Optional[Literal["url", "b64_json"]] | NotGiven = NOT_GIVEN, size: Optional[Literal["256x256", "512x512", "1024x1024"]] | NotGiven = NOT_GIVEN, @@ -52,7 +53,11 @@ def create_variation( image: The image to use as the basis for the variation(s). Must be a valid PNG file, less than 4MB, and square. - n: The number of images to generate. Must be between 1 and 10. + model: The model to use for image generation. Only `dall-e-2` is supported at this + time. + + n: The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only + `n=1` is supported. response_format: The format in which the generated images are returned. Must be one of `url` or `b64_json`. @@ -75,6 +80,7 @@ def create_variation( body = deepcopy_minimal( { "image": image, + "model": model, "n": n, "response_format": response_format, "size": size, @@ -104,6 +110,7 @@ def edit( image: FileTypes, prompt: str, mask: FileTypes | NotGiven = NOT_GIVEN, + model: Union[str, Literal["dall-e-2"], None] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, response_format: Optional[Literal["url", "b64_json"]] | NotGiven = NOT_GIVEN, size: Optional[Literal["256x256", "512x512", "1024x1024"]] | NotGiven = NOT_GIVEN, @@ -129,6 +136,9 @@ def edit( indicate where `image` should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as `image`. + model: The model to use for image generation. Only `dall-e-2` is supported at this + time. + n: The number of images to generate. Must be between 1 and 10. response_format: The format in which the generated images are returned. Must be one of `url` or @@ -154,6 +164,7 @@ def edit( "image": image, "prompt": prompt, "mask": mask, + "model": model, "n": n, "response_format": response_format, "size": size, @@ -181,9 +192,12 @@ def generate( self, *, prompt: str, + model: Union[str, Literal["dall-e-2", "dall-e-3"], None] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, + quality: Literal["standard", "hd"] | NotGiven = NOT_GIVEN, response_format: Optional[Literal["url", "b64_json"]] | NotGiven = NOT_GIVEN, - size: Optional[Literal["256x256", "512x512", "1024x1024"]] | NotGiven = NOT_GIVEN, + size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] | NotGiven = NOT_GIVEN, + style: Optional[Literal["vivid", "natural"]] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -197,15 +211,28 @@ def generate( Args: prompt: A text description of the desired image(s). The maximum length is 1000 - characters. + characters for `dall-e-2` and 4000 characters for `dall-e-3`. - n: The number of images to generate. Must be between 1 and 10. + model: The model to use for image generation. + + n: The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only + `n=1` is supported. + + quality: The quality of the image that will be generated. `hd` creates images with finer + details and greater consistency across the image. This param is only supported + for `dall-e-3`. response_format: The format in which the generated images are returned. Must be one of `url` or `b64_json`. size: The size of the generated images. Must be one of `256x256`, `512x512`, or - `1024x1024`. + `1024x1024` for `dall-e-2`. Must be one of `1024x1024`, `1792x1024`, or + `1024x1792` for `dall-e-3` models. + + style: The style of the generated images. Must be one of `vivid` or `natural`. Vivid + causes the model to lean towards generating hyper-real and dramatic images. + Natural causes the model to produce more natural, less hyper-real looking + images. This param is only supported for `dall-e-3`. user: A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. @@ -224,9 +251,12 @@ def generate( body=maybe_transform( { "prompt": prompt, + "model": model, "n": n, + "quality": quality, "response_format": response_format, "size": size, + "style": style, "user": user, }, image_generate_params.ImageGenerateParams, @@ -249,6 +279,7 @@ async def create_variation( self, *, image: FileTypes, + model: Union[str, Literal["dall-e-2"], None] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, response_format: Optional[Literal["url", "b64_json"]] | NotGiven = NOT_GIVEN, size: Optional[Literal["256x256", "512x512", "1024x1024"]] | NotGiven = NOT_GIVEN, @@ -267,7 +298,11 @@ async def create_variation( image: The image to use as the basis for the variation(s). Must be a valid PNG file, less than 4MB, and square. - n: The number of images to generate. Must be between 1 and 10. + model: The model to use for image generation. Only `dall-e-2` is supported at this + time. + + n: The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only + `n=1` is supported. response_format: The format in which the generated images are returned. Must be one of `url` or `b64_json`. @@ -290,6 +325,7 @@ async def create_variation( body = deepcopy_minimal( { "image": image, + "model": model, "n": n, "response_format": response_format, "size": size, @@ -319,6 +355,7 @@ async def edit( image: FileTypes, prompt: str, mask: FileTypes | NotGiven = NOT_GIVEN, + model: Union[str, Literal["dall-e-2"], None] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, response_format: Optional[Literal["url", "b64_json"]] | NotGiven = NOT_GIVEN, size: Optional[Literal["256x256", "512x512", "1024x1024"]] | NotGiven = NOT_GIVEN, @@ -344,6 +381,9 @@ async def edit( indicate where `image` should be edited. Must be a valid PNG file, less than 4MB, and have the same dimensions as `image`. + model: The model to use for image generation. Only `dall-e-2` is supported at this + time. + n: The number of images to generate. Must be between 1 and 10. response_format: The format in which the generated images are returned. Must be one of `url` or @@ -369,6 +409,7 @@ async def edit( "image": image, "prompt": prompt, "mask": mask, + "model": model, "n": n, "response_format": response_format, "size": size, @@ -396,9 +437,12 @@ async def generate( self, *, prompt: str, + model: Union[str, Literal["dall-e-2", "dall-e-3"], None] | NotGiven = NOT_GIVEN, n: Optional[int] | NotGiven = NOT_GIVEN, + quality: Literal["standard", "hd"] | NotGiven = NOT_GIVEN, response_format: Optional[Literal["url", "b64_json"]] | NotGiven = NOT_GIVEN, - size: Optional[Literal["256x256", "512x512", "1024x1024"]] | NotGiven = NOT_GIVEN, + size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] | NotGiven = NOT_GIVEN, + style: Optional[Literal["vivid", "natural"]] | NotGiven = NOT_GIVEN, user: str | NotGiven = NOT_GIVEN, # Use the following arguments if you need to pass additional parameters to the API that aren't available via kwargs. # The extra values given here take precedence over values defined on the client or passed to this method. @@ -412,15 +456,28 @@ async def generate( Args: prompt: A text description of the desired image(s). The maximum length is 1000 - characters. + characters for `dall-e-2` and 4000 characters for `dall-e-3`. - n: The number of images to generate. Must be between 1 and 10. + model: The model to use for image generation. + + n: The number of images to generate. Must be between 1 and 10. For `dall-e-3`, only + `n=1` is supported. + + quality: The quality of the image that will be generated. `hd` creates images with finer + details and greater consistency across the image. This param is only supported + for `dall-e-3`. response_format: The format in which the generated images are returned. Must be one of `url` or `b64_json`. size: The size of the generated images. Must be one of `256x256`, `512x512`, or - `1024x1024`. + `1024x1024` for `dall-e-2`. Must be one of `1024x1024`, `1792x1024`, or + `1024x1792` for `dall-e-3` models. + + style: The style of the generated images. Must be one of `vivid` or `natural`. Vivid + causes the model to lean towards generating hyper-real and dramatic images. + Natural causes the model to produce more natural, less hyper-real looking + images. This param is only supported for `dall-e-3`. user: A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. @@ -439,9 +496,12 @@ async def generate( body=maybe_transform( { "prompt": prompt, + "model": model, "n": n, + "quality": quality, "response_format": response_format, "size": size, + "style": style, "user": user, }, image_generate_params.ImageGenerateParams, diff --git a/src/openai/types/__init__.py b/src/openai/types/__init__.py index defaf13446..8f21480d5e 100644 --- a/src/openai/types/__init__.py +++ b/src/openai/types/__init__.py @@ -16,6 +16,7 @@ from .fine_tune_event import FineTuneEvent as FineTuneEvent from .images_response import ImagesResponse as ImagesResponse from .completion_usage import CompletionUsage as CompletionUsage +from .file_list_params import FileListParams as FileListParams from .completion_choice import CompletionChoice as CompletionChoice from .image_edit_params import ImageEditParams as ImageEditParams from .edit_create_params import EditCreateParams as EditCreateParams diff --git a/src/openai/types/audio/__init__.py b/src/openai/types/audio/__init__.py index 469bc6f25b..83afa060f8 100644 --- a/src/openai/types/audio/__init__.py +++ b/src/openai/types/audio/__init__.py @@ -4,6 +4,7 @@ from .translation import Translation as Translation from .transcription import Transcription as Transcription +from .speech_create_params import SpeechCreateParams as SpeechCreateParams from .translation_create_params import ( TranslationCreateParams as TranslationCreateParams, ) diff --git a/src/openai/types/audio/speech_create_params.py b/src/openai/types/audio/speech_create_params.py new file mode 100644 index 0000000000..06bea01746 --- /dev/null +++ b/src/openai/types/audio/speech_create_params.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["SpeechCreateParams"] + + +class SpeechCreateParams(TypedDict, total=False): + input: Required[str] + """The text to generate audio for. The maximum length is 4096 characters.""" + + model: Required[Union[str, Literal["tts-1", "tts-1-hd"]]] + """ + One of the available [TTS models](https://platform.openai.com/docs/models/tts): + `tts-1` or `tts-1-hd` + """ + + voice: Required[Literal["alloy", "echo", "fable", "onyx", "nova", "shimmer"]] + """The voice to use when generating the audio. + + Supported voices are `alloy`, `echo`, `fable`, `onyx`, `nova`, and `shimmer`. + """ + + response_format: Literal["mp3", "opus", "aac", "flac"] + """The format to audio in. Supported formats are `mp3`, `opus`, `aac`, and `flac`.""" + + speed: float + """The speed of the generated audio. + + Select a value from `0.25` to `4.0`. `1.0` is the default. + """ diff --git a/src/openai/types/audio/transcription_create_params.py b/src/openai/types/audio/transcription_create_params.py index f8f193484a..7bd70d7b48 100644 --- a/src/openai/types/audio/transcription_create_params.py +++ b/src/openai/types/audio/transcription_create_params.py @@ -38,8 +38,8 @@ class TranscriptionCreateParams(TypedDict, total=False): response_format: Literal["json", "text", "srt", "verbose_json", "vtt"] """ - The format of the transcript output, in one of these options: json, text, srt, - verbose_json, or vtt. + The format of the transcript output, in one of these options: `json`, `text`, + `srt`, `verbose_json`, or `vtt`. """ temperature: float diff --git a/src/openai/types/audio/translation_create_params.py b/src/openai/types/audio/translation_create_params.py index bfa5fc56d2..d3cb4b9e63 100644 --- a/src/openai/types/audio/translation_create_params.py +++ b/src/openai/types/audio/translation_create_params.py @@ -30,8 +30,8 @@ class TranslationCreateParams(TypedDict, total=False): response_format: str """ - The format of the transcript output, in one of these options: json, text, srt, - verbose_json, or vtt. + The format of the transcript output, in one of these options: `json`, `text`, + `srt`, `verbose_json`, or `vtt`. """ temperature: float diff --git a/src/openai/types/beta/__init__.py b/src/openai/types/beta/__init__.py new file mode 100644 index 0000000000..8b834f286d --- /dev/null +++ b/src/openai/types/beta/__init__.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from .thread import Thread as Thread +from .assistant import Assistant as Assistant +from .thread_deleted import ThreadDeleted as ThreadDeleted +from .asssitant_deleted import AsssitantDeleted as AsssitantDeleted +from .thread_create_params import ThreadCreateParams as ThreadCreateParams +from .thread_update_params import ThreadUpdateParams as ThreadUpdateParams +from .assistant_list_params import AssistantListParams as AssistantListParams +from .assistant_create_params import AssistantCreateParams as AssistantCreateParams +from .assistant_update_params import AssistantUpdateParams as AssistantUpdateParams +from .thread_create_and_run_params import ( + ThreadCreateAndRunParams as ThreadCreateAndRunParams, +) diff --git a/src/openai/types/beta/assistant.py b/src/openai/types/beta/assistant.py new file mode 100644 index 0000000000..9130b60363 --- /dev/null +++ b/src/openai/types/beta/assistant.py @@ -0,0 +1,112 @@ +# File generated from our OpenAPI spec by Stainless. + +import builtins +from typing import Dict, List, Union, Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["Assistant", "Tool", "ToolCodeInterpreter", "ToolRetreival", "ToolFunction", "ToolFunctionFunction"] + + +class ToolCodeInterpreter(BaseModel): + type: Literal["code_interpreter"] + """The type of tool being defined: `code_interpreter`""" + + +class ToolRetreival(BaseModel): + type: Literal["retreival"] + """The type of tool being defined: `retreival`""" + + +class ToolFunctionFunction(BaseModel): + description: str + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + name: str + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Dict[str, builtins.object] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + +class ToolFunction(BaseModel): + function: ToolFunctionFunction + """The function definition.""" + + type: Literal["function"] + """The type of tool being defined: `function`""" + + +Tool = Union[ToolCodeInterpreter, ToolRetreival, ToolFunction] + + +class Assistant(BaseModel): + id: str + """The identifier, which can be referenced in API endpoints.""" + + created_at: int + """The Unix timestamp (in seconds) for when the assistant was created.""" + + description: Optional[str] + """The description of the assistant. The maximum length is 512 characters.""" + + file_ids: List[str] + """ + A list of [file](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. + """ + + instructions: Optional[str] + """The system instructions that the assistant uses. + + The maximum length is 32768 characters. + """ + + metadata: Optional[builtins.object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + model: str + """ID of the model to use. + + You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + """ + + name: Optional[str] + """The name of the assistant. The maximum length is 256 characters.""" + + object: Literal["assistant"] + """The object type, which is always `assistant`.""" + + tools: List[Tool] + """A list of tool enabled on the assistant. + + There can be a maximum of 128 tools per assistant. Tools can be of types + `code_interpreter`, `retrieval`, or `function`. + """ diff --git a/src/openai/types/beta/assistant_create_params.py b/src/openai/types/beta/assistant_create_params.py new file mode 100644 index 0000000000..8b8f025c39 --- /dev/null +++ b/src/openai/types/beta/assistant_create_params.py @@ -0,0 +1,109 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = [ + "AssistantCreateParams", + "Tool", + "ToolAssistantToolsCode", + "ToolAssistantToolsRetrieval", + "ToolAssistantToolsFunction", + "ToolAssistantToolsFunctionFunction", +] + + +class AssistantCreateParams(TypedDict, total=False): + model: Required[str] + """ID of the model to use. + + You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + """ + + description: Optional[str] + """The description of the assistant. The maximum length is 512 characters.""" + + file_ids: List[str] + """ + A list of [file](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. + """ + + instructions: Optional[str] + """The system instructions that the assistant uses. + + The maximum length is 32768 characters. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + name: Optional[str] + """The name of the assistant. The maximum length is 256 characters.""" + + tools: List[Tool] + """A list of tool enabled on the assistant. + + There can be a maximum of 128 tools per assistant. Tools can be of types + `code_interpreter`, `retrieval`, or `function`. + """ + + +class ToolAssistantToolsCode(TypedDict, total=False): + type: Required[Literal["code_interpreter"]] + """The type of tool being defined: `code_interpreter`""" + + +class ToolAssistantToolsRetrieval(TypedDict, total=False): + type: Required[Literal["retreival"]] + """The type of tool being defined: `retreival`""" + + +class ToolAssistantToolsFunctionFunction(TypedDict, total=False): + description: Required[str] + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + name: Required[str] + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Required[Dict[str, object]] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + +class ToolAssistantToolsFunction(TypedDict, total=False): + function: Required[ToolAssistantToolsFunctionFunction] + """The function definition.""" + + type: Required[Literal["function"]] + """The type of tool being defined: `function`""" + + +Tool = Union[ToolAssistantToolsCode, ToolAssistantToolsRetrieval, ToolAssistantToolsFunction] diff --git a/src/openai/types/beta/assistant_list_params.py b/src/openai/types/beta/assistant_list_params.py new file mode 100644 index 0000000000..b2d794a43a --- /dev/null +++ b/src/openai/types/beta/assistant_list_params.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["AssistantListParams"] + + +class AssistantListParams(TypedDict, total=False): + after: str + """A cursor for use in pagination. + + `after` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include after=obj_foo in order to fetch the next page of the + list. + """ + + before: str + """A cursor for use in pagination. + + `before` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page + of the list. + """ + + limit: int + """A limit on the number of objects to be returned. + + Limit can range between 1 and 100, and the default is 20. + """ + + order: Literal["asc", "desc"] + """Sort order by the `created_at` timestamp of the objects. + + `asc` for ascending order and `desc` for descending order. + """ diff --git a/src/openai/types/beta/assistant_update_params.py b/src/openai/types/beta/assistant_update_params.py new file mode 100644 index 0000000000..fa838f51e3 --- /dev/null +++ b/src/openai/types/beta/assistant_update_params.py @@ -0,0 +1,111 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = [ + "AssistantUpdateParams", + "Tool", + "ToolAssistantToolsCode", + "ToolAssistantToolsRetrieval", + "ToolAssistantToolsFunction", + "ToolAssistantToolsFunctionFunction", +] + + +class AssistantUpdateParams(TypedDict, total=False): + description: Optional[str] + """The description of the assistant. The maximum length is 512 characters.""" + + file_ids: List[str] + """ + A list of [File](https://platform.openai.com/docs/api-reference/files) IDs + attached to this assistant. There can be a maximum of 20 files attached to the + assistant. Files are ordered by their creation date in ascending order. If a + file was previosuly attached to the list but does not show up in the list, it + will be deleted from the assistant. + """ + + instructions: Optional[str] + """The system instructions that the assistant uses. + + The maximum length is 32768 characters. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + model: str + """ID of the model to use. + + You can use the + [List models](https://platform.openai.com/docs/api-reference/models/list) API to + see all of your available models, or see our + [Model overview](https://platform.openai.com/docs/models/overview) for + descriptions of them. + """ + + name: Optional[str] + """The name of the assistant. The maximum length is 256 characters.""" + + tools: List[Tool] + """A list of tool enabled on the assistant. + + There can be a maximum of 128 tools per assistant. Tools can be of types + `code_interpreter`, `retrieval`, or `function`. + """ + + +class ToolAssistantToolsCode(TypedDict, total=False): + type: Required[Literal["code_interpreter"]] + """The type of tool being defined: `code_interpreter`""" + + +class ToolAssistantToolsRetrieval(TypedDict, total=False): + type: Required[Literal["retreival"]] + """The type of tool being defined: `retreival`""" + + +class ToolAssistantToolsFunctionFunction(TypedDict, total=False): + description: Required[str] + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + name: Required[str] + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Required[Dict[str, object]] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + +class ToolAssistantToolsFunction(TypedDict, total=False): + function: Required[ToolAssistantToolsFunctionFunction] + """The function definition.""" + + type: Required[Literal["function"]] + """The type of tool being defined: `function`""" + + +Tool = Union[ToolAssistantToolsCode, ToolAssistantToolsRetrieval, ToolAssistantToolsFunction] diff --git a/src/openai/types/beta/assistants/__init__.py b/src/openai/types/beta/assistants/__init__.py new file mode 100644 index 0000000000..9dbb3e2b8b --- /dev/null +++ b/src/openai/types/beta/assistants/__init__.py @@ -0,0 +1,8 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from .assistant_file import AssistantFile as AssistantFile +from .file_list_params import FileListParams as FileListParams +from .file_create_params import FileCreateParams as FileCreateParams +from .file_delete_response import FileDeleteResponse as FileDeleteResponse diff --git a/src/openai/types/beta/assistants/assistant_file.py b/src/openai/types/beta/assistants/assistant_file.py new file mode 100644 index 0000000000..1d1573ac0f --- /dev/null +++ b/src/openai/types/beta/assistants/assistant_file.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["AssistantFile"] + + +class AssistantFile(BaseModel): + id: str + """The identifier, which can be referenced in API endpoints.""" + + assistant_id: str + """The assistant ID that the file is attached to.""" + + created_at: int + """The Unix timestamp (in seconds) for when the assistant file was created.""" + + object: Literal["assistant.file"] + """The object type, which is always `assistant.file`.""" diff --git a/src/openai/types/beta/assistants/file_create_params.py b/src/openai/types/beta/assistants/file_create_params.py new file mode 100644 index 0000000000..f70f96fc1b --- /dev/null +++ b/src/openai/types/beta/assistants/file_create_params.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["FileCreateParams"] + + +class FileCreateParams(TypedDict, total=False): + file_id: Required[str] + """ + A [File](https://platform.openai.com/docs/api-reference/files) ID (with + `purpose="assistants"`) that the assistant should use. Useful for tools like + `retrieval` and `code_interpreter` that can access files. + """ diff --git a/src/openai/types/beta/assistants/file_delete_response.py b/src/openai/types/beta/assistants/file_delete_response.py new file mode 100644 index 0000000000..52c138feda --- /dev/null +++ b/src/openai/types/beta/assistants/file_delete_response.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["FileDeleteResponse"] + + +class FileDeleteResponse(BaseModel): + id: str + + deleted: bool + + object: Literal["assistant.file.deleted"] diff --git a/src/openai/types/beta/assistants/file_list_params.py b/src/openai/types/beta/assistants/file_list_params.py new file mode 100644 index 0000000000..397e35a0d1 --- /dev/null +++ b/src/openai/types/beta/assistants/file_list_params.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["FileListParams"] + + +class FileListParams(TypedDict, total=False): + after: str + """A cursor for use in pagination. + + `after` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include after=obj_foo in order to fetch the next page of the + list. + """ + + before: str + """A cursor for use in pagination. + + `before` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page + of the list. + """ + + limit: int + """A limit on the number of objects to be returned. + + Limit can range between 1 and 100, and the default is 20. + """ + + order: Literal["asc", "desc"] + """Sort order by the `created_at` timestamp of the objects. + + `asc` for ascending order and `desc` for descending order. + """ diff --git a/src/openai/types/beta/asssitant_deleted.py b/src/openai/types/beta/asssitant_deleted.py new file mode 100644 index 0000000000..258210e7fe --- /dev/null +++ b/src/openai/types/beta/asssitant_deleted.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["AsssitantDeleted"] + + +class AsssitantDeleted(BaseModel): + id: str + + deleted: bool + + object: Literal["assistant.deleted"] diff --git a/src/openai/types/beta/chat/__init__.py b/src/openai/types/beta/chat/__init__.py new file mode 100644 index 0000000000..b2f53e3525 --- /dev/null +++ b/src/openai/types/beta/chat/__init__.py @@ -0,0 +1,3 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations diff --git a/src/openai/types/beta/thread.py b/src/openai/types/beta/thread.py new file mode 100644 index 0000000000..a340bffd60 --- /dev/null +++ b/src/openai/types/beta/thread.py @@ -0,0 +1,28 @@ +# File generated from our OpenAPI spec by Stainless. + +import builtins +from typing import Optional +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["Thread"] + + +class Thread(BaseModel): + id: str + """The identifier, which can be referenced in API endpoints.""" + + created_at: int + """The Unix timestamp (in seconds) for when the thread was created.""" + + metadata: Optional[builtins.object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + object: Literal["thread"] + """The object type, which is always `thread`.""" diff --git a/src/openai/types/beta/thread_create_and_run_params.py b/src/openai/types/beta/thread_create_and_run_params.py new file mode 100644 index 0000000000..2955343ec0 --- /dev/null +++ b/src/openai/types/beta/thread_create_and_run_params.py @@ -0,0 +1,148 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = [ + "ThreadCreateAndRunParams", + "Thread", + "ThreadMessage", + "Tool", + "ToolAssistantToolsCode", + "ToolAssistantToolsRetrieval", + "ToolAssistantToolsFunction", + "ToolAssistantToolsFunctionFunction", +] + + +class ThreadCreateAndRunParams(TypedDict, total=False): + assistant_id: Required[str] + """ + The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to + execute this run. + """ + + instructions: Optional[str] + """Override the default system message of the assistant. + + This is useful for modifying the behavior on a per-run basis. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + model: Optional[str] + """ + The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to + be used to execute this run. If a value is provided here, it will override the + model associated with the assistant. If not, the model associated with the + assistant will be used. + """ + + thread: Thread + """If no thread is provided, an empty thread will be created.""" + + tools: Optional[List[Tool]] + """Override the tools the assistant can use for this run. + + This is useful for modifying the behavior on a per-run basis. + """ + + +class ThreadMessage(TypedDict, total=False): + content: Required[str] + """The content of the message.""" + + role: Required[Literal["user"]] + """The role of the entity that is creating the message. + + Currently only `user` is supported. + """ + + file_ids: List[str] + """ + A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that + the message should use. There can be a maximum of 10 files attached to a + message. Useful for tools like `retrieval` and `code_interpreter` that can + access and use files. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + +class Thread(TypedDict, total=False): + messages: List[ThreadMessage] + """ + A list of [messages](https://platform.openai.com/docs/api-reference/messages) to + start the thread with. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + +class ToolAssistantToolsCode(TypedDict, total=False): + type: Required[Literal["code_interpreter"]] + """The type of tool being defined: `code_interpreter`""" + + +class ToolAssistantToolsRetrieval(TypedDict, total=False): + type: Required[Literal["retreival"]] + """The type of tool being defined: `retreival`""" + + +class ToolAssistantToolsFunctionFunction(TypedDict, total=False): + description: Required[str] + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + name: Required[str] + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Required[Dict[str, object]] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + +class ToolAssistantToolsFunction(TypedDict, total=False): + function: Required[ToolAssistantToolsFunctionFunction] + """The function definition.""" + + type: Required[Literal["function"]] + """The type of tool being defined: `function`""" + + +Tool = Union[ToolAssistantToolsCode, ToolAssistantToolsRetrieval, ToolAssistantToolsFunction] diff --git a/src/openai/types/beta/thread_create_params.py b/src/openai/types/beta/thread_create_params.py new file mode 100644 index 0000000000..d2ec78bbc3 --- /dev/null +++ b/src/openai/types/beta/thread_create_params.py @@ -0,0 +1,51 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ThreadCreateParams", "Message"] + + +class ThreadCreateParams(TypedDict, total=False): + messages: List[Message] + """ + A list of [messages](https://platform.openai.com/docs/api-reference/messages) to + start the thread with. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + +class Message(TypedDict, total=False): + content: Required[str] + """The content of the message.""" + + role: Required[Literal["user"]] + """The role of the entity that is creating the message. + + Currently only `user` is supported. + """ + + file_ids: List[str] + """ + A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that + the message should use. There can be a maximum of 10 files attached to a + message. Useful for tools like `retrieval` and `code_interpreter` that can + access and use files. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ diff --git a/src/openai/types/beta/thread_deleted.py b/src/openai/types/beta/thread_deleted.py new file mode 100644 index 0000000000..410ac1aea0 --- /dev/null +++ b/src/openai/types/beta/thread_deleted.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ThreadDeleted"] + + +class ThreadDeleted(BaseModel): + id: str + + deleted: bool + + object: Literal["thread.deleted"] diff --git a/src/openai/types/beta/thread_update_params.py b/src/openai/types/beta/thread_update_params.py new file mode 100644 index 0000000000..6c1d32fc57 --- /dev/null +++ b/src/openai/types/beta/thread_update_params.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import TypedDict + +__all__ = ["ThreadUpdateParams"] + + +class ThreadUpdateParams(TypedDict, total=False): + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ diff --git a/src/openai/types/beta/threads/__init__.py b/src/openai/types/beta/threads/__init__.py new file mode 100644 index 0000000000..0cb557a514 --- /dev/null +++ b/src/openai/types/beta/threads/__init__.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from .run import Run as Run +from .thread_message import ThreadMessage as ThreadMessage +from .run_list_params import RunListParams as RunListParams +from .run_create_params import RunCreateParams as RunCreateParams +from .run_update_params import RunUpdateParams as RunUpdateParams +from .message_list_params import MessageListParams as MessageListParams +from .message_content_text import MessageContentText as MessageContentText +from .message_create_params import MessageCreateParams as MessageCreateParams +from .message_update_params import MessageUpdateParams as MessageUpdateParams +from .message_content_image_file import ( + MessageContentImageFile as MessageContentImageFile, +) +from .run_submit_tool_outputs_params import ( + RunSubmitToolOutputsParams as RunSubmitToolOutputsParams, +) +from .required_action_function_tool_call import ( + RequiredActionFunctionToolCall as RequiredActionFunctionToolCall, +) diff --git a/src/openai/types/beta/threads/message_content_image_file.py b/src/openai/types/beta/threads/message_content_image_file.py new file mode 100644 index 0000000000..eeba5a633c --- /dev/null +++ b/src/openai/types/beta/threads/message_content_image_file.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["MessageContentImageFile", "ImageFile"] + + +class ImageFile(BaseModel): + file_id: str + """ + The [File](https://platform.openai.com/docs/api-reference/files) ID of the image + in the message content. + """ + + +class MessageContentImageFile(BaseModel): + image_file: ImageFile + + type: Literal["image_file"] + """Always `image_file`.""" diff --git a/src/openai/types/beta/threads/message_content_text.py b/src/openai/types/beta/threads/message_content_text.py new file mode 100644 index 0000000000..b529a384c6 --- /dev/null +++ b/src/openai/types/beta/threads/message_content_text.py @@ -0,0 +1,74 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing import List, Union +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = [ + "MessageContentText", + "Text", + "TextAnnotation", + "TextAnnotationFileCitation", + "TextAnnotationFileCitationFileCitation", + "TextAnnotationFilePath", + "TextAnnotationFilePathFilePath", +] + + +class TextAnnotationFileCitationFileCitation(BaseModel): + file_id: str + """The ID of the specific File the citation is from.""" + + quote: str + """The specific quote in the file.""" + + +class TextAnnotationFileCitation(BaseModel): + end_index: int + + file_citation: TextAnnotationFileCitationFileCitation + + start_index: int + + text: str + """The text in the message content that needs to be replaced.""" + + type: Literal["file_citation"] + """Always `file_citation`.""" + + +class TextAnnotationFilePathFilePath(BaseModel): + file_id: str + """The ID of the file that was generated.""" + + +class TextAnnotationFilePath(BaseModel): + end_index: int + + file_path: TextAnnotationFilePathFilePath + + start_index: int + + text: str + """The text in the message content that needs to be replaced.""" + + type: Literal["file_path"] + """Always `file_path`.""" + + +TextAnnotation = Union[TextAnnotationFileCitation, TextAnnotationFilePath] + + +class Text(BaseModel): + annotations: List[TextAnnotation] + + value: str + """The data that makes up the text.""" + + +class MessageContentText(BaseModel): + text: Text + + type: Literal["text"] + """Always `text`.""" diff --git a/src/openai/types/beta/threads/message_create_params.py b/src/openai/types/beta/threads/message_create_params.py new file mode 100644 index 0000000000..8733f10b8a --- /dev/null +++ b/src/openai/types/beta/threads/message_create_params.py @@ -0,0 +1,35 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["MessageCreateParams"] + + +class MessageCreateParams(TypedDict, total=False): + content: Required[str] + """The content of the message.""" + + role: Required[Literal["user"]] + """The role of the entity that is creating the message. + + Currently only `user` is supported. + """ + + file_ids: List[str] + """ + A list of [File](https://platform.openai.com/docs/api-reference/files) IDs that + the message should use. There can be a maximum of 10 files attached to a + message. Useful for tools like `retrieval` and `code_interpreter` that can + access and use files. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ diff --git a/src/openai/types/beta/threads/message_list_params.py b/src/openai/types/beta/threads/message_list_params.py new file mode 100644 index 0000000000..31e407bb22 --- /dev/null +++ b/src/openai/types/beta/threads/message_list_params.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["MessageListParams"] + + +class MessageListParams(TypedDict, total=False): + after: str + """A cursor for use in pagination. + + `after` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include after=obj_foo in order to fetch the next page of the + list. + """ + + before: str + """A cursor for use in pagination. + + `before` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page + of the list. + """ + + limit: int + """A limit on the number of objects to be returned. + + Limit can range between 1 and 100, and the default is 20. + """ + + order: Literal["asc", "desc"] + """Sort order by the `created_at` timestamp of the objects. + + `asc` for ascending order and `desc` for descending order. + """ diff --git a/src/openai/types/beta/threads/message_update_params.py b/src/openai/types/beta/threads/message_update_params.py new file mode 100644 index 0000000000..2e3e1b4b1a --- /dev/null +++ b/src/openai/types/beta/threads/message_update_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["MessageUpdateParams"] + + +class MessageUpdateParams(TypedDict, total=False): + thread_id: Required[str] + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ diff --git a/src/openai/types/beta/threads/messages/__init__.py b/src/openai/types/beta/threads/messages/__init__.py new file mode 100644 index 0000000000..6046f68204 --- /dev/null +++ b/src/openai/types/beta/threads/messages/__init__.py @@ -0,0 +1,6 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from .message_file import MessageFile as MessageFile +from .file_list_params import FileListParams as FileListParams diff --git a/src/openai/types/beta/threads/messages/file_list_params.py b/src/openai/types/beta/threads/messages/file_list_params.py new file mode 100644 index 0000000000..3640b8508b --- /dev/null +++ b/src/openai/types/beta/threads/messages/file_list_params.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["FileListParams"] + + +class FileListParams(TypedDict, total=False): + thread_id: Required[str] + + after: str + """A cursor for use in pagination. + + `after` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include after=obj_foo in order to fetch the next page of the + list. + """ + + before: str + """A cursor for use in pagination. + + `before` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page + of the list. + """ + + limit: int + """A limit on the number of objects to be returned. + + Limit can range between 1 and 100, and the default is 20. + """ + + order: Literal["asc", "desc"] + """Sort order by the `created_at` timestamp of the objects. + + `asc` for ascending order and `desc` for descending order. + """ diff --git a/src/openai/types/beta/threads/messages/message_file.py b/src/openai/types/beta/threads/messages/message_file.py new file mode 100644 index 0000000000..5332dee962 --- /dev/null +++ b/src/openai/types/beta/threads/messages/message_file.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["MessageFile"] + + +class MessageFile(BaseModel): + id: str + """The identifier, which can be referenced in API endpoints.""" + + created_at: int + """The Unix timestamp (in seconds) for when the message file was created.""" + + message_id: str + """ + The ID of the [message](https://platform.openai.com/docs/api-reference/messages) + that the [File](https://platform.openai.com/docs/api-reference/files) is + attached to. + """ + + object: Literal["thread.message.file"] + """The object type, which is always `thread.message.file`.""" diff --git a/src/openai/types/beta/threads/required_action_function_tool_call.py b/src/openai/types/beta/threads/required_action_function_tool_call.py new file mode 100644 index 0000000000..0284d0f188 --- /dev/null +++ b/src/openai/types/beta/threads/required_action_function_tool_call.py @@ -0,0 +1,34 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ...._models import BaseModel + +__all__ = ["RequiredActionFunctionToolCall", "Function"] + + +class Function(BaseModel): + arguments: str + """The arguments that the model expects you to pass to the function.""" + + name: str + """The name of the function.""" + + +class RequiredActionFunctionToolCall(BaseModel): + id: str + """The ID of the tool call. + + This ID must be referenced when you submit the tool outputs in using the + [Submit tool outputs to run](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) + endpoint. + """ + + function: Function + """The function definition.""" + + type: Literal["function"] + """The type of tool call the output is required for. + + For now, this is always `function`. + """ diff --git a/src/openai/types/beta/threads/run.py b/src/openai/types/beta/threads/run.py new file mode 100644 index 0000000000..d06152fa5b --- /dev/null +++ b/src/openai/types/beta/threads/run.py @@ -0,0 +1,182 @@ +# File generated from our OpenAPI spec by Stainless. + +import builtins +from typing import Dict, List, Union, Optional +from typing_extensions import Literal + +from ...._models import BaseModel +from .required_action_function_tool_call import RequiredActionFunctionToolCall + +__all__ = [ + "Run", + "LastError", + "RequiredAction", + "RequiredActionSubmitToolOutputs", + "Tool", + "ToolAssistantToolsCode", + "ToolAssistantToolsRetrieval", + "ToolAssistantToolsFunction", + "ToolAssistantToolsFunctionFunction", +] + + +class LastError(BaseModel): + code: Literal["server_error", "rate_limit_exceeded"] + """One of `server_error` or `rate_limit_exceeded`.""" + + message: str + """A human-readable description of the error.""" + + +class RequiredActionSubmitToolOutputs(BaseModel): + tool_calls: List[RequiredActionFunctionToolCall] + """A list of the relevant tool calls.""" + + +class RequiredAction(BaseModel): + submit_tool_outputs: RequiredActionSubmitToolOutputs + """Details on the tool outputs needed for this run to continue.""" + + type: Literal["submit_tool_outputs"] + """For now, this is always `submit_tool_outputs`.""" + + +class ToolAssistantToolsCode(BaseModel): + type: Literal["code_interpreter"] + """The type of tool being defined: `code_interpreter`""" + + +class ToolAssistantToolsRetrieval(BaseModel): + type: Literal["retreival"] + """The type of tool being defined: `retreival`""" + + +class ToolAssistantToolsFunctionFunction(BaseModel): + description: str + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + name: str + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Dict[str, builtins.object] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + +class ToolAssistantToolsFunction(BaseModel): + function: ToolAssistantToolsFunctionFunction + """The function definition.""" + + type: Literal["function"] + """The type of tool being defined: `function`""" + + +Tool = Union[ToolAssistantToolsCode, ToolAssistantToolsRetrieval, ToolAssistantToolsFunction] + + +class Run(BaseModel): + id: str + """The identifier, which can be referenced in API endpoints.""" + + assistant_id: str + """ + The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) used for + execution of this run. + """ + + cancelled_at: Optional[int] + """The Unix timestamp (in seconds) for when the run was cancelled.""" + + completed_at: Optional[int] + """The Unix timestamp (in seconds) for when the run was completed.""" + + created_at: int + """The Unix timestamp (in seconds) for when the run was created.""" + + expires_at: int + """The Unix timestamp (in seconds) for when the run will expire.""" + + failed_at: Optional[int] + """The Unix timestamp (in seconds) for when the run failed.""" + + file_ids: List[str] + """ + The list of [File](https://platform.openai.com/docs/api-reference/files) IDs the + [assistant](https://platform.openai.com/docs/api-reference/assistants) used for + this run. + """ + + instructions: str + """ + The instructions that the + [assistant](https://platform.openai.com/docs/api-reference/assistants) used for + this run. + """ + + last_error: Optional[LastError] + """The last error associated with this run. Will be `null` if there are no errors.""" + + metadata: Optional[builtins.object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + model: str + """ + The model that the + [assistant](https://platform.openai.com/docs/api-reference/assistants) used for + this run. + """ + + object: Literal["assistant.run"] + """The object type, which is always `assistant.run`.""" + + required_action: Optional[RequiredAction] + """Details on the action required to continue the run. + + Will be `null` if no action is required. + """ + + started_at: Optional[int] + """The Unix timestamp (in seconds) for when the run was started.""" + + status: Literal[ + "queued", "in_progress", "requires_action", "cancelling", "cancelled", "failed", "completed", "expired" + ] + """ + The status of the run, which can be either `queued`, `in_progress`, + `requires_action`, `cancelling`, `cancelled`, `failed`, `completed`, or + `expired`. + """ + + thread_id: str + """ + The ID of the [thread](https://platform.openai.com/docs/api-reference/threads) + that was executed on as a part of this run. + """ + + tools: List[Tool] + """ + The list of tools that the + [assistant](https://platform.openai.com/docs/api-reference/assistants) used for + this run. + """ diff --git a/src/openai/types/beta/threads/run_create_params.py b/src/openai/types/beta/threads/run_create_params.py new file mode 100644 index 0000000000..41d2eeea03 --- /dev/null +++ b/src/openai/types/beta/threads/run_create_params.py @@ -0,0 +1,100 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Dict, List, Union, Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = [ + "RunCreateParams", + "Tool", + "ToolAssistantToolsCode", + "ToolAssistantToolsRetrieval", + "ToolAssistantToolsFunction", + "ToolAssistantToolsFunctionFunction", +] + + +class RunCreateParams(TypedDict, total=False): + assistant_id: Required[str] + """ + The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) to use to + execute this run. + """ + + instructions: Optional[str] + """Override the default system message of the assistant. + + This is useful for modifying the behavior on a per-run basis. + """ + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + model: Optional[str] + """ + The ID of the [Model](https://platform.openai.com/docs/api-reference/models) to + be used to execute this run. If a value is provided here, it will override the + model associated with the assistant. If not, the model associated with the + assistant will be used. + """ + + tools: Optional[List[Tool]] + """Override the tools the assistant can use for this run. + + This is useful for modifying the behavior on a per-run basis. + """ + + +class ToolAssistantToolsCode(TypedDict, total=False): + type: Required[Literal["code_interpreter"]] + """The type of tool being defined: `code_interpreter`""" + + +class ToolAssistantToolsRetrieval(TypedDict, total=False): + type: Required[Literal["retreival"]] + """The type of tool being defined: `retreival`""" + + +class ToolAssistantToolsFunctionFunction(TypedDict, total=False): + description: Required[str] + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + name: Required[str] + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Required[Dict[str, object]] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + +class ToolAssistantToolsFunction(TypedDict, total=False): + function: Required[ToolAssistantToolsFunctionFunction] + """The function definition.""" + + type: Required[Literal["function"]] + """The type of tool being defined: `function`""" + + +Tool = Union[ToolAssistantToolsCode, ToolAssistantToolsRetrieval, ToolAssistantToolsFunction] diff --git a/src/openai/types/beta/threads/run_list_params.py b/src/openai/types/beta/threads/run_list_params.py new file mode 100644 index 0000000000..5f41347718 --- /dev/null +++ b/src/openai/types/beta/threads/run_list_params.py @@ -0,0 +1,39 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, TypedDict + +__all__ = ["RunListParams"] + + +class RunListParams(TypedDict, total=False): + after: str + """A cursor for use in pagination. + + `after` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include after=obj_foo in order to fetch the next page of the + list. + """ + + before: str + """A cursor for use in pagination. + + `before` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page + of the list. + """ + + limit: int + """A limit on the number of objects to be returned. + + Limit can range between 1 and 100, and the default is 20. + """ + + order: Literal["asc", "desc"] + """Sort order by the `created_at` timestamp of the objects. + + `asc` for ascending order and `desc` for descending order. + """ diff --git a/src/openai/types/beta/threads/run_submit_tool_outputs_params.py b/src/openai/types/beta/threads/run_submit_tool_outputs_params.py new file mode 100644 index 0000000000..a960f0f06f --- /dev/null +++ b/src/openai/types/beta/threads/run_submit_tool_outputs_params.py @@ -0,0 +1,26 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import List +from typing_extensions import Required, TypedDict + +__all__ = ["RunSubmitToolOutputsParams", "ToolOutput"] + + +class RunSubmitToolOutputsParams(TypedDict, total=False): + thread_id: Required[str] + + tool_outputs: Required[List[ToolOutput]] + """A list of tools for which the outputs are being submitted.""" + + +class ToolOutput(TypedDict, total=False): + output: str + """The output of the tool call to be submitted to continue the run.""" + + tool_call_id: str + """ + The ID of the tool call in the `required_action` object within the run object + the output is being submitted for. + """ diff --git a/src/openai/types/beta/threads/run_update_params.py b/src/openai/types/beta/threads/run_update_params.py new file mode 100644 index 0000000000..09f81aa003 --- /dev/null +++ b/src/openai/types/beta/threads/run_update_params.py @@ -0,0 +1,20 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Required, TypedDict + +__all__ = ["RunUpdateParams"] + + +class RunUpdateParams(TypedDict, total=False): + thread_id: Required[str] + + metadata: Optional[object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ diff --git a/src/openai/types/beta/threads/runs/__init__.py b/src/openai/types/beta/threads/runs/__init__.py new file mode 100644 index 0000000000..72b972a986 --- /dev/null +++ b/src/openai/types/beta/threads/runs/__init__.py @@ -0,0 +1,13 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from .run_step import RunStep as RunStep +from .code_tool_call import CodeToolCall as CodeToolCall +from .step_list_params import StepListParams as StepListParams +from .function_tool_call import FunctionToolCall as FunctionToolCall +from .retrieval_tool_call import RetrievalToolCall as RetrievalToolCall +from .tool_calls_step_details import ToolCallsStepDetails as ToolCallsStepDetails +from .message_creation_step_details import ( + MessageCreationStepDetails as MessageCreationStepDetails, +) diff --git a/src/openai/types/beta/threads/runs/code_tool_call.py b/src/openai/types/beta/threads/runs/code_tool_call.py new file mode 100644 index 0000000000..f808005ecb --- /dev/null +++ b/src/openai/types/beta/threads/runs/code_tool_call.py @@ -0,0 +1,67 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing import List, Union +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = [ + "CodeToolCall", + "CodeInterpreter", + "CodeInterpreterOutput", + "CodeInterpreterOutputLogs", + "CodeInterpreterOutputImage", + "CodeInterpreterOutputImageImage", +] + + +class CodeInterpreterOutputLogs(BaseModel): + logs: str + """The text output from the Code Interpreter tool call.""" + + type: Literal["logs"] + """Always `logs`.""" + + +class CodeInterpreterOutputImageImage(BaseModel): + file_id: str + """ + The [file](https://platform.openai.com/docs/api-reference/files) ID of the + image. + """ + + +class CodeInterpreterOutputImage(BaseModel): + image: CodeInterpreterOutputImageImage + + type: Literal["image"] + """Always `image`.""" + + +CodeInterpreterOutput = Union[CodeInterpreterOutputLogs, CodeInterpreterOutputImage] + + +class CodeInterpreter(BaseModel): + input: str + """The input to the Code Interpreter tool call.""" + + outputs: List[CodeInterpreterOutput] + """The outputs from the Code Interpreter tool call. + + Code Interpreter can output one or more items, including text (`logs`) or images + (`image`). Each of these are represented by a different object type. + """ + + +class CodeToolCall(BaseModel): + id: str + """The ID of the tool call.""" + + code_interpreter: CodeInterpreter + """The Code Interpreter tool call definition.""" + + type: Literal["code_interpreter"] + """The type of tool call. + + This is always going to be `code_interpreter` for this type of tool call. + """ diff --git a/src/openai/types/beta/threads/runs/function_tool_call.py b/src/openai/types/beta/threads/runs/function_tool_call.py new file mode 100644 index 0000000000..f4cf8bbdd0 --- /dev/null +++ b/src/openai/types/beta/threads/runs/function_tool_call.py @@ -0,0 +1,38 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing import Optional +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["FunctionToolCall", "Function"] + + +class Function(BaseModel): + arguments: str + """The arguments passed to the function.""" + + name: str + """The name of the function.""" + + output: Optional[str] + """The output of the function. + + This will be `null` if the outputs have not been + [submitted](https://platform.openai.com/docs/api-reference/runs/submitToolOutputs) + yet. + """ + + +class FunctionToolCall(BaseModel): + id: str + """The ID of the tool call object.""" + + function: Function + """The definition of the function that was called.""" + + type: Literal["function"] + """The type of tool call. + + This is always going to be `function` for this type of tool call. + """ diff --git a/src/openai/types/beta/threads/runs/message_creation_step_details.py b/src/openai/types/beta/threads/runs/message_creation_step_details.py new file mode 100644 index 0000000000..29f9106ec0 --- /dev/null +++ b/src/openai/types/beta/threads/runs/message_creation_step_details.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["MessageCreationStepDetails", "MessageCreation"] + + +class MessageCreation(BaseModel): + message_id: str + """The ID of the message that was created by this run step.""" + + +class MessageCreationStepDetails(BaseModel): + message_creation: MessageCreation + + type: Literal["message_creation"] + """Always `message_creation``.""" diff --git a/src/openai/types/beta/threads/runs/retrieval_tool_call.py b/src/openai/types/beta/threads/runs/retrieval_tool_call.py new file mode 100644 index 0000000000..6cdbcdd93f --- /dev/null +++ b/src/openai/types/beta/threads/runs/retrieval_tool_call.py @@ -0,0 +1,21 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ....._models import BaseModel + +__all__ = ["RetrievalToolCall"] + + +class RetrievalToolCall(BaseModel): + id: str + """The ID of the tool call object.""" + + retrieval: object + """For now, this is always going to be an empty object.""" + + type: Literal["retrieval"] + """The type of tool call. + + This is always going to be `retrieval` for this type of tool call. + """ diff --git a/src/openai/types/beta/threads/runs/run_step.py b/src/openai/types/beta/threads/runs/run_step.py new file mode 100644 index 0000000000..17a567dc0e --- /dev/null +++ b/src/openai/types/beta/threads/runs/run_step.py @@ -0,0 +1,93 @@ +# File generated from our OpenAPI spec by Stainless. + +import builtins +from typing import Union, Optional +from typing_extensions import Literal + +from ....._models import BaseModel +from .tool_calls_step_details import ToolCallsStepDetails +from .message_creation_step_details import MessageCreationStepDetails + +__all__ = ["RunStep", "LastError", "StepDetails"] + + +class LastError(BaseModel): + code: Literal["server_error", "rate_limit_exceeded"] + """One of `server_error` or `rate_limit_exceeded`.""" + + message: str + """A human-readable description of the error.""" + + +StepDetails = Union[MessageCreationStepDetails, ToolCallsStepDetails] + + +class RunStep(BaseModel): + id: str + """The identifier of the run step, which can be referenced in API endpoints.""" + + assistant_id: str + """ + The ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) + associated with the run step. + """ + + cancelled_at: Optional[int] + """The Unix timestamp (in seconds) for when the run step was cancelled.""" + + completed_at: Optional[int] + """The Unix timestamp (in seconds) for when the run step completed.""" + + created_at: int + """The Unix timestamp (in seconds) for when the run step was created.""" + + expired_at: Optional[int] + """The Unix timestamp (in seconds) for when the run step expired. + + A step is considered expired if the parent run is expired. + """ + + failed_at: Optional[int] + """The Unix timestamp (in seconds) for when the run step failed.""" + + last_error: Optional[LastError] + """The last error associated with this run step. + + Will be `null` if there are no errors. + """ + + metadata: Optional[builtins.object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + object: Literal["assistant.run.step"] + """The object type, which is always `assistant.run.step``.""" + + run_id: str + """ + The ID of the [run](https://platform.openai.com/docs/api-reference/runs) that + this run step is a part of. + """ + + status: Literal["in_progress", "cancelled", "failed", "completed", "expired"] + """ + The status of the run, which can be either `in_progress`, `cancelled`, `failed`, + `completed`, or `expired`. + """ + + step_details: StepDetails + """The details of the run step.""" + + thread_id: str + """ + The ID of the [thread](https://platform.openai.com/docs/api-reference/threads) + that was run. + """ + + type: Literal["message_creation", "tool_calls"] + """The type of run step, which can be either `message_creation` or `tool_calls`.""" diff --git a/src/openai/types/beta/threads/runs/step_list_params.py b/src/openai/types/beta/threads/runs/step_list_params.py new file mode 100644 index 0000000000..9c7b6c64d0 --- /dev/null +++ b/src/openai/types/beta/threads/runs/step_list_params.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["StepListParams"] + + +class StepListParams(TypedDict, total=False): + thread_id: Required[str] + + after: str + """A cursor for use in pagination. + + `after` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include after=obj_foo in order to fetch the next page of the + list. + """ + + before: str + """A cursor for use in pagination. + + `before` is an object ID that defines your place in the list. For instance, if + you make a list request and receive 100 objects, ending with obj_foo, your + subsequent call can include before=obj_foo in order to fetch the previous page + of the list. + """ + + limit: int + """A limit on the number of objects to be returned. + + Limit can range between 1 and 100, and the default is 20. + """ + + order: Literal["asc", "desc"] + """Sort order by the `created_at` timestamp of the objects. + + `asc` for ascending order and `desc` for descending order. + """ diff --git a/src/openai/types/beta/threads/runs/tool_calls_step_details.py b/src/openai/types/beta/threads/runs/tool_calls_step_details.py new file mode 100644 index 0000000000..80eb90bf66 --- /dev/null +++ b/src/openai/types/beta/threads/runs/tool_calls_step_details.py @@ -0,0 +1,25 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing import List, Union +from typing_extensions import Literal + +from ....._models import BaseModel +from .code_tool_call import CodeToolCall +from .function_tool_call import FunctionToolCall +from .retrieval_tool_call import RetrievalToolCall + +__all__ = ["ToolCallsStepDetails", "ToolCall"] + +ToolCall = Union[CodeToolCall, RetrievalToolCall, FunctionToolCall] + + +class ToolCallsStepDetails(BaseModel): + tool_calls: List[ToolCall] + """An array of tool calls the run step was involved in. + + These can be associated with one of three types of tools: `code_interpreter`, + `retrieval`, or `function`. + """ + + type: Literal["tool_calls"] + """Always `tool_calls`.""" diff --git a/src/openai/types/beta/threads/thread_message.py b/src/openai/types/beta/threads/thread_message.py new file mode 100644 index 0000000000..0f782ef845 --- /dev/null +++ b/src/openai/types/beta/threads/thread_message.py @@ -0,0 +1,65 @@ +# File generated from our OpenAPI spec by Stainless. + +import builtins +from typing import List, Union, Optional +from typing_extensions import Literal + +from ...._models import BaseModel +from .message_content_text import MessageContentText +from .message_content_image_file import MessageContentImageFile + +__all__ = ["ThreadMessage", "Content"] + +Content = Union[MessageContentImageFile, MessageContentText] + + +class ThreadMessage(BaseModel): + id: str + """The identifier, which can be referenced in API endpoints.""" + + assistant_id: Optional[str] + """ + If applicable, the ID of the + [assistant](https://platform.openai.com/docs/api-reference/assistants) that + authored this message. + """ + + content: List[Content] + """The content of the message in array of text and/or images.""" + + created_at: int + """The Unix timestamp (in seconds) for when the message was created.""" + + file_ids: List[str] + """ + A list of [file](https://platform.openai.com/docs/api-reference/files) IDs that + the assistant should use. Useful for tools like retrieval and code_interpreter + that can access files. A maximum of 10 files can be attached to a message. + """ + + metadata: Optional[builtins.object] + """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. Keys can be a maximum of 64 characters long and values can be + a maxium of 512 characters long. + """ + + object: Literal["thread.message"] + """The object type, which is always `thread.message`.""" + + role: Literal["user", "assistant"] + """The entity that produced the message. One of `user` or `assistant`.""" + + run_id: Optional[str] + """ + If applicable, the ID of the + [run](https://platform.openai.com/docs/api-reference/runs) associated with the + authoring of this message. + """ + + thread_id: str + """ + The [thread](https://platform.openai.com/docs/api-reference/threads) ID that + this message belongs to. + """ diff --git a/src/openai/types/chat/__init__.py b/src/openai/types/chat/__init__.py index 2f23cf3ca4..5fe182f41e 100644 --- a/src/openai/types/chat/__init__.py +++ b/src/openai/types/chat/__init__.py @@ -7,6 +7,48 @@ from .chat_completion_chunk import ChatCompletionChunk as ChatCompletionChunk from .chat_completion_message import ChatCompletionMessage as ChatCompletionMessage from .completion_create_params import CompletionCreateParams as CompletionCreateParams +from .chat_completion_tool_param import ( + ChatCompletionToolParam as ChatCompletionToolParam, +) from .chat_completion_message_param import ( ChatCompletionMessageParam as ChatCompletionMessageParam, ) +from .chat_completion_message_tool_call import ( + ChatCompletionMessageToolCall as ChatCompletionMessageToolCall, +) +from .chat_completion_content_part_param import ( + ChatCompletionContentPartParam as ChatCompletionContentPartParam, +) +from .chat_completion_tool_message_param import ( + ChatCompletionToolMessageParam as ChatCompletionToolMessageParam, +) +from .chat_completion_user_message_param import ( + ChatCompletionUserMessageParam as ChatCompletionUserMessageParam, +) +from .chat_completion_system_message_param import ( + ChatCompletionSystemMessageParam as ChatCompletionSystemMessageParam, +) +from .chat_completion_function_message_param import ( + ChatCompletionFunctionMessageParam as ChatCompletionFunctionMessageParam, +) +from .chat_completion_assistant_message_param import ( + ChatCompletionAssistantMessageParam as ChatCompletionAssistantMessageParam, +) +from .chat_completion_content_part_text_param import ( + ChatCompletionContentPartTextParam as ChatCompletionContentPartTextParam, +) +from .chat_completion_message_tool_call_param import ( + ChatCompletionMessageToolCallParam as ChatCompletionMessageToolCallParam, +) +from .chat_completion_named_tool_choice_param import ( + ChatCompletionNamedToolChoiceParam as ChatCompletionNamedToolChoiceParam, +) +from .chat_completion_content_part_image_param import ( + ChatCompletionContentPartImageParam as ChatCompletionContentPartImageParam, +) +from .chat_completion_tool_choice_option_param import ( + ChatCompletionToolChoiceOptionParam as ChatCompletionToolChoiceOptionParam, +) +from .chat_completion_function_call_option_param import ( + ChatCompletionFunctionCallOptionParam as ChatCompletionFunctionCallOptionParam, +) diff --git a/src/openai/types/chat/chat_completion.py b/src/openai/types/chat/chat_completion.py index 8d7a0b9716..da12ee7c07 100644 --- a/src/openai/types/chat/chat_completion.py +++ b/src/openai/types/chat/chat_completion.py @@ -11,13 +11,14 @@ class Choice(BaseModel): - finish_reason: Literal["stop", "length", "function_call", "content_filter"] + finish_reason: Literal["stop", "length", "tool_calls", "content_filter", "function_call"] """The reason the model stopped generating tokens. This will be `stop` if the model hit a natural stop point or a provided stop sequence, `length` if the maximum number of tokens specified in the request was reached, `content_filter` if content was omitted due to a flag from our content - filters, or `function_call` if the model called a function. + filters, `tool_calls` if the model called a tool, or `function_call` + (deprecated) if the model called a function. """ index: int @@ -43,8 +44,15 @@ class ChatCompletion(BaseModel): model: str """The model used for the chat completion.""" - object: str + object: Literal["chat.completion"] """The object type, which is always `chat.completion`.""" + system_fingerprint: Optional[str] = None + """This fingerprint represents the backend configuration that the model runs with. + + Can be used in conjunction with the `seed` request parameter to understand when + backend changes have been made that might impact determinism. + """ + usage: Optional[CompletionUsage] = None """Usage statistics for the completion request.""" diff --git a/src/openai/types/chat/chat_completion_assistant_message_param.py b/src/openai/types/chat/chat_completion_assistant_message_param.py new file mode 100644 index 0000000000..abdd87c991 --- /dev/null +++ b/src/openai/types/chat/chat_completion_assistant_message_param.py @@ -0,0 +1,41 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import List, Optional +from typing_extensions import Literal, Required, TypedDict + +from .chat_completion_message_tool_call_param import ChatCompletionMessageToolCallParam + +__all__ = ["ChatCompletionAssistantMessageParam", "FunctionCall"] + + +class FunctionCall(TypedDict, total=False): + arguments: Required[str] + """ + The arguments to call the function with, as generated by the model in JSON + format. Note that the model does not always generate valid JSON, and may + hallucinate parameters not defined by your function schema. Validate the + arguments in your code before calling your function. + """ + + name: Required[str] + """The name of the function to call.""" + + +class ChatCompletionAssistantMessageParam(TypedDict, total=False): + content: Required[Optional[str]] + """The contents of the assistant message.""" + + role: Required[Literal["assistant"]] + """The role of the messages author, in this case `assistant`.""" + + function_call: FunctionCall + """Deprecated and replaced by `tool_calls`. + + The name and arguments of a function that should be called, as generated by the + model. + """ + + tool_calls: List[ChatCompletionMessageToolCallParam] + """The tool calls generated by the model, such as function calls.""" diff --git a/src/openai/types/chat/chat_completion_chunk.py b/src/openai/types/chat/chat_completion_chunk.py index 66610898b4..bbc46a37bb 100644 --- a/src/openai/types/chat/chat_completion_chunk.py +++ b/src/openai/types/chat/chat_completion_chunk.py @@ -4,9 +4,15 @@ from typing_extensions import Literal from ..._models import BaseModel -from .chat_completion_role import ChatCompletionRole -__all__ = ["ChatCompletionChunk", "Choice", "ChoiceDelta", "ChoiceDeltaFunctionCall"] +__all__ = [ + "ChatCompletionChunk", + "Choice", + "ChoiceDelta", + "ChoiceDeltaFunctionCall", + "ChoiceDeltaToolCall", + "ChoiceDeltaToolCallFunction", +] class ChoiceDeltaFunctionCall(BaseModel): @@ -22,31 +28,60 @@ class ChoiceDeltaFunctionCall(BaseModel): """The name of the function to call.""" +class ChoiceDeltaToolCallFunction(BaseModel): + arguments: Optional[str] = None + """ + The arguments to call the function with, as generated by the model in JSON + format. Note that the model does not always generate valid JSON, and may + hallucinate parameters not defined by your function schema. Validate the + arguments in your code before calling your function. + """ + + name: Optional[str] = None + """The name of the function to call.""" + + +class ChoiceDeltaToolCall(BaseModel): + index: int + + id: Optional[str] = None + """The ID of the tool call.""" + + function: Optional[ChoiceDeltaToolCallFunction] = None + + type: Optional[Literal["function"]] = None + """The type of the tool. Currently, only `function` is supported.""" + + class ChoiceDelta(BaseModel): content: Optional[str] = None """The contents of the chunk message.""" function_call: Optional[ChoiceDeltaFunctionCall] = None - """ + """Deprecated and replaced by `tool_calls`. + The name and arguments of a function that should be called, as generated by the model. """ - role: Optional[ChatCompletionRole] = None + role: Optional[Literal["system", "user", "assistant", "tool"]] = None """The role of the author of this message.""" + tool_calls: Optional[List[ChoiceDeltaToolCall]] = None + class Choice(BaseModel): delta: ChoiceDelta """A chat completion delta generated by streamed model responses.""" - finish_reason: Optional[Literal["stop", "length", "function_call", "content_filter"]] + finish_reason: Optional[Literal["stop", "length", "tool_calls", "content_filter", "function_call"]] """The reason the model stopped generating tokens. This will be `stop` if the model hit a natural stop point or a provided stop sequence, `length` if the maximum number of tokens specified in the request was reached, `content_filter` if content was omitted due to a flag from our content - filters, or `function_call` if the model called a function. + filters, `tool_calls` if the model called a tool, or `function_call` + (deprecated) if the model called a function. """ index: int @@ -72,5 +107,5 @@ class ChatCompletionChunk(BaseModel): model: str """The model to generate the completion.""" - object: str + object: Literal["chat.completion.chunk"] """The object type, which is always `chat.completion.chunk`.""" diff --git a/src/openai/types/chat/chat_completion_content_part_image_param.py b/src/openai/types/chat/chat_completion_content_part_image_param.py new file mode 100644 index 0000000000..2051786562 --- /dev/null +++ b/src/openai/types/chat/chat_completion_content_part_image_param.py @@ -0,0 +1,22 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionContentPartImageParam", "ImageURL"] + + +class ImageURL(TypedDict, total=False): + detail: Literal["auto", "low", "high"] + """Specifies the detail level of the image.""" + + url: str + """Either a URL of the image or the base64 encoded image data.""" + + +class ChatCompletionContentPartImageParam(TypedDict, total=False): + image_url: Required[ImageURL] + + type: Required[Literal["image_url"]] + """The type of the content part.""" diff --git a/src/openai/types/chat/chat_completion_content_part_param.py b/src/openai/types/chat/chat_completion_content_part_param.py new file mode 100644 index 0000000000..587578e2ef --- /dev/null +++ b/src/openai/types/chat/chat_completion_content_part_param.py @@ -0,0 +1,14 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Union + +from .chat_completion_content_part_text_param import ChatCompletionContentPartTextParam +from .chat_completion_content_part_image_param import ( + ChatCompletionContentPartImageParam, +) + +__all__ = ["ChatCompletionContentPartParam"] + +ChatCompletionContentPartParam = Union[ChatCompletionContentPartTextParam, ChatCompletionContentPartImageParam] diff --git a/src/openai/types/chat/chat_completion_content_part_text_param.py b/src/openai/types/chat/chat_completion_content_part_text_param.py new file mode 100644 index 0000000000..38edcf054e --- /dev/null +++ b/src/openai/types/chat/chat_completion_content_part_text_param.py @@ -0,0 +1,15 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionContentPartTextParam"] + + +class ChatCompletionContentPartTextParam(TypedDict, total=False): + text: Required[str] + """The text content.""" + + type: Required[Literal["text"]] + """The type of the content part.""" diff --git a/src/openai/types/chat/chat_completion_function_call_option_param.py b/src/openai/types/chat/chat_completion_function_call_option_param.py new file mode 100644 index 0000000000..72d41d908c --- /dev/null +++ b/src/openai/types/chat/chat_completion_function_call_option_param.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Required, TypedDict + +__all__ = ["ChatCompletionFunctionCallOptionParam"] + + +class ChatCompletionFunctionCallOptionParam(TypedDict, total=False): + name: Required[str] + """The name of the function to call.""" diff --git a/src/openai/types/chat/chat_completion_function_message_param.py b/src/openai/types/chat/chat_completion_function_message_param.py new file mode 100644 index 0000000000..1a16c5f5eb --- /dev/null +++ b/src/openai/types/chat/chat_completion_function_message_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionFunctionMessageParam"] + + +class ChatCompletionFunctionMessageParam(TypedDict, total=False): + content: Required[Optional[str]] + """The return value from the function call, to return to the model.""" + + name: Required[str] + """The name of the function to call.""" + + role: Required[Literal["function"]] + """The role of the messages author, in this case `function`.""" diff --git a/src/openai/types/chat/chat_completion_message.py b/src/openai/types/chat/chat_completion_message.py index 531eb3d43c..4749798a33 100644 --- a/src/openai/types/chat/chat_completion_message.py +++ b/src/openai/types/chat/chat_completion_message.py @@ -1,9 +1,10 @@ # File generated from our OpenAPI spec by Stainless. -from typing import Optional +from typing import List, Optional +from typing_extensions import Literal from ..._models import BaseModel -from .chat_completion_role import ChatCompletionRole +from .chat_completion_message_tool_call import ChatCompletionMessageToolCall __all__ = ["ChatCompletionMessage", "FunctionCall"] @@ -25,11 +26,15 @@ class ChatCompletionMessage(BaseModel): content: Optional[str] """The contents of the message.""" - role: ChatCompletionRole + role: Literal["assistant"] """The role of the author of this message.""" function_call: Optional[FunctionCall] = None - """ + """Deprecated and replaced by `tool_calls`. + The name and arguments of a function that should be called, as generated by the model. """ + + tool_calls: Optional[List[ChatCompletionMessageToolCall]] = None + """The tool calls generated by the model, such as function calls.""" diff --git a/src/openai/types/chat/chat_completion_message_param.py b/src/openai/types/chat/chat_completion_message_param.py index 29b8882573..7ec3d6a7b7 100644 --- a/src/openai/types/chat/chat_completion_message_param.py +++ b/src/openai/types/chat/chat_completion_message_param.py @@ -2,49 +2,20 @@ from __future__ import annotations -from typing import Optional -from typing_extensions import Literal, Required, TypedDict - -__all__ = ["ChatCompletionMessageParam", "FunctionCall"] - - -class FunctionCall(TypedDict, total=False): - arguments: Required[str] - """ - The arguments to call the function with, as generated by the model in JSON - format. Note that the model does not always generate valid JSON, and may - hallucinate parameters not defined by your function schema. Validate the - arguments in your code before calling your function. - """ - - name: Required[str] - """The name of the function to call.""" - - -class ChatCompletionMessageParam(TypedDict, total=False): - content: Required[Optional[str]] - """The contents of the message. - - `content` is required for all messages, and may be null for assistant messages - with function calls. - """ - - role: Required[Literal["system", "user", "assistant", "function"]] - """The role of the messages author. - - One of `system`, `user`, `assistant`, or `function`. - """ - - function_call: FunctionCall - """ - The name and arguments of a function that should be called, as generated by the - model. - """ - - name: str - """The name of the author of this message. - - `name` is required if role is `function`, and it should be the name of the - function whose response is in the `content`. May contain a-z, A-Z, 0-9, and - underscores, with a maximum length of 64 characters. - """ +from typing import Union + +from .chat_completion_tool_message_param import ChatCompletionToolMessageParam +from .chat_completion_user_message_param import ChatCompletionUserMessageParam +from .chat_completion_system_message_param import ChatCompletionSystemMessageParam +from .chat_completion_function_message_param import ChatCompletionFunctionMessageParam +from .chat_completion_assistant_message_param import ChatCompletionAssistantMessageParam + +__all__ = ["ChatCompletionMessageParam"] + +ChatCompletionMessageParam = Union[ + ChatCompletionSystemMessageParam, + ChatCompletionUserMessageParam, + ChatCompletionAssistantMessageParam, + ChatCompletionToolMessageParam, + ChatCompletionFunctionMessageParam, +] diff --git a/src/openai/types/chat/chat_completion_message_tool_call.py b/src/openai/types/chat/chat_completion_message_tool_call.py new file mode 100644 index 0000000000..63c72fcdca --- /dev/null +++ b/src/openai/types/chat/chat_completion_message_tool_call.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. + +from typing_extensions import Literal + +from ..._models import BaseModel + +__all__ = ["ChatCompletionMessageToolCall", "Function"] + + +class Function(BaseModel): + arguments: str + """ + The arguments to call the function with, as generated by the model in JSON + format. Note that the model does not always generate valid JSON, and may + hallucinate parameters not defined by your function schema. Validate the + arguments in your code before calling your function. + """ + + name: str + """The name of the function to call.""" + + +class ChatCompletionMessageToolCall(BaseModel): + id: str + """The ID of the tool call.""" + + function: Function + """The function that the model called.""" + + type: Literal["function"] + """The type of the tool. Currently, only `function` is supported.""" diff --git a/src/openai/types/chat/chat_completion_message_tool_call_param.py b/src/openai/types/chat/chat_completion_message_tool_call_param.py new file mode 100644 index 0000000000..a700f02c4f --- /dev/null +++ b/src/openai/types/chat/chat_completion_message_tool_call_param.py @@ -0,0 +1,31 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionMessageToolCallParam", "Function"] + + +class Function(TypedDict, total=False): + arguments: Required[str] + """ + The arguments to call the function with, as generated by the model in JSON + format. Note that the model does not always generate valid JSON, and may + hallucinate parameters not defined by your function schema. Validate the + arguments in your code before calling your function. + """ + + name: Required[str] + """The name of the function to call.""" + + +class ChatCompletionMessageToolCallParam(TypedDict, total=False): + id: Required[str] + """The ID of the tool call.""" + + function: Required[Function] + """The function that the model called.""" + + type: Required[Literal["function"]] + """The type of the tool. Currently, only `function` is supported.""" diff --git a/src/openai/types/chat/chat_completion_named_tool_choice_param.py b/src/openai/types/chat/chat_completion_named_tool_choice_param.py new file mode 100644 index 0000000000..4c6f20d2f1 --- /dev/null +++ b/src/openai/types/chat/chat_completion_named_tool_choice_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionNamedToolChoiceParam", "Function"] + + +class Function(TypedDict, total=False): + name: Required[str] + """The name of the function to call.""" + + +class ChatCompletionNamedToolChoiceParam(TypedDict, total=False): + function: Function + + type: Literal["function"] + """The type of the tool. Currently, only `function` is supported.""" diff --git a/src/openai/types/chat/chat_completion_role.py b/src/openai/types/chat/chat_completion_role.py index da8896a072..9fa2acb4bb 100644 --- a/src/openai/types/chat/chat_completion_role.py +++ b/src/openai/types/chat/chat_completion_role.py @@ -4,4 +4,4 @@ __all__ = ["ChatCompletionRole"] -ChatCompletionRole = Literal["system", "user", "assistant", "function"] +ChatCompletionRole = Literal["system", "user", "assistant", "tool", "function"] diff --git a/src/openai/types/chat/chat_completion_system_message_param.py b/src/openai/types/chat/chat_completion_system_message_param.py new file mode 100644 index 0000000000..ec08e00350 --- /dev/null +++ b/src/openai/types/chat/chat_completion_system_message_param.py @@ -0,0 +1,16 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionSystemMessageParam"] + + +class ChatCompletionSystemMessageParam(TypedDict, total=False): + content: Required[Optional[str]] + """The contents of the system message.""" + + role: Required[Literal["system"]] + """The role of the messages author, in this case `system`.""" diff --git a/src/openai/types/chat/chat_completion_tool_choice_option_param.py b/src/openai/types/chat/chat_completion_tool_choice_option_param.py new file mode 100644 index 0000000000..8104b26acb --- /dev/null +++ b/src/openai/types/chat/chat_completion_tool_choice_option_param.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Union +from typing_extensions import Literal + +from .chat_completion_named_tool_choice_param import ChatCompletionNamedToolChoiceParam + +__all__ = ["ChatCompletionToolChoiceOptionParam"] + +ChatCompletionToolChoiceOptionParam = Union[Literal["none", "auto"], ChatCompletionNamedToolChoiceParam] diff --git a/src/openai/types/chat/chat_completion_tool_message_param.py b/src/openai/types/chat/chat_completion_tool_message_param.py new file mode 100644 index 0000000000..51759a9a99 --- /dev/null +++ b/src/openai/types/chat/chat_completion_tool_message_param.py @@ -0,0 +1,19 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Optional +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionToolMessageParam"] + + +class ChatCompletionToolMessageParam(TypedDict, total=False): + content: Required[Optional[str]] + """The contents of the tool message.""" + + role: Required[Literal["tool"]] + """The role of the messages author, in this case `tool`.""" + + tool_call_id: Required[str] + """Tool call that this message is responding to.""" diff --git a/src/openai/types/chat/chat_completion_tool_param.py b/src/openai/types/chat/chat_completion_tool_param.py new file mode 100644 index 0000000000..4b7e6238c7 --- /dev/null +++ b/src/openai/types/chat/chat_completion_tool_param.py @@ -0,0 +1,42 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import Dict +from typing_extensions import Literal, Required, TypedDict + +__all__ = ["ChatCompletionToolParam", "Function"] + + +class Function(TypedDict, total=False): + name: Required[str] + """The name of the function to be called. + + Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length + of 64. + """ + + parameters: Required[Dict[str, object]] + """The parameters the functions accepts, described as a JSON Schema object. + + See the [guide](https://platform.openai.com/docs/guides/gpt/function-calling) + for examples, and the + [JSON Schema reference](https://json-schema.org/understanding-json-schema/) for + documentation about the format. + + To describe a function that accepts no parameters, provide the value + `{"type": "object", "properties": {}}`. + """ + + description: str + """ + A description of what the function does, used by the model to choose when and + how to call the function. + """ + + +class ChatCompletionToolParam(TypedDict, total=False): + function: Required[Function] + + type: Required[Literal["function"]] + """The type of the tool. Currently, only `function` is supported.""" diff --git a/src/openai/types/chat/chat_completion_user_message_param.py b/src/openai/types/chat/chat_completion_user_message_param.py new file mode 100644 index 0000000000..6f0cf34623 --- /dev/null +++ b/src/openai/types/chat/chat_completion_user_message_param.py @@ -0,0 +1,18 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing import List, Union +from typing_extensions import Literal, Required, TypedDict + +from .chat_completion_content_part_param import ChatCompletionContentPartParam + +__all__ = ["ChatCompletionUserMessageParam"] + + +class ChatCompletionUserMessageParam(TypedDict, total=False): + content: Required[Union[str, List[ChatCompletionContentPartParam], None]] + """The contents of the user message.""" + + role: Required[Literal["user"]] + """The role of the messages author, in this case `user`.""" diff --git a/src/openai/types/chat/completion_create_params.py b/src/openai/types/chat/completion_create_params.py index d681a90cd6..44b1abe576 100644 --- a/src/openai/types/chat/completion_create_params.py +++ b/src/openai/types/chat/completion_create_params.py @@ -5,13 +5,20 @@ from typing import Dict, List, Union, Optional from typing_extensions import Literal, Required, TypedDict +from .chat_completion_tool_param import ChatCompletionToolParam from .chat_completion_message_param import ChatCompletionMessageParam +from .chat_completion_tool_choice_option_param import ( + ChatCompletionToolChoiceOptionParam, +) +from .chat_completion_function_call_option_param import ( + ChatCompletionFunctionCallOptionParam, +) __all__ = [ "CompletionCreateParamsBase", "FunctionCall", - "FunctionCallFunctionCallOption", "Function", + "ResponseFormat", "CompletionCreateParamsNonStreaming", "CompletionCreateParamsStreaming", ] @@ -59,22 +66,28 @@ class CompletionCreateParamsBase(TypedDict, total=False): """ function_call: FunctionCall - """Controls how the model calls functions. + """Deprecated in favor of `tool_choice`. - "none" means the model will not call a function and instead generates a message. - "auto" means the model can pick between generating a message or calling a - function. Specifying a particular function via `{"name": "my_function"}` forces - the model to call that function. "none" is the default when no functions are - present. "auto" is the default if functions are present. + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via `{"name": "my_function"}` forces the model to call that + function. + + `none` is the default when no functions are present. `auto`` is the default if + functions are present. """ functions: List[Function] - """A list of functions the model may generate JSON inputs for.""" + """Deprecated in favor of `tools`. + + A list of functions the model may generate JSON inputs for. + """ logit_bias: Optional[Dict[str, int]] """Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the + Accepts a JSON object that maps tokens (specified by their token ID in the tokenizer) to an associated bias value from -100 to 100. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or @@ -103,6 +116,21 @@ class CompletionCreateParamsBase(TypedDict, total=False): [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) """ + response_format: ResponseFormat + """An object specifying the format that the model must output. + + Used to enable JSON mode. + """ + + seed: Optional[int] + """This feature is in Beta. + + If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. Determinism is not guaranteed, and you should refer to the + `system_fingerprint` response parameter to monitor changes in the backend. + """ + stop: Union[Optional[str], List[str]] """Up to 4 sequences where the API will stop generating further tokens.""" @@ -115,6 +143,26 @@ class CompletionCreateParamsBase(TypedDict, total=False): We generally recommend altering this or `top_p` but not both. """ + tool_choice: ChatCompletionToolChoiceOptionParam + """ + Controls which (if any) function is called by the model. `none` means the model + will not call a function and instead generates a message. `auto` means the model + can pick between generating a message or calling a function. Specifying a + particular function via + `{"type: "function", "function": {"name": "my_function"}}` forces the model to + call that function. + + `none` is the default when no functions are present. `auto` is the default if + functions are present. + """ + + tools: List[ChatCompletionToolParam] + """A list of tools the model may call. + + Currently, only functions are supported as a tool. Use this to provide a list of + functions the model may generate JSON inputs for. + """ + top_p: Optional[float] """ An alternative to sampling with temperature, called nucleus sampling, where the @@ -132,12 +180,7 @@ class CompletionCreateParamsBase(TypedDict, total=False): """ -class FunctionCallFunctionCallOption(TypedDict, total=False): - name: Required[str] - """The name of the function to call.""" - - -FunctionCall = Union[Literal["none", "auto"], FunctionCallFunctionCallOption] +FunctionCall = Union[Literal["none", "auto"], ChatCompletionFunctionCallOptionParam] class Function(TypedDict, total=False): @@ -167,6 +210,23 @@ class Function(TypedDict, total=False): """ +class ResponseFormat(TypedDict, total=False): + type: Literal["text", "json_object"] + """Setting to `json_object` enables JSON mode. + + This guarantees that the message the model generates is valid JSON. + + Note that your system prompt must still instruct the model to produce JSON, and + to help ensure you don't forget, the API will throw an error if the string + `JSON` does not appear in your system message. Also note that the message + content may be partial (i.e. cut off) if `finish_reason="length"`, which + indicates the generation exceeded `max_tokens` or the conversation exceeded the + max context length. + + Must be one of `text` or `json_object`. + """ + + class CompletionCreateParamsNonStreaming(CompletionCreateParamsBase): stream: Optional[Literal[False]] """If set, partial message deltas will be sent, like in ChatGPT. diff --git a/src/openai/types/completion.py b/src/openai/types/completion.py index 0a90838fd4..cd80498b16 100644 --- a/src/openai/types/completion.py +++ b/src/openai/types/completion.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import List, Optional +from typing_extensions import Literal from .._models import BaseModel from .completion_usage import CompletionUsage @@ -22,8 +23,15 @@ class Completion(BaseModel): model: str """The model used for completion.""" - object: str + object: Literal["text_completion"] """The object type, which is always "text_completion" """ + system_fingerprint: Optional[str] = None + """This fingerprint represents the backend configuration that the model runs with. + + Can be used in conjunction with the `seed` request parameter to understand when + backend changes have been made that might impact determinism. + """ + usage: Optional[CompletionUsage] = None """Usage statistics for the completion request.""" diff --git a/src/openai/types/completion_create_params.py b/src/openai/types/completion_create_params.py index 023c087d5f..3e56d4f7bf 100644 --- a/src/openai/types/completion_create_params.py +++ b/src/openai/types/completion_create_params.py @@ -73,7 +73,7 @@ class CompletionCreateParamsBase(TypedDict, total=False): logit_bias: Optional[Dict[str, int]] """Modify the likelihood of specified tokens appearing in the completion. - Accepts a json object that maps tokens (specified by their token ID in the GPT + Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this [tokenizer tool](/tokenizer?view=bpe) (which works for both GPT-2 and GPT-3) to convert text to token IDs. Mathematically, the bias is added to the logits @@ -122,6 +122,16 @@ class CompletionCreateParamsBase(TypedDict, total=False): [See more information about frequency and presence penalties.](https://platform.openai.com/docs/guides/gpt/parameter-details) """ + seed: Optional[int] + """ + If specified, our system will make a best effort to sample deterministically, + such that repeated requests with the same `seed` and parameters should return + the same result. + + Determinism is not guaranteed, and you should refer to the `system_fingerprint` + response parameter to monitor changes in the backend. + """ + stop: Union[Optional[str], List[str], None] """Up to 4 sequences where the API will stop generating further tokens. diff --git a/src/openai/types/create_embedding_response.py b/src/openai/types/create_embedding_response.py index eccd148d3c..7382bed6b9 100644 --- a/src/openai/types/create_embedding_response.py +++ b/src/openai/types/create_embedding_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import List +from typing_extensions import Literal from .._models import BaseModel from .embedding import Embedding @@ -23,7 +24,7 @@ class CreateEmbeddingResponse(BaseModel): model: str """The name of the model used to generate the embedding.""" - object: str + object: Literal["embedding"] """The object type, which is always "embedding".""" usage: Usage diff --git a/src/openai/types/edit.py b/src/openai/types/edit.py index 41b327534e..48bca2987b 100644 --- a/src/openai/types/edit.py +++ b/src/openai/types/edit.py @@ -33,7 +33,7 @@ class Edit(BaseModel): created: int """The Unix timestamp (in seconds) of when the edit was created.""" - object: str + object: Literal["edit"] """The object type, which is always `edit`.""" usage: CompletionUsage diff --git a/src/openai/types/embedding.py b/src/openai/types/embedding.py index 4579b9bb57..9c53704d5d 100644 --- a/src/openai/types/embedding.py +++ b/src/openai/types/embedding.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import List +from typing_extensions import Literal from .._models import BaseModel @@ -18,5 +19,5 @@ class Embedding(BaseModel): index: int """The index of the embedding in the list of embeddings.""" - object: str + object: Literal["embedding"] """The object type, which is always "embedding".""" diff --git a/src/openai/types/file_create_params.py b/src/openai/types/file_create_params.py index 07b068c5c6..a59ddb2817 100644 --- a/src/openai/types/file_create_params.py +++ b/src/openai/types/file_create_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing_extensions import Required, TypedDict +from typing_extensions import Literal, Required, TypedDict from .._types import FileTypes @@ -11,16 +11,15 @@ class FileCreateParams(TypedDict, total=False): file: Required[FileTypes] - """The file object (not file name) to be uploaded. + """The File object (not file name) to be uploaded.""" - If the `purpose` is set to "fine-tune", the file will be used for fine-tuning. - """ - - purpose: Required[str] + purpose: Required[Literal["fine-tune", "assistants"]] """The intended purpose of the uploaded file. Use "fine-tune" for - [fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning). This - allows us to validate the format of the uploaded file is correct for - fine-tuning. + [Fine-tuning](https://platform.openai.com/docs/api-reference/fine-tuning) and + "assistants" for + [Assistants](https://platform.openai.com/docs/api-reference/assistants) and + [Messages](https://platform.openai.com/docs/api-reference/messages). This allows + us to validate the format of the uploaded file is correct for fine-tuning. """ diff --git a/src/openai/types/file_deleted.py b/src/openai/types/file_deleted.py index a526b2b986..3ac8592ff6 100644 --- a/src/openai/types/file_deleted.py +++ b/src/openai/types/file_deleted.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. +from typing_extensions import Literal + from .._models import BaseModel __all__ = ["FileDeleted"] @@ -10,4 +12,4 @@ class FileDeleted(BaseModel): deleted: bool - object: str + object: Literal["file"] diff --git a/src/openai/types/file_list_params.py b/src/openai/types/file_list_params.py new file mode 100644 index 0000000000..a962dd239c --- /dev/null +++ b/src/openai/types/file_list_params.py @@ -0,0 +1,12 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +from typing_extensions import TypedDict + +__all__ = ["FileListParams"] + + +class FileListParams(TypedDict, total=False): + purpose: str + """Only return files with the given purpose.""" diff --git a/src/openai/types/file_object.py b/src/openai/types/file_object.py index dac24a88c5..4ae91b754e 100644 --- a/src/openai/types/file_object.py +++ b/src/openai/types/file_object.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import Optional +from typing_extensions import Literal from .._models import BaseModel @@ -12,7 +13,7 @@ class FileObject(BaseModel): """The file identifier, which can be referenced in the API endpoints.""" bytes: int - """The size of the file in bytes.""" + """The size of the file, in bytes.""" created_at: int """The Unix timestamp (in seconds) for when the file was created.""" @@ -20,21 +21,26 @@ class FileObject(BaseModel): filename: str """The name of the file.""" - object: str - """The object type, which is always "file".""" + object: Literal["file"] + """The object type, which is always `file`.""" - purpose: str - """The intended purpose of the file. Currently, only "fine-tune" is supported.""" + purpose: Literal["fine-tune", "fine-tune-results", "assistants", "assistants_output"] + """The intended purpose of the file. - status: Optional[str] = None + Supported values are `fine-tune`, `fine-tune-results`, `assistants`, and + `assistants_output`. """ - The current status of the file, which can be either `uploaded`, `processed`, - `pending`, `error`, `deleting` or `deleted`. + + status: Literal["uploaded", "processed", "error"] + """Deprecated. + + The current status of the file, which can be either `uploaded`, `processed`, or + `error`. """ status_details: Optional[str] = None - """Additional details about the status of the file. + """Deprecated. - If the file is in the `error` state, this will include a message describing the - error. + For details on why a fine-tuning training file failed validation, see the + `error` field on `fine_tuning.job`. """ diff --git a/src/openai/types/fine_tune.py b/src/openai/types/fine_tune.py index 4124def2f5..de1e097ee4 100644 --- a/src/openai/types/fine_tune.py +++ b/src/openai/types/fine_tune.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import List, Optional +from typing_extensions import Literal from .._models import BaseModel from .file_object import FileObject @@ -63,7 +64,7 @@ class FineTune(BaseModel): model: str """The base model that is being fine-tuned.""" - object: str + object: Literal["fine-tune"] """The object type, which is always "fine-tune".""" organization_id: str diff --git a/src/openai/types/fine_tune_event.py b/src/openai/types/fine_tune_event.py index 6499def98d..299f0de24b 100644 --- a/src/openai/types/fine_tune_event.py +++ b/src/openai/types/fine_tune_event.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. +from typing_extensions import Literal + from .._models import BaseModel __all__ = ["FineTuneEvent"] @@ -12,4 +14,4 @@ class FineTuneEvent(BaseModel): message: str - object: str + object: Literal["fine-tune-event"] diff --git a/src/openai/types/fine_tune_events_list_response.py b/src/openai/types/fine_tune_events_list_response.py index ca159d8772..c69746104d 100644 --- a/src/openai/types/fine_tune_events_list_response.py +++ b/src/openai/types/fine_tune_events_list_response.py @@ -1,6 +1,7 @@ # File generated from our OpenAPI spec by Stainless. from typing import List +from typing_extensions import Literal from .._models import BaseModel from .fine_tune_event import FineTuneEvent @@ -11,4 +12,4 @@ class FineTuneEventsListResponse(BaseModel): data: List[FineTuneEvent] - object: str + object: Literal["list"] diff --git a/src/openai/types/fine_tuning/fine_tuning_job.py b/src/openai/types/fine_tuning/fine_tuning_job.py index 2ae1cbb473..3897176a47 100644 --- a/src/openai/types/fine_tuning/fine_tuning_job.py +++ b/src/openai/types/fine_tuning/fine_tuning_job.py @@ -67,7 +67,7 @@ class FineTuningJob(BaseModel): model: str """The base model that is being fine-tuned.""" - object: str + object: Literal["fine_tuning.job"] """The object type, which is always "fine_tuning.job".""" organization_id: str @@ -80,7 +80,7 @@ class FineTuningJob(BaseModel): [Files API](https://platform.openai.com/docs/api-reference/files/retrieve-contents). """ - status: str + status: Literal["validating_files", "queued", "running", "succeeded", "failed", "cancelled"] """ The current status of the fine-tuning job, which can be either `validating_files`, `queued`, `running`, `succeeded`, `failed`, or `cancelled`. diff --git a/src/openai/types/fine_tuning/fine_tuning_job_event.py b/src/openai/types/fine_tuning/fine_tuning_job_event.py index c21a0503ab..62f268868b 100644 --- a/src/openai/types/fine_tuning/fine_tuning_job_event.py +++ b/src/openai/types/fine_tuning/fine_tuning_job_event.py @@ -16,4 +16,4 @@ class FineTuningJobEvent(BaseModel): message: str - object: str + object: Literal["fine_tuning.job.event"] diff --git a/src/openai/types/fine_tuning/job_create_params.py b/src/openai/types/fine_tuning/job_create_params.py index 2a67b81817..da750ffc19 100644 --- a/src/openai/types/fine_tuning/job_create_params.py +++ b/src/openai/types/fine_tuning/job_create_params.py @@ -58,6 +58,19 @@ class JobCreateParams(TypedDict, total=False): class Hyperparameters(TypedDict, total=False): + batch_size: Union[Literal["auto"], int] + """Number of examples in each batch. + + A larger batch size means that model parameters are updated less frequently, but + with lower variance. + """ + + learning_rate_multiplier: Union[Literal["auto"], float] + """Scaling factor for the learning rate. + + A smaller learning rate may be useful to avoid overfitting. + """ + n_epochs: Union[Literal["auto"], int] """The number of epochs to train the model for. diff --git a/src/openai/types/image.py b/src/openai/types/image.py index 4b8d1aaf18..a040caf7b6 100644 --- a/src/openai/types/image.py +++ b/src/openai/types/image.py @@ -14,5 +14,11 @@ class Image(BaseModel): `b64_json`. """ + revised_prompt: Optional[str] = None + """ + The prompt that was used to generate the image, if there was any revision to the + prompt. + """ + url: Optional[str] = None """The URL of the generated image, if `response_format` is `url` (default).""" diff --git a/src/openai/types/image_create_variation_params.py b/src/openai/types/image_create_variation_params.py index d3b439070e..7b015fc176 100644 --- a/src/openai/types/image_create_variation_params.py +++ b/src/openai/types/image_create_variation_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Union, Optional from typing_extensions import Literal, Required, TypedDict from .._types import FileTypes @@ -17,8 +17,17 @@ class ImageCreateVariationParams(TypedDict, total=False): Must be a valid PNG file, less than 4MB, and square. """ + model: Union[str, Literal["dall-e-2"], None] + """The model to use for image generation. + + Only `dall-e-2` is supported at this time. + """ + n: Optional[int] - """The number of images to generate. Must be between 1 and 10.""" + """The number of images to generate. + + Must be between 1 and 10. For `dall-e-3`, only `n=1` is supported. + """ response_format: Optional[Literal["url", "b64_json"]] """The format in which the generated images are returned. diff --git a/src/openai/types/image_edit_params.py b/src/openai/types/image_edit_params.py index ce07a9cb30..043885cc38 100644 --- a/src/openai/types/image_edit_params.py +++ b/src/openai/types/image_edit_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Union, Optional from typing_extensions import Literal, Required, TypedDict from .._types import FileTypes @@ -31,6 +31,12 @@ class ImageEditParams(TypedDict, total=False): PNG file, less than 4MB, and have the same dimensions as `image`. """ + model: Union[str, Literal["dall-e-2"], None] + """The model to use for image generation. + + Only `dall-e-2` is supported at this time. + """ + n: Optional[int] """The number of images to generate. Must be between 1 and 10.""" diff --git a/src/openai/types/image_generate_params.py b/src/openai/types/image_generate_params.py index 4999ed958d..7eca29a7ba 100644 --- a/src/openai/types/image_generate_params.py +++ b/src/openai/types/image_generate_params.py @@ -2,7 +2,7 @@ from __future__ import annotations -from typing import Optional +from typing import Union, Optional from typing_extensions import Literal, Required, TypedDict __all__ = ["ImageGenerateParams"] @@ -12,11 +12,25 @@ class ImageGenerateParams(TypedDict, total=False): prompt: Required[str] """A text description of the desired image(s). - The maximum length is 1000 characters. + The maximum length is 1000 characters for `dall-e-2` and 4000 characters for + `dall-e-3`. """ + model: Union[str, Literal["dall-e-2", "dall-e-3"], None] + """The model to use for image generation.""" + n: Optional[int] - """The number of images to generate. Must be between 1 and 10.""" + """The number of images to generate. + + Must be between 1 and 10. For `dall-e-3`, only `n=1` is supported. + """ + + quality: Literal["standard", "hd"] + """The quality of the image that will be generated. + + `hd` creates images with finer details and greater consistency across the image. + This param is only supported for `dall-e-3`. + """ response_format: Optional[Literal["url", "b64_json"]] """The format in which the generated images are returned. @@ -24,10 +38,20 @@ class ImageGenerateParams(TypedDict, total=False): Must be one of `url` or `b64_json`. """ - size: Optional[Literal["256x256", "512x512", "1024x1024"]] + size: Optional[Literal["256x256", "512x512", "1024x1024", "1792x1024", "1024x1792"]] """The size of the generated images. - Must be one of `256x256`, `512x512`, or `1024x1024`. + Must be one of `256x256`, `512x512`, or `1024x1024` for `dall-e-2`. Must be one + of `1024x1024`, `1792x1024`, or `1024x1792` for `dall-e-3` models. + """ + + style: Optional[Literal["vivid", "natural"]] + """The style of the generated images. + + Must be one of `vivid` or `natural`. Vivid causes the model to lean towards + generating hyper-real and dramatic images. Natural causes the model to produce + more natural, less hyper-real looking images. This param is only supported for + `dall-e-3`. """ user: str diff --git a/src/openai/types/model.py b/src/openai/types/model.py index 29e71b81a0..58f3997f70 100644 --- a/src/openai/types/model.py +++ b/src/openai/types/model.py @@ -1,5 +1,7 @@ # File generated from our OpenAPI spec by Stainless. +from typing_extensions import Literal + from .._models import BaseModel __all__ = ["Model"] @@ -12,7 +14,7 @@ class Model(BaseModel): created: int """The Unix timestamp (in seconds) when the model was created.""" - object: str + object: Literal["model"] """The object type, which is always "model".""" owned_by: str diff --git a/tests/api_resources/audio/test_speech.py b/tests/api_resources/audio/test_speech.py new file mode 100644 index 0000000000..89814c2dd3 --- /dev/null +++ b/tests/api_resources/audio/test_speech.py @@ -0,0 +1,110 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import httpx +import pytest +from respx import MockRouter + +from openai import OpenAI, AsyncOpenAI +from openai._types import BinaryResponseContent +from openai._client import OpenAI, AsyncOpenAI + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestSpeech: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_method_create(self, client: OpenAI, respx_mock: MockRouter) -> None: + respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + speech = client.audio.speech.create( + input="string", + model="string", + voice="alloy", + ) + assert isinstance(speech, BinaryResponseContent) + assert speech.json() == {"foo": "bar"} + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_method_create_with_all_params(self, client: OpenAI, respx_mock: MockRouter) -> None: + respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + speech = respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + client.audio.speech.create( + input="string", + model="string", + voice="alloy", + response_format="mp3", + speed=0.25, + ) + assert isinstance(speech, BinaryResponseContent) + assert speech.json() == {"foo": "bar"} + + @parametrize + @pytest.mark.respx(base_url=base_url) + def test_raw_response_create(self, client: OpenAI, respx_mock: MockRouter) -> None: + respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + response = client.audio.speech.with_raw_response.create( + input="string", + model="string", + voice="alloy", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + speech = response.parse() + assert isinstance(speech, BinaryResponseContent) + assert speech.json() == {"foo": "bar"} + + +class TestAsyncSpeech: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_method_create(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + speech = await client.audio.speech.create( + input="string", + model="string", + voice="alloy", + ) + assert isinstance(speech, BinaryResponseContent) + assert speech.json() == {"foo": "bar"} + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_method_create_with_all_params(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + speech = respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + await client.audio.speech.create( + input="string", + model="string", + voice="alloy", + response_format="mp3", + speed=0.25, + ) + assert isinstance(speech, BinaryResponseContent) + assert speech.json() == {"foo": "bar"} + + @parametrize + @pytest.mark.respx(base_url=base_url) + async def test_raw_response_create(self, client: AsyncOpenAI, respx_mock: MockRouter) -> None: + respx_mock.post("/audio/speech").mock(return_value=httpx.Response(200, json={"foo": "bar"})) + response = await client.audio.speech.with_raw_response.create( + input="string", + model="string", + voice="alloy", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + speech = response.parse() + assert isinstance(speech, BinaryResponseContent) + assert speech.json() == {"foo": "bar"} diff --git a/tests/api_resources/beta/__init__.py b/tests/api_resources/beta/__init__.py new file mode 100644 index 0000000000..1016754ef3 --- /dev/null +++ b/tests/api_resources/beta/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/beta/assistants/__init__.py b/tests/api_resources/beta/assistants/__init__.py new file mode 100644 index 0000000000..1016754ef3 --- /dev/null +++ b/tests/api_resources/beta/assistants/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/beta/assistants/test_files.py b/tests/api_resources/beta/assistants/test_files.py new file mode 100644 index 0000000000..2545640c57 --- /dev/null +++ b/tests/api_resources/beta/assistants/test_files.py @@ -0,0 +1,190 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.pagination import SyncCursorPage, AsyncCursorPage +from openai.types.beta.assistants import AssistantFile, FileDeleteResponse + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestFiles: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_create(self, client: OpenAI) -> None: + file = client.beta.assistants.files.create( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + file_id="string", + ) + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: OpenAI) -> None: + response = client.beta.assistants.files.with_raw_response.create( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + file_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + file = client.beta.assistants.files.retrieve( + "string", + assistant_id="string", + ) + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.assistants.files.with_raw_response.retrieve( + "string", + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + def test_method_list(self, client: OpenAI) -> None: + file = client.beta.assistants.files.list( + "string", + ) + assert_matches_type(SyncCursorPage[AssistantFile], file, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + file = client.beta.assistants.files.list( + "string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(SyncCursorPage[AssistantFile], file, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: OpenAI) -> None: + response = client.beta.assistants.files.with_raw_response.list( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(SyncCursorPage[AssistantFile], file, path=["response"]) + + @parametrize + def test_method_delete(self, client: OpenAI) -> None: + file = client.beta.assistants.files.delete( + "string", + assistant_id="string", + ) + assert_matches_type(FileDeleteResponse, file, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: OpenAI) -> None: + response = client.beta.assistants.files.with_raw_response.delete( + "string", + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(FileDeleteResponse, file, path=["response"]) + + +class TestAsyncFiles: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_create(self, client: AsyncOpenAI) -> None: + file = await client.beta.assistants.files.create( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + file_id="string", + ) + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + async def test_raw_response_create(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.files.with_raw_response.create( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + file_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + file = await client.beta.assistants.files.retrieve( + "string", + assistant_id="string", + ) + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.files.with_raw_response.retrieve( + "string", + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(AssistantFile, file, path=["response"]) + + @parametrize + async def test_method_list(self, client: AsyncOpenAI) -> None: + file = await client.beta.assistants.files.list( + "string", + ) + assert_matches_type(AsyncCursorPage[AssistantFile], file, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + file = await client.beta.assistants.files.list( + "string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(AsyncCursorPage[AssistantFile], file, path=["response"]) + + @parametrize + async def test_raw_response_list(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.files.with_raw_response.list( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(AsyncCursorPage[AssistantFile], file, path=["response"]) + + @parametrize + async def test_method_delete(self, client: AsyncOpenAI) -> None: + file = await client.beta.assistants.files.delete( + "string", + assistant_id="string", + ) + assert_matches_type(FileDeleteResponse, file, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.files.with_raw_response.delete( + "string", + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(FileDeleteResponse, file, path=["response"]) diff --git a/tests/api_resources/beta/chat/__init__.py b/tests/api_resources/beta/chat/__init__.py new file mode 100644 index 0000000000..1016754ef3 --- /dev/null +++ b/tests/api_resources/beta/chat/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/beta/test_assistants.py b/tests/api_resources/beta/test_assistants.py new file mode 100644 index 0000000000..5bbad1d7dd --- /dev/null +++ b/tests/api_resources/beta/test_assistants.py @@ -0,0 +1,254 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.pagination import SyncCursorPage, AsyncCursorPage +from openai.types.beta import Assistant, AsssitantDeleted + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestAssistants: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_create(self, client: OpenAI) -> None: + assistant = client.beta.assistants.create( + model="string", + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: OpenAI) -> None: + assistant = client.beta.assistants.create( + model="string", + description="string", + file_ids=["string", "string", "string"], + instructions="string", + metadata={}, + name="string", + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: OpenAI) -> None: + response = client.beta.assistants.with_raw_response.create( + model="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + assistant = client.beta.assistants.retrieve( + "string", + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.assistants.with_raw_response.retrieve( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_method_update(self, client: OpenAI) -> None: + assistant = client.beta.assistants.update( + "string", + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: OpenAI) -> None: + assistant = client.beta.assistants.update( + "string", + description="string", + file_ids=["string", "string", "string"], + instructions="string", + metadata={}, + model="string", + name="string", + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: OpenAI) -> None: + response = client.beta.assistants.with_raw_response.update( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + def test_method_list(self, client: OpenAI) -> None: + assistant = client.beta.assistants.list() + assert_matches_type(SyncCursorPage[Assistant], assistant, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + assistant = client.beta.assistants.list( + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(SyncCursorPage[Assistant], assistant, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: OpenAI) -> None: + response = client.beta.assistants.with_raw_response.list() + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(SyncCursorPage[Assistant], assistant, path=["response"]) + + @parametrize + def test_method_delete(self, client: OpenAI) -> None: + assistant = client.beta.assistants.delete( + "string", + ) + assert_matches_type(AsssitantDeleted, assistant, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: OpenAI) -> None: + response = client.beta.assistants.with_raw_response.delete( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(AsssitantDeleted, assistant, path=["response"]) + + +class TestAsyncAssistants: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_create(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.create( + model="string", + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.create( + model="string", + description="string", + file_ids=["string", "string", "string"], + instructions="string", + metadata={}, + name="string", + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_raw_response_create(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.with_raw_response.create( + model="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.retrieve( + "string", + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.with_raw_response.retrieve( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_method_update(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.update( + "string", + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.update( + "string", + description="string", + file_ids=["string", "string", "string"], + instructions="string", + metadata={}, + model="string", + name="string", + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_raw_response_update(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.with_raw_response.update( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(Assistant, assistant, path=["response"]) + + @parametrize + async def test_method_list(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.list() + assert_matches_type(AsyncCursorPage[Assistant], assistant, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.list( + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(AsyncCursorPage[Assistant], assistant, path=["response"]) + + @parametrize + async def test_raw_response_list(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.with_raw_response.list() + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(AsyncCursorPage[Assistant], assistant, path=["response"]) + + @parametrize + async def test_method_delete(self, client: AsyncOpenAI) -> None: + assistant = await client.beta.assistants.delete( + "string", + ) + assert_matches_type(AsssitantDeleted, assistant, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: + response = await client.beta.assistants.with_raw_response.delete( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + assistant = response.parse() + assert_matches_type(AsssitantDeleted, assistant, path=["response"]) diff --git a/tests/api_resources/beta/test_threads.py b/tests/api_resources/beta/test_threads.py new file mode 100644 index 0000000000..8fa1fc20ea --- /dev/null +++ b/tests/api_resources/beta/test_threads.py @@ -0,0 +1,318 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.types.beta import Thread, ThreadDeleted +from openai.types.beta.threads import Run + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestThreads: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_create(self, client: OpenAI) -> None: + thread = client.beta.threads.create() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: OpenAI) -> None: + thread = client.beta.threads.create( + messages=[ + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + ], + metadata={}, + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: OpenAI) -> None: + response = client.beta.threads.with_raw_response.create() + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + thread = client.beta.threads.retrieve( + "string", + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.threads.with_raw_response.retrieve( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_method_update(self, client: OpenAI) -> None: + thread = client.beta.threads.update( + "string", + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: OpenAI) -> None: + thread = client.beta.threads.update( + "string", + metadata={}, + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: OpenAI) -> None: + response = client.beta.threads.with_raw_response.update( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + def test_method_delete(self, client: OpenAI) -> None: + thread = client.beta.threads.delete( + "string", + ) + assert_matches_type(ThreadDeleted, thread, path=["response"]) + + @parametrize + def test_raw_response_delete(self, client: OpenAI) -> None: + response = client.beta.threads.with_raw_response.delete( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(ThreadDeleted, thread, path=["response"]) + + @parametrize + def test_method_create_and_run(self, client: OpenAI) -> None: + thread = client.beta.threads.create_and_run( + assistant_id="string", + ) + assert_matches_type(Run, thread, path=["response"]) + + @parametrize + def test_method_create_and_run_with_all_params(self, client: OpenAI) -> None: + thread = client.beta.threads.create_and_run( + assistant_id="string", + instructions="string", + metadata={}, + model="string", + thread={ + "messages": [ + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + ], + "metadata": {}, + }, + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Run, thread, path=["response"]) + + @parametrize + def test_raw_response_create_and_run(self, client: OpenAI) -> None: + response = client.beta.threads.with_raw_response.create_and_run( + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Run, thread, path=["response"]) + + +class TestAsyncThreads: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_create(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.create() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.create( + messages=[ + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + ], + metadata={}, + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_raw_response_create(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.with_raw_response.create() + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.retrieve( + "string", + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.with_raw_response.retrieve( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_method_update(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.update( + "string", + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.update( + "string", + metadata={}, + ) + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_raw_response_update(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.with_raw_response.update( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Thread, thread, path=["response"]) + + @parametrize + async def test_method_delete(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.delete( + "string", + ) + assert_matches_type(ThreadDeleted, thread, path=["response"]) + + @parametrize + async def test_raw_response_delete(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.with_raw_response.delete( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(ThreadDeleted, thread, path=["response"]) + + @parametrize + async def test_method_create_and_run(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.create_and_run( + assistant_id="string", + ) + assert_matches_type(Run, thread, path=["response"]) + + @parametrize + async def test_method_create_and_run_with_all_params(self, client: AsyncOpenAI) -> None: + thread = await client.beta.threads.create_and_run( + assistant_id="string", + instructions="string", + metadata={}, + model="string", + thread={ + "messages": [ + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + { + "role": "user", + "content": "x", + "file_ids": ["string"], + "metadata": {}, + }, + ], + "metadata": {}, + }, + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Run, thread, path=["response"]) + + @parametrize + async def test_raw_response_create_and_run(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.with_raw_response.create_and_run( + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + thread = response.parse() + assert_matches_type(Run, thread, path=["response"]) diff --git a/tests/api_resources/beta/threads/__init__.py b/tests/api_resources/beta/threads/__init__.py new file mode 100644 index 0000000000..1016754ef3 --- /dev/null +++ b/tests/api_resources/beta/threads/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/beta/threads/messages/__init__.py b/tests/api_resources/beta/threads/messages/__init__.py new file mode 100644 index 0000000000..1016754ef3 --- /dev/null +++ b/tests/api_resources/beta/threads/messages/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/beta/threads/messages/test_files.py b/tests/api_resources/beta/threads/messages/test_files.py new file mode 100644 index 0000000000..a5b68713e6 --- /dev/null +++ b/tests/api_resources/beta/threads/messages/test_files.py @@ -0,0 +1,128 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.pagination import SyncCursorPage, AsyncCursorPage +from openai.types.beta.threads.messages import MessageFile + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestFiles: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + file = client.beta.threads.messages.files.retrieve( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + thread_id="thread_AF1WoRqd3aJAHsqc9NY7iL8F", + message_id="msg_AF1WoRqd3aJAHsqc9NY7iL8F", + ) + assert_matches_type(MessageFile, file, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.threads.messages.files.with_raw_response.retrieve( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + thread_id="thread_AF1WoRqd3aJAHsqc9NY7iL8F", + message_id="msg_AF1WoRqd3aJAHsqc9NY7iL8F", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(MessageFile, file, path=["response"]) + + @parametrize + def test_method_list(self, client: OpenAI) -> None: + file = client.beta.threads.messages.files.list( + "string", + thread_id="string", + ) + assert_matches_type(SyncCursorPage[MessageFile], file, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + file = client.beta.threads.messages.files.list( + "string", + thread_id="string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(SyncCursorPage[MessageFile], file, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: OpenAI) -> None: + response = client.beta.threads.messages.files.with_raw_response.list( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(SyncCursorPage[MessageFile], file, path=["response"]) + + +class TestAsyncFiles: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + file = await client.beta.threads.messages.files.retrieve( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + thread_id="thread_AF1WoRqd3aJAHsqc9NY7iL8F", + message_id="msg_AF1WoRqd3aJAHsqc9NY7iL8F", + ) + assert_matches_type(MessageFile, file, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.messages.files.with_raw_response.retrieve( + "file-AF1WoRqd3aJAHsqc9NY7iL8F", + thread_id="thread_AF1WoRqd3aJAHsqc9NY7iL8F", + message_id="msg_AF1WoRqd3aJAHsqc9NY7iL8F", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(MessageFile, file, path=["response"]) + + @parametrize + async def test_method_list(self, client: AsyncOpenAI) -> None: + file = await client.beta.threads.messages.files.list( + "string", + thread_id="string", + ) + assert_matches_type(AsyncCursorPage[MessageFile], file, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + file = await client.beta.threads.messages.files.list( + "string", + thread_id="string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(AsyncCursorPage[MessageFile], file, path=["response"]) + + @parametrize + async def test_raw_response_list(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.messages.files.with_raw_response.list( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + file = response.parse() + assert_matches_type(AsyncCursorPage[MessageFile], file, path=["response"]) diff --git a/tests/api_resources/beta/threads/runs/__init__.py b/tests/api_resources/beta/threads/runs/__init__.py new file mode 100644 index 0000000000..1016754ef3 --- /dev/null +++ b/tests/api_resources/beta/threads/runs/__init__.py @@ -0,0 +1 @@ +# File generated from our OpenAPI spec by Stainless. diff --git a/tests/api_resources/beta/threads/runs/test_steps.py b/tests/api_resources/beta/threads/runs/test_steps.py new file mode 100644 index 0000000000..3f4f8c1022 --- /dev/null +++ b/tests/api_resources/beta/threads/runs/test_steps.py @@ -0,0 +1,128 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.pagination import SyncCursorPage, AsyncCursorPage +from openai.types.beta.threads.runs import RunStep + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestSteps: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + step = client.beta.threads.runs.steps.retrieve( + "string", + thread_id="string", + run_id="string", + ) + assert_matches_type(RunStep, step, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.threads.runs.steps.with_raw_response.retrieve( + "string", + thread_id="string", + run_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + step = response.parse() + assert_matches_type(RunStep, step, path=["response"]) + + @parametrize + def test_method_list(self, client: OpenAI) -> None: + step = client.beta.threads.runs.steps.list( + "string", + thread_id="string", + ) + assert_matches_type(SyncCursorPage[RunStep], step, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + step = client.beta.threads.runs.steps.list( + "string", + thread_id="string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(SyncCursorPage[RunStep], step, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: OpenAI) -> None: + response = client.beta.threads.runs.steps.with_raw_response.list( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + step = response.parse() + assert_matches_type(SyncCursorPage[RunStep], step, path=["response"]) + + +class TestAsyncSteps: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + step = await client.beta.threads.runs.steps.retrieve( + "string", + thread_id="string", + run_id="string", + ) + assert_matches_type(RunStep, step, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.steps.with_raw_response.retrieve( + "string", + thread_id="string", + run_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + step = response.parse() + assert_matches_type(RunStep, step, path=["response"]) + + @parametrize + async def test_method_list(self, client: AsyncOpenAI) -> None: + step = await client.beta.threads.runs.steps.list( + "string", + thread_id="string", + ) + assert_matches_type(AsyncCursorPage[RunStep], step, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + step = await client.beta.threads.runs.steps.list( + "string", + thread_id="string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(AsyncCursorPage[RunStep], step, path=["response"]) + + @parametrize + async def test_raw_response_list(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.steps.with_raw_response.list( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + step = response.parse() + assert_matches_type(AsyncCursorPage[RunStep], step, path=["response"]) diff --git a/tests/api_resources/beta/threads/test_messages.py b/tests/api_resources/beta/threads/test_messages.py new file mode 100644 index 0000000000..f3fe7dc2bb --- /dev/null +++ b/tests/api_resources/beta/threads/test_messages.py @@ -0,0 +1,234 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.pagination import SyncCursorPage, AsyncCursorPage +from openai.types.beta.threads import ThreadMessage + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestMessages: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_create(self, client: OpenAI) -> None: + message = client.beta.threads.messages.create( + "string", + content="x", + role="user", + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: OpenAI) -> None: + message = client.beta.threads.messages.create( + "string", + content="x", + role="user", + file_ids=["string"], + metadata={}, + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: OpenAI) -> None: + response = client.beta.threads.messages.with_raw_response.create( + "string", + content="x", + role="user", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + message = client.beta.threads.messages.retrieve( + "string", + thread_id="string", + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.threads.messages.with_raw_response.retrieve( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_method_update(self, client: OpenAI) -> None: + message = client.beta.threads.messages.update( + "string", + thread_id="string", + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: OpenAI) -> None: + message = client.beta.threads.messages.update( + "string", + thread_id="string", + metadata={}, + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: OpenAI) -> None: + response = client.beta.threads.messages.with_raw_response.update( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + def test_method_list(self, client: OpenAI) -> None: + message = client.beta.threads.messages.list( + "string", + ) + assert_matches_type(SyncCursorPage[ThreadMessage], message, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + message = client.beta.threads.messages.list( + "string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(SyncCursorPage[ThreadMessage], message, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: OpenAI) -> None: + response = client.beta.threads.messages.with_raw_response.list( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(SyncCursorPage[ThreadMessage], message, path=["response"]) + + +class TestAsyncMessages: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_create(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.create( + "string", + content="x", + role="user", + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.create( + "string", + content="x", + role="user", + file_ids=["string"], + metadata={}, + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_raw_response_create(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.messages.with_raw_response.create( + "string", + content="x", + role="user", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.retrieve( + "string", + thread_id="string", + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.messages.with_raw_response.retrieve( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_method_update(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.update( + "string", + thread_id="string", + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.update( + "string", + thread_id="string", + metadata={}, + ) + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_raw_response_update(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.messages.with_raw_response.update( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(ThreadMessage, message, path=["response"]) + + @parametrize + async def test_method_list(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.list( + "string", + ) + assert_matches_type(AsyncCursorPage[ThreadMessage], message, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + message = await client.beta.threads.messages.list( + "string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(AsyncCursorPage[ThreadMessage], message, path=["response"]) + + @parametrize + async def test_raw_response_list(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.messages.with_raw_response.list( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + message = response.parse() + assert_matches_type(AsyncCursorPage[ThreadMessage], message, path=["response"]) diff --git a/tests/api_resources/beta/threads/test_runs.py b/tests/api_resources/beta/threads/test_runs.py new file mode 100644 index 0000000000..d323dfc354 --- /dev/null +++ b/tests/api_resources/beta/threads/test_runs.py @@ -0,0 +1,308 @@ +# File generated from our OpenAPI spec by Stainless. + +from __future__ import annotations + +import os + +import pytest + +from openai import OpenAI, AsyncOpenAI +from tests.utils import assert_matches_type +from openai._client import OpenAI, AsyncOpenAI +from openai.pagination import SyncCursorPage, AsyncCursorPage +from openai.types.beta.threads import Run + +base_url = os.environ.get("TEST_API_BASE_URL", "http://127.0.0.1:4010") +api_key = "My API Key" + + +class TestRuns: + strict_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = OpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + def test_method_create(self, client: OpenAI) -> None: + run = client.beta.threads.runs.create( + "string", + assistant_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_method_create_with_all_params(self, client: OpenAI) -> None: + run = client.beta.threads.runs.create( + "string", + assistant_id="string", + instructions="string", + metadata={}, + model="string", + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_raw_response_create(self, client: OpenAI) -> None: + response = client.beta.threads.runs.with_raw_response.create( + "string", + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_method_retrieve(self, client: OpenAI) -> None: + run = client.beta.threads.runs.retrieve( + "string", + thread_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_raw_response_retrieve(self, client: OpenAI) -> None: + response = client.beta.threads.runs.with_raw_response.retrieve( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_method_update(self, client: OpenAI) -> None: + run = client.beta.threads.runs.update( + "string", + thread_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_method_update_with_all_params(self, client: OpenAI) -> None: + run = client.beta.threads.runs.update( + "string", + thread_id="string", + metadata={}, + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_raw_response_update(self, client: OpenAI) -> None: + response = client.beta.threads.runs.with_raw_response.update( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_method_list(self, client: OpenAI) -> None: + run = client.beta.threads.runs.list( + "string", + ) + assert_matches_type(SyncCursorPage[Run], run, path=["response"]) + + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + run = client.beta.threads.runs.list( + "string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(SyncCursorPage[Run], run, path=["response"]) + + @parametrize + def test_raw_response_list(self, client: OpenAI) -> None: + response = client.beta.threads.runs.with_raw_response.list( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(SyncCursorPage[Run], run, path=["response"]) + + @parametrize + def test_method_cancel(self, client: OpenAI) -> None: + run = client.beta.threads.runs.cancel( + "string", + thread_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_raw_response_cancel(self, client: OpenAI) -> None: + response = client.beta.threads.runs.with_raw_response.cancel( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_method_submit_tool_outputs(self, client: OpenAI) -> None: + run = client.beta.threads.runs.submit_tool_outputs( + "string", + thread_id="string", + tool_outputs=[{}, {}, {}], + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + def test_raw_response_submit_tool_outputs(self, client: OpenAI) -> None: + response = client.beta.threads.runs.with_raw_response.submit_tool_outputs( + "string", + thread_id="string", + tool_outputs=[{}, {}, {}], + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + +class TestAsyncRuns: + strict_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=True) + loose_client = AsyncOpenAI(base_url=base_url, api_key=api_key, _strict_response_validation=False) + parametrize = pytest.mark.parametrize("client", [strict_client, loose_client], ids=["strict", "loose"]) + + @parametrize + async def test_method_create(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.create( + "string", + assistant_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.create( + "string", + assistant_id="string", + instructions="string", + metadata={}, + model="string", + tools=[{"type": "code_interpreter"}, {"type": "code_interpreter"}, {"type": "code_interpreter"}], + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_raw_response_create(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.with_raw_response.create( + "string", + assistant_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_method_retrieve(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.retrieve( + "string", + thread_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_raw_response_retrieve(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.with_raw_response.retrieve( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_method_update(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.update( + "string", + thread_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_method_update_with_all_params(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.update( + "string", + thread_id="string", + metadata={}, + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_raw_response_update(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.with_raw_response.update( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_method_list(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.list( + "string", + ) + assert_matches_type(AsyncCursorPage[Run], run, path=["response"]) + + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.list( + "string", + after="string", + before="string", + limit=0, + order="asc", + ) + assert_matches_type(AsyncCursorPage[Run], run, path=["response"]) + + @parametrize + async def test_raw_response_list(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.with_raw_response.list( + "string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(AsyncCursorPage[Run], run, path=["response"]) + + @parametrize + async def test_method_cancel(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.cancel( + "string", + thread_id="string", + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_raw_response_cancel(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.with_raw_response.cancel( + "string", + thread_id="string", + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_method_submit_tool_outputs(self, client: AsyncOpenAI) -> None: + run = await client.beta.threads.runs.submit_tool_outputs( + "string", + thread_id="string", + tool_outputs=[{}, {}, {}], + ) + assert_matches_type(Run, run, path=["response"]) + + @parametrize + async def test_raw_response_submit_tool_outputs(self, client: AsyncOpenAI) -> None: + response = await client.beta.threads.runs.with_raw_response.submit_tool_outputs( + "string", + thread_id="string", + tool_outputs=[{}, {}, {}], + ) + assert response.http_request.headers.get("X-Stainless-Lang") == "python" + run = response.parse() + assert_matches_type(Run, run, path=["response"]) diff --git a/tests/api_resources/chat/test_completions.py b/tests/api_resources/chat/test_completions.py index dacf5d2596..132e00039b 100644 --- a/tests/api_resources/chat/test_completions.py +++ b/tests/api_resources/chat/test_completions.py @@ -39,11 +39,6 @@ def test_method_create_with_all_params_overload_1(self, client: OpenAI) -> None: messages=[ { "content": "string", - "function_call": { - "arguments": "string", - "name": "string", - }, - "name": "string", "role": "system", } ], @@ -61,9 +56,38 @@ def test_method_create_with_all_params_overload_1(self, client: OpenAI) -> None: max_tokens=0, n=1, presence_penalty=-2, + response_format={"type": "json_object"}, + seed=-9223372036854776000, stop="string", stream=False, temperature=1, + tool_choice="none", + tools=[ + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + ], top_p=1, user="user-1234", ) @@ -103,11 +127,6 @@ def test_method_create_with_all_params_overload_2(self, client: OpenAI) -> None: messages=[ { "content": "string", - "function_call": { - "arguments": "string", - "name": "string", - }, - "name": "string", "role": "system", } ], @@ -126,8 +145,37 @@ def test_method_create_with_all_params_overload_2(self, client: OpenAI) -> None: max_tokens=0, n=1, presence_penalty=-2, + response_format={"type": "json_object"}, + seed=-9223372036854776000, stop="string", temperature=1, + tool_choice="none", + tools=[ + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + ], top_p=1, user="user-1234", ) @@ -172,11 +220,6 @@ async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenA messages=[ { "content": "string", - "function_call": { - "arguments": "string", - "name": "string", - }, - "name": "string", "role": "system", } ], @@ -194,9 +237,38 @@ async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenA max_tokens=0, n=1, presence_penalty=-2, + response_format={"type": "json_object"}, + seed=-9223372036854776000, stop="string", stream=False, temperature=1, + tool_choice="none", + tools=[ + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + ], top_p=1, user="user-1234", ) @@ -236,11 +308,6 @@ async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenA messages=[ { "content": "string", - "function_call": { - "arguments": "string", - "name": "string", - }, - "name": "string", "role": "system", } ], @@ -259,8 +326,37 @@ async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenA max_tokens=0, n=1, presence_penalty=-2, + response_format={"type": "json_object"}, + seed=-9223372036854776000, stop="string", temperature=1, + tool_choice="none", + tools=[ + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + { + "type": "function", + "function": { + "description": "string", + "name": "string", + "parameters": {"foo": "bar"}, + }, + }, + ], top_p=1, user="user-1234", ) diff --git a/tests/api_resources/fine_tuning/test_jobs.py b/tests/api_resources/fine_tuning/test_jobs.py index 9defcadab6..5716a23d54 100644 --- a/tests/api_resources/fine_tuning/test_jobs.py +++ b/tests/api_resources/fine_tuning/test_jobs.py @@ -34,7 +34,11 @@ def test_method_create_with_all_params(self, client: OpenAI) -> None: job = client.fine_tuning.jobs.create( model="gpt-3.5-turbo", training_file="file-abc123", - hyperparameters={"n_epochs": "auto"}, + hyperparameters={ + "batch_size": "auto", + "learning_rate_multiplier": "auto", + "n_epochs": "auto", + }, suffix="x", validation_file="file-abc123", ) @@ -146,7 +150,11 @@ async def test_method_create_with_all_params(self, client: AsyncOpenAI) -> None: job = await client.fine_tuning.jobs.create( model="gpt-3.5-turbo", training_file="file-abc123", - hyperparameters={"n_epochs": "auto"}, + hyperparameters={ + "batch_size": "auto", + "learning_rate_multiplier": "auto", + "n_epochs": "auto", + }, suffix="x", validation_file="file-abc123", ) diff --git a/tests/api_resources/test_completions.py b/tests/api_resources/test_completions.py index 7b48e88ed2..b12fd6401e 100644 --- a/tests/api_resources/test_completions.py +++ b/tests/api_resources/test_completions.py @@ -41,6 +41,7 @@ def test_method_create_with_all_params_overload_1(self, client: OpenAI) -> None: max_tokens=16, n=1, presence_penalty=-2, + seed=-9223372036854776000, stop="\n", stream=False, suffix="test.", @@ -82,6 +83,7 @@ def test_method_create_with_all_params_overload_2(self, client: OpenAI) -> None: max_tokens=16, n=1, presence_penalty=-2, + seed=-9223372036854776000, stop="\n", suffix="test.", temperature=1, @@ -126,6 +128,7 @@ async def test_method_create_with_all_params_overload_1(self, client: AsyncOpenA max_tokens=16, n=1, presence_penalty=-2, + seed=-9223372036854776000, stop="\n", stream=False, suffix="test.", @@ -167,6 +170,7 @@ async def test_method_create_with_all_params_overload_2(self, client: AsyncOpenA max_tokens=16, n=1, presence_penalty=-2, + seed=-9223372036854776000, stop="\n", suffix="test.", temperature=1, diff --git a/tests/api_resources/test_files.py b/tests/api_resources/test_files.py index 389763586e..d668c2d0c7 100644 --- a/tests/api_resources/test_files.py +++ b/tests/api_resources/test_files.py @@ -25,7 +25,7 @@ class TestFiles: def test_method_create(self, client: OpenAI) -> None: file = client.files.create( file=b"raw file contents", - purpose="string", + purpose="fine-tune", ) assert_matches_type(FileObject, file, path=["response"]) @@ -33,7 +33,7 @@ def test_method_create(self, client: OpenAI) -> None: def test_raw_response_create(self, client: OpenAI) -> None: response = client.files.with_raw_response.create( file=b"raw file contents", - purpose="string", + purpose="fine-tune", ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() @@ -60,6 +60,13 @@ def test_method_list(self, client: OpenAI) -> None: file = client.files.list() assert_matches_type(SyncPage[FileObject], file, path=["response"]) + @parametrize + def test_method_list_with_all_params(self, client: OpenAI) -> None: + file = client.files.list( + purpose="string", + ) + assert_matches_type(SyncPage[FileObject], file, path=["response"]) + @parametrize def test_raw_response_list(self, client: OpenAI) -> None: response = client.files.with_raw_response.list() @@ -109,7 +116,7 @@ class TestAsyncFiles: async def test_method_create(self, client: AsyncOpenAI) -> None: file = await client.files.create( file=b"raw file contents", - purpose="string", + purpose="fine-tune", ) assert_matches_type(FileObject, file, path=["response"]) @@ -117,7 +124,7 @@ async def test_method_create(self, client: AsyncOpenAI) -> None: async def test_raw_response_create(self, client: AsyncOpenAI) -> None: response = await client.files.with_raw_response.create( file=b"raw file contents", - purpose="string", + purpose="fine-tune", ) assert response.http_request.headers.get("X-Stainless-Lang") == "python" file = response.parse() @@ -144,6 +151,13 @@ async def test_method_list(self, client: AsyncOpenAI) -> None: file = await client.files.list() assert_matches_type(AsyncPage[FileObject], file, path=["response"]) + @parametrize + async def test_method_list_with_all_params(self, client: AsyncOpenAI) -> None: + file = await client.files.list( + purpose="string", + ) + assert_matches_type(AsyncPage[FileObject], file, path=["response"]) + @parametrize async def test_raw_response_list(self, client: AsyncOpenAI) -> None: response = await client.files.with_raw_response.list() diff --git a/tests/api_resources/test_images.py b/tests/api_resources/test_images.py index fa7fb6d533..c7f5e5bcd2 100644 --- a/tests/api_resources/test_images.py +++ b/tests/api_resources/test_images.py @@ -31,6 +31,7 @@ def test_method_create_variation(self, client: OpenAI) -> None: def test_method_create_variation_with_all_params(self, client: OpenAI) -> None: image = client.images.create_variation( image=b"raw file contents", + model="dall-e-2", n=1, response_format="url", size="1024x1024", @@ -61,6 +62,7 @@ def test_method_edit_with_all_params(self, client: OpenAI) -> None: image=b"raw file contents", prompt="A cute baby sea otter wearing a beret", mask=b"raw file contents", + model="dall-e-2", n=1, response_format="url", size="1024x1024", @@ -89,9 +91,12 @@ def test_method_generate(self, client: OpenAI) -> None: def test_method_generate_with_all_params(self, client: OpenAI) -> None: image = client.images.generate( prompt="A cute baby sea otter", + model="dall-e-3", n=1, + quality="standard", response_format="url", size="1024x1024", + style="vivid", user="user-1234", ) assert_matches_type(ImagesResponse, image, path=["response"]) @@ -122,6 +127,7 @@ async def test_method_create_variation(self, client: AsyncOpenAI) -> None: async def test_method_create_variation_with_all_params(self, client: AsyncOpenAI) -> None: image = await client.images.create_variation( image=b"raw file contents", + model="dall-e-2", n=1, response_format="url", size="1024x1024", @@ -152,6 +158,7 @@ async def test_method_edit_with_all_params(self, client: AsyncOpenAI) -> None: image=b"raw file contents", prompt="A cute baby sea otter wearing a beret", mask=b"raw file contents", + model="dall-e-2", n=1, response_format="url", size="1024x1024", @@ -180,9 +187,12 @@ async def test_method_generate(self, client: AsyncOpenAI) -> None: async def test_method_generate_with_all_params(self, client: AsyncOpenAI) -> None: image = await client.images.generate( prompt="A cute baby sea otter", + model="dall-e-3", n=1, + quality="standard", response_format="url", size="1024x1024", + style="vivid", user="user-1234", ) assert_matches_type(ImagesResponse, image, path=["response"])