Spaces:
Sleeping
Sleeping
| """OpenAI Responses API integration.""" | |
| from __future__ import annotations | |
| from collections.abc import Iterable | |
| from openai import APIConnectionError, APIStatusError, AuthenticationError, OpenAI, RateLimitError | |
| def format_openai_error(error: Exception) -> str: | |
| """Return a learner-friendly error message.""" | |
| if isinstance(error, AuthenticationError): | |
| return ( | |
| "The OpenAI API key was rejected. Please check that OPENAI_API_KEY is " | |
| "set correctly in Hugging Face Secrets." | |
| ) | |
| if isinstance(error, RateLimitError): | |
| return ( | |
| "The request was rate limited or the account may have quota or billing " | |
| "limits. Please wait briefly, then check OpenAI usage and billing settings." | |
| ) | |
| if isinstance(error, APIConnectionError): | |
| return ( | |
| "The app could not reach OpenAI. Please check the network connection and " | |
| "try again." | |
| ) | |
| if isinstance(error, APIStatusError): | |
| status = getattr(error, "status_code", "unknown") | |
| return ( | |
| f"OpenAI returned an API error with status {status}. Please review the " | |
| "API key, model name, quota, billing status, and request details." | |
| ) | |
| return "An unexpected AI service error occurred. Please try again or review the Space logs." | |
| def stream_tutor_response( | |
| *, | |
| api_key: str, | |
| model: str, | |
| system_instructions: str, | |
| messages: list[dict[str, str]], | |
| ) -> Iterable[str]: | |
| """Yield text deltas from the current event-based OpenAI Responses API stream.""" | |
| client = OpenAI(api_key=api_key) | |
| input_messages = [ | |
| {"role": message["role"], "content": message["content"]} | |
| for message in messages | |
| if message.get("role") in {"user", "assistant"} and message.get("content") | |
| ] | |
| stream = client.responses.create( | |
| model=model, | |
| instructions=system_instructions, | |
| input=input_messages, | |
| stream=True, | |
| ) | |
| for event in stream: | |
| if getattr(event, "type", None) == "response.output_text.delta": | |
| delta = getattr(event, "delta", "") | |
| if delta: | |
| yield delta | |