-
-
Notifications
You must be signed in to change notification settings - Fork 10.7k
[CLI] Use streaming in CLI chat and completion commands #23769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -45,6 +45,28 @@ def _interactive_cli(args: argparse.Namespace) -> tuple[str, OpenAI]: | |||||
return model_name, openai_client | ||||||
|
||||||
|
||||||
def _print_chat_stream(stream) -> str: | ||||||
output = "" | ||||||
for chunk in stream: | ||||||
delta = chunk.choices[0].delta | ||||||
if delta.content: | ||||||
output += delta.content | ||||||
print(delta.content, end="", flush=True) | ||||||
print() | ||||||
return output | ||||||
|
||||||
|
||||||
def _print_completion_stream(stream) -> str: | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For consistency and to improve type safety, please add a type hint for the You'll need to ensure the necessary types are imported within a from typing import TYPE_CHECKING
if TYPE_CHECKING:
from openai import Stream
from openai.types import Completion
Suggested change
|
||||||
output = "" | ||||||
for chunk in stream: | ||||||
text = chunk.choices[0].text | ||||||
if text is not None: | ||||||
output += text | ||||||
print(text, end="", flush=True) | ||||||
print() | ||||||
return output | ||||||
|
||||||
|
||||||
def chat(system_prompt: str | None, model_name: str, client: OpenAI) -> None: | ||||||
conversation: list[ChatCompletionMessageParam] = [] | ||||||
if system_prompt is not None: | ||||||
|
@@ -58,14 +80,11 @@ def chat(system_prompt: str | None, model_name: str, client: OpenAI) -> None: | |||||
break | ||||||
conversation.append({"role": "user", "content": input_message}) | ||||||
|
||||||
chat_completion = client.chat.completions.create(model=model_name, | ||||||
messages=conversation) | ||||||
|
||||||
response_message = chat_completion.choices[0].message | ||||||
output = response_message.content | ||||||
|
||||||
conversation.append(response_message) # type: ignore | ||||||
print(output) | ||||||
stream = client.chat.completions.create(model=model_name, | ||||||
messages=conversation, | ||||||
stream=True) | ||||||
output = _print_chat_stream(stream) | ||||||
conversation.append({"role": "assistant", "content": output}) | ||||||
|
||||||
|
||||||
def _add_query_options( | ||||||
|
@@ -108,9 +127,11 @@ def cmd(args: argparse.Namespace) -> None: | |||||
if args.quick: | ||||||
conversation.append({"role": "user", "content": args.quick}) | ||||||
|
||||||
chat_completion = client.chat.completions.create( | ||||||
model=model_name, messages=conversation) | ||||||
print(chat_completion.choices[0].message.content) | ||||||
stream = client.chat.completions.create(model=model_name, | ||||||
messages=conversation, | ||||||
stream=True) | ||||||
output = _print_chat_stream(stream) | ||||||
conversation.append({"role": "assistant", "content": output}) | ||||||
return | ||||||
|
||||||
print("Please enter a message for the chat model:") | ||||||
|
@@ -121,14 +142,11 @@ def cmd(args: argparse.Namespace) -> None: | |||||
break | ||||||
conversation.append({"role": "user", "content": input_message}) | ||||||
|
||||||
chat_completion = client.chat.completions.create( | ||||||
model=model_name, messages=conversation) | ||||||
|
||||||
response_message = chat_completion.choices[0].message | ||||||
output = response_message.content | ||||||
|
||||||
conversation.append(response_message) # type: ignore | ||||||
print(output) | ||||||
stream = client.chat.completions.create(model=model_name, | ||||||
messages=conversation, | ||||||
stream=True) | ||||||
output = _print_chat_stream(stream) | ||||||
conversation.append({"role": "assistant", "content": output}) | ||||||
|
||||||
@staticmethod | ||||||
def add_cli_args(parser: FlexibleArgumentParser) -> FlexibleArgumentParser: | ||||||
|
@@ -168,9 +186,10 @@ def cmd(args: argparse.Namespace) -> None: | |||||
model_name, client = _interactive_cli(args) | ||||||
|
||||||
if args.quick: | ||||||
completion = client.completions.create(model=model_name, | ||||||
prompt=args.quick) | ||||||
print(completion.choices[0].text) | ||||||
stream = client.completions.create(model=model_name, | ||||||
prompt=args.quick, | ||||||
stream=True) | ||||||
_print_completion_stream(stream) | ||||||
Comment on lines
+189
to
+192
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The streaming API call can raise exceptions. To make the CLI more robust, please wrap this call in a try:
stream = client.completions.create(model=model_name,
prompt=args.quick,
stream=True)
_print_completion_stream(stream)
except Exception as e:
print(f"\nAn error occurred: {e}") |
||||||
return | ||||||
|
||||||
print("Please enter prompt to complete:") | ||||||
|
@@ -179,10 +198,10 @@ def cmd(args: argparse.Namespace) -> None: | |||||
input_prompt = input("> ") | ||||||
except EOFError: | ||||||
break | ||||||
completion = client.completions.create(model=model_name, | ||||||
prompt=input_prompt) | ||||||
output = completion.choices[0].text | ||||||
print(output) | ||||||
stream = client.completions.create(model=model_name, | ||||||
prompt=input_prompt, | ||||||
stream=True) | ||||||
_print_completion_stream(stream) | ||||||
Comment on lines
+201
to
+204
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The streaming API call can raise exceptions. To make the CLI more robust, please wrap this call in a try:
stream = client.completions.create(model=model_name,
prompt=input_prompt,
stream=True)
_print_completion_stream(stream)
except Exception as e:
print(f"\nAn error occurred: {e}") |
||||||
|
||||||
@staticmethod | ||||||
def add_cli_args(parser: FlexibleArgumentParser) -> FlexibleArgumentParser: | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To improve type safety and code readability, please add a type hint for the
stream
parameter. Theopenai
client returns aStream
ofChatCompletionChunk
objects. Using a string forward reference for the type hint is a good practice here.You'll need to ensure the necessary types are imported within a
TYPE_CHECKING
block:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1