Add agent_stream.py

This commit is contained in:
2026-05-24 20:10:21 +00:00
parent a5b32d91fc
commit 3e44263e0d
+90
View File
@@ -0,0 +1,90 @@
"""Simple streaming AI agent using OpenAI ChatCompletion API.
The module exposes a single function ``stream_chat`` that yields
text fragments as they arrive from the model. It is intentionally
lightweight so it can be used as a dropin component in larger
applications.
Dependencies
------------
* ``openai`` official OpenAI SDK
Environment
-----------
An OpenAI API key must be available either as the environment
variable ``OPENAI_API_KEY`` or passed explicitly via the
``api_key`` argument.
"""
from __future__ import annotations
import os
from typing import Iterable, Generator, Dict, List, Any
import openai
# Ensure the OpenAI key is set when the module is imported.
# Users can override by passing ``api_key`` to ``stream_chat``.
openai.api_key = os.getenv("OPENAI_API_KEY")
def stream_chat(
messages: List[Dict[str, str]],
*,
model: str = "gpt-3.5-turbo",
temperature: float = 0.7,
api_key: str | None = None,
) -> Generator[str, None, None]:
"""Yield model output token by token.
Parameters
----------
messages:
A list of message objects compatible with the ChatCompletion API.
model:
The model to use. Defaults to ``gpt-3.5-turbo``.
temperature:
Sampling temperature. Defaults to 0.7.
api_key:
Optional API key. If provided it overrides the environment
variable.
Yields
------
str
The next fragment of the assistant's reply.
"""
if api_key is not None:
openai.api_key = api_key
# The SDK returns an iterator over chunks when stream=True.
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=temperature,
stream=True,
)
# The response is an iterator of chunks. Each chunk contains a
# ``choices[0].delta`` dict with the text fragment.
for chunk in response:
try:
delta = chunk["choices"][0]["delta"]
if "content" in delta:
yield delta["content"]
except Exception as exc: # pragma: no cover defensive
# In a real application you might log this.
print(f"Error processing chunk: {exc}")
continue
# If the module is executed directly, run a small demo.
if __name__ == "__main__": # pragma: no cover
demo_messages = [
{"role": "user", "content": "Write a short poem about the ocean."}
]
print("Streaming response: ")
for token in stream_chat(demo_messages):
print(token, end="", flush=True)
print()