Spaces:
Sleeping
Sleeping
| """Shared contracts and JSON helpers for LLM providers.""" | |
| from __future__ import annotations | |
| import json | |
| from typing import Any, Protocol | |
| class LlmProviderError(RuntimeError): | |
| """Raised when an LLM provider cannot return a usable response.""" | |
| class JsonLlmProvider(Protocol): | |
| """Provider protocol shared by real and fake JSON LLM providers.""" | |
| def complete_json( | |
| self, | |
| *, | |
| system_prompt: str, | |
| user_prompt: str, | |
| output_schema: dict[str, Any], | |
| metadata: dict[str, Any], | |
| ) -> dict[str, Any]: | |
| ... | |
| def build_json_response_format( | |
| *, | |
| output_schema: dict[str, Any], | |
| metadata: dict[str, Any], | |
| use_json_schema: bool, | |
| strict: bool, | |
| default_schema_name: str, | |
| ) -> dict[str, Any]: | |
| if not use_json_schema or not output_schema: | |
| return {"type": "json_object"} | |
| return { | |
| "type": "json_schema", | |
| "json_schema": { | |
| "name": json_schema_name(metadata, default_name=default_schema_name), | |
| "strict": strict, | |
| "schema": output_schema, | |
| }, | |
| } | |
| def json_schema_name(metadata: dict[str, Any], *, default_name: str) -> str: | |
| raw = "_".join( | |
| str(metadata.get(key, "")).strip() | |
| for key in ("strategy_name", "purpose", "stage", "call_id") | |
| if metadata.get(key) | |
| ) | |
| if not raw: | |
| raw = default_name | |
| safe = [character if character.isalnum() or character in {"_", "-"} else "_" for character in raw] | |
| name = "".join(safe).strip("_") or default_name | |
| if not name[0].isalpha(): | |
| name = f"{default_name}_{name}" | |
| return name[:64] | |
| def parse_json_content(content: Any) -> Any: | |
| """Parse model content that may wrap JSON in surrounding text.""" | |
| text = content_to_text(content).strip() | |
| try: | |
| return json.loads(text) | |
| except json.JSONDecodeError: | |
| start = text.find("{") | |
| end = text.rfind("}") | |
| if start >= 0 and end >= start: | |
| return json.loads(text[start : end + 1]) | |
| raise | |
| def extract_chat_message_content(body: dict[str, Any], *, provider_name: str) -> Any: | |
| try: | |
| choice = body["choices"][0] | |
| message = choice["message"] | |
| return message.get("content") | |
| except (KeyError, IndexError, TypeError) as exc: | |
| raise LlmProviderError(f"{provider_name} returned an unexpected response payload: {body!r}") from exc | |
| def content_to_text(content: Any) -> str: | |
| if isinstance(content, str): | |
| return content | |
| if isinstance(content, list): | |
| parts: list[str] = [] | |
| for item in content: | |
| if isinstance(item, dict): | |
| parts.append(str(item.get("text") or item.get("content") or "")) | |
| else: | |
| parts.append(str(item)) | |
| return "".join(parts) | |
| return str(content or "") | |