This file (AGENTS.md) provides context and instructions for AI agents working on this repository, outlining the project's purpose, structure, and our collaborative workflow.
The Antigravity SDK for Java is an unofficial, community-driven Java port of the Python-based Antigravity SDK. It bridges the gap for enterprise Java developers who want to build, configure, host, and execute powerful AI agents natively in Java. It aims for full feature parity with the official Python SDK, supporting streaming, tool calling, model context protocol (MCP), and multimodal inputs.
This is a multi-module Maven project using Java 21:
antigravity-sdk-parent: The root POM managing dependencies and plugin versions.antigravity-sdk-protocol: A generated artifact. It compiles the.protofiles from the upstream Antigravity repository into Java classes using theprotobuf-maven-plugin.antigravity-sdk-wrapper: The core SDK logic (~140KB).- The Go Harness: This SDK does not run an LLM directly. Instead, it wraps a pre-compiled native Go binary called
localharness. - Hybrid Platform Resolution:
PlatformResolverresolves the native binary in order:- Local override via
ANTIGRAVITY_HARNESS_PATHenvironment variable orantigravity.harness.pathsystem property. - Cached binary in
~/.antigravity/bin/<slice>/localharness(verified against.versionstamp). - Embedded classpath resource (if an offline classifier JAR from
antigravity-sdk-harnessis present). - On-demand lazy download via
HarnessDownloader(direct streaming from PyPI wheels, enabled by default, controllable viaantigravity.harness.download=true|false).
- Local override via
- Communication: The Java SDK communicates with the Go harness via standard input/output (for initialization) and WebSockets (for active turn streaming and chunk aggregation).
- Data Modeling: Pure data-carrying objects (e.g.,
AgentResponse,InteractionRequest,AgentResponseChunk) are implemented as modern Java 21recordclasses for ergonomics and immutability.
- The Go Harness: This SDK does not run an LLM directly. Instead, it wraps a pre-compiled native Go binary called
antigravity-sdk-harness: Dedicated artifact packaging native Go binaries (~37-43MB per platform classifier, ~236MB forall) for air-gapped or offline enterprise deployments:- Classifiers:
linux-x86_64,linux-aarch64,osx-aarch64,osx-x86_64,windows-x86_64,windows-aarch64, andall. - The 6 native binaries (~750MB uncompressed) exceed GitHub's 100MB limit and are gitignored. The script
./sync-harness.shsynchronizes binaries intoantigravity-sdk-harness/src/main/resources/google/antigravity/bin/.
- Classifiers:
This entire project was autonomously generated and implemented by me (the Antigravity agent) under the strict guidance of you (the human developer). Our pair-programming workflow operates as follows:
- Human Guidance: You provide high-level directions, architectural decisions, and code reviews. You guide the priority of features (like adding hooks, converting to records, or supporting MCP).
- Agent Execution: I proactively write the Java code, generate and update tests, build the project, and fix compilation errors.
- Proactive Refactoring: Whenever a class is purely carrying data, I should proactively suggest or use Java 21
recordstructures. - Testing First: Before declaring a feature complete, I will run the test suite and ensure all tests pass (accounting for expected transient
localharnessnetwork delays). - Documentation & Skill Synchronization: Whenever the Antigravity Java SDK evolves (new features, API changes, hooks, policies, capabilities, etc.), agents MUST proactively update
README.mdand the official Agent Skill underskills/antigravity-sdk-java/(SKILL.mdandskills/antigravity-sdk-java/references/) to keep developer documentation and AI agent skill guidance synchronized with the codebase.
- Java Version: Java 21. Agents must ensure they use Java 21 compatible syntax and standard library features.
- Maven Wrapper: Always use the provided Maven wrapper (
./mvnw). Do not rely on globally installedmvnorgradle. - Compilation:
./mvnw clean compile - Fast Unit Testing:
./mvnw test(Runs fast offline unit tests;@Tag("integration")is excluded by default) - Live Integration Testing:
./mvnw test -Pintegration-testsor./mvnw test -Dgroups=integration - Code Formatting:
./mvnw spotless:apply
- No FQNs: Never use Fully Qualified Names (FQNs) directly in the code (e.g.,
java.util.List<String> list = ...). Always import the classes at the top of the file. - Code Formatting: The project uses the Maven Spotless plugin with the Eclipse formatter. Always run
./mvnw spotless:applyand ensure the code passes before committing. - License Headers: Spotless will automatically inject the Apache 2.0 license header. Do not manually add copyright headers.
- Framework: We use JUnit 6 (JUnit Jupiter).
- Test Categorization (
@Tag):- Unit Tests (
@Tag("unit")): Fast, offline tests evaluating configuration, policies, data structures, and SDK wrappers without invokinglocalharnessor external APIs. These run by default during./mvnw test. - Integration Tests (
@Tag("integration")): Live network tests that launch the nativelocalharnessGo binary and communicate with remote model APIs. Excluded by default in./mvnw test; run explicitly via./mvnw test -Pintegration-testsor-Dgroups=integration.
- Unit Tests (
- Bounded Futures & Timeouts:
- Never use unbounded
.join(): Always use bounded calls likeagent.chat(...).get(45, TimeUnit.SECONDS)ororTimeout(...)to prevent hanging test runs if localharness or the network stalls. - Per-Test Timeout: Annotate integration test classes or methods with JUnit 5
@Timeout(e.g.,@Timeout(value = 60, unit = TimeUnit.SECONDS)).
- Never use unbounded
- Asynchronous Assertions: Because agent interactions happen asynchronously over WebSockets and
CompletableFutures, never useThread.sleep()for waiting on agent responses in tests. Always useAwaitilitywith a tight timeout (e.g.,await().atMost(30, TimeUnit.SECONDS)). - Resilient Assertions: Avoid rigid string matching on non-deterministic LLM tool responses (e.g. strict lowercased JSON string prefixes). Check for key semantic contents instead to prevent unnecessary retries.
Keeping this SDK at feature parity with the upstream Antigravity project requires a rigorous six-step sync process whenever new features are released:
-
Update the Go Harness Binaries:
- Execute
./sync-harness.sh. This script scrapes the Python Package Index (PyPI), downloads the latest upstream wheels, extracts the native Go binaries for all supported platforms, and places them insrc/main/resources/google/antigravity/bin/. - Keep the extracted Python package directory (or unpack to
/tmp/antigravity_upstream/) to enable direct Python source diffing.
- Execute
-
Accurate Protocol Extraction (Never Guess Field Names):
- The upstream wheel contains compiled Python descriptors (
localharness_pb2.pyandcontent_pb2.py), which embed the serializedFileDescriptorProto. - Rule: Never manually guess or hand-edit proto field names (e.g. naming a field
complex_user_inputinstead ofuser_input). Go'slocalharnessbinary uses strict Protobuf unmarshalling and will immediately reject unknown JSON fields withfailed to unmarshal: unknown field. - Extraction Command: Decompile the serialized descriptor directly from Python:
import google.protobuf.descriptor_pb2 as d_pb2 from google.antigravity.proto import localharness_pb2 proto = d_pb2.FileDescriptorProto() localharness_pb2.DESCRIPTOR.CopyToProto(proto) print(proto)
- Update
antigravity-sdk-protocol/src/main/proto/localharness.prototo strictly match the extracted descriptor.
- The upstream wheel contains compiled Python descriptors (
-
Systematic Python SDK Source & Test Audit (Never Skip):
- Wire descriptors only cover the Go harness contract; high-level developer ergonomics, tool sets, builder options, and policies live in the Python codebase.
- Run a diff between the previous and new upstream Python source (
google/antigravity/):types.py: Check for new/deprecated enum values, updated tool categorization methods (BuiltinTools.deprecated(),minimal(),readOnly(),defaultTools()), and new data structures.connections/&connection_config.py: Check all builder options acrossLocalOpenAIAgentConfig,LiteRTAgentConfig, and local agent strategies for forwarded properties (budgets, continuation modes, policies).hooks/policy.py: Check policy function signatures, callbacks (e.g., justification arguments), and decision evaluations.*_test.py: Inspect newly added test cases intypes_test.py,local_connection_test.py,policy_test.py, etc. Upstream tests are the authoritative specification for all new behaviors.
-
Regenerate, Refactor & Create Parity Tests:
- Recompile protocol and wrapper (
./mvnw clean compile). - Update wrapper classes and builders to support new options, enums, records, and configs.
- Create a dedicated unit test suite for the release (e.g.
FeatureParity<version>Test.java) systematically verifying all audited diff items before running live tests.
- Recompile protocol and wrapper (
-
Verify Wire Compatibility & Local Smoke Testing:
- Run fast unit tests:
./mvnw test - Run at least one live integration test against the newly extracted
localharnessbinary (e.g.,./mvnw test -Pintegration-tests -Dtest=InteractiveAskQuestionTest) or run full integration tests (./mvnw test -Pintegration-tests) to verify that the native Go binary successfully unmarshals allInputEventandHarnessConfigJSON messages over WebSockets.
- Run fast unit tests:
-
Update Skill & Documentation:
- Update
README.mdand the official Agent Skill (skills/antigravity-sdk-java/SKILL.mdandskills/antigravity-sdk-java/references/) with new features, configuration options, and code samples.
- Update