AX is undergoing a significant redesign, moving away from a single CLI with
an embedded Python harness toward a general-purpose orchestration layer for
agentic tasks. The repository is reorganized around three binaries: ax-server
exposes a gRPC API for submitting Task manifests, ax-controller runs as a
horizontally scaled reconciler that consumes work from Redis Streams, and
ax-task-runner executes tasks inside sandboxed workers. Task state now lives
in Redis rather than Kubernetes CRDs so the system can handle millions of
short-lived tasks without straining etcd. The legacy Python harness, ATE
client, SQL event log, and skill examples are removed, and new design,
concepts, manifest, networking, runner, and sandbox docs plus Kubernetes
deploy manifests describe the new architecture.
The docker_agent example largely duplicates remote_agent (both
implement AX's native AgentService directly via gRPC). Removing it
in favor of the simpler remote_agent example.
Fixes#132
We don't allow sub agents to use the controller to make agent handoffs anymore.
Split AgentMessage into AgentRequest and AgentResponse proto definitions.
## Summary
- Move text streaming logic in `DockerAgent` `Connect` method outside of
the `keepLooping` check.
- This ensures that intermediate text outputs (reasoning, thoughts, or
status updates) emitted by the model during tool calls (like
`activate_skill`) are correctly streamed back to the client instead of
being ignored.
So we don't accidentally promote this option. There are also rough edges
in this implementation that we don't have time to fix, e.g. the use of
kubectl.
## Summary
Add a self-contained Python sample agent
(`examples/a2a_agent/coding_agent.py`) that serves as the end-to-end
reference for AX's A2A bridge. Built on Google ADK's LlmAgent (Gemini),
exposes the agent over A2A on three transports (gRPC, JSON-RPC,
HTTP+JSON REST), and exercises HITL, streaming/polling, multi-scheme
auth, and FilePart artifacts.
## Features exercised
- HITL save-confirmation via `TASK_STATE_INPUT_REQUIRED`, mapped to
ADK's `LongRunningFunctionTool` semantics — the agent proposes a path
and waits for the user's "yes" before writing.
- Returns the saved Python source as a `text/x-python` FilePart
attachment alongside the agent's text reply; on decline, emits the
proposed code as a fenced markdown block instead.
- Optional dual-scheme auth (`--auth`): AgentCard advertises Bearer and
API key as alternatives (OR semantics); symmetric enforcement via HTTP
middleware + gRPC interceptor.
- Streaming and polling-fallback paths (`--no-streaming` disables
streaming in the AgentCard so clients exercise the polling fallback).
- Inline script metadata (`# /// script`) — runnable via `uv run`
without a separate venv.
## Run
```bash
# Gemini API key: export GOOGLE_API_KEY=...
# or Vertex AI: export GOOGLE_GENAI_USE_VERTEXAI=TRUE
# export GOOGLE_CLOUD_PROJECT=<project>
# export GOOGLE_CLOUD_LOCATION=<region>
uv run examples/a2a_agent/coding_agent.py
uv run examples/a2a_agent/coding_agent.py --no-streaming # polling fallback
uv run examples/a2a_agent/coding_agent.py --auth # enable dual-scheme auth (set CODING_AGENT_AUTH_TOKEN)
This PR introduces a standalone `DockerAgent` example and fixes an
infinite loop bug in the planner. It also addresses several code review
comments for robustness and cleanups.
- ConversationId is added in the reply agent message of the remote agent
example. Without conversation id the message gets rejected. (The ate
agent and k8s sandbox agent have it added in the previous PR).
This PR adds a new conversation_id field in AgentMessage.
Also add the conversationID to the signature of Agent.Connect and
Executor.Exec so that we can:
1. propagate conversationID from controller to sub-agent, like remote
agent, a2a agent
2. propagate conversationID to substrate worker
The conversationID is unused by anything yet. It will be picked up by
a2a agents in follow up PRs, and possibly substrate agent as well.
AX won't be doing any healthchecks itself. agent.HealthCheck is obsolete
now. We keep the AgentService.HealthCheck RPC to ensure agent
implementators provide a health check mechanism on wire for job
schedulers.
This PR adds Colab agents into AX. The main use case covered:
1. From a local python script, run it with Colab VM, optionally download
output images, and convert it to a notebook and save in Google Drive.
2. From a remote notebook in Google Drive, run it with Colab VM, get the
output in AX and optionally download output images.
Note: This is only available in gLinux for internal Google version of
Colab CLI. Expect the OSS version coming soon. Instructions at
docs/colab-agent.md.
The changes introduce a conversation log to delegate the history storage
and retrieval to AX. Instead of treating every task/execution as a new
isolated event, AX now supports conversational history.
Conversational history is implemented as a layer above the execution
log. Executions are still logged separately and with much more rich
context that enables resumption within the lifetime of an execution.
With this change, controller natively can identify an execution that is
waiting for resumption from the conversation log. Clients don't need to
know about the underlying execution identifier.
The change also removed the WIP forking capability until we stabilize
the event log schema and the concepts. We will implement it as a follow
up change.
`ExecRequest` is updated to support conversation identifier and
`last_seen_seq`. Sequence numbers will be used to be able to resume
playing from a moment client has since the last. If client connection
disappears, we will still be able to communicate the outputs during a
reconnect.
Some follow-up changes after this change is merged:
- Support for `last_seen_seq`, `seq` number in the ExecResponse.
- Implementation of forking.
- Potential schema changes to conversation_log and execution_log.
- More README updates.
- Rewrite of the trace viewer tool with the new schema once the logs are
more stable.
- Controller will introduce its own OutputHandler to emit additional
fields, e.g. `seq`.
- Remove redundancy between conversation_log and execution_log.
Interactions Content doesn't include a "role" and we introduced this
field in our own copy. Remove "role" from Content in preparation to
switch to the actual Contual message.
This change introduces AgentService.Connect RPC and replaces Process.
- Connect allows bidirectionally executing agents.
- Connect needs to be started with AgentStart and need to be followed
with AgentOutputs.
- Thought the repo, task is renamed to execution.
- SQLite schema is updated accordingly.
- agent.Task is removed because AgentStart represents the required
fields to start a new agent call.
- Instructions on README should just work.
- Remote agent connections should be established at every Process. The
connection is only active during the lifetime of an execution and need
to be closed once Process completes.
- Fix the history curation in the planner agent
- Ensure we only uppercase the last message and ignore the history.
**Description**
This PR transitions the lifecycle management of GKE Agent Sandbox
WarmPools from programmatic configuration in Go to declarative
Kubernetes manifests.
By removing the hardcoded WarmPool configurations and CreateWarmPool
logic from the
sandboxclient
, we decouple the application logic from the infrastructure state. Users
can now natively manage their entire sandbox and pool environments using
standard kubectl apply workflows (via
sandbox-template-and-pool.yaml
).
**Key Changes**
- Removed Programmatic Pool Creation: Removed CreateWarmPool and
DeleteWarmPool from
internal/sandboxclient/client.go
.
- Removed Config Structs: Removed pool size and template specs from
internal/config/config.go and agent/sandbox.go
- Declarative Manifests: Consolidated the template and pool
configurations into a single, deployable
examples/sandbox_agent/sandbox-template-and-pool.yaml file.
- Documentation: Updated README.md to reflect the new kubectl apply
workflow for infrastructure setup.