managed-agent-platform

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 16, 2026 License: Apache-2.0

README

managed-agent-platform

An open-source, self-hostable platform for long-horizon AI agents, written in Go.

Run the whole thing on-prem or in your own VPC — your data and your compute never leave your boundary.

Status: v0.1.0 — the v1 loop is complete. The wire-compatible control-plane API, the append-only session event log with SSE streaming, config-driven model providers (Anthropic-protocol and OpenAI-compatible), the brain orchestration loop, tool execution in per-session Docker or Kubernetes sandboxes, and permission policies with human-in-the-loop approval all work end to end. A BYOC worker runs a self-hosted session's tools on your own compute over the wire-compatible work API, with dead-worker recovery and one OTel trace across the process boundary. The real ant CLI — including ant beta:worker — drives all of it unchanged. Deploy locally with docker-compose or to Kubernetes with the Helm chart; see CHANGELOG.md for what has landed and the issue tracker for what's next.

Why

Most agent platforms are SaaS: your source code, your prompts, and your tool output all flow through someone else's infrastructure. For enterprises with data-residency, compliance, or air-gap requirements, that's a non-starter.

This project is that platform, self-hosted:

  • Bring your own model. Providers are config-driven (protocol · model · base_url · api_key). The Anthropic-protocol provider works against any endpoint speaking Anthropic Messages — a gateway, a proxy, or a self-hosted model — and an OpenAI-compatible provider covers OpenAI, vLLM, and most internal gateways. Nothing hard-codes a vendor endpoint.
  • Bring your own compute. Sandboxes run on Docker or Kubernetes under your control. Customer-run workers pull work from the platform, so no inbound network access is required into your environment.
  • Observability is built in. OpenTelemetry traces, metrics, and logs over standard OTLP — point it at your existing Jaeger/Tempo/Prometheus stack.

Relationship to Claude Managed Agents

We take Anthropic's Claude Managed Agents as our reference implementation: we adopt its domain model and keep our public REST API wire-compatible with it, so the real ant CLI and the Anthropic SDKs can drive this server unchanged.

This is a deliberate compatibility and design choice, not an attempt to reproduce that product. Where our goals — self-hosting, pluggable model backends, first-class OTel — call for something different, we diverge on purpose and document why.

Architecture

An agent is three independently-swappable pieces:

Piece What it is Property
Session An append-only event log (Postgres) The single source of truth. All durable state lives here.
Brain (harness) The loop that calls the model and routes tool calls Stateless, horizontally scalable. If it crashes, any fresh brain replays the log and continues.
Sandbox (hands) A disposable per-session container that runs tools Cattle, not pets. A dying container is one tool-call error, not a lost session.

Execution is fully asynchronous through the event log and a work queue. The brain never runs tools in-process: it emits agent.tool_use, an executor pulls that work, runs it inside a sandbox, and posts the result back; the brain wakes and continues. Platform-managed sandboxes and customer-run (BYOC) workers are the same pull protocol at two deployment points.

Two security invariants, adopted from the reference design:

  1. Credentials never reach the sandbox. Repos are cloned with a token the sandbox never sees; tool credentials are injected at egress.
  2. A session is not a context window. The harness may replay, slice, or rewind the event log before feeding the model, so context strategy is never baked into an irreversible compaction.

Roadmap

v1 delivered the core loop: create agent → create environment → create session → send a message → the model calls a tool → an executor runs it in a sandbox → results stream back over SSE → a human approves a gated tool → the session goes idle.

Progress is tracked in:

Deferred past v1 (seams reserved, not implemented — each tracked as an issue): secret vaults and egress credential injection, scheduled deployments, memory stores, multi-agent threads, skills, and multi-tenant RBAC/SSO.

Development

Requires Go 1.26+ and Docker (the storage and API contract tests start their own disposable Postgres containers, and the sandbox, shell, toolset, and executor tests start a disposable debian:stable-slim container). The Kubernetes sandbox provider's contract test additionally needs a cluster — a local kind cluster works, and CI provisions one. A missing daemon or cluster is a hard test failure, not a skip, so the coverage gate cannot be hollowed out.

make build                 # build (go build ./...)
make test                  # unit + contract tests (go test -count=1, with coverage profile)
make vet fmt-check         # lint
make verify                # the whole Go gate (CI additionally runs its helm/compose jobs)

Run the platform locally with the docker-compose stack — controlplane, brain, and executor against a bundled Postgres (and an optional Jaeger):

cd deploy/compose
cp .env.example .env          # set CONTROLPLANE_API_KEY
docker compose up --build     # control plane on http://localhost:8080 (loopback)

Then drive it with the real CLI: ANTHROPIC_API_KEY=<key> ant --base-url http://localhost:8080 beta:agents list (management commands take --base-url explicitly; they ignore ANTHROPIC_BASE_URL, which only the worker/auth subcommands honor). The stack idles until you point the brain at your model endpoint (copy model-providers.example.json and set MODEL_PROVIDERS_FILE). See deploy/compose/README.md for details; production deploys use the Helm chart.

Contributions are welcome. Please read CLAUDE.md first — it documents the architecture, the non-negotiable design principles, and the working conventions (notably: never guess at the wire schema; verify against the real ant CLI).

License

Apache-2.0

Directories

Path Synopsis
cmd
brain command
Command brain runs the model-turn orchestration pool: it claims model_turn work from the shared Postgres queue, replays session event logs into provider requests, and writes the turns back as Anthropic-native events.
Command brain runs the model-turn orchestration pool: it claims model_turn work from the shared Postgres queue, replays session event logs into provider requests, and writes the turns back as Anthropic-native events.
controlplane command
Command controlplane serves the wire-compatible Managed Agents REST API: resource CRUD backed by Postgres.
Command controlplane serves the wire-compatible Managed Agents REST API: resource CRUD backed by Postgres.
executor command
Command executor runs the platform-managed sandbox worker: it claims tool_exec work from the shared Postgres queue, runs the built-in toolset inside per-session Docker containers, and appends the agent.tool_result events the brain resumes on.
Command executor runs the platform-managed sandbox worker: it claims tool_exec work from the shared Postgres queue, runs the built-in toolset inside per-session Docker containers, and appends the agent.tool_result events the brain resumes on.
worker command
Command worker runs the BYOC (bring-your-own-compute) sandbox worker: it polls the control plane's self_hosted work queue over HTTP, runs the built-in toolset inside per-session Docker containers on the customer's own compute, and posts the user.tool_result events back over the session API.
Command worker runs the BYOC (bring-your-own-compute) sandbox worker: it polls the control plane's self_hosted work queue over HTTP, runs the built-in toolset inside per-session Docker containers on the customer's own compute, and posts the user.tool_result events back over the session API.
internal
api
Package api implements the wire-compatible control-plane REST surface: Anthropic Managed Agents resource CRUD (agents / environments / sessions) with the reference paths, JSON shapes, ID prefixes, pagination envelope, error envelope, and x-api-key management auth.
Package api implements the wire-compatible control-plane REST surface: Anthropic Managed Agents resource CRUD (agents / environments / sessions) with the reference paths, JSON shapes, ID prefixes, pagination envelope, error envelope, and x-api-key management auth.
brain
Package brain is the orchestration loop (the plan's component 3): a stateless harness that claims model_turn work, replays the session's event log into a provider request, streams the model's turn back into Anthropic-native events, and drives the session state machine at turn end.
Package brain is the orchestration loop (the plan's component 3): a stateless harness that claims model_turn work, replays the session's event log into a provider request, streams the model's turn back into Anthropic-native events, and drives the session state machine at turn end.
domain
Package domain holds the Anthropic-native core types that are the single source of truth for the platform.
Package domain holds the Anthropic-native core types that are the single source of truth for the platform.
events
Package events implements the append-only session event log — the single source of truth for session state — plus its live fan-out: per-session seq allocation, list queries, a Postgres LISTEN/NOTIFY broker for SSE subscribers, ephemeral event_start/event_delta preview frames, and the span.* events emitted from the same instrumentation point as OTel spans.
Package events implements the append-only session event log — the single source of truth for session state — plus its live fan-out: per-session seq allocation, list queries, a Postgres LISTEN/NOTIFY broker for SSE subscribers, ephemeral event_start/event_delta preview frames, and the span.* events emitted from the same instrumentation point as OTel spans.
executor
Package executor is the hands' consumer: it pulls tool_exec work from the queue, runs the built-in toolset inside the session's sandbox, and appends the agent.tool_result events the brain resumes on.
Package executor is the hands' consumer: it pulls tool_exec work from the queue, runs the built-in toolset inside the session's sandbox, and appends the agent.tool_result events the brain resumes on.
pgtest
Package pgtest is test support: it starts one Dockerized Postgres per test binary and hands out freshly-migrated databases, the same pattern the store/events/api suites carry privately.
Package pgtest is test support: it starts one Dockerized Postgres per test binary and hands out freshly-migrated databases, the same pattern the store/events/api suites carry privately.
provider
Package provider abstracts model backends behind Anthropic Messages semantics.
Package provider abstracts model backends behind Anthropic Messages semantics.
provider/anthropic
Package anthropic adapts any endpoint speaking the Anthropic Messages protocol to the provider interface, via the official SDK with a configurable base URL — an enterprise gateway, a proxy, or a self-hosted model are all just configuration.
Package anthropic adapts any endpoint speaking the Anthropic Messages protocol to the provider interface, via the official SDK with a configurable base URL — an enterprise gateway, a proxy, or a self-hosted model are all just configuration.
provider/openai
Package openai adapts an OpenAI Chat Completions endpoint (OpenAI itself, a vLLM server, or an internal OpenAI-compatible gateway) to the provider interface.
Package openai adapts an OpenAI Chat Completions endpoint (OpenAI itself, a vLLM server, or an internal OpenAI-compatible gateway) to the provider interface.
queue
Package queue is the internal work queue over Postgres (FOR UPDATE SKIP LOCKED, per the plan's component 4).
Package queue is the internal work queue over Postgres (FOR UPDATE SKIP LOCKED, per the plan's component 4).
sandbox
Package sandbox is the "hands" boundary: a disposable per-session container where the built-in toolset executes.
Package sandbox is the "hands" boundary: a disposable per-session container where the built-in toolset executes.
sandbox/backend
Package backend selects a sandbox provider by name, so the executor and the BYOC worker construct Docker or Kubernetes "hands" from the same config point instead of hard-coding one.
Package backend selects a sandbox provider by name, so the executor and the BYOC worker construct Docker or Kubernetes "hands" from the same config point instead of hard-coding one.
sandbox/docker
Package docker is the v1 sandbox backend: one disposable container per session, driven over the Docker Engine API.
Package docker is the v1 sandbox backend: one disposable container per session, driven over the Docker Engine API.
sandbox/k8s
Package k8s is the Kubernetes sandbox backend: one disposable Pod per session, driven over the Kubernetes API.
Package k8s is the Kubernetes sandbox backend: one disposable Pod per session, driven over the Kubernetes API.
sandbox/sandboxtest
Package sandboxtest is the contract suite every sandbox.Provider must pass (CLAUDE.md: backend variability lives behind an interface with one shared suite).
Package sandboxtest is the contract suite every sandbox.Provider must pass (CLAUDE.md: backend variability lives behind an interface with one shared suite).
sandbox/shell
Package shell runs the built-in bash tool as a persistent per-session shell, on top of the sandbox's stateless Exec + file primitives — no new backend surface.
Package shell runs the built-in bash tool as a persistent per-session shell, on top of the sandbox's stateless Exec + file primitives — no new backend surface.
store
Package store owns the Postgres schema.
Package store owns the Postgres schema.
telemetry
Package telemetry initializes OpenTelemetry tracing and metrics for one process and provides W3C trace-context propagation helpers.
Package telemetry initializes OpenTelemetry tracing and metrics for one process and provides W3C trace-context propagation helpers.
toolset
Package toolset is the built-in agent_toolset_20260401: the six tools the platform executes for the model — bash, read, write, edit, glob, grep — run inside the session's sandbox.
Package toolset is the built-in agent_toolset_20260401: the six tools the platform executes for the model — bash, read, write, edit, glob, grep — run inside the session's sandbox.
worker
Package worker is the BYOC (bring-your-own-compute) consumer of the work queue: the customer-hosted twin of internal/executor.
Package worker is the BYOC (bring-your-own-compute) consumer of the work queue: the customer-hosted twin of internal/executor.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL