Commit Graph
82 Commits
Author SHA1 Message Date
Jaana Dogan 233820befc make tasks immutable and revisit lifecycle management
Make Task manifests fully immutable once created, removing `UpdateTask`
in favor of `CreateTask` and driving lifecycle transitions (suspend,
resume, delete) through dedicated RPCs and event stream processing.

- Proto: Replace `UpdateTask` with `CreateTask` in AX service.
- Proto: Remove mutable `suspend` field from `TaskSpec` and reserve field 2.
- API / Server: Implement `CreateTask` with duplicate name rejection
  (`codes.AlreadyExists`). Update `SuspendTask`, `ResumeTask`, and `DeleteTask`
  to transition status phase and publish lifecycle events.
- Store: Remove redundant `SetTaskSuspended` and `MarkTaskDeleting` methods;
  standardize on `CreateTask`, `UpdateTaskStatus`, `DeleteTask`, and
  `PublishEvent`.
- Controller: Decouple spec reconciliation from task suspension; introduce
  `ReconcileSuspend` to handle checkpointing and pausing actors on Substrate.
- CLI: Update `ax apply` to submit tasks via `CreateTask`.
- Docs: Update design docs and specifications to reflect task immutability.
2026-09-24 04:03:32 -07:00
JBD dc4f36cdba Restructure AX into a general-purpose orchestration layer for agentic tasks
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.
2026-09-19 20:14:43 -07:00
Jaana Dogan 2282424ebc Make the public facing ExecutionService more InteractionsService-like (#339)
We want AX to be compatible with the Interactions API protocol as much as possible. This PR aligns the proto with Steps and with the Interactions semantics. We will follow up with more changes to make it more compatible with Interactions while preserving a `conversation_id` based history model.

`ConversationService` is removed for now until we know what kind of data operations we want to provide for event log management.
2026-08-11 22:52:05 -07:00
Jaana Dogan 72b51a4893 Rename ControllerService to ExecutionService (#242) 2026-07-06 10:30:46 -07:00
Jaana Dogan ee1d8cfd8f Initial commit of the OpenTelemetry trace exposition (#226)
Refactor telemetry configuration and resolve deprecated GCP metadata calls:
- Replace deprecated `metadata.ProjectID()` and `metadata.OnGCE()` with context-aware versions.
- Update `telemetry.SetTraceProvider` to accept variadic `otlptracegrpc.Option`s and remove the hardcoded endpoint parameter.
- Add `telemetry.WithGCPCredentials()` helper to encapsulate GCP-specific credentials.
- Isolate GCP-specific server telemetry configuration into a new `serve_gcp.go` file.

Fix premature gRPC stream cancellation in the harness execution clients:
- Update the client receive loop to drain the stream until `io.EOF` after receiving the `HarnessEnd` frame, preventing `CANCELLED` errors in telemetry.
- Encapsulate the stream draining and message dispatching logic into a shared `drainStream` helper in a new `stream.go` file.
- Clean up unused `io` imports in `antigravity.go` and `substrate.go`.

Follow-up:
- End-to-end trace context propagation to HarnessService deployments
- End-to-end trace context propagation to Substrate calls
2026-06-30 22:47:56 -07:00
Jaana Dogan 4aad1a6605 Consolidate controller and config packages by removing v2 suffixes (#179)
Also remove ununsed ExecutionEvent from proto.
2026-06-25 15:32:21 -07:00
Jaana Dogan 9737fd7033 Migrate controller and registry to internal/controller2 (#176)
* Cleanup the repo and move to controller2

* Migrate controller and registry to internal/controller2

- Remove the legacy harness build tag

* refactor: move GeminiConfig definition from internal/config to internal/gemini package

* test: replace controller registry with dummy implementation and update dependency constraints in go.mod

* chore: remove harness build and test steps from GitHub Actions workflow
2026-06-25 15:21:28 -07:00
Jaana Dogan 5425c993f4 Remove forking capabilities until controller2 is stable (#130)
* Remove forking capabilities until controller2 is stable

* chore: add Apache 2.0 license headers to generated python protobuf files
2026-06-17 14:16:21 -07:00
Jaana Dogan c281998ce7 refactor: remove ate build tag and consolidate server implementation (#119) 2026-06-16 07:37:57 -07:00
anj-s a033a403b9 impl: gRPC server logging interceptors (#68) 2026-06-10 14:25:36 -07:00
anj-s ceaa29cf5e slog: Initialize structured JSON logging for serve and axepp (#61) 2026-06-08 13:52:48 -07:00
Jaana Dogan 3f66a615ea Make controller2 wiring work (#35)
- Register antigravity harness
- Don't reset the agent_id, we want to stick to the same agent
- Make sure registry isn't nil at controller2.New

This is a follow up for #33.
2026-05-29 20:23:30 -07:00
Junjie Wang b8d190f32c Wire up controller2 and harness by a build tag. (#33) 2026-05-27 16:26:44 -07:00
Jaana Dogan cdb0b348ea go fmt ./... (#11) 2026-05-20 22:35:36 -07:00
Jaana Dogan af899c8036 Demo and many other fixes (#331)
- Make changes to the testagents for a realistic sub agent demo
- Sanitize agent names, replace - with _ to avoid malformation errors
- Increase the idle networking timeout across different configs, set a
high GKE ingress timeout to enable long running operations
- Register AX_TEST_AGENTS with description and name
- Make changes to the symptom prompt and disable bash tool improve the
selection quality for the demo
- Move inflight tracking to server to avoid double suspension 
- Make the resumption command to honor --server if set

Follow up:
- Remove AX_TEST_AGENTS once we don't need them.
- Work on Gemini planner to support better selection among the agents
and the bash tool.
2026-05-11 14:28:36 -07:00
Jaana Dogan 0193abf5d4 Add some logging for server RPCs (#310) 2026-05-07 01:19:32 -07:00
Jaana Dogan 3243d7ceaf Rename EventLogService to ConversationService (#307)
We will make conversation actors to be forkable from snapshots in the
upcoming weeks. Renaming this service so it represents more than just
event log operations.
2026-05-06 22:52:49 -07:00
JoyceLiu 63216ea21d server: drop dead HealthCheck method on dummyAgent test fixture (#303)
The dummyAgent test fixture defined a HealthCheck method that was never
part of the agent.Agent interface and had no callers. Remove it so the
fixture matches the actual interface (Connect, Close) and nothing else.
2026-05-06 21:46:50 -07:00
JoyceLiu 6d60b40ac5 fork: validate src_seq exists, and update README for fork requirement on dest_conversation_id (#292)
Two related fork fixes uncovered while testing `ax fork --src-seq`:

1. controller.Fork: validate src_seq exists in source. Previously,
passing a non-existent src_seq (e.g. a typo or stale checkpoint)
silently degraded to "fork all events", which is misleading. Mirror the
validation tryResuming already does for --last-seq and return "src_seq N
not found in conversation X".

2. server.ForkConversation: update the README to require destiation
conversation id. this is required for Substrate integration
 
 
Tests:
- controller: TestController_Fork_SrcSeqNotFound covers the new
validation and asserts no events are appended on failure.
2026-05-06 09:03:04 -07:00
Jaana Dogan 19067c1e79 Fix the broken ate build (#282) 2026-05-05 17:40:47 -07:00
Jaana Dogan 1cf68d66db Introduce a gRPC interceptor to suspend the server actor (#279)
We will revisit this. If in the 50 ms window, another request comes, the
client will disconnect when we suspend.
2026-05-04 21:01:06 -07:00
Junjie Wang 4b9de6aa68 Feat: support A2A agent in AX. (#274)
Adds an A2A (Agent-to-Agent) protocol bridge so AX can communicate with
A2A-compliant external agents.

## Changes
```text
internal/auth/                             # NEW shared auth package
├── auth.go
└── auth_test.go
internal/experimental/a2abridge/           # A2A bridge (renamed from a2autil)
├── auth.go
├── auth_test.go
├── mappings.go
├── mappings_test.go
├── a2a_internal_state.go
├── a2a_internal_state_test.go
├── a2a_converter.go
├── a2a_converter_test.go
├── a2a_event_handler.go
└── a2a_event_handler_test.go
internal/experimental/agent/a2a.go         bridge orchestrator (A2AAgent type)
internal/config/config.go                  unified RemoteAgentConfig + A2AConfig
internal/controller/registry.go            RegisterRemote dispatcher (axp | a2a)
internal/cliutil/cliutil.go                registration loop
cmd/ax/exec.go                             binary-content no-op
cmd/ax/trace.go                            new role CSS
ax.yaml                                    a2a coding-agent example
go.mod, go.sum                             +github.com/a2aproject/a2a-go/v2 v2.2.0
proto/ax.proto + generated .pb.go          new Content types
```

(TODO) Implement credential refresh on `TaskStateAuthRequired`
(currently only static `api_key`/`bearer` is implemented).
2026-05-04 14:49:34 -07:00
Jaana Dogan 55d5b1b1ea Deploy AX to Substrate (#228)
This change introduces an EPP to create/resume actor the incoming
conversation_id. We also introduce an ax-shell image and a demo pod for
testing purposes.

Follow up changes:
- Suspend the AX server automatically after the request is sent.
- Explore failure cases and how we can ensure suspension safely even if
AX server crashes.
- EventLogService.Fork shouldn't autogenerate a dest_conversation_id.
dest_conversation_id should always be supplied from the client for
routing.

This change also removes the RegisterAgent RPC. Actor
resumption/suspension requires a valid conversation_id for all RPCs and
RegisterAgent no longer fits into this new constraint.
2026-05-04 08:23:48 -07:00
Jaana Dogan 849aaf0853 refactor: rename EventLogService methods and update gRPC stubs (#266) 2026-04-30 08:50:22 -07:00
Junjie Wang a6d8a2803f Add conversation_id in AgentMessage and Agent interface. (#244)
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.
2026-04-23 11:54:21 -07:00
anj-sandanj-s d736972e54 feat(ax): Implement Conversation Forking and Fix Trace Viewer Ordering (#229)
1. Conversation Forking

Protocol: Added Fork RPC to EventLogService with support for specifying
source conversation, sequence number (checkpoint), and optional
destination ID.
Controller: Implemented the Fork method to clone events while preserving
shared execution references.
CLI: Added root-level ax fork command. It supports both remote mode (via
--server) and "headless" local mode (reading ax.yaml or custom config
via --config).

2. Trace Viewer Fixes
Display Correct ID: Fixed the trace viewer to display the actual
Conversation ID in the terminal output and UI header instead of the
random root execution ID.
Chronological Ordering: Fixed a bug where execution cards were sorted
alphabetically by their random UUID ExecID. They are now sorted
chronologically based on the order they occurred in the conversation.

3. Testing
Added unit tests for the forking logic in the controller.
Added integration tests for the server-side RPC.

Co-authored-by: anj-s <anjalisridhar@google.com>
2026-04-20 12:48:53 -07:00
Jaana Dogan ee9c62acdf Rename the proto package (#206)
Remove redundant AX* prefix from service names.
2026-04-15 11:22:03 -07:00
Jaana Dogan 7aaff128df Remove the obsolete health check response at registration (#204) 2026-04-14 12:17:37 -07:00
Jaana Dogan edcd9d8edd Add AXEventLogService (#194)
This change introduces AXEventLogService to allow AX clients to be able
to operate event log operations. As a part of this change, we are also
allowing clients to be able delete a conversation (including all of its
sub executions).

Follow up:
- We should introduce an `ax eventlog` to make it possible to trigger
some of these operations directly from the CLI.
- Move `ax fork` to `ax eventlog fork`.
2026-04-13 21:17:59 -07:00
Jaana Dogan 2d02cf8a70 Remove health monitoring (#186)
We need to return an error if an agent becomes available even though
being registered as an agent. Health check based selection causes
quality regression that are hard to debug and isn't the expected
behavior.
2026-04-07 08:50:05 -07:00
Jaana Dogan f6b0df6317 Resume from last_seen_seq (#184)
Depends on https://github.com/google-gemini/ax/pull/183.

Change also removes the expectations that Content types should include
some whitespace. For token by token streaming, we will use ContentBlock
and ax exec can behave differently.
2026-04-06 22:30:32 -07:00
Jaana Dogan e8eb96f374 Introduce the conversation log (#182)
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.
2026-04-06 11:35:33 -07:00
JoyceLiu e03846fba7 Enforce remote agent health check on registration (#152)
This PR enforces a mandatory 5-second health check timeout when
registering new remote agents in the controller registry. It also
updates the `TestRegistry_GracefulShutdown` testing suite to properly
attach workload agents to a mock server.

### Implementation Detail
If an agent fails the health check (e.g. offline during initialization),
the registration is *not* rejected. Instead, the server registers the
agent with its `Healthy` flag set to `false`, logs a clear connection
`Warning`, and informs the CLI that it will be retried in the
background. This ensures that the AX Server can still successfully start
up and load its initial `ax.yaml` configuration even if some remote
agents are strictly offline at boot time.

### Validation
Verified the implementation successfully against the AX Server via `ax
register` CUJs. Here are the logs for the E2E verification:

**CLI Registration Output:**
```text
======================================
TEST 1: Registration (Remote agent offline)
=> Attempting to register an offline agent on port 50053...
Agent registered successfully, but represents an unreachable address at localhost:50053.
It will be retried in the background.

======================================
TEST 2: Registration (Remote agent online)
=> Attempting to register an online agent on port 50051...
Agent test-remote-online registered successfully.
```

**AX Server Logs Tracking Status:**
```text
2026/03/27 23:35:22 Starting AX server at :8494...
2026/03/27 23:35:24 Warning: remote agent test-remote-offline is unreachable or unhealthy during registration: health check failed: rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp 127.0.0.1:50053: connect: connection refused"
```
2026-03-27 17:07:52 -07:00
Jaana Dogan 38d14a1afa Introduce Message to remove "role" from Content (#145)
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.
2026-03-25 18:23:29 -07:00
Jaana Dogan 173eeac5f0 Move the agent package into internal (#136)
agent package is only used by the controller, move it under the internal
package.
2026-03-23 21:52:55 -07:00
Jaana Dogan 878a3c384f Allow starting executions bidirectionally (#127)
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.
2026-03-23 11:51:41 -07:00
Jaana Dogan 4cc7ea7cdc Allow incoming Exec requests to provide an agent config (#97) 2026-03-16 16:28:51 -07:00
Jaana Dogan 3828779172 Rename the project name from GAR to AX (#95) 2026-03-16 14:06:13 -07:00
Jaana Dogan bf69b06e11 Remove UnregisterAgent (#93)
Unregistering has complicated side effects and we don't want to support
this for now.
2026-03-16 13:29:07 -07:00
Jaana Dogan ea3d9c51c6 Remove the notion of session ID (#94) 2026-03-16 13:26:38 -07:00
Jaana Dogan aca4e9e2a8 Rename trigger to exec (#92)
Rename trigger to exec across the code base.
2026-03-16 12:38:21 -07:00
Jaana Dogan 7554465a1c Introduction of task executor (#91)
We are replacing the current loop executor with a new internal execution
framework. This update refactors the majority of the project's core
logic to improve stability and performance.

We introduce a new Task Executor, moving away from simple
request-response agent loops toward a more structured, stateful
execution model. The core of this update is the addition of a Task
struct and a TaskExecutor interface, which allow agents to trigger
sub-tasks and manage complex workflows. This change enables better
recursion and delegation between different agents, such as the testing
coding agent and specialized worker agents. The new executor framework
supports confirmation propagation and leaves the confirmation handling
to the agent implementation.

The update introduces a new persistent Event Log system to track every
step of a task's execution. By recording inputs, outputs, and state
changes to a newline-delimited JSON file, the system can now "rehydrate"
sessions at any point. This allows the executor to resume from a
consistent state after a crash or restart, and provides a durable
history of agent actions.

The change refactors the Controller and various agent implementations to
support these new interfaces. It includes updates to the CLI trigger
tool to handle interactive confirmation prompts more effectively and
manage conversation history across task boundaries. Comprehensive tests
for the new Task Manager, including fan-out execution and resume
capabilities, are also included to ensure reliability in concurrent
environments.

The change also introduces a "gemini" agent to make it easier to make
Gemini calls without having to write any new code. We default to the
Flash models but can follow up with some configuration options to
override the default settings.

Trigger now also allows starting execution from any available agent, `$
trigger --agent <agent_id>`.

The new capabilities can be explorable and testable with the
internal/testagent.

Follow up changes after this change is merged:
- Fixing Gemini planner and skills support
- gar trigger will be rename to gar exec
- We will remove the session IDs and replace them with IDs/task IDs
- Exec over the wire, changes to AgentService
- Task log in SQLite
- Trace view tool to be able to inspect the logs
2026-03-16 12:12:38 -07:00
Jaana Dogan b9816d9fbf Close the controller at graceful stop (#62) 2026-02-23 23:42:04 -08:00
Jaana Dogan 8ce13d34e1 Allow different types of agents to be registerable via GARService (#59)
New types (e.g. container type) will require different fields. Introduce
a oneof config.
2026-02-23 12:15:39 -08:00
JoyceLiu da40ee3c95 feat: implement graceful shutdown for server (#42)
minor change to allow graceful shutdown for server

tested: 

lhuan-mac:forkSession-cleanup lhuan$ ./gar serve
--dangerously-skip-approvals
2026/02/17 10:30:03 Starting GAR server at :8494...

^C2026/02/17 10:30:05
2026-02-17 14:52:51 -08:00
Jaana Dogan 4619c37205 Consistent naming for source and destination in forks (#37)
* Shortern the source identifiers consistently
* Use the same style in proto and the flags
2026-02-13 22:53:33 -08:00
JoyceLiu 439ff22183 clean up TriggerSession - no longer allow auto fork (#36)
1. server.triggerSession - remove checkPointId, destinationSourceId from
this RPC.
3. cmd / trigger.go - correspondingly remove checkpointId,
destinationSourceId from gar trigger
4. user CUJ: user should explicitly "gar fork" then "gar trigger"
2026-02-13 18:47:01 -08:00
Jaana Dogan cb3c7a2a88 Remove GetSession again (#35)
This change has been accidentally reverted by at #25, and was originally
merged via #33.
2026-02-13 16:51:22 -08:00
JoyceLiu 9f9622480f support forSession
support forkSession from a specific checkpoint 
tested with unitTest + manual test 

```
lhuan-mac:forkSession lhuan$ ./gar trigger --input "test_fork"  --session session678 --checkpoint 11c9717c-f273-4770-8755-5785bfae2b30
[STATE_RUNNING] TEST
[STATE_RUNNING] TEST
[STATE_RUNNING] TEST_FORK
```
2026-02-13 14:56:00 -08:00
Jaana Dogan e0798818f2 Remove GetSession RPC (#33)
GetSession will be redesigned to allow event log entry listing and to
provide more capabilities. Removing this RPC for now.
2026-02-13 13:58:59 -08:00