Python 88.3%
TypeScript 7.6%
Shell 4.1%
1"""Smoke tests for the OpenAI Agents platform (Agents API beta, Vaults, ChatKit, retired Assistants).23Cheap tests (always run): read-only list calls and gating checks (no inference, $0).4Expensive tests (RUN_EXPENSIVE_TESTS=true): create agent + session, stream one turn, clean up (~$0.003 on gpt-5.6-luna).5"""6from __future__ import annotations78import json9import os10import time1112import pytest1314AGENTS = {"OpenAI-Beta": "agents=v1"}15CHATKIT = {"OpenAI-Beta": "chatkit_beta=v1"}16AGENTS_MODEL = os.environ.get("ATLAS_AGENTS_MODEL", "gpt-5.6-luna") # cheapest model accepted by Managed Agents (live 2026-09-18)171819def test_agents_requires_beta_header(openai):20 st, body, _ = openai("GET", "/v1/agents?limit=1", note="test: missing beta header")21 assert st == 40022 assert body["error"]["code"] == "invalid_beta"23 assert "agents=v1" in body["error"]["message"]242526def test_agents_query_beta_flag_is_not_accepted(openai):27 st, body, _ = openai("GET", "/v1/agents?limit=1&beta=true", note="test: ?beta=true")28 assert st == 400 and body["error"]["code"] == "invalid_beta"293031@pytest.mark.parametrize("path", ["/v1/agents", "/v1/agents/sessions", "/v1/agents/environments/templates", "/v1/vaults"])32def test_agents_list_endpoints(openai, path):33 st, body, _ = openai("GET", f"{path}?limit=1", extra_headers=AGENTS, note=f"test: list {path}")34 assert st == 200, body35 assert body["object"] == "list"36 for k in ("data", "first_id", "last_id", "has_more"):37 assert k in body383940def test_chatkit_threads_list(openai):41 st, body, _ = openai("GET", "/v1/chatkit/threads?limit=1", extra_headers=CHATKIT, note="test: chatkit threads list")42 assert st == 200 and body["object"] == "list"434445def test_unknown_session_is_json_404(openai):46 st, body, _ = openai("GET", "/v1/agents/sessions/sess_doesnotexist", extra_headers=AGENTS, note="test: bogus session")47 assert st == 40448 assert body["error"]["code"] == "not_found_error"495051def test_assistants_api_is_retired(openai):52 """Sunset 2026-08-26: the routes answer 404 with an EMPTY body (not a JSON error)."""53 st, body, _ = openai("GET", "/v1/assistants?limit=1", extra_headers={"OpenAI-Beta": "assistants=v2"}, note="test: assistants retired")54 assert st == 40455 assert body in (b"", None) or body == b""565758@pytest.mark.run_expensive_tests59def test_agent_session_roundtrip_stream(openai):60 st, agent, _ = openai("POST", "/v1/agents", {"name": "atlas-test", "model": AGENTS_MODEL, "instructions": "Reply with OK."}, extra_headers=AGENTS, note="test: create agent")61 assert st == 201, agent62 try:63 st, lines, hdrs = openai("POST", "/v1/agents/sessions", {"agent_id": agent["id"], "environment": {"type": "none"}, "input": "Reply with OK.", "stream": True},64 extra_headers={**AGENTS, "Accept": "text/event-stream"}, stream=True, timeout=240, est_cost_usd=0.0015, note="test: create session stream")65 assert st == 201, lines66 assert "text/event-stream" in hdrs.get("Content-Type", "")67 types, session_id, text, t0 = [], None, "", time.time()68 for line in lines:69 if not line.startswith("data:"):70 continue71 ev = json.loads(line[5:])72 types.append(ev["type"])73 if ev["type"] == "agent.session.created":74 session_id = ev["session"]["id"]75 if ev["type"] == "agent.session.turn.output_text.done":76 text = ev["text"]77 if ev["type"] in ("agent.session.turn.completed", "agent.session.turn.failed", "agent.session.turn.cancelled", "agent.session.failed", "error") or time.time() - t0 > 200:78 break79 assert types[0] == "agent.session.created"80 assert "agent.session.turn.completed" in types, types81 assert "OK" in text82 st, items, _ = openai("GET", f"/v1/agents/sessions/{session_id}/items?order=asc", extra_headers=AGENTS, note="test: list items")83 assert st == 200 and [i["role"] for i in items["data"] if i["type"] == "message"] == ["user", "assistant"]84 st, turns, _ = openai("GET", f"/v1/agents/sessions/{session_id}/turns", extra_headers=AGENTS, note="test: list turns")85 assert st == 200 and turns["data"][0]["status"] == "completed" and turns["data"][0]["subagent_id"] is None86 st, deleted, _ = openai("DELETE", f"/v1/agents/sessions/{session_id}", extra_headers=AGENTS, note="test: delete session")87 assert st == 200 and deleted["object"] == "agent.session.deleted"88 finally:89 openai("DELETE", f"/v1/agents/{agent['id']}", extra_headers=AGENTS, note="test: delete agent")90