Python 88.3%
TypeScript 7.6%
Shell 4.1%
1#!/usr/bin/env python32"""Anthropic Managed Agents (beta): create agent -> environment -> session -> user.message -> stream SSE -> cleanup.34STATUS: LIVE_VERIFIED 2026-09-18 — the identical HTTP sequence (env → agent → session with string-cents budget → user.message → SSE stream → cleanup) ran via scripts/live.py (tmp-live/platform-anthropic/agents-probes-2.json); this file itself was not executed.5Model: claude-haiku-4-5-202510016Beta header: anthropic-beta: managed-agents-2026-04-017Budget: max budget minimal -- session budget capped at 5 US cents ({"amount": "5", "currency": "USD"}),8 prompt "Reply with OK.", no tools (nothing executes in the sandbox). Names prefixed "atlas-platform-agent".910Uses scripts.live.anthropic_request (auth injected from .env, every call logged to reports/live-requests.jsonl,11keys masked). SSE is read with stream=True, which returns a line iterator over the HTTP response.12Every resource created here is removed in `finally`: DELETE session (after interrupt if still running),13POST /v1/agents/{id}/archive (agents have no delete endpoint), DELETE /v1/environments/{id} (falls back to archive).1415Run: .venv/bin/python examples/anthropic/agents/create_agent_session_stream.py16Docs: https://platform.claude.com/docs/en/managed-agents/quickstart17 https://platform.claude.com/docs/en/managed-agents/events-and-streaming18"""19from __future__ import annotations2021import json22import sys23import time24from pathlib import Path2526ROOT = Path(__file__).resolve().parents[3]27sys.path.insert(0, str(ROOT))28from scripts.live import anthropic_request # noqa: E4022930BETA = "managed-agents-2026-04-01"31MODEL = "claude-haiku-4-5-20251001"32TS = int(time.time())33# Haiku 4.5 list price (USD per 1M tokens) used only for the est_cost_usd log field.34IN_PRICE, OUT_PRICE = 1.0, 5.0353637def ant(method: str, path: str, body=None, note: str = "", **kw):38 st, resp, _ = anthropic_request(method, path, body, beta=BETA, note=note, **kw)39 if st >= 300:40 raise RuntimeError(f"{method} {path} -> {st}: {json.dumps(resp)[:500] if not isinstance(resp, bytes) else resp[:500]!r}")41 return resp424344def main() -> int:45 agent_id = env_id = session_id = None46 try:47 # 1) Agent: versioned resource; no tools so nothing runs in the sandbox.48 agent = ant("POST", "/v1/agents", {49 "name": f"atlas-platform-agent-{TS}",50 "model": MODEL,51 "system": "You are a terse test agent. Reply with OK.",52 "metadata": {"origin": "api-atlas"},53 }, note="managed-agents create agent")54 agent_id = agent["id"]55 print("agent:", agent_id, "version", agent["version"])5657 # 2) Environment: cloud sandbox with limited egress (least privilege).58 env = ant("POST", "/v1/environments", {59 "name": f"atlas-platform-agent-env-{TS}",60 "config": {"type": "cloud", "networking": {"type": "limited", "allowed_hosts": ["example.com"]}},61 }, note="managed-agents create environment")62 env_id = env["id"]63 print("environment:", env_id)6465 # 3) Session with a hard 5-cent list-cost budget (only attachable at creation).66 session = ant("POST", "/v1/sessions", {67 "agent": agent_id,68 "environment_id": env_id,69 "title": f"atlas-platform-agent-session-{TS}",70 "budget": {"type": "limit", "max_list_cost": {"amount": "5", "currency": "USD"}},71 }, note="managed-agents create session")72 session_id = session["id"]73 print("session:", session_id, "status", session["status"])7475 # 4) Open the SSE stream BEFORE sending the message (only later events are delivered).76 st, lines, _hdrs = anthropic_request(77 "GET", f"/v1/sessions/{session_id}/events/stream", beta=BETA,78 extra_headers={"accept": "text/event-stream"}, content_type=None, stream=True, timeout=200,79 note="managed-agents stream events")80 if st >= 300:81 raise RuntimeError(f"stream -> {st}: {lines}")8283 # 5) Send the user message (returns as soon as the event is queued).84 ant("POST", f"/v1/sessions/{session_id}/events", {85 "events": [{"type": "user.message", "content": [{"type": "text", "text": "Reply with OK."}]}],86 }, note="managed-agents send user.message")8788 # 6) Consume the stream until the session goes idle (or errors / 180 s deadline).89 deadline = time.time() + 18090 seen: list[str] = []91 usage = None92 for line in lines:93 if time.time() > deadline:94 print("timeout waiting for session.status_idle")95 break96 if not line.startswith("data:"):97 continue98 ev = json.loads(line[5:].strip())99 seen.append(ev["type"])100 if ev["type"] == "agent.message":101 print("[agent.message]", "".join(c.get("text", "") for c in ev["content"] if c.get("type") == "text"))102 elif ev["type"] == "session.usage":103 usage = ev.get("usage")104 print("[session.usage] list_cost", (usage or {}).get("list_cost"), "active_seconds", (usage or {}).get("active_seconds"))105 elif ev["type"] == "session.status_idle":106 print("[session.status_idle] stop_reason", ev["stop_reason"]["type"])107 break108 elif ev["type"] == "session.error":109 print("[session.error]", ev["error"].get("type"), ev["error"].get("retry_status", {}).get("type"))110 break111 else:112 print(f"[{ev['type']}]")113 print("event sequence:", " -> ".join(seen))114115 # 7) Final snapshot; log an estimated cost from token usage.116 fin = ant("GET", f"/v1/sessions/{session_id}", note="managed-agents get session")117 u = fin.get("usage") or {}118 est = (u.get("input_tokens", 0) * IN_PRICE + u.get("output_tokens", 0) * OUT_PRICE) / 1e6119 print(json.dumps({"status": fin["status"], "usage": u, "est_cost_usd_tokens_only": round(est, 6)}, indent=2))120 return 0121 finally:122 # Cleanup: every resource this script created.123 try:124 if session_id:125 s = ant("GET", f"/v1/sessions/{session_id}")126 if s["status"] == "running":127 ant("POST", f"/v1/sessions/{session_id}/events", {"events": [{"type": "user.interrupt"}]})128 for _ in range(30):129 time.sleep(2)130 if ant("GET", f"/v1/sessions/{session_id}")["status"] != "running":131 break132 ant("DELETE", f"/v1/sessions/{session_id}", note="cleanup delete session")133 print("deleted session", session_id)134 if agent_id:135 ant("POST", f"/v1/agents/{agent_id}/archive", note="cleanup archive agent")136 print("archived agent", agent_id)137 if env_id:138 try:139 ant("DELETE", f"/v1/environments/{env_id}", note="cleanup delete environment")140 print("deleted environment", env_id)141 except RuntimeError:142 ant("POST", f"/v1/environments/{env_id}/archive", note="cleanup archive environment")143 print("archived environment", env_id)144 except Exception as exc: # noqa: BLE001145 print("cleanup error:", exc)146147148if __name__ == "__main__":149 raise SystemExit(main())150