Repository navigation
feat!: SDK phase 1 stack (#11–#23) into main - #25
Merged
Merged
Conversation
Adds the P1 SDK egress plan (.claude/plans/p1-sdk-egress-routes.md) and a
regression test: with the egress base
http://egress/computer-agent-api/agentos/api (with or without a trailing slash
or /v1) the agent is read from exactly
GET http://egress/computer-agent-api/agentos/api/v1/agents/{id} with x-api-key.
api_base() already yields a single /agentos/api, so no code changes; the module
docstring and USING_THE_SDK.md §3 and §6 name the egress path.
Plan phase 1 (R2, D1).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The egress proxy serves no /events route, so the sink cannot reach AgentOS from a sandbox. Removed: AgentOSHttpSink (telemetry/sinks/agentos_http.py), its lazy export, the drop-in auto-attach from AGENTOS_INGEST_URL / discovery, the events_url setting and COMPUTERAGENT_EVENTS_URL. build_pipeline takes only telemetry_url. examples/with_agentos.py is deleted; multi_sink.py and run_live_demo.py keep their OtelSink; the stale ingest_live_e2e section of examples/e2e/README.md is dropped. Plan phase 2 (Q4, D14). BREAKING CHANGE: AgentOSHttpSink, events_url and COMPUTERAGENT_EVENTS_URL are removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The user's message and every tool call go to POST {guardrails_url}/v1/check
(ops input and tool-input); the agent gateway applies the org's and the
agent's RAI policies and owns fail-open.
- guardrails_url / COMPUTERAGENT_GUARDRAILS_URL replaces srs_url and
agent_api_url; no org-policy fetch, rai_policy_id ignored.
- No verdict blocks the message or denies the tool.
- Tool calls carry the engine's tool-use id as call_id; none -> deny.
- Delete policy/srs_client.py and policy/org_policy.py.
BREAKING CHANGE: COMPUTERAGENT_GUARDRAILS_URL is required;
COMPUTERAGENT_SRS_URL and COMPUTERAGENT_AGENT_API_URL are no longer read.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(policy)!: check guardrails through the egress proxy
SrsPolicyEngine, srs_authorizer_from_env and computeragent.policy.srs are
deleted; nothing fetches {srs}/rai/policies/{id}. The built-in guardrails
gate replaces them; OPA and Cedar engines remain for custom gates.
BREAKING CHANGE: computeragent.policy no longer exports SrsPolicyEngine or
srs_authorizer_from_env.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
refactor(policy)!: remove the standalone SRS policy engine
…very client An egress answer carrying X-Cas-Token / X-Cas-Token-Expires-At extends the token's chain (sbt_ token, later expiry, sent with the newest token); every later egress request from every client carries the newest token. - egress_token: process-wide CREDENTIAL, httpx hooks, install(), stamping_session(); Settings.api_key() resolves the chain. - Agent resolve, guardrails client and gitagent's Anthropic/OpenAI clients carry the hooks. - egress_forwarder: a loopback h11 forwarder for the Claude CLI's model and MCP calls; the coordinator rewrites their egress URLs per turn. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(harness): adopt sandbox tokens reissued by the egress proxy in every client
Each OTLP export is encoded and split recursively under a 960 KiB budget; a single record over it is dropped with a count-only WARN, and the export fails if any part failed. Span and log processors export 128 at a time. The exporters use a stamping requests session that sets x-api-key from api_key() per request, so reissued sandbox tokens apply to telemetry. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(telemetry): split OTLP exports to fit the egress proxy's limit
…s proxy with the API key - COMPUTERAGENT_SESSION_STORE_URL / session_store_url (optional, no query or fragment) sets the http store's base URL via with_base_url(). - The http store sends only x-api-key (LYZR_API_KEY per request, as the newest sandbox token); the store token, its refresh and expiry_of are gone. - A descriptor without a kind is reported by its keys, never its values. BREAKING CHANGE: HttpSessionStore no longer takes token or auto_refresh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(session-stores)!: route the HTTP session store through the egress proxy with the API key
Each bound MCP server is {mcp_url}/{quote(tool_name)} with no query; the
server-id path and ?tools= query are removed (the gateway resolves both from
its registry). Docs use COMPUTERAGENT_MCP_URL=http://egress/mcp/v1.
BREAKING CHANGE: the MCP URL shape changes to {mcp_url}/{name}.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(harness)!: address MCP servers by name through the egress proxy
…t's gateway sections The agent document (after old-CAS #164) is read from llm.config.model and mcp.servers; guardrails is not read. The model-gateway fields and refusals, mcp_mode and DEFAULT_MCP_MODE are removed; every binding is attached to the engine. For gitagent a model without a provider prefix gets openai:. BREAKING CHANGE: ResolvedAgent loses gateway_* fields, has_native_gateway and mcp_mode; legacy document fields are no longer read. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ions feat(harness)!: read the model and MCP servers from the agent document's gateway sections
The engine's ANTHROPIC_API_KEY / OPENAI_API_KEY / LYZR_API_KEY and the bound MCP servers' x-api-key are set from Settings.api_key() at every turn (and at boot); servers the loader or caller supplied are untouched. A missing key fails the turn before the engine starts. build_gateway_envs holds no key; key_envs() returns the three variables. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(harness): pick up the Lyzr key every turn
computeragent.server (extra `server`), run as `python -m computeragent.server` on 0.0.0.0:8080: Lambda MicroVM lifecycle hooks, health, sessions, messages, events (SSE with Last-Event-ID replay), end-input, cancel, approvals and the workspace file routes, following computeragent-enterprise's harness-server. - One ComputerAgent per session from the image's settings; envs.LYZR_API_KEY seeds the key and each message's credential replaces it; turns run one at a time per process. - Events in sse-events.ts shapes: ca_turn_started and ca_redaction_decision (observed inline on the telemetry pipeline), sdk_message in the TS SDK's JSON shape, ca_permission_request/decision, ca_usage_snapshot before the turn's result, one ca_session_ended per session. - File routes confined to the workspace; deletes remove a file or an empty directory only. - Plan: Q16-Q18 resolved with the plan's recommendations; the turn-end wording corrected to the reference harness's behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(server): serve the CAS harness API from the stage image
The app server also answers AgentCore: GET /ping (Healthy / HealthyBusy while
a turn runs) and POST /invocations, relay envelope v1 dispatched in-process to
its own routes. Streamed answers start with the `: ca-relay` head frame; other
answers return as {relay, instance, status, headers, body | bodyBase64}; a
malformed envelope is status 400 AGENTCORE_RELAY_REQUEST_INVALID. The
instance id is minted on the first invocation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
feat(server): serve the AgentCore relay envelope
…es the agent and token per session
The settings' environment variables are renamed so each says what it is:
COMPUTER_AGENT_ID, COMPUTER_AGENT_ENGINE, COMPUTER_AGENT_EGRESS_PROXY_SECRET
(was LYZR_API_KEY) and COMPUTER_AGENT_EGRESS_{API,LLM,MCP,GUARDRAILS,
TELEMETRY,SESSION_STORE}_URL, plus COMPUTER_AGENT_GAP_DIR. Constructor
arguments are unchanged; no old name is read.
Old CAS now passes COMPUTER_AGENT_EGRESS_PROXY_SECRET and COMPUTER_AGENT_ID
in POST /v1/sessions envs: the app server seeds the token from it and builds
the session's agent from the id, falling back to the image's own.
events() bounded each read with asyncio.wait_for(frames.__anext__(), 20 s). On a timeout, wait_for cancelled the EventLog generator inside its wait for new events; a cancelled async generator is finished, so the next read raised StopAsyncIteration and the response ended right after the first keepalive. On Lambda MicroVM CAS reported STREAM_UPSTREAM_LOST on any 20 s quiet gap. EventLog.iterate now takes the keepalive and yields None when it expires, so no cancellation crosses the generator.
The Claude CLI keys transcripts by its own per-process UUID, so a new sandbox for the same conversation looked under a key nobody wrote and started blank, and agentos had no stable id to file the store under (old-CAS plan 10). With ComputerAgent(session_id=..., session_store=...), PinnedSessionStore puts that id on every append and load; project_key and subpath are kept. The Claude engine runs the CLI under uuid5(session_id): on the first turn of a process it loads the store once and starts a new conversation under that UUID, or resumes the stored one. Every process serving a conversation then uses the same CLI UUID, so the stored entries' ids always match. The app server already passes session_id = the CAS sessionId. Without session_id nothing changes.
Both example images install the otel extra and set COMPUTER_AGENT_EGRESS_TELEMETRY_URL=<egress>/otlp.
policy_config_url and fetch_policy_binding had no caller since 371c815 (0.4.0, one run mode). AgentOS has dropped the ingest/policy-config/{name} route they read (computeragent-enterprise a8843c9) because the agent gateway applies org and agent policies, so a direct caller got a 404 that read as "no policy". bind_policy stays: PUT /agents/{id}/policy is still served.
CAS now passes the six egress routes per session, beside the token and the
agent id: COMPUTER_AGENT_EGRESS_{API,LLM,MCP,GUARDRAILS,SESSION_STORE,
TELEMETRY}_URL in POST /v1/sessions envs. Each is used only when the image's
own environment does not set it, and an agent factory's arguments win over
both, so one image runs against whatever proxy CAS names while an image or
its code can still pin a route.
Rename the examples to examples/sdk_default_lambda_microvm and examples/sdk_default_agentcore: they build the images UAT CAS boots when an agent names no MicroVM image or AgentCore runtime of its own. Their .env now bakes only the engine; CAS passes the agent id, the sandbox token and the six egress routes per session, so one image runs against whichever egress proxy CAS names.
…og the instance Matches CAS's AgentCore relay (computeragent-enterprise #158). - PY1: AgentCore never forwards a caller's disconnect, so CAS names every envelope with x-ca-relay-stream: <uuid v4> and sends DELETE /_relay/streams/<id> when its caller goes away or before it re-attaches. The relay strips the header before dispatch, keeps a map id -> open call, and answers the DELETE itself: it closes that call (the relayed /events stream ends and its subscriber detaches) -> relayed 204; an unknown or non-UUID id -> relayed 404. Logs relay.stream.opened / relay.stream.closed. - PY2: AgentCore cuts any answer at 104,857,600 bytes. A JSON envelope over that is replaced by a relayed 502 AGENTCORE_RESPONSE_TOO_LARGE (source CAS_RUNTIME, retry false, meta.maxBytes) instead of a cut body. Event streams are not capped. - PY3: the per-microVM instance id is logged once, as relay.instance, when it is minted on the first invocation.
feat!: sandbox images for AgentCore and Lambda MicroVM; per-session agent, SSE keepalive fix, session_id-keyed store
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings the phase-1 stack to
main. #10 (cas-phase-1→main) merged before the stacked PRs, somainhas only v0.6.0. #11–#23 were merged into intermediate branches, andfeat/p1-sdk-2-remove-events-sinkholds all of them. Its tree is identical to the top of the stack (feat/p1-sdk-13-sandbox-images).Contents (already reviewed and merged as)
/guardrails/v1/check)llm/mcpsections of the agent document (needs old-CAS #164)COMPUTER_AGENT_*setting names, per-session agent, SSE keepalive fix, session store keyed bysession_idNotes
main: 93 files, +8477 / −3555.COMPUTER_AGENT_*names (feat!: sandbox images for AgentCore and Lambda MicroVM; per-session agent, SSE keepalive fix, session_id-keyed store #23), and the agent document is read from the #164 shape (feat(harness)!: read the model and MCP servers from the agent document's gateway sections #19).🤖 Generated with Claude Code