From caa6eea172e2d228cd52cc6b4a37945e443384ee Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Fri, 14 Aug 2026 23:38:38 -0400 Subject: [PATCH 1/7] feat: make aforge exec the default harness --- .env.example | 5 +++++ Dockerfile | 10 ++++++++-- README.md | 4 +++- agentfield-package.yaml | 8 ++++++++ docker-compose.yml | 3 ++- pyproject.toml | 5 ++++- src/cloudsecurity_af/app.py | 1 + src/cloudsecurity_af/config.py | 9 ++++++++- tests/test_config.py | 28 ++++++++++++++++++++++++++-- 9 files changed, 65 insertions(+), 8 deletions(-) diff --git a/.env.example b/.env.example index 41bd575..31a55cf 100644 --- a/.env.example +++ b/.env.example @@ -5,6 +5,11 @@ OPENROUTER_API_KEY=sk-or-... AGENTFIELD_SERVER=http://localhost:8080 AGENTFIELD_API_KEY= +# AForge exec is the default. Set HARNESS_PROVIDER=opencode to roll back. +HARNESS_PROVIDER=aforge +AGENTFIELD_AFORGE_COMMAND=exec +# CLOUDSECURITY_AFORGE_BIN=/absolute/path/to/aforge + # Optional: Model overrides HARNESS_MODEL=openrouter/moonshotai/kimi-k2.5 AI_MODEL=openrouter/moonshotai/kimi-k2.5 diff --git a/Dockerfile b/Dockerfile index af1e36d..2decfb1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,7 @@ +ARG AFORGE_IMAGE=ghcr.io/agent-field/aforge-v2:chat-v2-exec +FROM ${AFORGE_IMAGE} AS aforge + + FROM python:3.11-slim AS builder ENV PYTHONDONTWRITEBYTECODE=1 \ @@ -14,7 +18,7 @@ COPY pyproject.toml README.md ./ COPY src/ src/ RUN pip install --no-cache-dir --prefix=/install \ - "agentfield>=0.1.0" \ + "agentfield @ git+https://github.com/Agent-Field/agentfield.git@bfd34426d1bdec3cbbfa946682a22ef0a1b91503#subdirectory=sdk/python" \ "pydantic>=2.0" \ "httpx>=0.27" \ "python-dotenv>=1.0" \ @@ -27,7 +31,8 @@ FROM python:3.11-slim AS runtime ENV PYTHONDONTWRITEBYTECODE=1 \ PYTHONUNBUFFERED=1 \ AGENTFIELD_SERVER=http://agentfield:8080 \ - HARNESS_PROVIDER=opencode \ + HARNESS_PROVIDER=aforge \ + AGENTFIELD_AFORGE_COMMAND=exec \ HARNESS_MODEL=openrouter/moonshotai/kimi-k2.5 \ AI_MODEL=openrouter/moonshotai/kimi-k2.5 \ PORT=8005 \ @@ -55,6 +60,7 @@ RUN mkdir -p /home/cloudsecurity/.config/opencode && \ chown -R cloudsecurity:cloudsecurity /home/cloudsecurity/.config COPY --from=builder /install /usr/local +COPY --from=aforge /aforge /usr/local/bin/aforge COPY src/ /app/src/ USER cloudsecurity diff --git a/README.md b/README.md index e1cc5c1..43a1206 100644 --- a/README.md +++ b/README.md @@ -326,7 +326,9 @@ See [`docs/GITHUB_ACTIONS.md`](docs/GITHUB_ACTIONS.md) for full Tier 1 and Tier | `AGENTFIELD_SERVER` | No | `http://localhost:8080` | AgentField control plane URL | | `NODE_ID` | No | `cloudsecurity` | Agent node identifier | | `OPENROUTER_API_KEY` | Yes | - | Model provider credential | -| `CLOUDSECURITY_PROVIDER` | No | `opencode` | Harness provider override | +| `CLOUDSECURITY_PROVIDER` | No | `aforge` | Harness provider override; use `opencode` for rollback | +| `AGENTFIELD_AFORGE_COMMAND` | No | `exec` | AForge headless command (`do` remains an explicit override) | +| `CLOUDSECURITY_AFORGE_BIN` | No | `aforge` | Path to the AForge executable | | `CLOUDSECURITY_MODEL` | No | `openrouter/minimax/minimax-m2.5` | Harness model | | `CLOUDSECURITY_AI_MODEL` | No | `CLOUDSECURITY_MODEL`/`AI_MODEL` fallback | `.ai()` gate model | | `CLOUDSECURITY_MAX_TURNS` | No | `50` | Max turns per harness call | diff --git a/agentfield-package.yaml b/agentfield-package.yaml index 004149c..1b20aab 100644 --- a/agentfield-package.yaml +++ b/agentfield-package.yaml @@ -26,6 +26,14 @@ user_environment: description: Control-plane API key (if auth is enabled) type: secret scope: global + - name: HARNESS_PROVIDER + description: Coding-agent harness provider (aforge by default; opencode for rollback) + default: aforge + - name: AGENTFIELD_AFORGE_COMMAND + description: AForge headless command + default: exec + - name: CLOUDSECURITY_AFORGE_BIN + description: Optional path to the AForge binary (defaults to aforge on PATH) - name: HARNESS_MODEL description: Model the harness uses default: openrouter/moonshotai/kimi-k2.5 diff --git a/docker-compose.yml b/docker-compose.yml index b73c0fe..4746445 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,7 +27,8 @@ services: - AGENTFIELD_SERVER=http://agentfield:8080 - AGENTFIELD_API_KEY=${AGENTFIELD_API_KEY:-} - AGENT_CALLBACK_URL=http://cloudsecurity-af:8005 - - HARNESS_PROVIDER=opencode + - HARNESS_PROVIDER=${HARNESS_PROVIDER:-aforge} + - AGENTFIELD_AFORGE_COMMAND=${AGENTFIELD_AFORGE_COMMAND:-exec} - HARNESS_MODEL=${HARNESS_MODEL:-openrouter/moonshotai/kimi-k2.5} - AI_MODEL=${AI_MODEL:-openrouter/moonshotai/kimi-k2.5} - OPENROUTER_API_KEY=${OPENROUTER_API_KEY} diff --git a/pyproject.toml b/pyproject.toml index d123652..ea9016e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" requires-python = ">=3.11" authors = [{ name = "AgentField", email = "hello@agentfield.dev" }] dependencies = [ - "agentfield>=0.1.0", + "agentfield @ git+https://github.com/Agent-Field/agentfield.git@bfd34426d1bdec3cbbfa946682a22ef0a1b91503#subdirectory=sdk/python", "pydantic>=2.0", "httpx>=0.27", "pyhcl2>=2.0", @@ -29,6 +29,9 @@ dev = [ [tool.hatch.build.targets.wheel] packages = ["src/cloudsecurity_af"] +[tool.hatch.metadata] +allow-direct-references = true + [tool.ruff] target-version = "py311" line-length = 120 diff --git a/src/cloudsecurity_af/app.py b/src/cloudsecurity_af/app.py index 94badff..3b0515c 100644 --- a/src/cloudsecurity_af/app.py +++ b/src/cloudsecurity_af/app.py @@ -44,6 +44,7 @@ max_turns=_ai_config.max_turns, env=_ai_config.provider_env(), opencode_bin=_ai_config.opencode_bin, + aforge_bin=_ai_config.aforge_bin, permission_mode="auto", ), ai_config=AIConfig( diff --git a/src/cloudsecurity_af/config.py b/src/cloudsecurity_af/config.py index 9a3ee21..0e7dc97 100644 --- a/src/cloudsecurity_af/config.py +++ b/src/cloudsecurity_af/config.py @@ -86,7 +86,7 @@ def from_input(cls, scan_input: CloudSecurityInput, repo_path: str) -> ScanConfi class AIIntegrationConfig(BaseModel): provider: str = Field( - default_factory=lambda: os.getenv("CLOUDSECURITY_PROVIDER", os.getenv("HARNESS_PROVIDER", "opencode")) + default_factory=lambda: os.getenv("CLOUDSECURITY_PROVIDER", os.getenv("HARNESS_PROVIDER", "aforge")) ) harness_model: str = Field( default_factory=lambda: os.getenv( @@ -102,6 +102,12 @@ class AIIntegrationConfig(BaseModel): ) max_turns: int = Field(default_factory=lambda: int(os.getenv("CLOUDSECURITY_MAX_TURNS", "50"))) opencode_bin: str = Field(default_factory=lambda: os.getenv("CLOUDSECURITY_OPENCODE_BIN", "opencode")) + aforge_bin: str = Field( + default_factory=lambda: os.getenv( + "CLOUDSECURITY_AFORGE_BIN", + os.getenv("AFORGE_BIN", "aforge"), + ) + ) @classmethod def from_env(cls) -> AIIntegrationConfig: @@ -125,6 +131,7 @@ def provider_env(self) -> dict[str, str]: "AZURE_SUBSCRIPTION_ID", ) env: dict[str, str] = {key: value for key in env_keys if (value := os.getenv(key))} + env["AGENTFIELD_AFORGE_COMMAND"] = os.getenv("AGENTFIELD_AFORGE_COMMAND", "exec") xdg = os.getenv("XDG_DATA_HOME") or os.path.join(tempfile.gettempdir(), "opencode-shared-data") os.makedirs(xdg, exist_ok=True) env["XDG_DATA_HOME"] = xdg diff --git a/tests/test_config.py b/tests/test_config.py index 64a7cd1..900e389 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -3,16 +3,40 @@ import pytest from cloudsecurity_af.config import ( - BudgetConfig, - DepthProfile, DEPTH_CHAIN_LIMITS, DEPTH_HUNTER_MAP, DEPTH_PROVER_CAPS, + AIIntegrationConfig, + BudgetConfig, + DepthProfile, ScanConfig, ) from cloudsecurity_af.schemas.input import CloudSecurityInput +def test_aforge_exec_is_the_default_harness(monkeypatch: pytest.MonkeyPatch) -> None: + for key in ( + "CLOUDSECURITY_PROVIDER", + "HARNESS_PROVIDER", + "CLOUDSECURITY_AFORGE_BIN", + "AFORGE_BIN", + "AGENTFIELD_AFORGE_COMMAND", + ): + monkeypatch.delenv(key, raising=False) + + config = AIIntegrationConfig.from_env() + + assert config.provider == "aforge" + assert config.aforge_bin == "aforge" + assert config.provider_env()["AGENTFIELD_AFORGE_COMMAND"] == "exec" + + +def test_opencode_remains_an_explicit_rollback(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("HARNESS_PROVIDER", "opencode") + + assert AIIntegrationConfig.from_env().provider == "opencode" + + class TestDepthProfile: def test_enum_values(self) -> None: assert DepthProfile.QUICK.value == "quick" From 380280f89b4ff621dbd44c785f7db1543388dc32 Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Mon, 17 Aug 2026 11:08:24 -0400 Subject: [PATCH 2/7] build(docker): fetch the released AForge CLI instead of pulling a registry image The image pulled `ghcr.io/agent-field/aforge-v2:chat-v2-exec` and copied `/aforge` out of it. That package is not publicly pullable, so an out-of-the-box `docker compose up --build` failed for anyone without registry access. Replace it with a fetch stage that downloads the released binary over plain HTTPS from the public download host, decompresses it, and verifies the *decompressed* binary's SHA-256 against the release `checksums.txt` before it is copied into the runtime image. The verification is a hard build failure: an absent or mismatched checksum line aborts the build. `AFORGE_BASE_URL` and `AFORGE_VERSION` stay overridable build args, and docker-compose forwards both from the environment, so a mirror or a newer build can be selected without editing the Dockerfile. Co-Authored-By: Claude Fable 5 --- .env.example | 5 +++++ Dockerfile | 36 +++++++++++++++++++++++++++++++++--- docker-compose.yml | 3 +++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.env.example b/.env.example index 31a55cf..358dc7d 100644 --- a/.env.example +++ b/.env.example @@ -10,6 +10,11 @@ HARNESS_PROVIDER=aforge AGENTFIELD_AFORGE_COMMAND=exec # CLOUDSECURITY_AFORGE_BIN=/absolute/path/to/aforge +# Optional: build-time overrides for where the AForge CLI is downloaded from +# (consumed by `docker compose build`, not by the running agent). +# AFORGE_BASE_URL=https://agentfield.ai/downloads/aforge +# AFORGE_VERSION=build-9b3ff482de3f + # Optional: Model overrides HARNESS_MODEL=openrouter/moonshotai/kimi-k2.5 AI_MODEL=openrouter/moonshotai/kimi-k2.5 diff --git a/Dockerfile b/Dockerfile index 2decfb1..9fa1d1e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,35 @@ -ARG AFORGE_IMAGE=ghcr.io/agent-field/aforge-v2:chat-v2-exec -FROM ${AFORGE_IMAGE} AS aforge +# The AForge CLI is fetched from the public release download host rather than +# pulled from a container registry, so the build needs no registry credentials. +# Both ARGs are overridable (--build-arg) to point at a mirror or a newer build. +ARG AFORGE_BASE_URL=https://agentfield.ai/downloads/aforge +ARG AFORGE_VERSION=build-9b3ff482de3f + +FROM debian:bookworm-slim AS aforge + +ARG AFORGE_BASE_URL +ARG AFORGE_VERSION +ARG TARGETARCH + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl && \ + rm -rf /var/lib/apt/lists/* + +# Download aforge-linux-.gz, decompress it, and verify the *decompressed* +# binary against the release checksums file (which hashes the raw binaries). +RUN set -eux; \ + arch="${TARGETARCH:-$(dpkg --print-architecture)}"; \ + mkdir -p /out; \ + cd /out; \ + curl -fsSL "${AFORGE_BASE_URL}/${AFORGE_VERSION}/aforge-linux-${arch}.gz" -o aforge.gz; \ + gunzip -c aforge.gz > aforge; \ + rm aforge.gz; \ + curl -fsSL "${AFORGE_BASE_URL}/${AFORGE_VERSION}/checksums.txt" -o checksums.txt; \ + grep " aforge-linux-${arch}$" checksums.txt | sed 's/ aforge-linux-.*/ aforge/' > aforge.sha256; \ + test -s aforge.sha256; \ + sha256sum -c aforge.sha256; \ + rm checksums.txt aforge.sha256; \ + chmod +x aforge FROM python:3.11-slim AS builder @@ -60,7 +90,7 @@ RUN mkdir -p /home/cloudsecurity/.config/opencode && \ chown -R cloudsecurity:cloudsecurity /home/cloudsecurity/.config COPY --from=builder /install /usr/local -COPY --from=aforge /aforge /usr/local/bin/aforge +COPY --from=aforge /out/aforge /usr/local/bin/aforge COPY src/ /app/src/ USER cloudsecurity diff --git a/docker-compose.yml b/docker-compose.yml index 4746445..24dfe33 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,9 @@ services: build: context: . dockerfile: Dockerfile + args: + AFORGE_BASE_URL: ${AFORGE_BASE_URL:-https://agentfield.ai/downloads/aforge} + AFORGE_VERSION: ${AFORGE_VERSION:-build-9b3ff482de3f} ports: - "8005:8005" environment: From 6c59b3d3cde105b75d09277dad5ffccb5955deaf Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Mon, 17 Aug 2026 11:08:31 -0400 Subject: [PATCH 3/7] build(deps): pin agentfield to the released 0.1.129 SDK from PyPI The unreleased git SHA pin required `allow-direct-references` and a `git`-capable build environment, and it pinned an SDK that no consumer could resolve from an index. `agentfield>=0.1.129` is on PyPI and already ships the Python AForge harness provider (`agentfield/harness/providers/aforge.py`), which runs `aforge exec --json -w ` and accepts the `aforge_bin` field this agent sets on `HarnessConfig`. Co-Authored-By: Claude Fable 5 --- Dockerfile | 2 +- pyproject.toml | 5 +---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 9fa1d1e..1361b08 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,7 +48,7 @@ COPY pyproject.toml README.md ./ COPY src/ src/ RUN pip install --no-cache-dir --prefix=/install \ - "agentfield @ git+https://github.com/Agent-Field/agentfield.git@bfd34426d1bdec3cbbfa946682a22ef0a1b91503#subdirectory=sdk/python" \ + "agentfield>=0.1.129" \ "pydantic>=2.0" \ "httpx>=0.27" \ "python-dotenv>=1.0" \ diff --git a/pyproject.toml b/pyproject.toml index ea9016e..cdbb4d6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" requires-python = ">=3.11" authors = [{ name = "AgentField", email = "hello@agentfield.dev" }] dependencies = [ - "agentfield @ git+https://github.com/Agent-Field/agentfield.git@bfd34426d1bdec3cbbfa946682a22ef0a1b91503#subdirectory=sdk/python", + "agentfield>=0.1.129", "pydantic>=2.0", "httpx>=0.27", "pyhcl2>=2.0", @@ -29,9 +29,6 @@ dev = [ [tool.hatch.build.targets.wheel] packages = ["src/cloudsecurity_af"] -[tool.hatch.metadata] -allow-direct-references = true - [tool.ruff] target-version = "py311" line-length = 120 From a2e40fbb9cbdce518f842031c132644f352744b8 Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Mon, 17 Aug 2026 11:08:40 -0400 Subject: [PATCH 4/7] test,docs: cover the AForge binary override and document the build args MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add two behaviour tests: `CLOUDSECURITY_AFORGE_BIN`/`AFORGE_BIN` override the resolved binary path, and the pinned agentfield floor actually accepts the `provider="aforge"` + `aforge_bin=...` HarnessConfig this agent constructs — so dropping the SDK floor below the release that carries the AForge provider fails the suite instead of failing at runtime. Document `AFORGE_BASE_URL`/`AFORGE_VERSION` in the README, and correct the `AGENTFIELD_AFORGE_COMMAND` row: the shipped SDK always runs `aforge exec`, so that variable is forward-looking rather than a live switch. Co-Authored-By: Claude Fable 5 --- README.md | 22 ++++++++++++++++++++-- tests/test_config.py | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 43a1206..1658d9b 100644 --- a/README.md +++ b/README.md @@ -327,14 +327,32 @@ See [`docs/GITHUB_ACTIONS.md`](docs/GITHUB_ACTIONS.md) for full Tier 1 and Tier | `NODE_ID` | No | `cloudsecurity` | Agent node identifier | | `OPENROUTER_API_KEY` | Yes | - | Model provider credential | | `CLOUDSECURITY_PROVIDER` | No | `aforge` | Harness provider override; use `opencode` for rollback | -| `AGENTFIELD_AFORGE_COMMAND` | No | `exec` | AForge headless command (`do` remains an explicit override) | -| `CLOUDSECURITY_AFORGE_BIN` | No | `aforge` | Path to the AForge executable | +| `AGENTFIELD_AFORGE_COMMAND` | No | `exec` | AForge headless command. Forward-looking: the shipped SDK always runs `aforge exec` | +| `CLOUDSECURITY_AFORGE_BIN` | No | `aforge` | Path to the AForge executable (falls back to `AFORGE_BIN`) | | `CLOUDSECURITY_MODEL` | No | `openrouter/minimax/minimax-m2.5` | Harness model | | `CLOUDSECURITY_AI_MODEL` | No | `CLOUDSECURITY_MODEL`/`AI_MODEL` fallback | `.ai()` gate model | | `CLOUDSECURITY_MAX_TURNS` | No | `50` | Max turns per harness call | | `CLOUDSECURITY_REPO_PATH` | No | cwd | Local repository path fallback | | `AGENT_CALLBACK_URL` | No | `http://127.0.0.1:8004` | Agent callback endpoint | +### AForge CLI in the Docker image + +The image downloads the released AForge CLI at build time, decompresses it, and +verifies its SHA-256 against the release `checksums.txt` before installing it to +`/usr/local/bin/aforge`. Two build args control where it comes from: + +| Build arg | Default | Purpose | +|---|---|---| +| `AFORGE_BASE_URL` | `https://agentfield.ai/downloads/aforge` | Download host serving `/aforge-linux-.gz` and `/checksums.txt` | +| `AFORGE_VERSION` | `build-9b3ff482de3f` | Released AForge build to install | + +```bash +docker build --build-arg AFORGE_VERSION=build-9b3ff482de3f -t cloudsecurity-af . +``` + +`docker compose build` reads the same two values from the environment (or `.env`), +so a mirror can be selected without editing the Dockerfile. + ### Core `CloudSecurityInput` Fields - `repo_url`, `branch`, `commit_sha`, `base_commit_sha` diff --git a/tests/test_config.py b/tests/test_config.py index 900e389..a6e0fc6 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -37,6 +37,39 @@ def test_opencode_remains_an_explicit_rollback(monkeypatch: pytest.MonkeyPatch) assert AIIntegrationConfig.from_env().provider == "opencode" +def test_aforge_bin_is_overridable(monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.delenv("CLOUDSECURITY_AFORGE_BIN", raising=False) + monkeypatch.setenv("AFORGE_BIN", "/opt/aforge/bin/aforge") + + assert AIIntegrationConfig.from_env().aforge_bin == "/opt/aforge/bin/aforge" + + monkeypatch.setenv("CLOUDSECURITY_AFORGE_BIN", "/usr/local/bin/aforge") + + assert AIIntegrationConfig.from_env().aforge_bin == "/usr/local/bin/aforge" + + +def test_installed_sdk_supports_the_aforge_harness(monkeypatch: pytest.MonkeyPatch) -> None: + """The pinned agentfield floor must accept the provider/bin this agent wires up.""" + from agentfield import HarnessConfig + + for key in ("CLOUDSECURITY_PROVIDER", "HARNESS_PROVIDER", "CLOUDSECURITY_AFORGE_BIN", "AFORGE_BIN"): + monkeypatch.delenv(key, raising=False) + config = AIIntegrationConfig.from_env() + + harness = HarnessConfig( + provider=config.provider, + model=config.harness_model, + max_turns=config.max_turns, + env=config.provider_env(), + opencode_bin=config.opencode_bin, + aforge_bin=config.aforge_bin, + permission_mode="auto", + ) + + assert harness.provider == "aforge" + assert harness.aforge_bin == "aforge" + + class TestDepthProfile: def test_enum_values(self) -> None: assert DepthProfile.QUICK.value == "quick" From 69c5a71692665376f7a5b76942bf4eae1130994b Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Mon, 17 Aug 2026 13:12:28 -0400 Subject: [PATCH 5/7] chore: pin aforge to v0.1.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aforge-v2 cut its first semver release (v0.1.0), so the AFORGE_VERSION default moves off the build- coordinate onto the tag. Bumping the string is what busts the fetch layer's cache, so this is what actually pulls the released binary instead of restoring the stale one. Moves all four places the coordinate is written: the Dockerfile ARG, the docker-compose build arg fallback, the .env.example hint, and the README build-arg table and override example. The AgentField SDK pin is deliberately left alone — it bumps on its own release. Co-Authored-By: Claude Fable 5 --- .env.example | 2 +- Dockerfile | 2 +- README.md | 4 ++-- docker-compose.yml | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.env.example b/.env.example index 358dc7d..1514622 100644 --- a/.env.example +++ b/.env.example @@ -13,7 +13,7 @@ AGENTFIELD_AFORGE_COMMAND=exec # Optional: build-time overrides for where the AForge CLI is downloaded from # (consumed by `docker compose build`, not by the running agent). # AFORGE_BASE_URL=https://agentfield.ai/downloads/aforge -# AFORGE_VERSION=build-9b3ff482de3f +# AFORGE_VERSION=v0.1.0 # Optional: Model overrides HARNESS_MODEL=openrouter/moonshotai/kimi-k2.5 diff --git a/Dockerfile b/Dockerfile index 1361b08..21bdf74 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ # pulled from a container registry, so the build needs no registry credentials. # Both ARGs are overridable (--build-arg) to point at a mirror or a newer build. ARG AFORGE_BASE_URL=https://agentfield.ai/downloads/aforge -ARG AFORGE_VERSION=build-9b3ff482de3f +ARG AFORGE_VERSION=v0.1.0 FROM debian:bookworm-slim AS aforge diff --git a/README.md b/README.md index 1658d9b..de3ab91 100644 --- a/README.md +++ b/README.md @@ -344,10 +344,10 @@ verifies its SHA-256 against the release `checksums.txt` before installing it to | Build arg | Default | Purpose | |---|---|---| | `AFORGE_BASE_URL` | `https://agentfield.ai/downloads/aforge` | Download host serving `/aforge-linux-.gz` and `/checksums.txt` | -| `AFORGE_VERSION` | `build-9b3ff482de3f` | Released AForge build to install | +| `AFORGE_VERSION` | `v0.1.0` | Released AForge version to install | ```bash -docker build --build-arg AFORGE_VERSION=build-9b3ff482de3f -t cloudsecurity-af . +docker build --build-arg AFORGE_VERSION=v0.1.0 -t cloudsecurity-af . ``` `docker compose build` reads the same two values from the environment (or `.env`), diff --git a/docker-compose.yml b/docker-compose.yml index 24dfe33..4582ed9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -23,7 +23,7 @@ services: dockerfile: Dockerfile args: AFORGE_BASE_URL: ${AFORGE_BASE_URL:-https://agentfield.ai/downloads/aforge} - AFORGE_VERSION: ${AFORGE_VERSION:-build-9b3ff482de3f} + AFORGE_VERSION: ${AFORGE_VERSION:-v0.1.0} ports: - "8005:8005" environment: From 3f23b9f25912ab5194574a1448b4787971f02b2d Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Mon, 17 Aug 2026 21:41:26 -0400 Subject: [PATCH 6/7] chore: pin agentfield>=0.1.130 (aforge default release) 0.1.130 is the first agentfield release cut after the aforge exec harness landed as the default provider. Raise the floor in both the package metadata and the runtime image so a fresh install and a fresh container build both resolve the release this agent is verified against. Co-Authored-By: Claude Fable 5 --- Dockerfile | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 21bdf74..fcd7bdc 100644 --- a/Dockerfile +++ b/Dockerfile @@ -48,7 +48,7 @@ COPY pyproject.toml README.md ./ COPY src/ src/ RUN pip install --no-cache-dir --prefix=/install \ - "agentfield>=0.1.129" \ + "agentfield>=0.1.130" \ "pydantic>=2.0" \ "httpx>=0.27" \ "python-dotenv>=1.0" \ diff --git a/pyproject.toml b/pyproject.toml index cdbb4d6..b413296 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -11,7 +11,7 @@ license = "Apache-2.0" requires-python = ">=3.11" authors = [{ name = "AgentField", email = "hello@agentfield.dev" }] dependencies = [ - "agentfield>=0.1.129", + "agentfield>=0.1.130", "pydantic>=2.0", "httpx>=0.27", "pyhcl2>=2.0", From e46c9b33faae79e883a3773cd122cdec668a5349 Mon Sep 17 00:00:00 2001 From: Abir Abbas Date: Mon, 17 Aug 2026 22:12:51 -0400 Subject: [PATCH 7/7] docs: AGENTFIELD_AFORGE_COMMAND is a live exec|do selector on agentfield>=0.1.130 The "forward-looking / always runs exec" wording was written against 0.1.129. 0.1.130 reads AGENTFIELD_AFORGE_COMMAND (default `exec`, `do` opts into the routed workflow), so describe the real behaviour. Co-Authored-By: Claude Fable 5 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index de3ab91..a91a877 100644 --- a/README.md +++ b/README.md @@ -327,7 +327,7 @@ See [`docs/GITHUB_ACTIONS.md`](docs/GITHUB_ACTIONS.md) for full Tier 1 and Tier | `NODE_ID` | No | `cloudsecurity` | Agent node identifier | | `OPENROUTER_API_KEY` | Yes | - | Model provider credential | | `CLOUDSECURITY_PROVIDER` | No | `aforge` | Harness provider override; use `opencode` for rollback | -| `AGENTFIELD_AFORGE_COMMAND` | No | `exec` | AForge headless command. Forward-looking: the shipped SDK always runs `aforge exec` | +| `AGENTFIELD_AFORGE_COMMAND` | No | `exec` | AForge headless command the SDK runs: `exec` (default) or `do`. Read by agentfield>=0.1.130 | | `CLOUDSECURITY_AFORGE_BIN` | No | `aforge` | Path to the AForge executable (falls back to `AFORGE_BIN`) | | `CLOUDSECURITY_MODEL` | No | `openrouter/minimax/minimax-m2.5` | Harness model | | `CLOUDSECURITY_AI_MODEL` | No | `CLOUDSECURITY_MODEL`/`AI_MODEL` fallback | `.ai()` gate model |