feat: Integrate Antigravity harness with fallback in Controller V2#22
feat: Integrate Antigravity harness with fallback in Controller V2#22anj-s wants to merge 1 commit into
Conversation
fb6dd6c to
e5d6fee
Compare
…ntric design This PR implements the integration of the Antigravity agent as the first built-in harness in AX Controller V2, satisfying the first item on the AX roadmap. It also refactors the architecture to make `Registry` the Single Source of Truth (SSOT) and introduces robust fallback mechanisms. ### Goals 1. **Built-in Harness Integration**: Enable AX Controller V2 to execute Python-based Antigravity agents. 2. **Registry-Centric Architecture (SSOT)**: Centralize the management of both agents and harnesses in the `Registry`. 3. **Inverted Control (Dependency Injection)**: Decouple the `Controller` from harness creation by passing `Registry` as an input config. 4. **Resilient Fallbacks**: Implement build-time (script check) and runtime (registration check) fallbacks to a Test Harness to prevent failures in unconfigured environments. 5. **End-to-End Verification**: Provide a comprehensive E2E demonstration script. ### Key Changes - **Registry Updates (`internal/controller2/registry.go`)**: Added support for registering and retrieving Go `Harness` instances in `Registry`. - **Controller V2 Refactoring (`internal/controller2/controller.go`)**: - Received `Registry` as an input config in `New`. - Updated `Exec` to retrieve the harness from the registry using `AgentId` at runtime, falling back to the test harness if not found. - **Antigravity Go Harness (`internal/harness/antigravity.go`)**: - Implemented `AntigravityHarness` which executes the Python agent as a subprocess, passing the prompt as an argument. - Captured stdout and returned it as a streamed message. - Added a TODO to migrate to a gRPC server in the next step to avoid subprocess overhead. - **Python Agent Modification (`examples/antigravity_agent/agent.py`)**: Modified the script to accept dynamic prompt inputs from command line arguments. - **Verification (`internal/controller2/controller_test.go`, `fork_test.go`, `e2e.go`)**: - Updated unit tests to adapt to the new `Registry` injection. - Added unit tests for both build-time (implemented manually in test setup) and runtime fallbacks. - Created `e2e.go` in the root to demonstrate all 3 execution paths (Runtime Fallback, Build-time Fallback, and actual Antigravity Happy Path).
e5d6fee to
7b7d8bd
Compare
|
|
||
| // Run implements Execution.Run. | ||
| // It executes the Python agent as a subprocess, passing the last user message as an argument. | ||
| func (e *antigravityExecution) Run(ctx context.Context, handler Handler) error { |
There was a problem hiding this comment.
For discussion: I am wondering what is the desired call sequence for Execution.Queue(...) and Execution.Run(...)?
If each call of Queue(...) is followed by exactly one call of Run(...), shall we merge them into one?
If multiple calls of Run(...) are needed to consume pending messages in a queue, how the Execution should notify the caller if more calls to run is needed or not?
|
|
||
| h := harnesstest.New() | ||
| // Retrieve harness from registry | ||
| h, err := d.registry.GetHarness(req.AgentId) |
There was a problem hiding this comment.
Looks like we are retrieving an existing harness instance given an agent id. Are we mixing the two concepts here?
| return firstErr | ||
| } | ||
| // RegisterHarness registers a harness. | ||
| func (r *Registry) RegisterHarness(id string, h harness.Harness) { |
There was a problem hiding this comment.
As mentioned in the other thread, we can call it harnessId to be more explicit.
| mu sync.RWMutex | ||
| agents map[string]agent.Agent | ||
| agentInfo map[string]*agent.AgentInfo | ||
| harnesses map[string]harness.Harness |
There was a problem hiding this comment.
We are using the registry for both agents and harnesses. (ok to be not in this pr) - do we plan to let the registry in the controller package to only manage harnesses? I think the agents managed by a harness is a harness implementation detail.
| func (e *antigravityExecution) Run(ctx context.Context, handler Handler) error { | ||
| e.mu.Lock() | ||
| inputs := e.queued | ||
| e.queued = nil |
There was a problem hiding this comment.
The conversation history is lost here. For a poc implementation I think it's OK. But we should clarify if the controller is responsible to queue all history for the execution, or if the execution class itself is responsible to maintain the history.
This change implements the integration of the Antigravity agent as a harness in AX Controller V2 as a first step to validate the surface. We are using a subprocess with input/output message as a first step.
Key changes: