refactor(agent): remove legacy in-process backend, rename harnesses pi_core/pi_agenta#4833
Conversation
…i_core/pi_agenta The deployed agent service always runs the sandbox-agent backend (app.py select_backend), so the in-process Pi path was dead. Remove it and the `backend` wire selector, and make the harness names explicit: `pi` -> `pi_core`, `agenta` -> `pi_agenta` (`claude` unchanged). Both pi_core and pi_agenta still drive the ACP agent "pi"; pi_agenta is Pi with Agenta's forced skills/prompt/policy. No backward compatibility (the feature is not in production). Removed: - runner engines/pi.ts (in-process engine) and its sandboxPermission guard - the backend branch + AGENT_BACKEND handling in cli.ts/server.ts (always runSandboxAgent) - the `backend` field from protocol.ts AgentRunRequest and wire.py request_to_wire - the _ENGINE constant + AGENT_BACKEND env injection in the SDK sandbox_agent backend - `pi` from version.ts ENGINES (now ["sandbox-agent"]) Renamed harness enum VALUES (Python symbols/class names unchanged): HarnessType enum, RunSelection default, capabilities table keys, version.ts HARNESSES, run-plan.ts acpAgent remap, the agent_config catalog type, the service schemas default, and the FE connectionUtils map + playground/transport defaults. Golden run_request.pi.json -> run_request.pi_core.json; both goldens drop `backend`. Also collapsed the agent-config default (it was hand-maintained in three places, each edited by this rename) into one shared build_agent_v0_default builder in the SDK, consumed by the builtin interface (bare) and the service (with the platform skill + sandbox boundary as named args), with an acceptance test pinning inspect == runtime. Fixed the stale protocol.ts SandboxPermission comment: the network policy IS enforced on Daytona; the local sidecar rejects a restricted-network run under strict; filesystem is declared-only. Docs synced (same PR): the agent-workflows documentation pages, the interface inventory and its index, and services/agent/AGENTS.md. Tests green: runner 160, SDK unit 940 + integration 4, service agent 34, FE playground 26 + entity-ui 18. Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThe PR renames Pi-family harness identifiers to ChangesSandbox-agent harness migration
Sequence Diagram(s)sequenceDiagram
participant serverTs as server.ts
participant cliTs as cli.ts
participant runSandboxAgent
participant request_to_wire
participant SandboxAgentBackend
serverTs->>runSandboxAgent: POST /run request
cliTs->>runSandboxAgent: CLI request
runSandboxAgent->>request_to_wire: build harness-based payload
request_to_wire-->>runSandboxAgent: /run JSON without backend
runSandboxAgent->>SandboxAgentBackend: deliver request
SandboxAgentBackend->>SandboxAgentBackend: stream subprocess run
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Railway Preview Environment
Updated at 2026-06-25T10:55:16.800Z |
…t URI Implements the contract-versioning POC slice (PR #4829): give the harness a versioned slug + display name in the agent_config interface, and bind the live agent handler to the builtin URI (architecture-followups issue 2). Builds on the harness rename (#4833). Harness slug+name (interface only): one SDK source `HARNESS_IDENTITIES` (agents/dtos.py) maps each HarnessType to a versioned slug `agenta:harness:<value>:v0` (the repo's slug grammar) + a display name. `AgentConfigSchema.harness` now emits both a flat `enum` (back-compat) and a `oneOf` of `{const,title,x-ag-harness-slug}`; the FE EnumSelectControl reads the oneOf for labels and writes the bare const. The stored/wire/ runtime harness value stays the bare string, so the /run wire, golden fixtures, and both wire-contract tests are unchanged. Issue 2 (bind the builtin URI): create_agent_app() registers the instrumented `_agent` (auto_instrument BEFORE register, so tracing survives) and overrides the interface under `agenta:builtin:agent:v0` via a new `register_interface` helper, so retrieve_handler / retrieve_interface return the live handler and the same schemas /inspect advertises. Fixed the stale agent CONFIGURATION_REGISTRY entry to the canonical `{"agent": build_agent_v0_default()}`. Deferred per the POC spec: the /run `version` field, the if/elif version dispatch, and the /health protocol skew read. Tests: SDK 945 (+5 harness-identity), service agent 38 (+4 builtin-uri binding), wire contract Python 20 + TS 160 unchanged, FE entity-ui 23 (+5 EnumSelectControl) + playground 26. Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
sdks/python/oss/tests/pytest/unit/agents/test_wire_contract.py (1)
468-472: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick winStale
piharness_options key — rename topi_core.This is the only remaining
"pi"slice key in the renamed cohort. The assertion still passes (a Pi config renders noharnessFilesfrom its options regardless of the key), but leaving the old name in the contract-guard test means it silently stops representing the realpi_coreslice.🔧 Proposed fix
config = PiAgentConfig( harness_options={ - "pi": {"system": "You are Pi."}, + "pi_core": {"system": "You are Pi."}, "claude": {"permissions": {"default_mode": "plan"}}, } )
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 47b423b2-9178-43bb-af93-1113b83b6914
📒 Files selected for processing (69)
docs/design/agent-workflows/documentation/adapters/agenta.mddocs/design/agent-workflows/documentation/adapters/pi.mddocs/design/agent-workflows/documentation/agent-configuration.mddocs/design/agent-workflows/documentation/architecture.mddocs/design/agent-workflows/documentation/ground-truth.mddocs/design/agent-workflows/documentation/ports-and-adapters.mddocs/design/agent-workflows/documentation/protocol.mddocs/design/agent-workflows/documentation/sessions.mddocs/design/agent-workflows/documentation/skills.mddocs/design/agent-workflows/documentation/tools.mddocs/design/agent-workflows/interfaces/README.mddocs/design/agent-workflows/interfaces/cross-service/runner-to-harness.mddocs/design/agent-workflows/interfaces/cross-service/service-to-agent-runner.mddocs/design/agent-workflows/interfaces/in-service/backend-adapter.mddocs/design/agent-workflows/interfaces/in-service/neutral-runtime-dtos.mddocs/design/agent-workflows/interfaces/in-service/runner-engine-internals.mddocs/design/agent-workflows/interfaces/public-edge/agent-config-schema.mddocs/design/agent-workflows/interfaces/public-edge/agent-messages.mddocs/design/agent-workflows/interfaces/public-edge/workflow-invoke.mddocs/design/agent-workflows/projects/harness-rename/status.mdsdks/python/agenta/sdk/agents/adapters/harnesses.pysdks/python/agenta/sdk/agents/adapters/sandbox_agent.pysdks/python/agenta/sdk/agents/capabilities.pysdks/python/agenta/sdk/agents/dtos.pysdks/python/agenta/sdk/agents/utils/wire.pysdks/python/agenta/sdk/engines/running/interfaces.pysdks/python/agenta/sdk/utils/types.pysdks/python/oss/tests/pytest/integration/agents/_fake_runner_backend.pysdks/python/oss/tests/pytest/integration/agents/test_transport_roundtrip.pysdks/python/oss/tests/pytest/unit/agents/connections/test_capabilities.pysdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.pysdks/python/oss/tests/pytest/unit/agents/connections/test_resolver.pysdks/python/oss/tests/pytest/unit/agents/golden/run_request.claude.jsonsdks/python/oss/tests/pytest/unit/agents/golden/run_request.pi_core.jsonsdks/python/oss/tests/pytest/unit/agents/platform/test_connections_http.pysdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.pysdks/python/oss/tests/pytest/unit/agents/test_dtos_agent_config.pysdks/python/oss/tests/pytest/unit/agents/test_dtos_capabilities_events.pysdks/python/oss/tests/pytest/unit/agents/test_harness_adapters.pysdks/python/oss/tests/pytest/unit/agents/test_wire_contract.pysdks/python/oss/tests/pytest/unit/test_skill_config_catalog.pyservices/agent/AGENTS.mdservices/agent/src/cli.tsservices/agent/src/engines/pi.tsservices/agent/src/engines/sandbox_agent/run-plan.tsservices/agent/src/protocol.tsservices/agent/src/server.tsservices/agent/src/tools/callback.tsservices/agent/src/tools/dispatch.tsservices/agent/src/tools/mcp-bridge.tsservices/agent/src/version.tsservices/agent/tests/unit/cli.test.tsservices/agent/tests/unit/pi-capability-guard.test.tsservices/agent/tests/unit/pi-provider-env.test.tsservices/agent/tests/unit/sandbox-agent-run-plan.test.tsservices/agent/tests/unit/server.test.tsservices/agent/tests/unit/tool-dispatch.test.tsservices/agent/tests/unit/wire-contract.test.tsservices/oss/src/agent/app.pyservices/oss/src/agent/schemas.pyservices/oss/tests/pytest/unit/agent/test_default_agent_config.pyservices/oss/tests/pytest/unit/agent/test_invoke_handler.pyservices/oss/tests/pytest/unit/agent/test_select_backend.pyweb/oss/src/components/AgentChatSlice/assets/transport.tsweb/packages/agenta-entity-ui/src/DrillInView/SchemaControls/connectionUtils.tsweb/packages/agenta-entity-ui/tests/unit/connectionUtils.test.tsweb/packages/agenta-playground/src/state/execution/agentRequest.tsweb/packages/agenta-playground/tests/unit/agentMode.test.tsweb/packages/agenta-playground/tests/unit/agentRequest.test.ts
💤 Files with no reviewable changes (6)
- services/agent/tests/unit/pi-provider-env.test.ts
- services/agent/tests/unit/pi-capability-guard.test.ts
- sdks/python/oss/tests/pytest/unit/agents/skills/test_skills_e2e.py
- services/agent/src/engines/pi.ts
- sdks/python/oss/tests/pytest/unit/agents/golden/run_request.claude.json
- sdks/python/oss/tests/pytest/unit/agents/connections/test_dtos_model_ref.py
| - **Harness:** which agent runs. Supported values are `pi_core`, `claude`, and experimental | ||
| `pi_agenta`. Default `pi_core`. `pi_core` and `pi_agenta` both drive the `pi` ACP agent; | ||
| `pi_agenta` is Pi with Agenta's forced opinion. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Clarify the pi_agenta description.
“Forced opinion” doesn’t match the contract wording elsewhere and is easy to misread. Use the actual forced skills/prompt/policy description instead.
📝 Suggested fix
- `pi_agenta` is Pi with Agenta's forced opinion.
+ `pi_agenta` is Pi with Agenta's forced skills, prompt, and policy.📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - **Harness:** which agent runs. Supported values are `pi_core`, `claude`, and experimental | |
| `pi_agenta`. Default `pi_core`. `pi_core` and `pi_agenta` both drive the `pi` ACP agent; | |
| `pi_agenta` is Pi with Agenta's forced opinion. | |
| - **Harness:** which agent runs. Supported values are `pi_core`, `claude`, and experimental | |
| `pi_agenta`. Default `pi_core`. `pi_core` and `pi_agenta` both drive the `pi` ACP agent; | |
| `pi_agenta` is Pi with Agenta's forced skills, prompt, and policy. |
| The runner drives one engine, the sandbox-agent ACP path (`engines/sandbox_agent.ts`). The | ||
| `harness` field selects the agent; there is no engine selector on the wire. |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Fix the stale engine-path reference.
engines/sandbox_agent.ts does not match the implementation path used in this stack, so this doc points readers at a dead or misleading location. Please update it to the canonical module path.
♻️ Suggested edit
- The runner drives one engine, the sandbox-agent ACP path (`engines/sandbox_agent.ts`).
+ The runner drives one engine, the sandbox-agent ACP path (`services/agent/src/engines/sandbox_agent/run-plan.ts`).📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| The runner drives one engine, the sandbox-agent ACP path (`engines/sandbox_agent.ts`). The | |
| `harness` field selects the agent; there is no engine selector on the wire. | |
| The runner drives one engine, the sandbox-agent ACP path (`services/agent/src/engines/sandbox_agent/run-plan.ts`). The | |
| `harness` field selects the agent; there is no engine selector on the wire. |
✅ Action performedReview finished.
|
…t URI Implements the contract-versioning POC slice (PR #4829): give the harness a versioned slug + display name in the agent_config interface, and bind the live agent handler to the builtin URI (architecture-followups issue 2). Builds on the harness rename (#4833). Harness slug+name (interface only): one SDK source `HARNESS_IDENTITIES` (agents/dtos.py) maps each HarnessType to a versioned slug `agenta:harness:<value>:v0` (the repo's slug grammar) + a display name. `AgentConfigSchema.harness` now emits both a flat `enum` (back-compat) and a `oneOf` of `{const,title,x-ag-harness-slug}`; the FE EnumSelectControl reads the oneOf for labels and writes the bare const. The stored/wire/ runtime harness value stays the bare string, so the /run wire, golden fixtures, and both wire-contract tests are unchanged. Issue 2 (bind the builtin URI): create_agent_app() registers the instrumented `_agent` (auto_instrument BEFORE register, so tracing survives) and overrides the interface under `agenta:builtin:agent:v0` via a new `register_interface` helper, so retrieve_handler / retrieve_interface return the live handler and the same schemas /inspect advertises. Fixed the stale agent CONFIGURATION_REGISTRY entry to the canonical `{"agent": build_agent_v0_default()}`. Deferred per the POC spec: the /run `version` field, the if/elif version dispatch, and the /health protocol skew read. Tests: SDK 945 (+5 harness-identity), service agent 38 (+4 builtin-uri binding), wire contract Python 20 + TS 160 unchanged, FE entity-ui 23 (+5 EnumSelectControl) + playground 26. Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
|
Addressed CodeRabbit's one substantive finding (commit
Skipped the two doc-wording nitpicks (architecture.md services/agent typecheck + skills/wire-contract tests green. |
Context
The deployed agent service always uses the sandbox-agent backend. The in-process Pi engine (
engines/pi.ts) and thebackendwire field that selected it were dead code. Separately, the harness valuespiandagentawere undescriptive: both drive the Pi agent, but one adds Agenta-forced skills and policy. The names did not communicate that distinction.This is a pre-production contract, so there is no backward-compat burden and no deprecation shim.
Changes
Two coupled contract changes:
engines/pi.ts, thebackendengine selector on the/runwire, and theAGENT_BACKENDplumbing. The runner now drives one engine;harnessselects the agent.pi→pi_core,agenta→pi_agenta(claudeunchanged). Bothpi_coreandpi_agentastill drive the ACP agentpi;pi_agentais Pi with Agenta's forced skills/prompt/policy.Rename map
pipi_coreagentapi_agentaclaudeclaude(unchanged)The
backendwire field is removed. Python symbols/class names (HarnessType.PI,PiAgentConfig,AgentaAgentConfig) are unchanged; only the enum string.valuemoved.Before / after
/runrequest:{"backend": "sandbox-agent", "harness": "pi", ...}→{"harness": "pi_core", ...}(no engine selector).version.ts:ENGINES = ["pi","sandbox-agent"]→["sandbox-agent"];HARNESSES = ["pi","claude","agenta"]→["pi_core","claude","pi_agenta"].run_request.pi.json→run_request.pi_core.json; both goldens dropbackend.Also in this PR
/inspectschema, the catalog field defaults), each hand-edited by this rename. Collapsed to onebuild_agent_v0_default(...)builder in the SDK; the service passes its only extras (the platform skill slug, the sandbox boundary) as named args. New acceptance test pins/inspectdefault == runtime.protocol.tsSandboxPermissioncomment: the network policy is enforced on Daytona; the local sidecar rejects a restricted-network run understrict;filesystemis declared-only.External integrations (Composio / the tool gateway / connections / MCP / Daytona) are unchanged by this PR.
Scope / risk
Python enum
.valuestrings changed. Any caller that constructs a/runbody by hand with"harness": "pi"or"harness": "agenta"will get a validation error from the new runner. The Python SDKHarnessTypeenum values changed, so code that serializes them to strings needs to pick up the new SDK. No database migration; harness values are not persisted.Tests (all green)
tscclean, 25 files / 160 tests.Notes
big-agents.chore/agent-remove-load-session(base of this PR) because it owns the shared docs this PR also edits.agenta(Connection.mode), the ACP agent idpi, andRuntimeAuthContext.backendare different concepts and were not renamed.How to QA
Prerequisites: Local dev stack with the agent sidecar running (SDK +
services/agent/Node runner, orrun.shwith the--devflag). Python SDK installed from the updated branch.Steps:
/runrequest with the old harness value and confirm rejection:/runrequest with the new harness value and confirm acceptance:backendis no longer a valid/runfield by including it:pi_coreandpi_agenta(notpi/agenta).Expected result: Old harness strings fail validation; new strings are accepted. The playground form labels match the new values.
Automated tests:
Edge cases: A stored agent config with
harness: "pi"in the database would fail to apply after this rename. Confirm no migration is needed (the harness value is set at request time from a fresh/inspect, not read back from a stored config blob).https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc