Python 88.3%
TypeScript 7.6%
Shell 4.1%
1// Anthropic Managed Agents (beta) — create agent -> create environment -> create session ->2// send user.message -> stream SSE events (raw fetch) -> clean up everything created.3//4// STATUS: 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.5// Model: claude-haiku-4-5-202510016// Beta header: anthropic-beta: managed-agents-2026-04-017// Budget: max budget minimal — session budget capped at 5 US cents, prompt "Reply with OK.", no tools.8// Names are prefixed "atlas-platform-agent".9//10// Run: node --env-file=.env --experimental-strip-types examples/anthropic/agents/create_agent_session_stream.ts11// Uses process.env.ANTHROPIC_API_KEY only; never prints it.12//13// Docs: https://platform.claude.com/docs/en/managed-agents/quickstart14// https://platform.claude.com/docs/en/managed-agents/events-and-streaming1516const API_KEY = process.env.ANTHROPIC_API_KEY;17if (!API_KEY) throw new Error("ANTHROPIC_API_KEY missing (node --env-file=.env ...)");18const BASE = process.env.ANTHROPIC_BASE_URL ?? "https://api.anthropic.com";19const BETA = "managed-agents-2026-04-01";20const MODEL = "claude-haiku-4-5-20251001";21const TS = Date.now();2223const headers: Record<string, string> = {24 "x-api-key": API_KEY,25 "anthropic-version": "2023-06-01",26 "anthropic-beta": BETA,27 "content-type": "application/json",28};2930async function ant<T = any>(method: string, path: string, body?: unknown): Promise<T> {31 const res = await fetch(BASE + path, { method, headers, body: body === undefined ? undefined : JSON.stringify(body) });32 const text = await res.text();33 if (!res.ok) throw new Error(`${method} ${path} -> ${res.status}: ${text.slice(0, 500)}`);34 return text ? (JSON.parse(text) as T) : (undefined as T);35}3637let agentId = "", envId = "", sessionId = "";38const abort = new AbortController();3940async function cleanup() {41 abort.abort();42 try {43 if (sessionId) {44 let s = await ant("GET", `/v1/sessions/${sessionId}`);45 if (s.status === "running") {46 await ant("POST", `/v1/sessions/${sessionId}/events`, { events: [{ type: "user.interrupt" }] });47 for (let i = 0; i < 30 && s.status === "running"; i++) {48 await new Promise((r) => setTimeout(r, 2000));49 s = await ant("GET", `/v1/sessions/${sessionId}`);50 }51 }52 await ant("DELETE", `/v1/sessions/${sessionId}`);53 console.log("deleted session", sessionId);54 }55 if (agentId) { await ant("POST", `/v1/agents/${agentId}/archive`); console.log("archived agent", agentId); }56 if (envId) {57 try { await ant("DELETE", `/v1/environments/${envId}`); console.log("deleted environment", envId); }58 catch { await ant("POST", `/v1/environments/${envId}/archive`); console.log("archived environment", envId); }59 }60 } catch (e) { console.error("cleanup error:", (e as Error).message); }61}6263async function main() {64 // 1) Agent (no tools => nothing executes in the sandbox)65 const agent = await ant("POST", "/v1/agents", {66 name: `atlas-platform-agent-${TS}`, model: MODEL,67 system: "You are a terse test agent. Reply with OK.", metadata: { origin: "api-atlas" },68 });69 agentId = agent.id; console.log("agent:", agentId, "v" + agent.version);7071 // 2) Environment (cloud sandbox, limited egress)72 const env = await ant("POST", "/v1/environments", {73 name: `atlas-platform-agent-env-${TS}`,74 config: { type: "cloud", networking: { type: "limited", allowed_hosts: ["example.com"] } },75 });76 envId = env.id; console.log("environment:", envId);7778 // 3) Session with a 5-cent hard budget79 const session = await ant("POST", "/v1/sessions", {80 agent: agentId, environment_id: envId, title: `atlas-platform-agent-session-${TS}`,81 budget: { type: "limit", max_list_cost: { amount: "5", currency: "USD" } },82 });83 sessionId = session.id; console.log("session:", sessionId, "status=" + session.status);8485 // 4) Open the stream before sending the message86 const streamRes = await fetch(`${BASE}/v1/sessions/${sessionId}/events/stream`, {87 headers: { ...headers, accept: "text/event-stream" }, signal: abort.signal,88 });89 if (!streamRes.ok || !streamRes.body) throw new Error(`stream -> ${streamRes.status}`);9091 // 5) Send user.message92 await ant("POST", `/v1/sessions/${sessionId}/events`, {93 events: [{ type: "user.message", content: [{ type: "text", text: "Reply with OK." }] }],94 });9596 // 6) Parse SSE ("data: {...}" lines) until session.status_idle / session.error / timeout97 const reader = streamRes.body.getReader();98 const dec = new TextDecoder();99 let buf = "";100 const timer = setTimeout(() => abort.abort(), 180_000);101 const seen: string[] = [];102 outer: while (true) {103 const { value, done } = await reader.read().catch(() => ({ value: undefined, done: true }));104 if (done) break;105 buf += dec.decode(value, { stream: true });106 let idx: number;107 while ((idx = buf.indexOf("\n")) >= 0) {108 const line = buf.slice(0, idx).trimEnd(); buf = buf.slice(idx + 1);109 if (!line.startsWith("data:")) continue;110 const ev = JSON.parse(line.slice(5).trim());111 seen.push(ev.type);112 if (ev.type === "agent.message") {113 console.log("[agent.message]", ev.content.filter((c: any) => c.type === "text").map((c: any) => c.text).join(""));114 } else if (ev.type === "session.usage") {115 console.log("[session.usage] list_cost=", ev.usage?.list_cost?.amount, "active_seconds=", ev.usage?.active_seconds);116 } else if (ev.type === "session.status_idle") {117 console.log("[session.status_idle] stop_reason=", ev.stop_reason?.type); break outer;118 } else if (ev.type === "session.error") {119 console.log("[session.error]", ev.error?.type, ev.error?.retry_status?.type); break outer;120 } else {121 console.log(`[${ev.type}]`);122 }123 }124 }125 clearTimeout(timer);126 console.log("event sequence:", seen.join(" -> "));127128 // 7) Final snapshot129 const fin = await ant("GET", `/v1/sessions/${sessionId}`);130 console.log(JSON.stringify({ status: fin.status, usage: fin.usage }, null, 2));131}132133main().catch((e) => { console.error("error:", (e as Error).message); process.exitCode = 1; }).finally(cleanup);134