antigravity-sdk-e2e-dev
This Claude Code skill provides an end-to-end development and testing environment for the Antigravity SDK harness, which integrates Google's Antigravity Python SDK into Omnigent and bridges system tools as custom tools for Gemini-native agents. Use this skill when developing, testing, or debugging the antigravity executor, harness authentication, model behavior, or tool bridging against a live local Omnigent server rather than relying solely on unit tests.
git clone --depth 1 https://github.com/omnigent-ai/omnigent /tmp/antigravity-sdk-e2e-dev && cp -r /tmp/antigravity-sdk-e2e-dev/.claude/skills/antigravity-sdk-e2e-dev ~/.claude/skills/antigravity-sdk-e2e-devSKILL.md
# Antigravity SDK harness: end-to-end dev & testing
The `antigravity` harness drives Google's **Antigravity Python SDK**
(`google-antigravity`, an in-process `Agent`/`Conversation`) and bridges
Omnigent's `sys_*` tools into the SDK as `custom_tools`. It is **Gemini-native**:
it authenticates with a Gemini / Antigravity API key (or Vertex AI) and has **no
OpenAI-compatible gateway / Databricks path**. This skill is the proven recipe
for running it **for real** against a live local server — not just the unit
tests.
> The harness runs as a **local runner** from your current checkout, so
> `omni run <bundle> --server <url>` exercises exactly the code you're on.
## Prerequisites (check these first)
1. **You're on the branch you want to test.** The antigravity harness merged to
`main` (#194). Test on `main` unless validating a specific branch.
2. **A Gemini API key is configured.** The SDK *requires* one (`AIza…`); there
is no login flow. Verify (booleans only — never print the key):
```bash
.venv/bin/python -c "from omnigent.onboarding.antigravity_auth import antigravity_api_key_configured as c; import os; print('config:', c(), 'env:', bool(os.environ.get('GEMINI_API_KEY') or os.environ.get('ANTIGRAVITY_API_KEY')))"
```
If both are `False`, run `omni setup` → **Antigravity** and paste a key, or
`export GEMINI_API_KEY=AIza…`.
3. **`google-antigravity` is installed** (the `antigravity` extra —
`pip install "omnigent[antigravity]"`):
`.venv/bin/python -c "import google.antigravity as a; print(a.__file__)"`.
4. **glibc ≥ ~2.36.** The SDK spawns a **native `localharness` binary** that
needs a recent glibc (`GLIBC_ABI_DT_RELR`). Check `ldd --version | head -1`.
On an older host the turn fails at setup with
`RuntimeError: … localharness: … version 'GLIBC_ABI_DT_RELR' not found`. Dev
workaround on a glibc-2.31 box: point the SDK at a loader-shim via
`ANTIGRAVITY_HARNESS_PATH=/path/to/shim` that runs the *untouched* bundled
binary through a newer glibc's loader (see the auto-memory note
`antigravity-harness-glibc-native-binary.md`). The shim is dev-only — the
real fix is a glibc-≥2.36 host.
5. **Network egress to the Gemini backend.** The native binary talks to
Google's API; a turn that hangs or fails to connect on a locked-down host is
usually an egress problem, not a harness bug.
## Step 1 — start a local server
```bash
cd /path/to/omnigent
.venv/bin/omni server start # spawns a detached server on a free loopback port
.venv/bin/omni server status # prints the URL, e.g. http://127.0.0.1:6767
```
Use the **printed URL** below as `$SERVER`. (You can also run a foreground
server on a fixed port with `omnigent server --port 7777 --no-open`.)
## Step 2 — build an antigravity agent bundle
A spec with `spec_version` **must be a directory containing `config.yaml`** —
not a single `.yaml` file. Minimal antigravity agent (no `auth:` block → it
resolves the key from the `antigravity:` config / ambient env):
```bash
mkdir -p /tmp/agy-dev
cat > /tmp/agy-dev/config.yaml <<'YAML'
spec_version: 1
name: agy-dev
description: Antigravity SDK dev/test agent.
executor:
type: omnigent
config:
harness: antigravity
model: gemini-3.5-flash # default; gemini-3-pro 404s on a plain AI-Studio key
prompt: |
You are a terse test agent. Answer in as few words as possible.
YAML
```
For sub-agents, tools, guardrails/policies, copy the field shapes from
`examples/polly/config.yaml` and `examples/debby/config.yaml`.
## Step 3 — run a turn (and smoke-test)
```bash
SERVER=http://127.0.0.1:6767 # the URL from `omni server status`
timeout 280 .venv/bin/omni run /tmp/agy-dev \
-p "Reply with exactly the single word: PONG" \
--server "$SERVER" 2>&1
```
A healthy run prints connection lines then the assistant reply (`PONG`). If
that works, the full stack is good: Gemini key, glibc/native binary, egress,
streaming, harness.
- **Shell / file tools:** add `--tools coding`.
- **Specific model:** add `--model gemini-2.5-flash` (or another Gemini id).
## Targeted scenarios
| Goal | How |
|------|-----|
| Native tools (shell/edit/read) | `--tools coding`, prompt to create→read→edit a file and run a shell command; confirm it actually touches disk |
| Bridged `sys_*` / sub-agent dispatch | declare a sub-agent (`tools.agents`/`spawn`), prompt the agent to delegate — exercises the `custom_tools` bridge + `PostToolCallHook` |
| Model routing | run the same bundle with several `--model` Gemini ids; note which actually runs |
| Vertex AI auth | set `executor.config.vertex: true` + `project`/`location` and use GCP application-default creds instead of an API key |
| Policy / guardrail | add a guardrail that denies a keyword; confirm it blocks (see the **sharp edges** below — LLM-phase + tool-call enforcement was incomplete at merge) |
| Per-session brain override | run a bundle agent (polly/debby) and select `antigravity` as the brain harness (it's in `BRAIN_HARNESS_LABELS`) |
| Concurrency / leaks | fire several `omni run … &` at once; then `pgrep -af localharness` to check for orphaned native subprocesses |
## Gotchas (these cost real time)
1. **`config.yaml`'s `server:` defaults to a *remote* server.** Omitting
`--server` sends your turn to that remote deploy — which may be **stale** and
reject the antigravity harness with `executor.config.harness: must be one of
[…], got 'antigravity'`. **Always pass `--server http://127.0.0.1:<port>`**
for local testing. (That allowlist is `omnigent/spec/_omnigent_compat.py`; if
a *local* server rejects `antigravity`, it's running stale code — restart it
from your checkout.)
2. **A spec with `spec_version` must be a directory + `config.yaml`**, never a
single `.yaml` file.
3. **Antigravity needs a Gemini key** (no login). Resolution precedence: spec
`executor.auth` (api_key) > stored `antigravity:` config block (`omni setup`)
> ambient `GEMINI_API_KEY` / `ANTIGRAVITY_API_KEY`.Spin up a live local Omnigent server and exercise the Cursor SDK harness end-to-end — build cursor agents, run real turns, smoke-test, and bug-bash. Load when developing, testing, or debugging the cursor harness (omnigent/inner/cursor_executor.py, cursor_harness.py, cursor_auth.py) or its auth / model / tool-bridge behavior.
Run the Omnigent server as a Docker compose stack (server + Postgres) on any Docker host — your laptop, a VPS, EC2 by hand, or as the base layer of any container-platform deploy. Invoke when the user wants to build the image, bring up the compose stack, debug the stack on a host they already have, or extend the stack for a new platform.
Have the Claude and GPT partners critique each other's answers across a configurable number of rounds (default 1) before converging on a synthesis. Use when the user wants the two perspectives stress-tested against each other, not just shown side by side.
Verify an implementer's diff with an INDEPENDENT, different-vendor sub-agent (diff plus contract only); turn blocking issues into fix-tasks and loop until clean.
Run independent subtasks in parallel — one git worktree and one implementation sub-agent per task, each opening its own PR — then cross-review every PR. polly never merges; the human does.
Delegate read-only investigation, debugging, audit, search, or code-understanding tasks to sub-agents; synthesize only from their structured reports.
Patterns and templates for generating valid Omnigent agent directories. Load when ready to create files.
Detect Python agent frameworks from code imports and map them to Omnigent executor types. Load when the user has existing agent code to integrate.