Skip to content

feat(agent): replace sandbox with an optional sidecar uri (allowlist-gated routing)#4836

Closed
mmabrouk wants to merge 2 commits into
big-agentsfrom
docs/sidecar-uri-config
Closed

feat(agent): replace sandbox with an optional sidecar uri (allowlist-gated routing)#4836
mmabrouk wants to merge 2 commits into
big-agentsfrom
docs/sidecar-uri-config

Conversation

@mmabrouk

@mmabrouk mmabrouk commented Jun 24, 2026

Copy link
Copy Markdown
Member

Replaces the per-run sandbox selector on the agent config with an optional sidecar
uri that routes the /run request, gated server-side by an allowlist. Builds on #4840
(config-structure cleanup), which moved the run-selection fields onto AgentConfig.

From PR #4821 review comment 3469613625:
the reviewer asked for an optional uri pointing at the sidecar that the service uses to
route, falling back to env vars when unset. The follow-up decision (D7) was that uri
should replace sandbox outright — the address drives routing, and each sidecar picks
its own sandbox provider (local or Daytona) from its own environment.

What changed

uri replaces sandbox. sandbox is removed from AgentConfig, AgentConfigSchema,
build_agent_v0_default, and the playground control. A new optional uri field is the
sidecar (agent runner) address.

Routing. select_backend now routes by the config's uri. Precedence:

agent_config.uri (validated) → AGENTA_AGENT_RUNNER_URL → local runner CLI

Unset uri (the default) is exactly today's behavior. The sidecar is no longer told which
sandbox to use per run; it reads SANDBOX_AGENT_PROVIDER from its own env.

Security: an allowlist gate, default-off. A caller-supplied address is where the
service ships resolved provider keys and bearer tokens, so it is an SSRF / secret-
exfiltration risk. A uri is honored only when its origin is on
AGENTA_AGENT_RUNNER_URI_ALLOWLIST (comma-separated origins). Default empty means every
override is rejected
— the feature ships off; only the env-var / local path works until an
operator opts in. Matching is on parsed origin (not substring), restricted to http/https.
A disallowed uri fails loud (UnsupportedRunnerUriError), never a silent fallback (which
would let a caller probe the allowlist or mask a misconfiguration).

Playground. No uri control is surfaced — it is an operator/testing routing override,
not a normal authoring field. The sandbox selector is removed from the form.

The wire (golden unchanged)

uri is not a /run wire field: it is consumed entirely service-side in
select_backend, so the golden fixtures are untouched. The /run wire still carries a
constant sandbox: "local" the unchanged runner defaults correctly on.

Deferred (runner-branch follow-up): removing the wire-level sandbox field would force
a protocol.ts / golden / runner change, which lives on a separate stack branch
(services/agent/**). This PR keeps the golden unchanged and leaves that removal to the
runner branch, per POC scope.

Files

  • SDK: agents/dtos.py (remove sandbox, add uri, _clean_uri), utils/types.py
    (AgentConfigSchema + build_agent_v0_default).
  • Service: agent/config.py (AGENTA_AGENT_RUNNER_URI_ALLOWLIST, validate_runner_uri,
    resolve_runner_url, UnsupportedRunnerUriError), agent/app.py (select_backend routes
    by uri).
  • FE: AgentConfigControl.tsx (drop sandbox selector), agentRequest.ts / selectors.ts
    (drop the sandbox default + heuristic arm).
  • Tests: SDK test_dtos_agent_config.py; service test_select_backend.py (full allowlist +
    precedence matrix), test_default_agent_config.py; FE agentMode.test.ts,
    agentRequest.test.ts. Wire-contract golden untouched.
  • Docs: agent-config-schema.md, agent-service-handler.md, service-to-agent-runner.md,
    running-the-agent.md (new env var), and the sidecar-uri-config project (DESIGN →
    IMPLEMENTED).

Tests

  • SDK agents: 344 passed.
  • Service agent: 45 passed (includes the new allowlist/precedence matrix).
  • FE playground: 121 passed; entity-ui + playground typecheck/build green.
  • ruff format + check clean; prettier + eslint clean on changed source.

https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc

@dosubot dosubot Bot added the size:XL This PR changes 500-999 lines, ignoring generated files. label Jun 24, 2026
@vercel

vercel Bot commented Jun 24, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jun 25, 2026 11:38am

Request Review

@dosubot dosubot Bot added the documentation Improvements or additions to documentation label Jun 24, 2026
@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e3c71cf-2e77-499d-a007-3ef7904e89e6

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds an optional uri sidecar routing field to agent configuration, updates backend resolution to validate and honor it before environment-variable fallback, and removes the old sandbox selector from docs, service wiring, UI, and playground defaults.

Changes

Sidecar URI routing change

Layer / File(s) Summary
Design and interface docs
docs/design/agent-workflows/projects/sidecar-uri-config/*, docs/design/agent-workflows/interfaces/*, docs/design/agent-workflows/documentation/running-the-agent.md
Adds and updates design and interface documentation for the uri routing field, backend precedence, wire behavior, and the allowlist security model.
SDK and service routing
sdks/python/agenta/sdk/*, services/oss/src/agent/*, services/oss/tests/pytest/unit/agent/*, sdks/python/oss/tests/pytest/unit/agents/*
Replaces sandbox selection with uri in the SDK model, parses the new field, and routes service backend selection through the validated runner URL resolver.
UI, playground, and tests
web/packages/agenta-entity-ui/*, web/packages/agenta-playground/*
Removes the sandbox selector from the agent UI and playground defaults, updates agent-mode detection, and adjusts unit tests for the new uri-based run selection.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 38.46% which is insufficient. The required threshold is 60.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: replacing sandbox with an optional sidecar URI and allowlist-gated routing.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the routing, security, UI, and wire-contract changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/sidecar-uri-config

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

harness: str = "pi_core"
sandbox: str = "local"
permission_policy: PermissionPolicy = "auto"
uri: Optional[str] = None # sidecar (runner) address; unset → env-var fallback

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the uri should take the place of thr sandbox and the sandbox should be removed, as I always tell you we are still in the POC stage. We don't care about packward compatibikitz.

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 1ab3d478-bc89-4c56-8651-689403cdfcec

📥 Commits

Reviewing files that changed from the base of the PR and between 9cbcbfd and 0f411b3.

📒 Files selected for processing (6)
  • docs/design/agent-workflows/projects/sidecar-uri-config/README.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/context.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/plan.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/research.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/security.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/status.md

Comment thread docs/design/agent-workflows/projects/sidecar-uri-config/security.md
Comment thread docs/design/agent-workflows/projects/sidecar-uri-config/security.md
@mmabrouk mmabrouk force-pushed the docs/sidecar-uri-config branch from 0f411b3 to 6ac6712 Compare June 24, 2026 23:11
@dosubot dosubot Bot added size:XXL This PR changes 1000+ lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Jun 24, 2026
@mmabrouk mmabrouk changed the base branch from big-agents to feat/agent-config-structure-cleanup June 24, 2026 23:12
@dosubot dosubot Bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:XXL This PR changes 1000+ lines, ignoring generated files. labels Jun 24, 2026
@mmabrouk mmabrouk changed the title docs(agent): plan optional sidecar uri in the agent config feat(agent): replace sandbox with an optional sidecar uri (allowlist-gated routing) Jun 24, 2026
@mmabrouk

Copy link
Copy Markdown
Member Author

Reused this design PR for the implementation (per queue-implement-feature). Changes mapped to scope:

uri replaces sandbox (D7). Removed sandbox from AgentConfig (dtos.py), AgentConfigSchema + build_agent_v0_default (utils/types.py), and the playground control. Added optional uri (the sidecar address) parsed by _parse_run_selection (_clean_uri: trim-or-None, not case-folded).

Routing. select_backend (services/oss/src/agent/app.py) routes by resolve_runner_url(agent_config.uri): precedence uri (validated) → AGENTA_AGENT_RUNNER_URL → local CLI. Unset uri = today's behavior.

Allowlist gate, default-off (security). New AGENTA_AGENT_RUNNER_URI_ALLOWLIST + validate_runner_uri + UnsupportedRunnerUriError in services/oss/src/agent/config.py. Default empty = every uri rejected (feature off). Origin match (not substring), http/https only, fail loud (no silent fallback).

Wire decision. uri is NOT a /run wire field (consumed service-side) — golden fixtures UNCHANGED. The wire still carries a constant sandbox: "local" the unchanged runner defaults on. Removing the wire-level sandbox field is a deferred runner-branch follow-up (would force protocol.ts/golden/runner changes; out of scope for this config/service/FE slice).

FE. Dropped the sandbox EnumSelectControl; removed the sandbox default in agentRequest.ts and the dead sandbox arm of the agent-mode heuristic in selectors.ts. No uri control surfaced (operator/testing concern).

Docs. agent-config-schema.md, agent-service-handler.md, service-to-agent-runner.md, running-the-agent.md (new env var), sidecar-uri-config project (DESIGN → IMPLEMENTED).

Tests: SDK agents 344, service agent 45 (incl. full allowlist/precedence matrix), FE playground 121; ruff/prettier/eslint clean; golden untouched.

Base set to #4840 (config-structure cleanup) so the diff is isolated. Not merged to big-agents.

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jun 24, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@github-actions

github-actions Bot commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Image tag pr-4836-e38865b
Status Failed
Logs View workflow run
Updated at 2026-06-25T12:18:19.433Z

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
services/oss/tests/pytest/unit/agent/test_default_agent_config.py (1)

42-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert raw uri omission, not just parsed None.

These tests prove the defaults parse as uri=None, but they do not lock the stronger contract this PR describes: the shipped default config omits the uri key entirely. If a later change starts emitting "uri": null, the current assertions still pass while the /inspect payload shape changes. Please add absence checks for both inspect_default and builtin_default.

Also applies to: 64-79


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0bf62cb2-d3f0-4f4e-9fa5-7dc11df4a2a9

📥 Commits

Reviewing files that changed from the base of the PR and between 0f411b3 and 6ac6712.

📒 Files selected for processing (22)
  • docs/design/agent-workflows/documentation/running-the-agent.md
  • docs/design/agent-workflows/interfaces/cross-service/service-to-agent-runner.md
  • docs/design/agent-workflows/interfaces/in-service/agent-service-handler.md
  • docs/design/agent-workflows/interfaces/public-edge/agent-config-schema.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/README.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/context.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/plan.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/research.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/security.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/status.md
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/agenta/sdk/utils/types.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_agent_config.py
  • services/oss/src/agent/app.py
  • services/oss/src/agent/config.py
  • services/oss/tests/pytest/unit/agent/test_default_agent_config.py
  • services/oss/tests/pytest/unit/agent/test_select_backend.py
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/AgentConfigControl.tsx
  • web/packages/agenta-playground/src/state/execution/agentRequest.ts
  • web/packages/agenta-playground/src/state/execution/selectors.ts
  • web/packages/agenta-playground/tests/unit/agentMode.test.ts
  • web/packages/agenta-playground/tests/unit/agentRequest.test.ts
✅ Files skipped from review due to trivial changes (6)
  • docs/design/agent-workflows/projects/sidecar-uri-config/context.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/status.md
  • docs/design/agent-workflows/documentation/running-the-agent.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/README.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/research.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/plan.md

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Inline review comments failed to post. This is likely due to GitHub's internal server error or limits when posting large numbers of comments. If you are seeing this consistently it is likely a permissions issue. Please check "Moderation" -> "Code review limits" under your organization settings.

Actionable comments posted: 5

🧹 Nitpick comments (1)
services/oss/tests/pytest/unit/agent/test_default_agent_config.py (1)

42-61: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert raw uri omission, not just parsed None.

These tests prove the defaults parse as uri=None, but they do not lock the stronger contract this PR describes: the shipped default config omits the uri key entirely. If a later change starts emitting "uri": null, the current assertions still pass while the /inspect payload shape changes. Please add absence checks for both inspect_default and builtin_default.

Also applies to: 64-79


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 0bf62cb2-d3f0-4f4e-9fa5-7dc11df4a2a9

📥 Commits

Reviewing files that changed from the base of the PR and between 0f411b3 and 6ac6712.

📒 Files selected for processing (22)
  • docs/design/agent-workflows/documentation/running-the-agent.md
  • docs/design/agent-workflows/interfaces/cross-service/service-to-agent-runner.md
  • docs/design/agent-workflows/interfaces/in-service/agent-service-handler.md
  • docs/design/agent-workflows/interfaces/public-edge/agent-config-schema.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/README.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/context.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/plan.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/research.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/security.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/status.md
  • sdks/python/agenta/sdk/agents/dtos.py
  • sdks/python/agenta/sdk/utils/types.py
  • sdks/python/oss/tests/pytest/unit/agents/test_dtos_agent_config.py
  • services/oss/src/agent/app.py
  • services/oss/src/agent/config.py
  • services/oss/tests/pytest/unit/agent/test_default_agent_config.py
  • services/oss/tests/pytest/unit/agent/test_select_backend.py
  • web/packages/agenta-entity-ui/src/DrillInView/SchemaControls/AgentConfigControl.tsx
  • web/packages/agenta-playground/src/state/execution/agentRequest.ts
  • web/packages/agenta-playground/src/state/execution/selectors.ts
  • web/packages/agenta-playground/tests/unit/agentMode.test.ts
  • web/packages/agenta-playground/tests/unit/agentRequest.test.ts
✅ Files skipped from review due to trivial changes (6)
  • docs/design/agent-workflows/projects/sidecar-uri-config/context.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/status.md
  • docs/design/agent-workflows/documentation/running-the-agent.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/README.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/research.md
  • docs/design/agent-workflows/projects/sidecar-uri-config/plan.md
🛑 Comments failed to post (5)
docs/design/agent-workflows/interfaces/public-edge/agent-config-schema.md (1)

20-30: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Separate schema defaults from service-prefilled defaults in this table.

The Default column currently mixes AgentConfigSchema defaults with /inspect-time service extras. In particular, skills reads as though the schema itself defaults to one embedded skill, but the model default is [] and that skill is added only by the service-side build_agent_v0_default(skill_slug=...). Clarifying that split here would keep the public contract page aligned with the actual schema/default builder behavior.

sdks/python/agenta/sdk/agents/dtos.py (1)

960-963: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Honor an explicit null URI instead of falling back to defaults.

source.get("uri") makes “field omitted” and "uri": null indistinguishable here. If defaults.uri is set, a caller cannot clear that override: {agent: {uri: null}} still resolves to the default sidecar instead of the env/local fallback, which breaks the nullable uri contract.

Suggested fix
-    raw_uri = source.get("uri")
-    uri = _clean_uri(raw_uri) if raw_uri is not None else defaults.uri
+    if "uri" in source:
+        uri = _clean_uri(source.get("uri"))
+    else:
+        uri = defaults.uri
📝 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 = str(source.get("harness") or defaults.harness).lower()
    if "uri" in source:
        uri = _clean_uri(source.get("uri"))
    else:
        uri = defaults.uri
    permission_policy = str(
services/oss/src/agent/config.py (1)

103-111: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Treat blank uri overrides as unset.

A whitespace-only override currently goes down the rejection path because Line 110 checks truthiness before trimming. That makes an optional field fail loud instead of taking the documented env/local fallback.

Proposed fix
 def resolve_runner_url(override: Optional[str]) -> Optional[str]:
@@
-    if override:
+    if override and override.strip():
         return validate_runner_uri(override)
     return runner_url()
📝 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.

def resolve_runner_url(override: Optional[str]) -> Optional[str]:
    """Routing precedence: a validated request override, else the env var, else ``None``.

    ``override`` (the agent config's ``uri``) wins when set and allowlisted; a rejected override
    raises (``UnsupportedRunnerUriError``) rather than falling back. When ``override`` is unset
    this is exactly today's behavior: ``AGENTA_AGENT_RUNNER_URL`` if set, else ``None`` (the
    local runner CLI in ``AGENTA_AGENT_RUNNER_DIR``)."""
    if override and override.strip():
        return validate_runner_uri(override)
web/packages/agenta-playground/src/state/execution/agentRequest.ts (1)

177-193: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Strip hidden uri overrides before sending playground runs.

The playground no longer surfaces uri, but this helper still forwards any existing agent.uri/flat uri unchanged. Since the service now gives that field highest routing precedence, imported or previously saved configs can keep targeting a sidecar the author cannot see or clear.

Proposed fix
 const withAgentRunDefaults = (config: Record<string, unknown>): Record<string, unknown> => {
     const agent = config.agent
     if (agent && typeof agent === "object") {
+        const {uri: _uri, ...agentConfig} = agent as Record<string, unknown>
         return {
             ...config,
-            agent: {harness: "pi_core", ...(agent as Record<string, unknown>)},
+            agent: {harness: "pi_core", ...agentConfig},
         }
     }
-    return {harness: "pi_core", ...config}
+    const {uri: _uri, ...flatConfig} = config
+    return {harness: "pi_core", ...flatConfig}
 }
📝 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.

/**
 * Default the agent run-selection field `harness` onto the AGENT CONFIG (`parameters.agent`),
 * not as a top-level params sibling. It is part of one `AgentConfig` now, so it belongs inside
 * the `agent` block. A value the resolved config already carries always wins; the schema nests
 * the config under `agent`, but a flat config (no `agent` key) is still defaulted at the top
 * level so a non-schema config keeps working. The sidecar `uri` is left unset (the server's
 * env-var routing fallback); it is an operator override, not a per-run default.
 */
const withAgentRunDefaults = (config: Record<string, unknown>): Record<string, unknown> => {
    const agent = config.agent
    if (agent && typeof agent === "object") {
        const {uri: _uri, ...agentConfig} = agent as Record<string, unknown>
        return {
            ...config,
            agent: {harness: "pi_core", ...agentConfig},
        }
    }
    const {uri: _uri, ...flatConfig} = config
    return {harness: "pi_core", ...flatConfig}
}
web/packages/agenta-playground/src/state/execution/selectors.ts (1)

1288-1294: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Legacy agent-mode fallback misses the nested agent.harness shape.

This PR now defaults harness inside the agent block, but the last-resort heuristic still only checks config.harness. When workflowType and the schema marker are both unavailable, nested agent configs will still be classified as non-agent.

Proposed fix
         const config = get(workflowMolecule.selectors.configuration(entityId)) as
             | Record<string, unknown>
             | null
             | undefined
-        return Boolean(config?.harness)
+        const agent =
+            config?.agent && typeof config.agent === "object"
+                ? (config.agent as Record<string, unknown>)
+                : null
+        const agentConfig =
+            config?.agent_config && typeof config.agent_config === "object"
+                ? (config.agent_config as Record<string, unknown>)
+                : null
+        return Boolean(config?.harness ?? agent?.harness ?? agentConfig?.harness)
     }),
 )
📝 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.

        // Legacy heuristic — a stored config carrying top-level harness.
        // Kept as a last resort; delete once WP-6 is the sole source of truth.
        const config = get(workflowMolecule.selectors.configuration(entityId)) as
            | Record<string, unknown>
            | null
            | undefined
        const agent =
            config?.agent && typeof config.agent === "object"
                ? (config.agent as Record<string, unknown>)
                : null
        const agentConfig =
            config?.agent_config && typeof config.agent_config === "object"
                ? (config.agent_config as Record<string, unknown>)
                : null
        return Boolean(config?.harness ?? agent?.harness ?? agentConfig?.harness)

@mmabrouk

Copy link
Copy Markdown
Member Author

CodeRabbit's review found no substantive code change for this PR. The 2 inline comments are both on the security.md design doc (SSRF-via-DNS-rebinding and loopback policy) — design-review prompts on an explicitly-open security design, not code defects. The implemented allowlist gate is default-OFF (opt-in), matches origin exactly, and restricts scheme to http/https; DNS-rebinding hardening is captured as a deferred open question. No commit needed on this lane (it was restacked onto the upstream fixes and force-pushed).

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, one thing I think that was not very well communicated: the URI should not only be a URL. The URI should be an identifier that allows it to see both, in our case:

  • the URL for the sandbox, which is a Docker container or whatever
  • which sandbox it's using, basically local or Daytona
    Basically, the front end would show local and Daytona as options, especially right now in development. It will then build the URI that would include local and Daytona. In this case, it's totally right for the front end to hardcode the URL part. We don't need to send it to the front end for the moment. This is just for development.
    In reality, this whole URI would be an environment variable. The idea is that that environment variable would include both the sandbox URL and which mode it uses. Obviously, from this URI, the service from this sidecar can be used. When you talk to the site, can you use a run.sh to provide this? I'd say yes, why not? It looks not the best solution, but it's an okay solution.

mmabrouk added 2 commits June 25, 2026 12:56
Design workspace for an optional `uri` on the agent run config that names the
sidecar (agent runner) address. When set, the service routes `/run` there; when
unset, it falls back to AGENTA_AGENT_RUNNER_URL / the local runner. Spun out of
PR #4821 review comment 3469613625. Design only, no code.

Key decisions: `uri` is a RunSelection field (where a run goes, like `sandbox`),
not the neutral AgentConfig, and not a `/run` wire field (consumed service-side
in select_backend; golden fixtures untouched). A caller-supplied address is
gated by a server-side allowlist, default-off, because the service ships
resolved secrets + bearer tokens to whatever URL it picks.

Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
Replace the per-run sandbox selector with an optional sidecar uri that routes
the /run request, gated server-side by an allowlist (default empty = off).

Claude-Session: https://claude.ai/code/session_01GYo3UEfvsZpncagqb28Mbc
@mmabrouk mmabrouk force-pushed the feat/agent-config-structure-cleanup branch from cec8c43 to 3f051c8 Compare June 25, 2026 11:36
@mmabrouk mmabrouk force-pushed the docs/sidecar-uri-config branch from f444322 to 66ef5ba Compare June 25, 2026 11:36
@mmabrouk mmabrouk changed the base branch from feat/agent-config-structure-cleanup to big-agents June 25, 2026 18:28
@mmabrouk

Copy link
Copy Markdown
Member Author

Closing per JP (CTO): the sidecar-URI approach is not the right direction. The sandbox (local/daytona) interface stays as-is; the playground builds any composite identifier it needs on top, rather than exposing a user-facing uri field. Superseded — not merging this approach.

@mmabrouk mmabrouk closed this Jun 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size:XL This PR changes 500-999 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant