Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions .claude/commands/agent-runtime-kit/upgrade.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: "Agent Runtime Kit: Upgrade"
description: Inspect and safely upgrade agent-runtime-kit vendor SDK dependencies
description: Upgrade and adapt agent-runtime-kit vendor SDK integrations through a verified pull request
category: Workflow
tags: [agent-runtime-kit, sdk-evolution, upgrade, workflow]
---
Expand All @@ -9,12 +9,11 @@ tags: [agent-runtime-kit, sdk-evolution, upgrade, workflow]

Read and follow the canonical repository workflow in
`.codex/skills/agent-runtime-kit-upgrade/SKILL.md`. That file owns candidate
discovery, no-cooloff resolution, report-first gates, local upgrade
authorization, verification, and PR publication rules; do not duplicate or
discovery, no-cooloff resolution, report-first gates, upstream adaptation,
verification, and PR publication rules; do not duplicate or
weaken them here.

For this Claude command, use `claude-agent-sdk` with `--extra claude` unless the
user selected another runtime. Preserve every other authorization boundary from
the canonical workflow: an explicit SDK upgrade request permits the gated local
dependency update, while branch, commit, push, PR, merge, and release actions
remain separately authorized.
user selected another runtime. Complete the canonical workflow, including the
necessary source adaptations and regular PR, for an upgrade invocation. Honor
explicit report-only or local-only limits. Never auto-merge or publish a release.
280 changes: 150 additions & 130 deletions .codex/skills/agent-runtime-kit-upgrade/SKILL.md

Large diffs are not rendered by default.

18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ All notable changes to this project are documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Unreleased

### Changed

- Updated tested Claude Agent SDK to `0.2.152` and Google Antigravity SDK to
`0.1.16`; the Codex SDK and its coupled CLI remain at `0.147.0`.
- Upgrade skill invocations now include necessary runtime adaptations,
verification, and a regular pull request. Explicit report-only and local-only
requests retain their narrower scope.

### Fixed

- Antigravity preserves explicit `vertex=True` with an API key for Vertex
Express authentication, rejects mixed regional credentials, and refuses older
SDKs or configurations that would silently drop the requested endpoint.
- Release-note collection recognizes versions present only in a GitHub
discussion title and rejects unrelated or longer version-prefix matches.

## 0.5.1 - 2026-08-29

### Added
Expand Down
20 changes: 17 additions & 3 deletions docs/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -188,11 +188,25 @@ constructor, `GEMINI_API_KEY`, or `GOOGLE_API_KEY`. Without an API key, the
adapter uses Vertex AI config with Google ADC when a project can be discovered
from ADC, `GOOGLE_CLOUD_PROJECT`, or `GCLOUD_PROJECT`; location defaults to
`global` unless `GOOGLE_CLOUD_LOCATION`, `GOOGLE_CLOUD_REGION`, or
`CLOUD_ML_REGION` is set. Precedence: an explicit constructor `api_key` is the
most specific request and wins; otherwise an explicit
`CLOUD_ML_REGION` is set. An explicit constructor `api_key` takes precedence over
ambient credentials. With `vertex=True`, that key selects Vertex Express mode
(supported by released `google-antigravity>=0.1.16` versions): no ADC, project,
or location is required. Older or unverifiable SDK releases raise
`UnsupportedTaskInputError` for Express mode; their existing authentication
modes remain available. Explicit project/location arguments cannot be combined
with Express mode. For example:

```python
runtime = AntigravityAgentRuntime(vertex=True, api_key=vertex_express_key)
```

Without an explicit key, an explicit
`AntigravityAgentRuntime(vertex=True, ...)` takes precedence over an ambient
`GEMINI_API_KEY`/`GOOGLE_API_KEY`, so a Vertex-configured runtime is never
silently redirected to the Gemini API by an exported environment key. Under
silently redirected to the Gemini API by an exported environment key. When no
model is supplied, the adapter preserves the vendor default (`gemini-3.8-flash`
in Antigravity 0.1.16); supply `default_model` or `AgentTask.model` when a stable
model selection is required. Under
`PERMISSIVE`, `disallowed_tools` maps to `CapabilitiesConfig.disabled_tools`
(the baseline is every tool, so "enable everything else" is exact); under any
other posture the deny-list is folded into an allow-list of the mode's baseline
Expand Down
9 changes: 9 additions & 0 deletions docs/sdk-evolution-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@ The SDK evolution agent is a local dogfood workflow for keeping
agent-runtime-kit aligned with Claude Agent SDK, OpenAI Codex SDK, and Google
Antigravity SDK as those upstream packages evolve.

For a complete upgrade, invoke the repository's
[`agent-runtime-kit-upgrade` skill](../.codex/skills/agent-runtime-kit-upgrade/SKILL.md).
It collects evidence first, maps upstream implementation trends to the current
integration, implements the necessary adapter/runtime changes with tests and
docs, applies the compatible dependency update, and creates a verified regular
pull request. Explicit report-only and local-only requests retain those limits.
The CLI examples below describe the underlying runner; its report-only default
and dependency-only implementation lane are stages within that broader skill.

For the intended architecture, evidence contract, behavior probe strategy,
changelog strategy, caveats, and alternatives, see
[`docs/sdk-evolution-agent-design.md`](sdk-evolution-agent-design.md).
Expand Down
25 changes: 19 additions & 6 deletions examples/sdk_evolution_agent/release_notes.py
Original file line number Diff line number Diff line change
Expand Up @@ -349,23 +349,31 @@ def _summaries_for_interval(
) -> list[str]:
text = _prefer_github_discussion_body(text)
lines = [line.strip() for line in text.splitlines()]
version_patterns = [to_version]
versions = [to_version]
if from_version:
version_patterns.append(from_version)
versions.append(from_version)
version_patterns = [
re.compile(rf"(?<![\w.+-])v?{re.escape(version)}(?![\w.+-])") for version in versions
]
# A baseline mention or a longer version sharing the candidate's prefix is
# not release evidence for the candidate itself.
if not version_patterns[0].search(text):
return []
matches: list[str] = []
for index, line in enumerate(lines):
if not line:
continue
if any(pattern and pattern in line for pattern in version_patterns):
if any(pattern.search(line) for pattern in version_patterns):
matches.append(_clean_summary(line))
for nearby in lines[index + 1 : index + 9]:
cleaned = _clean_summary(nearby)
if cleaned:
matches.append(cleaned)
if not matches and to_version:
compact = re.sub(r"\s+", " ", text)
version_index = compact.find(to_version)
if version_index >= 0:
version_match = version_patterns[0].search(compact)
if version_match:
version_index = version_match.start()
start = max(0, version_index - 160)
end = min(len(compact), version_index + 320)
matches.append(_clean_summary(compact[start:end]))
Expand All @@ -380,7 +388,12 @@ def _prefer_github_discussion_body(text: str) -> str:
)
if not match:
return text
return match.group("body")
# GitHub release discussions may identify the version only in the page
# title, while the comment body describes the changes without repeating it.
# Keep that title attached to its body, excluding navigation and replies.
title = re.search(r"<title\b[^>]*>(.*?)</title>", text, flags=re.DOTALL | re.IGNORECASE)
body = match.group("body")
return f"{title.group(1)}\n{body}" if title else body


def _release_note_links_for_version(source_url: str, text: str, to_version: str) -> tuple[str, ...]:
Expand Down
57 changes: 50 additions & 7 deletions src/agent_runtime_kit/adapters/antigravity.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
optional_str,
output_schema_from,
package_availability,
package_version,
resolve_structured_output,
select_model,
validate_model_configuration,
Expand Down Expand Up @@ -98,6 +99,10 @@ def __init__(
policy_module: Any | None = None,
reuse_process: bool = False,
) -> None:
if api_key and vertex is True and (project or location):
raise ValueError(
"Vertex Express API-key authentication cannot be combined with project/location"
)
self._default_model = default_model
self._supported_models = validate_model_configuration(default_model, supported_models)
self._api_key = api_key
Expand Down Expand Up @@ -149,7 +154,7 @@ async def check_readiness(self) -> RuntimeReadiness:
message="An Antigravity API-key credential signal is configured.",
package=availability.package,
version=availability.version,
metadata={"auth_source": "api-key"},
metadata={"auth_source": self._auth_config().source},
)
if self._vertex is False:
return self._missing_credentials_readiness(availability)
Expand Down Expand Up @@ -319,7 +324,13 @@ def _load_sdk(self) -> _AntigravitySDK:
self.kind,
"google-antigravity is not installed. Install agent-runtime-kit[antigravity].",
) from exc
return _AntigravitySDK(Agent, LocalAgentConfig, types, policy) # pragma: no cover
return _AntigravitySDK(
Agent,
LocalAgentConfig,
types,
policy,
supports_vertex_express=_supports_vertex_express(package_version("google-antigravity")),
)

def _build_config(
self,
Expand All @@ -329,6 +340,12 @@ def _build_config(
auth: _AntigravityAuthConfig,
sdk: _AntigravitySDK,
) -> tuple[Any, list[str]]:
if auth.api_key is not None and auth.vertex is True and not sdk.supports_vertex_express:
raise UnsupportedTaskInputError(
self.kind,
"vertex",
"Vertex Express requires a released google-antigravity>=0.1.16 SDK",
)
for server in task.mcp_servers:
if server.env:
raise UnsupportedTaskInputError(
Expand Down Expand Up @@ -366,9 +383,11 @@ def _build_config(
# LocalAgentConfig no longer accepts (instead of a TypeError) and record
# them — except the tool posture (and workspace scoping when requested),
# which must fail closed rather than run with the SDK's default access.
required = ["capabilities", "policies"]
required = {"capabilities": "permissions", "policies": "permissions"}
if auth.api_key is not None and auth.vertex is True:
required.update(api_key="api_key", vertex="vertex")
if config_kwargs["workspaces"]:
required.append("workspaces")
required["workspaces"] = "permissions"
supported, dropped = filter_supported_kwargs(
sdk.config_cls, config_kwargs, required=required, kind=self.kind
)
Expand Down Expand Up @@ -670,9 +689,14 @@ def _vertex_auth_config(self) -> _AntigravityAuthConfig:
return _AntigravityAuthConfig(source="none")

def _auth_config(self) -> _AntigravityAuthConfig:
# An explicit constructor api_key is the most specific request and wins.
# An explicit key selects credentials without erasing an explicit
# endpoint: vertex=True plus a key is Vertex Express, without ADC.
if self._api_key:
return _AntigravityAuthConfig(api_key=self._api_key, source="api-key")
return _AntigravityAuthConfig(
api_key=self._api_key,
vertex=self._vertex,
source="vertex-express-api-key" if self._vertex is True else "api-key",
)
# Explicit vertex=True takes precedence over an ambient env API key, so
# AntigravityAgentRuntime(vertex=True, project=...) is not silently
# redirected to the Gemini API just because GEMINI_API_KEY is exported.
Expand Down Expand Up @@ -703,11 +727,30 @@ def _runtime_dir(self, name: str) -> Path:


class _AntigravitySDK:
def __init__(self, agent_cls: Any, config_cls: Any, types: Any, policy: Any) -> None:
def __init__(
self,
agent_cls: Any,
config_cls: Any,
types: Any,
policy: Any,
*,
supports_vertex_express: bool = True,
) -> None:
self.agent_cls = agent_cls
self.config_cls = config_cls
self.types = types
self.policy = policy
self.supports_vertex_express = supports_vertex_express


def _supports_vertex_express(version: str | None) -> bool:
# 0.1.15 exposes the same kwargs, so field presence cannot establish native
# Express support. Enable it only for a verifiable released SDK; injected
# SDK implementations own their capability contract independently.
released = re.fullmatch(
r"(\d+)\.(\d+)\.(\d+)(?:\.post\d+)?(?:\+[a-zA-Z0-9._-]+)?", version or ""
)
return released is not None and tuple(int(part) for part in released.groups()) >= (0, 1, 16)


@dataclass(frozen=True)
Expand Down
4 changes: 2 additions & 2 deletions src/agent_runtime_kit/compatibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def __post_init__(self) -> None:
package="claude-agent-sdk",
module="claude_agent_sdk",
version_specifier=">=0.2.87,<0.3",
tested_version="0.2.148",
tested_version="0.2.152",
),
RuntimeCompatibility(
kind=AgentRuntimeKind.CODEX_AGENT_SDK,
Expand All @@ -85,7 +85,7 @@ def __post_init__(self) -> None:
package="google-antigravity",
module="google.antigravity",
version_specifier=">=0.1.2,<0.2",
tested_version="0.1.15",
tested_version="0.1.16",
),
)

Expand Down
Loading
Loading