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
94 changes: 85 additions & 9 deletions api/oss/src/utils/env.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import os
import hashlib
import warnings
from typing import List, Optional
from uuid import getnode
from json import loads
from urllib.parse import urlparse, quote_plus

from pydantic import BaseModel, ConfigDict, model_validator
from pydantic import BaseModel, ConfigDict, Field, model_validator


_TRUTHY = {"true", "1", "t", "y", "yes", "on", "enable", "enabled"}
Expand Down Expand Up @@ -969,28 +970,103 @@ def enabled(self) -> bool:

_SANDBOX_LOCAL_WARNED = False

# Sandbox providers this runner can provision. Kept in lockstep with the runner's
# KNOWN_SANDBOX_PROVIDER_IDS and the SDK's KNOWN_SANDBOX_PROVIDERS so all three readers agree.
_KNOWN_SANDBOX_PROVIDERS = ("local", "daytona")


def _parse_enabled_sandbox_providers(raw: Optional[str]) -> List[str]:
"""Parse ``AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS`` with the runner's rules.

Unset -> ``["local"]``; explicit empty invalid; ids normalized lowercase; unknown and
duplicate ids invalid. Reimplements the TypeScript runner parser so the API's provider
pre-filter matches the runner's final authority (runner-selfhosting-cleanup/interface.md
sections 2 and 4).
"""
if raw is None:
return ["local"]
trimmed = raw.strip()
if trimmed == "":
raise ValueError(
"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS is set but empty; unset it for the "
"default 'local', or list at least one provider."
)
ids = [part.strip().lower() for part in trimmed.split(",")]
seen: set = set()
for provider_id in ids:
if provider_id == "":
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS has an empty entry in '{trimmed}'."
)
if provider_id not in _KNOWN_SANDBOX_PROVIDERS:
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists unknown provider "
f"'{provider_id}'; known: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
)
if provider_id in seen:
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists provider '{provider_id}' "
f"more than once."
)
seen.add(provider_id)
return ids


def _parse_default_sandbox_provider(raw: Optional[str], enabled: List[str]) -> str:
"""Parse ``AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER``; unset -> ``local``; must be enabled."""
value = (raw or "").strip().lower() or "local"
if value not in _KNOWN_SANDBOX_PROVIDERS:
raise ValueError(
f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER is unknown provider '{value}'; "
f"known: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
)
if value not in enabled:
raise ValueError(
f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER '{value}' is not in the enabled set "
f"[{', '.join(enabled)}]."
)
return value
Comment on lines +1001 to +1028

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Error text has drifted from the SDK/runner's "in-lockstep" implementations.

The docstring above (lines 981-984) states this reimplements the runner's parser "so all three readers agree," but two messages have drifted from the SDK's sandbox_providers.py and the runner's runner-config.ts (both in this cohort/context): the unknown-provider message says "known:" here vs. "known providers:" there, and the default-not-in-enabled-set message here drops the "Add it to AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS or change the default." remediation sentence present in both other implementations. Operators debugging via the API get a less actionable error than via the runner.

🐛 Proposed fix to re-sync message text
         if provider_id not in _KNOWN_SANDBOX_PROVIDERS:
             raise ValueError(
                 f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists unknown provider "
-                f"'{provider_id}'; known: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
+                f"'{provider_id}'; known providers: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
             )
     if value not in enabled:
         raise ValueError(
             f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER '{value}' is not in the enabled set "
-            f"[{', '.join(enabled)}]."
+            f"[{', '.join(enabled)}]. Add it to AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS "
+            f"or change the default."
         )
📝 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.

Suggested change
if provider_id not in _KNOWN_SANDBOX_PROVIDERS:
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists unknown provider "
f"'{provider_id}'; known: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
)
if provider_id in seen:
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists provider '{provider_id}' "
f"more than once."
)
seen.add(provider_id)
return ids
def _parse_default_sandbox_provider(raw: Optional[str], enabled: List[str]) -> str:
"""Parse ``AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER``; unset -> ``local``; must be enabled."""
value = (raw or "").strip().lower() or "local"
if value not in _KNOWN_SANDBOX_PROVIDERS:
raise ValueError(
f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER is unknown provider '{value}'; "
f"known: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
)
if value not in enabled:
raise ValueError(
f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER '{value}' is not in the enabled set "
f"[{', '.join(enabled)}]."
)
return value
if provider_id not in _KNOWN_SANDBOX_PROVIDERS:
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists unknown provider "
f"'{provider_id}'; known providers: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
)
if provider_id in seen:
raise ValueError(
f"AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS lists provider '{provider_id}' "
f"more than once."
)
seen.add(provider_id)
return ids
def _parse_default_sandbox_provider(raw: Optional[str], enabled: List[str]) -> str:
"""Parse ``AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER``; unset -> ``local``; must be enabled."""
value = (raw or "").strip().lower() or "local"
if value not in _KNOWN_SANDBOX_PROVIDERS:
raise ValueError(
f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER is unknown provider '{value}'; "
f"known providers: {', '.join(_KNOWN_SANDBOX_PROVIDERS)}."
)
if value not in enabled:
raise ValueError(
f"AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER '{value}' is not in the enabled set "
f"[{', '.join(enabled)}]. Add it to AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS "
f"or change the default."
)
return value



def _enabled_sandbox_providers_default() -> List[str]:
return _parse_enabled_sandbox_providers(
os.getenv("AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS")
)


def _default_sandbox_provider_default() -> str:
return _parse_default_sandbox_provider(
os.getenv("AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER"),
_enabled_sandbox_providers_default(),
)


class RunnerConfig(BaseModel):
"""Agent runner (services/runner) sidecar configuration."""

concurrency_limit: int = int(os.getenv("AGENTA_RUNNER_CONCURRENCY_LIMIT") or "1000")

# `local` sandbox runs unconfined host bash — not a tenant boundary; on by default
# for zero-config self-host. Canonical declaration; services/oss reads the same var directly.
sandbox_local_allowed: bool = (
os.getenv("AGENTA_SANDBOX_LOCAL_ALLOWED") or "true"
).lower() in _TRUTHY
# The sandbox-provider registry the runner and API share. `local` is unconfined host bash —
# not a tenant boundary; enabled by default for zero-config self-host. Canonical declaration;
# services/oss and the SDK read the same variables directly with the same rules.
enabled_sandbox_providers: List[str] = Field(
default_factory=_enabled_sandbox_providers_default
)
default_sandbox_provider: str = Field(
default_factory=_default_sandbox_provider_default
)

model_config = ConfigDict(extra="ignore")

@model_validator(mode="after")
def _warn_local_sandbox(self) -> "RunnerConfig":
global _SANDBOX_LOCAL_WARNED
if self.sandbox_local_allowed and not _SANDBOX_LOCAL_WARNED:
if "local" in self.enabled_sandbox_providers and not _SANDBOX_LOCAL_WARNED:
_SANDBOX_LOCAL_WARNED = True
warnings.warn(
"AGENTA_SANDBOX_LOCAL_ALLOWED is on (default): local sandbox is not a "
"tenant boundary. Set it to false to harden a shared/multi-tenant deployment.",
"local sandbox is enabled (default): it is unconfined host bash, not a "
"tenant boundary. Set AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS=daytona to "
"harden a shared/multi-tenant deployment.",
stacklevel=2,
)
return self
Comment on lines +1052 to 1072

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Show the relevant section with line numbers and nearby context.
sed -n '980,1125p' api/oss/src/utils/env.py

# Find parseRunnerConfig and related helpers in the same file.
rg -n "parseRunnerConfig|_enabled_sandbox_providers_default|_default_sandbox_provider_default|RunnerConfig|field_validator|model_validator" api/oss/src/utils/env.py

Repository: Agenta-AI/agenta

Length of output: 7137


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== env.py relevant excerpt =="
sed -n '980,1125p' api/oss/src/utils/env.py

echo
echo "== search for RunnerConfig usages =="
rg -n "RunnerConfig\(" -S .

echo
echo "== search for parseRunnerConfig definition/usages =="
rg -n "parseRunnerConfig" -S api/oss/src/utils/env.py .

Repository: Agenta-AI/agenta

Length of output: 9305


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from typing import List, Optional
from pydantic import BaseModel, Field, model_validator

KNOWN = {"local", "daytona"}

def parse_enabled(raw: Optional[str]) -> List[str]:
    if raw is None:
        return ["local"]
    return [x.strip().lower() for x in raw.split(",")]

def parse_default(raw: Optional[str], enabled: List[str]) -> str:
    value = (raw or "").strip().lower() or "local"
    if value not in enabled:
        raise ValueError(f"{value} not enabled")
    return value

def enabled_default() -> List[str]:
    return parse_enabled(None)

def default_default() -> str:
    return parse_default(None, enabled_default())

class M(BaseModel):
    enabled_sandbox_providers: List[str] = Field(default_factory=enabled_default)
    default_sandbox_provider: str = Field(default_factory=default_default)

    `@model_validator`(mode="after")
    def warn(self):
        return self

print("M() ->", M())
print("M(enabled_sandbox_providers=['daytona'], default_sandbox_provider='daytona') ->",
      M(enabled_sandbox_providers=['daytona'], default_sandbox_provider='daytona'))
try:
    print(M(enabled_sandbox_providers=['not-a-real-provider'], default_sandbox_provider='local'))
except Exception as e:
    print(type(e).__name__, e)
try:
    print(M(enabled_sandbox_providers=['daytona'], default_sandbox_provider='local'))
except Exception as e:
    print(type(e).__name__, e)
PY

Repository: Agenta-AI/agenta

Length of output: 537


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from typing import List, Optional
from pydantic import BaseModel, Field, model_validator

def parse_enabled(raw: Optional[str]) -> List[str]:
    if raw is None:
        return ["local"]
    return [x.strip().lower() for x in raw.split(",")]

def parse_default(raw: Optional[str], enabled: List[str]) -> str:
    value = (raw or "").strip().lower() or "local"
    if value not in enabled:
        raise ValueError(f"{value} not enabled")
    return value

def enabled_default() -> List[str]:
    return parse_enabled(None)

def default_default() -> str:
    return parse_default(None, enabled_default())

class M(BaseModel):
    enabled_sandbox_providers: List[str] = Field(default_factory=enabled_default)
    default_sandbox_provider: str = Field(default_factory=default_default)

    `@model_validator`(mode="after")
    def warn(self):
        return self

print("M() ->", M())
print("M(enabled_sandbox_providers=['daytona'], default_sandbox_provider='daytona') ->",
      M(enabled_sandbox_providers=['daytona'], default_sandbox_provider='daytona'))
for kwargs in [
    dict(enabled_sandbox_providers=['not-a-real-provider'], default_sandbox_provider='local'),
    dict(enabled_sandbox_providers=['daytona'], default_sandbox_provider='local'),
]:
    try:
        print("TRY", kwargs, "=>", M(**kwargs))
    except Exception as e:
        print("ERR", kwargs, "=>", type(e).__name__, e)
PY

Repository: Agenta-AI/agenta

Length of output: 723


Move the sandbox-provider checks onto the model itself RunnerConfig(enabled_sandbox_providers=...) currently accepts invalid values because the parsing/consistency logic only runs through default_factory. Put the provider parsing and the enabled/default subset check in a field_validator or model_validator(mode="after") so the invariant holds for every construction path.

Expand Down
111 changes: 72 additions & 39 deletions api/oss/tests/pytest/unit/utils/test_env_runner_config.py
Original file line number Diff line number Diff line change
@@ -1,60 +1,93 @@
"""Unit tests for `RunnerConfig.sandbox_local_allowed` (api/oss/src/utils/env.py).
"""Unit tests for the API-side sandbox-provider registry parser (api/oss/src/utils/env.py).

Declarative config only: the value is a class-level default evaluated at import time
(same pattern as `WebhooksConfig.allow_insecure`), so tests reload the module after
setting/clearing the env var. See test_webhooks_utils.py for the precedent this mirrors.
The actual runtime gate lives in services/oss/src/agent/app.py (this env var's canonical
declaration only, not a second live enforcement point in the api service).
The API reimplements the runner's `AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS` /
`AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER` parsing so its provider pre-filter matches the
runner's final authority. These cases mirror the runner's TypeScript parser tests
(runner-selfhosting-cleanup/qa.md section 2) so both readers agree on every input.
"""

import importlib

import pytest

from oss.src.utils import env

def test_sandbox_local_allowed_defaults_true(monkeypatch):
monkeypatch.delenv("AGENTA_SANDBOX_LOCAL_ALLOWED", raising=False)
from oss.src.utils import env

importlib.reload(env)
assert env.RunnerConfig().sandbox_local_allowed is True
# --- Parser rules (pure functions, no env) -------------------------------------- #


@pytest.mark.parametrize("value", ["true", "1", "yes", "on"])
def test_sandbox_local_allowed_true_values(monkeypatch, value):
from oss.src.utils import env
def test_enabled_unset_gives_local():
assert env._parse_enabled_sandbox_providers(None) == ["local"]

monkeypatch.setenv("AGENTA_SANDBOX_LOCAL_ALLOWED", value)
try:
importlib.reload(env)
assert env.RunnerConfig().sandbox_local_allowed is True
finally:
monkeypatch.delenv("AGENTA_SANDBOX_LOCAL_ALLOWED", raising=False)
importlib.reload(env)

def test_enabled_explicit_pair_is_set_equal_order_independent():
a = env._parse_enabled_sandbox_providers("local,daytona")
b = env._parse_enabled_sandbox_providers("daytona,local")
assert sorted(a) == sorted(b) == ["daytona", "local"]

@pytest.mark.parametrize("value", ["false", "0", "no", "off"])
def test_sandbox_local_allowed_false_values(monkeypatch, value):
from oss.src.utils import env

monkeypatch.setenv("AGENTA_SANDBOX_LOCAL_ALLOWED", value)
try:
importlib.reload(env)
assert env.RunnerConfig().sandbox_local_allowed is False
finally:
monkeypatch.delenv("AGENTA_SANDBOX_LOCAL_ALLOWED", raising=False)
importlib.reload(env)
def test_enabled_normalizes_whitespace_and_case():
assert env._parse_enabled_sandbox_providers(" LOCAL , Daytona ") == [
"local",
"daytona",
]


def test_sandbox_local_allowed_true_when_unset_after_reload(monkeypatch):
from oss.src.utils import env
@pytest.mark.parametrize("raw", ["", " "])
def test_enabled_explicit_empty_fails(raw):
with pytest.raises(ValueError):
env._parse_enabled_sandbox_providers(raw)

monkeypatch.delenv("AGENTA_SANDBOX_LOCAL_ALLOWED", raising=False)
try:
importlib.reload(env)
assert env.RunnerConfig().sandbox_local_allowed is True
finally:
importlib.reload(env)

def test_enabled_duplicate_fails():
with pytest.raises(ValueError):
env._parse_enabled_sandbox_providers("local,local")


def test_enabled_unknown_fails():
with pytest.raises(ValueError):
env._parse_enabled_sandbox_providers("local,e2b")


def test_default_unset_gives_local():
assert env._parse_default_sandbox_provider(None, ["local"]) == "local"


def test_default_outside_enabled_fails():
with pytest.raises(ValueError):
env._parse_default_sandbox_provider("local", ["daytona"])


def test_default_honors_explicit_enabled_value():
assert (
env._parse_default_sandbox_provider("daytona", ["local", "daytona"])
== "daytona"
)


# --- RunnerConfig integration (default_factory reads the environment) ----------- #


def test_runner_config_defaults_local_when_unset(monkeypatch):
monkeypatch.delenv("AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS", raising=False)
monkeypatch.delenv("AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER", raising=False)
config = env.RunnerConfig()
assert config.enabled_sandbox_providers == ["local"]
assert config.default_sandbox_provider == "local"


def test_runner_config_reads_enabled_pair(monkeypatch):
monkeypatch.setenv("AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS", "local,daytona")
monkeypatch.setenv("AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER", "daytona")
config = env.RunnerConfig()
assert config.enabled_sandbox_providers == ["local", "daytona"]
assert config.default_sandbox_provider == "daytona"


def test_runner_config_rejects_invalid_enabled(monkeypatch):
monkeypatch.setenv("AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS", "local,e2b")
with pytest.raises(Exception):
env.RunnerConfig()


def test_sandbox_runner_defaults_local_when_unset(monkeypatch):
Expand Down
19 changes: 9 additions & 10 deletions hosting/docker-compose/ee/docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -407,18 +407,17 @@ services:
# OTLP tracing-export fallback AND the session heartbeat/record-persist calls.
AGENTA_API_INTERNAL_URL: ${AGENTA_API_INTERNAL_URL:-http://api:8000}
AGENTA_API_KEY: ${AGENTA_API_KEY:-}
SANDBOX_AGENT_PROVIDER: ${SANDBOX_AGENT_PROVIDER:-local}
DAYTONA_API_KEY: ${DAYTONA_API_KEY:-}
DAYTONA_API_URL: ${DAYTONA_API_URL:-}
DAYTONA_TARGET: ${DAYTONA_TARGET:-}
DAYTONA_SNAPSHOT: ${DAYTONA_SNAPSHOT:-agenta-sandbox-pi}
DAYTONA_SNAPSHOT_AGENT: ${DAYTONA_SNAPSHOT_AGENT:-}
DAYTONA_IMAGE: ${DAYTONA_IMAGE:-}
DAYTONA_AUTOSTOP: ${DAYTONA_AUTOSTOP:-}
AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS: ${AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS:-local}
AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER: ${AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER:-local}
AGENTA_RUNNER_DAYTONA_API_KEY: ${AGENTA_RUNNER_DAYTONA_API_KEY:-}
AGENTA_RUNNER_DAYTONA_API_URL: ${AGENTA_RUNNER_DAYTONA_API_URL:-}
AGENTA_RUNNER_DAYTONA_TARGET: ${AGENTA_RUNNER_DAYTONA_TARGET:-}
AGENTA_RUNNER_DAYTONA_SNAPSHOT: ${AGENTA_RUNNER_DAYTONA_SNAPSHOT:-}
AGENTA_RUNNER_DAYTONA_IMAGE: ${AGENTA_RUNNER_DAYTONA_IMAGE:-}
AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES: ${AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES:-}
AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS: ${AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS:-}
AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM: ${AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM:-}
DAYTONA_AUTODELETE: ${DAYTONA_AUTODELETE:-}
AGENTA_AGENT_SANDBOX_PI_INSTALLED: ${AGENTA_AGENT_SANDBOX_PI_INSTALLED:-false}
AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES: ${AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES:-}
# === STORAGE ============================================== #
volumes:
- ../../../services/runner/src:/app/src
Expand Down
19 changes: 9 additions & 10 deletions hosting/docker-compose/ee/docker-compose.gh.local.yml
Original file line number Diff line number Diff line change
Expand Up @@ -273,19 +273,18 @@ services:
AGENTA_RUNNER_HOST: ${AGENTA_RUNNER_HOST:-0.0.0.0}
AGENTA_API_INTERNAL_URL: ${AGENTA_API_INTERNAL_URL:-http://api:8000}
AGENTA_API_KEY: ${AGENTA_API_KEY:-}
SANDBOX_AGENT_PROVIDER: ${SANDBOX_AGENT_PROVIDER:-local}
AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS: ${AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS:-local}
AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER: ${AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER:-local}
PI_CODING_AGENT_DIR: ${PI_CODING_AGENT_DIR:-/pi-agent}
DAYTONA_API_KEY: ${DAYTONA_API_KEY:-}
DAYTONA_API_URL: ${DAYTONA_API_URL:-}
DAYTONA_TARGET: ${DAYTONA_TARGET:-}
DAYTONA_SNAPSHOT: ${DAYTONA_SNAPSHOT:-}
DAYTONA_SNAPSHOT_AGENT: ${DAYTONA_SNAPSHOT_AGENT:-}
DAYTONA_IMAGE: ${DAYTONA_IMAGE:-}
DAYTONA_AUTOSTOP: ${DAYTONA_AUTOSTOP:-}
AGENTA_RUNNER_DAYTONA_API_KEY: ${AGENTA_RUNNER_DAYTONA_API_KEY:-}
AGENTA_RUNNER_DAYTONA_API_URL: ${AGENTA_RUNNER_DAYTONA_API_URL:-}
AGENTA_RUNNER_DAYTONA_TARGET: ${AGENTA_RUNNER_DAYTONA_TARGET:-}
AGENTA_RUNNER_DAYTONA_SNAPSHOT: ${AGENTA_RUNNER_DAYTONA_SNAPSHOT:-}
AGENTA_RUNNER_DAYTONA_IMAGE: ${AGENTA_RUNNER_DAYTONA_IMAGE:-}
AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES: ${AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES:-}
AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS: ${AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS:-}
AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM: ${AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM:-}
DAYTONA_AUTODELETE: ${DAYTONA_AUTODELETE:-}
AGENTA_AGENT_SANDBOX_PI_INSTALLED: ${AGENTA_AGENT_SANDBOX_PI_INSTALLED:-true}
AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES: ${AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES:-}
# === NETWORK ============================================== #
networks:
- agenta-ee-gh-network
Expand Down
19 changes: 9 additions & 10 deletions hosting/docker-compose/ee/docker-compose.gh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,19 +271,18 @@ services:
AGENTA_RUNNER_HOST: ${AGENTA_RUNNER_HOST:-0.0.0.0}
AGENTA_API_INTERNAL_URL: ${AGENTA_API_INTERNAL_URL:-http://api:8000}
AGENTA_API_KEY: ${AGENTA_API_KEY:-}
SANDBOX_AGENT_PROVIDER: ${SANDBOX_AGENT_PROVIDER:-local}
AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS: ${AGENTA_RUNNER_ENABLED_SANDBOX_PROVIDERS:-local}
AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER: ${AGENTA_RUNNER_DEFAULT_SANDBOX_PROVIDER:-local}
PI_CODING_AGENT_DIR: ${PI_CODING_AGENT_DIR:-/pi-agent}
DAYTONA_API_KEY: ${DAYTONA_API_KEY:-}
DAYTONA_API_URL: ${DAYTONA_API_URL:-}
DAYTONA_TARGET: ${DAYTONA_TARGET:-}
DAYTONA_SNAPSHOT: ${DAYTONA_SNAPSHOT:-}
DAYTONA_SNAPSHOT_AGENT: ${DAYTONA_SNAPSHOT_AGENT:-}
DAYTONA_IMAGE: ${DAYTONA_IMAGE:-}
DAYTONA_AUTOSTOP: ${DAYTONA_AUTOSTOP:-}
AGENTA_RUNNER_DAYTONA_API_KEY: ${AGENTA_RUNNER_DAYTONA_API_KEY:-}
AGENTA_RUNNER_DAYTONA_API_URL: ${AGENTA_RUNNER_DAYTONA_API_URL:-}
AGENTA_RUNNER_DAYTONA_TARGET: ${AGENTA_RUNNER_DAYTONA_TARGET:-}
AGENTA_RUNNER_DAYTONA_SNAPSHOT: ${AGENTA_RUNNER_DAYTONA_SNAPSHOT:-}
AGENTA_RUNNER_DAYTONA_IMAGE: ${AGENTA_RUNNER_DAYTONA_IMAGE:-}
AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES: ${AGENTA_RUNNER_DAYTONA_AUTOSTOP_MINUTES:-}
AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS: ${AGENTA_RUNNER_DAYTONA_SESSION_IDLE_TTL_MS:-}
AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM: ${AGENTA_RUNNER_DAYTONA_SESSION_MAX_WARM:-}
DAYTONA_AUTODELETE: ${DAYTONA_AUTODELETE:-}
AGENTA_AGENT_SANDBOX_PI_INSTALLED: ${AGENTA_AGENT_SANDBOX_PI_INSTALLED:-true}
AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES: ${AGENTA_RUNNER_DAYTONA_AUTODELETE_MINUTES:-}
# === NETWORK ============================================== #
networks:
- agenta-ee-gh-network
Expand Down
Loading
Loading