feat: harden public OpenAI API contracts
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
"""Wire-format helpers for the public Responses API subset."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
from db.models import OpenAIResponse
|
||||
|
||||
|
||||
def encode_sse(event: dict[str, Any]) -> bytes:
|
||||
"""Encode one named Responses event as an SSE record."""
|
||||
|
||||
return (
|
||||
f"event: {event['type']}\n"
|
||||
f"data: {json.dumps(event, ensure_ascii=False)}\n\n"
|
||||
).encode("utf-8")
|
||||
|
||||
|
||||
class SSEEventSequence:
|
||||
"""Attach the monotonically increasing sequence required by SDK models."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._next = 0
|
||||
|
||||
def encode(self, event_type: str, **payload: Any) -> bytes:
|
||||
event = {
|
||||
"type": event_type,
|
||||
"sequence_number": self._next,
|
||||
**payload,
|
||||
}
|
||||
self._next += 1
|
||||
return encode_sse(event)
|
||||
|
||||
|
||||
def assistant_text_item(item_id: str, text: str) -> dict[str, Any]:
|
||||
return {
|
||||
"id": item_id,
|
||||
"type": "message",
|
||||
"status": "completed",
|
||||
"role": "assistant",
|
||||
"content": [
|
||||
{
|
||||
"type": "output_text",
|
||||
"text": text,
|
||||
"annotations": [],
|
||||
}
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def build_output_items(
|
||||
*,
|
||||
text: str,
|
||||
text_item_id: str,
|
||||
function_calls: list[dict[str, Any]],
|
||||
) -> list[dict[str, Any]]:
|
||||
items: list[dict[str, Any]] = []
|
||||
if text:
|
||||
items.append(assistant_text_item(text_item_id, text))
|
||||
items.extend(function_calls)
|
||||
return items
|
||||
|
||||
|
||||
def output_lifecycle_events(
|
||||
row: OpenAIResponse,
|
||||
*,
|
||||
started_text_items: set[str],
|
||||
replay_text: bool,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Build terminal item events shared by live and idempotent streams."""
|
||||
|
||||
events: list[dict[str, Any]] = []
|
||||
for output_index, item in enumerate(row.output_items or []):
|
||||
if item.get("type") != "message":
|
||||
pending_item = {**item, "status": "in_progress"}
|
||||
if item.get("type") == "function_call":
|
||||
pending_item["arguments"] = ""
|
||||
events.append(
|
||||
{
|
||||
"type": "response.output_item.added",
|
||||
"output_index": output_index,
|
||||
"item": pending_item,
|
||||
}
|
||||
)
|
||||
if item.get("type") == "function_call":
|
||||
item_id = str(item.get("id") or "")
|
||||
arguments = str(item.get("arguments") or "")
|
||||
if arguments:
|
||||
events.append(
|
||||
{
|
||||
"type": "response.function_call_arguments.delta",
|
||||
"item_id": item_id,
|
||||
"output_index": output_index,
|
||||
"delta": arguments,
|
||||
}
|
||||
)
|
||||
events.append(
|
||||
{
|
||||
"type": "response.function_call_arguments.done",
|
||||
"item_id": item_id,
|
||||
"output_index": output_index,
|
||||
"name": str(item.get("name") or ""),
|
||||
"arguments": arguments,
|
||||
}
|
||||
)
|
||||
events.append(
|
||||
{
|
||||
"type": "response.output_item.done",
|
||||
"output_index": output_index,
|
||||
"item": item,
|
||||
}
|
||||
)
|
||||
continue
|
||||
|
||||
item_id = str(item["id"])
|
||||
content = item.get("content") or []
|
||||
part = content[0] if content else {
|
||||
"type": "output_text",
|
||||
"text": "",
|
||||
"annotations": [],
|
||||
}
|
||||
text = str(part.get("text") or "")
|
||||
if item_id not in started_text_items:
|
||||
events.extend(
|
||||
[
|
||||
{
|
||||
"type": "response.output_item.added",
|
||||
"output_index": output_index,
|
||||
"item": {**item, "status": "in_progress", "content": []},
|
||||
},
|
||||
{
|
||||
"type": "response.content_part.added",
|
||||
"item_id": item_id,
|
||||
"output_index": output_index,
|
||||
"content_index": 0,
|
||||
"part": {
|
||||
"type": "output_text",
|
||||
"text": "",
|
||||
"annotations": [],
|
||||
},
|
||||
},
|
||||
]
|
||||
)
|
||||
started_text_items.add(item_id)
|
||||
if replay_text and text:
|
||||
events.append(
|
||||
{
|
||||
"type": "response.output_text.delta",
|
||||
"item_id": item_id,
|
||||
"output_index": output_index,
|
||||
"content_index": 0,
|
||||
"delta": text,
|
||||
"logprobs": [],
|
||||
}
|
||||
)
|
||||
events.extend(
|
||||
[
|
||||
{
|
||||
"type": "response.output_text.done",
|
||||
"item_id": item_id,
|
||||
"output_index": output_index,
|
||||
"content_index": 0,
|
||||
"text": text,
|
||||
"logprobs": [],
|
||||
},
|
||||
{
|
||||
"type": "response.content_part.done",
|
||||
"item_id": item_id,
|
||||
"output_index": output_index,
|
||||
"content_index": 0,
|
||||
"part": part,
|
||||
},
|
||||
{
|
||||
"type": "response.output_item.done",
|
||||
"output_index": output_index,
|
||||
"item": item,
|
||||
},
|
||||
]
|
||||
)
|
||||
return events
|
||||
|
||||
|
||||
def stored_input_items(row: OpenAIResponse) -> list[dict[str, Any]]:
|
||||
"""Backfill stable wire IDs for records created before contract v1."""
|
||||
|
||||
result: list[dict[str, Any]] = []
|
||||
for index, stored in enumerate(row.input_items or []):
|
||||
item = dict(stored)
|
||||
item.setdefault("id", f"item_{row.id}_{index}")
|
||||
item.setdefault("status", "completed")
|
||||
result.append(item)
|
||||
return result
|
||||
Reference in New Issue
Block a user