Skip to content

Commit 6cc5158

Browse files
committed
feat(api): add usage metadata when streaming (openai#1395)
1 parent 2a678e3 commit 6cc5158

11 files changed

+97
-3
lines changed

.stats.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
configured_endpoints: 64
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-97c9a5f089049dc9eb5cee9475558049003e37e42202cab39e59d75e08b4c613.yml
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/openai-edb5af3ade0cd27cf366b0654b90c7a81c43c433e11fc3f6e621e2c779de10d4.yml

api.md

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ from openai.types.chat import (
4343
ChatCompletionMessageToolCall,
4444
ChatCompletionNamedToolChoice,
4545
ChatCompletionRole,
46+
ChatCompletionStreamOptions,
4647
ChatCompletionSystemMessageParam,
4748
ChatCompletionTokenLogprob,
4849
ChatCompletionTool,

src/openai/resources/chat/completions.py

+23
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from ...types.chat.chat_completion_chunk import ChatCompletionChunk
2828
from ...types.chat.chat_completion_tool_param import ChatCompletionToolParam
2929
from ...types.chat.chat_completion_message_param import ChatCompletionMessageParam
30+
from ...types.chat.chat_completion_stream_options_param import ChatCompletionStreamOptionsParam
3031
from ...types.chat.chat_completion_tool_choice_option_param import ChatCompletionToolChoiceOptionParam
3132

3233
__all__ = ["Completions", "AsyncCompletions"]
@@ -59,6 +60,7 @@ def create(
5960
seed: Optional[int] | NotGiven = NOT_GIVEN,
6061
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
6162
stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN,
63+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
6264
temperature: Optional[float] | NotGiven = NOT_GIVEN,
6365
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
6466
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -165,6 +167,8 @@ def create(
165167
message.
166168
[Example Python code](https://cookbook.openai.com/examples/how_to_stream_completions).
167169
170+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
171+
168172
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
169173
make the output more random, while lower values like 0.2 will make it more
170174
focused and deterministic.
@@ -227,6 +231,7 @@ def create(
227231
response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN,
228232
seed: Optional[int] | NotGiven = NOT_GIVEN,
229233
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
234+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
230235
temperature: Optional[float] | NotGiven = NOT_GIVEN,
231236
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
232237
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -333,6 +338,8 @@ def create(
333338
334339
stop: Up to 4 sequences where the API will stop generating further tokens.
335340
341+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
342+
336343
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
337344
make the output more random, while lower values like 0.2 will make it more
338345
focused and deterministic.
@@ -395,6 +402,7 @@ def create(
395402
response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN,
396403
seed: Optional[int] | NotGiven = NOT_GIVEN,
397404
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
405+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
398406
temperature: Optional[float] | NotGiven = NOT_GIVEN,
399407
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
400408
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -501,6 +509,8 @@ def create(
501509
502510
stop: Up to 4 sequences where the API will stop generating further tokens.
503511
512+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
513+
504514
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
505515
make the output more random, while lower values like 0.2 will make it more
506516
focused and deterministic.
@@ -563,6 +573,7 @@ def create(
563573
seed: Optional[int] | NotGiven = NOT_GIVEN,
564574
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
565575
stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN,
576+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
566577
temperature: Optional[float] | NotGiven = NOT_GIVEN,
567578
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
568579
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -594,6 +605,7 @@ def create(
594605
"seed": seed,
595606
"stop": stop,
596607
"stream": stream,
608+
"stream_options": stream_options,
597609
"temperature": temperature,
598610
"tool_choice": tool_choice,
599611
"tools": tools,
@@ -639,6 +651,7 @@ async def create(
639651
seed: Optional[int] | NotGiven = NOT_GIVEN,
640652
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
641653
stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN,
654+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
642655
temperature: Optional[float] | NotGiven = NOT_GIVEN,
643656
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
644657
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -745,6 +758,8 @@ async def create(
745758
message.
746759
[Example Python code](https://cookbook.openai.com/examples/how_to_stream_completions).
747760
761+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
762+
748763
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
749764
make the output more random, while lower values like 0.2 will make it more
750765
focused and deterministic.
@@ -807,6 +822,7 @@ async def create(
807822
response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN,
808823
seed: Optional[int] | NotGiven = NOT_GIVEN,
809824
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
825+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
810826
temperature: Optional[float] | NotGiven = NOT_GIVEN,
811827
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
812828
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -913,6 +929,8 @@ async def create(
913929
914930
stop: Up to 4 sequences where the API will stop generating further tokens.
915931
932+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
933+
916934
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
917935
make the output more random, while lower values like 0.2 will make it more
918936
focused and deterministic.
@@ -975,6 +993,7 @@ async def create(
975993
response_format: completion_create_params.ResponseFormat | NotGiven = NOT_GIVEN,
976994
seed: Optional[int] | NotGiven = NOT_GIVEN,
977995
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
996+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
978997
temperature: Optional[float] | NotGiven = NOT_GIVEN,
979998
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
980999
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -1081,6 +1100,8 @@ async def create(
10811100
10821101
stop: Up to 4 sequences where the API will stop generating further tokens.
10831102
1103+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
1104+
10841105
temperature: What sampling temperature to use, between 0 and 2. Higher values like 0.8 will
10851106
make the output more random, while lower values like 0.2 will make it more
10861107
focused and deterministic.
@@ -1143,6 +1164,7 @@ async def create(
11431164
seed: Optional[int] | NotGiven = NOT_GIVEN,
11441165
stop: Union[Optional[str], List[str]] | NotGiven = NOT_GIVEN,
11451166
stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN,
1167+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
11461168
temperature: Optional[float] | NotGiven = NOT_GIVEN,
11471169
tool_choice: ChatCompletionToolChoiceOptionParam | NotGiven = NOT_GIVEN,
11481170
tools: Iterable[ChatCompletionToolParam] | NotGiven = NOT_GIVEN,
@@ -1174,6 +1196,7 @@ async def create(
11741196
"seed": seed,
11751197
"stop": stop,
11761198
"stream": stream,
1199+
"stream_options": stream_options,
11771200
"temperature": temperature,
11781201
"tool_choice": tool_choice,
11791202
"tools": tools,

src/openai/resources/completions.py

+23
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
make_request_options,
2424
)
2525
from ..types.completion import Completion
26+
from ..types.chat.chat_completion_stream_options_param import ChatCompletionStreamOptionsParam
2627

2728
__all__ = ["Completions", "AsyncCompletions"]
2829

@@ -53,6 +54,7 @@ def create(
5354
seed: Optional[int] | NotGiven = NOT_GIVEN,
5455
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
5556
stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN,
57+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
5658
suffix: Optional[str] | NotGiven = NOT_GIVEN,
5759
temperature: Optional[float] | NotGiven = NOT_GIVEN,
5860
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -156,6 +158,8 @@ def create(
156158
message.
157159
[Example Python code](https://cookbook.openai.com/examples/how_to_stream_completions).
158160
161+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
162+
159163
suffix: The suffix that comes after a completion of inserted text.
160164
161165
This parameter is only supported for `gpt-3.5-turbo-instruct`.
@@ -203,6 +207,7 @@ def create(
203207
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
204208
seed: Optional[int] | NotGiven = NOT_GIVEN,
205209
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
210+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
206211
suffix: Optional[str] | NotGiven = NOT_GIVEN,
207212
temperature: Optional[float] | NotGiven = NOT_GIVEN,
208213
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -306,6 +311,8 @@ def create(
306311
stop: Up to 4 sequences where the API will stop generating further tokens. The
307312
returned text will not contain the stop sequence.
308313
314+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
315+
309316
suffix: The suffix that comes after a completion of inserted text.
310317
311318
This parameter is only supported for `gpt-3.5-turbo-instruct`.
@@ -353,6 +360,7 @@ def create(
353360
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
354361
seed: Optional[int] | NotGiven = NOT_GIVEN,
355362
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
363+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
356364
suffix: Optional[str] | NotGiven = NOT_GIVEN,
357365
temperature: Optional[float] | NotGiven = NOT_GIVEN,
358366
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -456,6 +464,8 @@ def create(
456464
stop: Up to 4 sequences where the API will stop generating further tokens. The
457465
returned text will not contain the stop sequence.
458466
467+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
468+
459469
suffix: The suffix that comes after a completion of inserted text.
460470
461471
This parameter is only supported for `gpt-3.5-turbo-instruct`.
@@ -503,6 +513,7 @@ def create(
503513
seed: Optional[int] | NotGiven = NOT_GIVEN,
504514
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
505515
stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN,
516+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
506517
suffix: Optional[str] | NotGiven = NOT_GIVEN,
507518
temperature: Optional[float] | NotGiven = NOT_GIVEN,
508519
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -531,6 +542,7 @@ def create(
531542
"seed": seed,
532543
"stop": stop,
533544
"stream": stream,
545+
"stream_options": stream_options,
534546
"suffix": suffix,
535547
"temperature": temperature,
536548
"top_p": top_p,
@@ -573,6 +585,7 @@ async def create(
573585
seed: Optional[int] | NotGiven = NOT_GIVEN,
574586
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
575587
stream: Optional[Literal[False]] | NotGiven = NOT_GIVEN,
588+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
576589
suffix: Optional[str] | NotGiven = NOT_GIVEN,
577590
temperature: Optional[float] | NotGiven = NOT_GIVEN,
578591
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -676,6 +689,8 @@ async def create(
676689
message.
677690
[Example Python code](https://cookbook.openai.com/examples/how_to_stream_completions).
678691
692+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
693+
679694
suffix: The suffix that comes after a completion of inserted text.
680695
681696
This parameter is only supported for `gpt-3.5-turbo-instruct`.
@@ -723,6 +738,7 @@ async def create(
723738
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
724739
seed: Optional[int] | NotGiven = NOT_GIVEN,
725740
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
741+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
726742
suffix: Optional[str] | NotGiven = NOT_GIVEN,
727743
temperature: Optional[float] | NotGiven = NOT_GIVEN,
728744
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -826,6 +842,8 @@ async def create(
826842
stop: Up to 4 sequences where the API will stop generating further tokens. The
827843
returned text will not contain the stop sequence.
828844
845+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
846+
829847
suffix: The suffix that comes after a completion of inserted text.
830848
831849
This parameter is only supported for `gpt-3.5-turbo-instruct`.
@@ -873,6 +891,7 @@ async def create(
873891
presence_penalty: Optional[float] | NotGiven = NOT_GIVEN,
874892
seed: Optional[int] | NotGiven = NOT_GIVEN,
875893
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
894+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
876895
suffix: Optional[str] | NotGiven = NOT_GIVEN,
877896
temperature: Optional[float] | NotGiven = NOT_GIVEN,
878897
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -976,6 +995,8 @@ async def create(
976995
stop: Up to 4 sequences where the API will stop generating further tokens. The
977996
returned text will not contain the stop sequence.
978997
998+
stream_options: Options for streaming response. Only set this when you set `stream: true`.
999+
9791000
suffix: The suffix that comes after a completion of inserted text.
9801001
9811002
This parameter is only supported for `gpt-3.5-turbo-instruct`.
@@ -1023,6 +1044,7 @@ async def create(
10231044
seed: Optional[int] | NotGiven = NOT_GIVEN,
10241045
stop: Union[Optional[str], List[str], None] | NotGiven = NOT_GIVEN,
10251046
stream: Optional[Literal[False]] | Literal[True] | NotGiven = NOT_GIVEN,
1047+
stream_options: Optional[ChatCompletionStreamOptionsParam] | NotGiven = NOT_GIVEN,
10261048
suffix: Optional[str] | NotGiven = NOT_GIVEN,
10271049
temperature: Optional[float] | NotGiven = NOT_GIVEN,
10281050
top_p: Optional[float] | NotGiven = NOT_GIVEN,
@@ -1051,6 +1073,7 @@ async def create(
10511073
"seed": seed,
10521074
"stop": stop,
10531075
"stream": stream,
1076+
"stream_options": stream_options,
10541077
"suffix": suffix,
10551078
"temperature": temperature,
10561079
"top_p": top_p,

src/openai/types/chat/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from .chat_completion_content_part_param import ChatCompletionContentPartParam as ChatCompletionContentPartParam
1515
from .chat_completion_tool_message_param import ChatCompletionToolMessageParam as ChatCompletionToolMessageParam
1616
from .chat_completion_user_message_param import ChatCompletionUserMessageParam as ChatCompletionUserMessageParam
17+
from .chat_completion_stream_options_param import ChatCompletionStreamOptionsParam as ChatCompletionStreamOptionsParam
1718
from .chat_completion_system_message_param import ChatCompletionSystemMessageParam as ChatCompletionSystemMessageParam
1819
from .chat_completion_function_message_param import (
1920
ChatCompletionFunctionMessageParam as ChatCompletionFunctionMessageParam,

src/openai/types/chat/chat_completion_chunk.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from typing_extensions import Literal
55

66
from ..._models import BaseModel
7+
from ..completion_usage import CompletionUsage
78
from .chat_completion_token_logprob import ChatCompletionTokenLogprob
89

910
__all__ = [
@@ -105,7 +106,8 @@ class ChatCompletionChunk(BaseModel):
105106
choices: List[Choice]
106107
"""A list of chat completion choices.
107108
108-
Can be more than one if `n` is greater than 1.
109+
Can contain more than one elements if `n` is greater than 1. Can also be empty
110+
for the last chunk if you set `stream_options: {"include_usage": true}`.
109111
"""
110112

111113
created: int
@@ -126,3 +128,11 @@ class ChatCompletionChunk(BaseModel):
126128
Can be used in conjunction with the `seed` request parameter to understand when
127129
backend changes have been made that might impact determinism.
128130
"""
131+
132+
usage: Optional[CompletionUsage] = None
133+
"""
134+
An optional field that will only be present when you set
135+
`stream_options: {"include_usage": true}` in your request. When present, it
136+
contains a null value except for the last chunk which contains the token usage
137+
statistics for the entire request.
138+
"""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
2+
3+
from __future__ import annotations
4+
5+
from typing_extensions import TypedDict
6+
7+
__all__ = ["ChatCompletionStreamOptionsParam"]
8+
9+
10+
class ChatCompletionStreamOptionsParam(TypedDict, total=False):
11+
include_usage: bool
12+
"""If set, an additional chunk will be streamed before the `data: [DONE]` message.
13+
14+
The `usage` field on this chunk shows the token usage statistics for the entire
15+
request, and the `choices` field will always be an empty array. All other chunks
16+
will also include a `usage` field, but with a null value.
17+
"""

src/openai/types/chat/completion_create_params.py

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from ..chat_model import ChatModel
1010
from .chat_completion_tool_param import ChatCompletionToolParam
1111
from .chat_completion_message_param import ChatCompletionMessageParam
12+
from .chat_completion_stream_options_param import ChatCompletionStreamOptionsParam
1213
from .chat_completion_tool_choice_option_param import ChatCompletionToolChoiceOptionParam
1314
from .chat_completion_function_call_option_param import ChatCompletionFunctionCallOptionParam
1415

@@ -141,6 +142,9 @@ class CompletionCreateParamsBase(TypedDict, total=False):
141142
stop: Union[Optional[str], List[str]]
142143
"""Up to 4 sequences where the API will stop generating further tokens."""
143144

145+
stream_options: Optional[ChatCompletionStreamOptionsParam]
146+
"""Options for streaming response. Only set this when you set `stream: true`."""
147+
144148
temperature: Optional[float]
145149
"""What sampling temperature to use, between 0 and 2.
146150

0 commit comments

Comments
 (0)