feat(v1): add prime-agent harness over native ACP - #2248
Conversation
Drives prime-agent's own ACP mode through the existing ACP helper rather than the pi harness's third-party pi-acp adapter. That adapter spawns `pi --mode rpc` and hard-codes pi's RPC command and event union, so prime-agent's IPython-only tool model, subagents, autonomous gates, goals, and heartbeats either degrade to a generic tool call or disappear. prime-agent speaks ACP natively as of its ACP mode, and carries the concepts ACP has no field for in a namespaced `ai.primeintellect.prime-agent` `_meta` envelope, so a rollout can observe them without the harness parsing a private protocol. Targets the current launch() contract. HOME is pinned per trace because prime-agent writes session and kernel state beneath it and concurrent rollouts must not share either.
| ) | ||
| await runtime.run(["chmod", "+x", wrapper], {}) | ||
|
|
||
| return await PRIME_AGENT_ACP.run( |
There was a problem hiding this comment.
🟠 High prime_agent/harness.py:180
Each launch creates a per-trace directory .vf-prime-agent-{trace.id} and uses it as HOME and PI_CODING_AGENT_DIR, but the harness never removes it. Session and IPython kernel state accumulate on the runtime for every rollout, consuming disk and leaving rollout artifacts behind after scoring. Consider adding a cleanup override that deletes agent_dir.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/harnesses/prime_agent/harness.py around line 180:
Each `launch` creates a per-trace directory `.vf-prime-agent-{trace.id}` and uses it as `HOME` and `PI_CODING_AGENT_DIR`, but the harness never removes it. Session and IPython kernel state accumulate on the runtime for every rollout, consuming disk and leaving rollout artifacts behind after scoring. Consider adding a `cleanup` override that deletes `agent_dir`.
| SKILLS_DIR = ".agents/skills" | ||
| INSTALLER_URL = "https://pub-728493de92a943e2a9b2d17b4719f318.r2.dev/install.sh" | ||
|
|
||
| INSTALL = r""" |
There was a problem hiding this comment.
🟠 High prime_agent/harness.py:29
INSTALL runs npm install without provisioning a Node.js toolchain first. Under the default python:3.11-slim runtime image used by the Docker, Modal, and Prime runtimes, npm is not present, so setup() fails with npm: not found and the harness cannot launch. Install Node.js/npm as part of this script, as the existing Pi harness does.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/harnesses/prime_agent/harness.py around line 29:
`INSTALL` runs `npm install` without provisioning a Node.js toolchain first. Under the default `python:3.11-slim` runtime image used by the Docker, Modal, and Prime runtimes, `npm` is not present, so `setup()` fails with `npm: not found` and the harness cannot launch. Install Node.js/npm as part of this script, as the existing Pi harness does.
| SKILLS_DIR = ".agents/skills" | ||
| INSTALLER_URL = "https://pub-728493de92a943e2a9b2d17b4719f318.r2.dev/install.sh" | ||
|
|
||
| INSTALL = r""" |
There was a problem hiding this comment.
🟡 Medium prime_agent/harness.py:29
The install guard at if [ -x "$VF_PRIME_AGENT_BIN" ] only checks whether the binary already exists. On a reused runtime, a different config.version or tarball_url is never compared against what was previously installed, so the first installed release is silently reused and later rollouts run the wrong Prime Agent version. Consider persisting the requested release/tarball identifier alongside the install and comparing it before taking the early exit.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/harnesses/prime_agent/harness.py around line 29:
The install guard at `if [ -x "$VF_PRIME_AGENT_BIN" ]` only checks whether the binary already exists. On a reused runtime, a different `config.version` or `tarball_url` is never compared against what was previously installed, so the first installed release is silently reused and later rollouts run the wrong Prime Agent version. Consider persisting the requested release/tarball identifier alongside the install and comparing it before taking the early exit.
| ) | ||
| await runtime.run(["chmod", "+x", wrapper], {}) | ||
|
|
||
| return await PRIME_AGENT_ACP.run( |
There was a problem hiding this comment.
🟡 Medium prime_agent/harness.py:180
The system_prompt is passed to the model twice: once via --append-system-prompt on line 163, and again as a system content block through the system_prompt argument to PRIME_AGENT_ACP.run on line 186. The model receives duplicate instructions, wasting context and potentially altering behavior. Pass system_prompt=None to PRIME_AGENT_ACP.run so only the --append-system-prompt flag is used.
🚀 Reply "fix it for me" or copy this AI Prompt for your agent:
In file @verifiers/v1/harnesses/prime_agent/harness.py around line 180:
The `system_prompt` is passed to the model twice: once via `--append-system-prompt` on line 163, and again as a `system` content block through the `system_prompt` argument to `PRIME_AGENT_ACP.run` on line 186. The model receives duplicate instructions, wasting context and potentially altering behavior. Pass `system_prompt=None` to `PRIME_AGENT_ACP.run` so only the `--append-system-prompt` flag is used.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ae6f0fd. Configure here.
| ["sh", "-c", f'exec "$PWD/{wrapper}"'], | ||
| prompt, | ||
| mcp_urls=mcp_urls, | ||
| system_prompt=system_prompt, |
There was a problem hiding this comment.
System prompt applied twice
High Severity
system_prompt is passed both as --append-system-prompt and as system_prompt= into ACP.run. The ACP helper also injects that text into the prompt on new sessions, so tasks with a system prompt deliver it twice—once via the agent flag and again as prompt content—unlike the pi harness, which only uses the CLI flag.
Reviewed by Cursor Bugbot for commit ae6f0fd. Configure here.
| # instead of running the interactive installer script. | ||
| npm install --no-audit --no-fund --prefix "$VF_PRIME_AGENT_DIR" \ | ||
| "$VF_PRIME_AGENT_TARBALL" | ||
| """ |
There was a problem hiding this comment.
Install assumes Node is present
High Severity
The install script runs npm install without ensuring Node.js/npm exist, and the launch path never puts a Node binary on PATH. The default Docker image is python:3.11-slim, which has neither, so setup fails where the sibling pi harness bootstraps Node first.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit ae6f0fd. Configure here.
| # instead of running the interactive installer script. | ||
| npm install --no-audit --no-fund --prefix "$VF_PRIME_AGENT_DIR" \ | ||
| "$VF_PRIME_AGENT_TARBALL" | ||
| """ |
There was a problem hiding this comment.
Stale install ignores version pin
Medium Severity
INSTALL exits early whenever VF_PRIME_AGENT_BIN is already executable, without comparing version or tarball_url. A shared /tmp/vf-prime-agent cache therefore keeps serving the first installed build after the pin or tarball override changes, breaking the reproducibility the config claims.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit ae6f0fd. Configure here.
ApprovabilityVerdict: Needs human review 4 blocking correctness issues found. This PR introduces a new harness component with substantial new integration logic. Multiple unresolved high-severity comments identify bugs that would cause setup failures (missing Node.js), incorrect behavior (duplicate system prompts), and resource leaks (no cleanup). Human review needed. You can customize Macroscope's approvability policy. Learn more. |
|
Closing until the prime-agent ACP mode PR is merged and a release is cut. Reopening once the pinned version can point at a release that actually has |


Adds a
prime-agentharness for v1, driving prime-agent's native ACP mode through the existingverifiers/v1/acp/helper.Depends on PrimeIntellect-ai/prime-agent#613, which adds
--mode acp. It should land, and a release cut, before this merges — the pinnedversionhere needs bumping to that release.Why not the
piharnessThe
piharness reaches prime-agent's upstream through third-partypi-acp@0.0.31(svkozak/pi-acp), which spawnspi --mode rpcand hard-codes pi's RPC command and event union. prime-agent has diverged substantially, and those differences are exactly what a rollout wants to observe:pi-acpcan only render as a genericothertool call with no cell semantics or rich outputprime-agent now speaks ACP natively, so this harness talks to it directly. Nothing here parses a private protocol.
Design
Targets the current
launch()contract onmain. I read #2116 and #2141 first: both are open, unapproved, andmergeable: false, and #2141's own review objects to its dual-API shape. #2141 keepslaunch()/resume()as an adapter, so this harness continues to work if that lands and can later opt into persistence by overridingopen_session()and returningACP.session(...).endpoint+secret, registered as an ordinary OpenAI-compatible providerSUPPORTS_MCP,SUPPORTS_RESUME,SUPPORTS_SKILLS,APPENDS_SYSTEM_PROMPTHOMEis pinned per trace, because prime-agent writes session state and IPython kernel state beneath it and concurrent rollouts must not share eitherautonomous+gatesmap to--autonomous/--autonomous-gate; gates withoutautonomousis rejected rather than silently ignoredVerification
harness_class("prime-agent")→PrimeAgentHarness, instantiated viaharness_config_type+load_harnessmode: "acp", provider/model,--autonomous-gate, and--append-system-promptall land--gateand--exclude-tools, neither of which exists.disabled_toolsnow raises instead of emitting a flag that would be ignoreduv run ruff check,ruff format --check,uv run ty check verifiers, anduv run pytest tests/all passPer AGENTS.md ("prefer e2e tests over unit tests; extra unit tests clog the repo") I added no test file; the checks above were run as throwaway scripts.
Note
Committed with
--no-verify: the pre-commit and pre-push hooks runuv run --locked, and my local uv (0.11.25) writes lockfile revision 3 against this repo's revision 4, so the hook fails on an unrelated lockfile rewrite.uv.lockis untouched in this branch, and I ran each hook's underlying command directly instead — all pass.Note
Cursor Bugbot is generating a summary for commit ae6f0fd. Configure here.
Note
Add
PrimeAgentHarnessto run prime-agent over native ACPPrimeAgentHarness, which installs prime-agent on demand via npm and executes it in ACP mode with per-trace directory isolation./tmp/vf-prime-agent; subsequent runs skip if the binary already exists.PrimeAgentHarnessConfigexposesversion(default0.5.1), optionaltarball_urloverride,autonomousmode, andgates.models.jsonwiring the intercept provider to the supplied OpenAI-compatible endpoint, setsPI_OFFLINE=1/PI_TELEMETRY=0, and supports MCP URLs, skills, and system prompt appending.ValueErroris raised immediately ifdisabled_toolsis set or ifgatesare provided withoutautonomous=True.📊 Macroscope summarized ae6f0fd. 3 files reviewed, 0 issues evaluated, 0 issues filtered, 0 comments posted
🗂️ Filtered Issues
No issues evaluated.