From 358e52ffef23d79210e2396b3eb0913faeac25ab Mon Sep 17 00:00:00 2001 From: Tejas Polakam Date: Fri, 2 Oct 2026 12:56:41 -0400 Subject: [PATCH] refactor(sandbox)!: remove the sandbox priority knob priority was threaded from the CLI, the deploy steps, the rubrics judge, run overrides and the explorer down to every SandboxProvider create method, but no provider in this repo reads it (local and modal ignored it, modal_vm and e2b documented it as inert). Its only consumer, a hosted backend's scheduling tiers, isn't part of this repo. Stored step documents that still carry priority or judge_priority load and drop the key. Co-Authored-By: Claude Opus 5.5 --- src/agent_env/a2a_agent/a2a_agent.py | 3 +-- src/agent_env/cli/a2a_agent/deploy.py | 6 ++---- src/agent_env/cli/env/deploy.py | 6 ++---- src/agent_env/env/envs/mcp_server.py | 4 ++-- src/agent_env/env/envs/multi_env.py | 4 ++-- src/agent_env/env/envs/website.py | 4 ++-- src/agent_env/explorer/routers/runs.py | 7 ++----- .../ui/src/components/start-runs-panel.tsx | 4 ++-- .../ui/src/hooks/useRunGroupPolling.ts | 3 --- .../ui/src/lib/task-runner-run.smoke.ts | 2 +- .../explorer/ui/src/lib/task-runner-run.ts | 2 -- .../env_providers/env_gateway_provider.py | 19 ++++--------------- .../env_providers/env_server_provider.py | 5 +---- .../providers/env_state/local_postgres.py | 2 +- .../sandbox_providers/e2b/provider.py | 7 ++----- .../sandbox_providers/local_sandbox.py | 7 ++----- .../sandbox_providers/modal_sandbox.py | 7 ++----- .../sandbox_providers/modal_vm_sandbox.py | 6 ++---- .../sandbox_providers/sandbox_provider.py | 5 +---- .../task_step/task_steps/deploy_agent.py | 8 -------- .../task_step/task_steps/deploy_env.py | 11 ++--------- .../task_step/task_steps/deploy_sandbox.py | 6 ------ .../task_steps/verifiers/rubrics_verifier.py | 8 -------- .../envs/test_mcp_server_container_mode.py | 12 ++++++------ .../envs/test_mcp_server_plugin_provider.py | 4 ++-- .../envs/test_multi_env_plugin_provider.py | 2 +- tst/unit/explorer/explorer_app_test.py | 10 ++++------ .../env_gateway_provider_test.py | 4 ++-- .../env_providers/env_server_provider_test.py | 4 ++-- tst/unit/task/step_journal_test.py | 2 +- .../attribution_serialization_test.py | 3 --- .../task_step/context_ops_journal_test.py | 10 +++++----- tst/unit/task_step/deploy_env_test.py | 2 +- tst/unit/task_step/retry_test.py | 4 ++-- tst/unit/task_step/stored_priority_test.py | 19 +++++++++++++++++++ 35 files changed, 78 insertions(+), 134 deletions(-) create mode 100644 tst/unit/task_step/stored_priority_test.py diff --git a/src/agent_env/a2a_agent/a2a_agent.py b/src/agent_env/a2a_agent/a2a_agent.py index 4801db1f..a84ff315 100644 --- a/src/agent_env/a2a_agent/a2a_agent.py +++ b/src/agent_env/a2a_agent/a2a_agent.py @@ -416,7 +416,6 @@ async def deploy( sandbox_type: str | None = None, sandbox: Sandbox | None = None, enable_docker: bool = False, - priority: Optional[int] = None, network_policy: NetworkPolicy | None = None, *, attribution: Optional[Attribution] = None, @@ -449,7 +448,7 @@ async def deploy( image_name=image_name, port=a2a_port, env=merged_env, cpu=cpu, memory=memory, disk_size_gb=disk_size_gb, timeout=ttl_seconds, attribution=attribution, - priority=priority, network_policy=network_policy, + network_policy=network_policy, ) self._owns_sandbox = True logger.info(f"Sandbox created: {self._sandbox.sandbox_id} (mode={self._sandbox.mode})") diff --git a/src/agent_env/cli/a2a_agent/deploy.py b/src/agent_env/cli/a2a_agent/deploy.py index af68d031..5c6ae687 100644 --- a/src/agent_env/cli/a2a_agent/deploy.py +++ b/src/agent_env/cli/a2a_agent/deploy.py @@ -21,9 +21,7 @@ help="Sandbox backend(s): a built-in (modal, modal_vm, e2b, local) " "or a name from [sandbox.providers] in .agentenv/config.toml; comma-separated for a " "fallback chain. Defaults to [sandbox].agent_default (else local) when omitted.") -@click.option("--priority", type=int, default=0, show_default=True, - help="Sandbox priority: 0=interactive, 1=non_interactive (honoured by backends with priority tiers)") -def deploy(agent_id: str, agent_version: int | None, env_var_pairs: tuple[str, ...], ttl_seconds: int, sandbox: str, priority: int): +def deploy(agent_id: str, agent_version: int | None, env_var_pairs: tuple[str, ...], ttl_seconds: int, sandbox: str): """Deploy an A2A agent on a sandbox VM.""" from agent_env.providers import build_sandbox_provider, set_agent_sandbox_provider @@ -49,7 +47,7 @@ def deploy(agent_id: str, agent_version: int | None, env_var_pairs: tuple[str, . click.echo(f"Deploying (ttl={ttl_seconds}s)...") with run_scope(agent.id): - deployed = asyncio.run(agent.deploy(ttl_seconds=ttl_seconds, env_vars=env_vars if env_vars else None, priority=priority)) + deployed = asyncio.run(agent.deploy(ttl_seconds=ttl_seconds, env_vars=env_vars if env_vars else None)) click.echo("Deployed!") click.echo("Instance ID: " + click.style(deployed.instance_id, fg="green")) diff --git a/src/agent_env/cli/env/deploy.py b/src/agent_env/cli/env/deploy.py index edd781a9..770e5e38 100644 --- a/src/agent_env/cli/env/deploy.py +++ b/src/agent_env/cli/env/deploy.py @@ -26,8 +26,6 @@ help="Override default_service_db_env_id (on Modal its images must be in the configured image store)") @click.option("--gateway", "gateway_env_id", default=None, help="Override default_gateway_env_id") -@click.option("--priority", type=int, default=0, show_default=True, - help="Sandbox priority: 0=interactive, 1=non_interactive (honoured by backends with priority tiers)") @click.option("--disk-size-gb", type=float, default=10.0, show_default=True, help="Sandbox VM disk size in GB. Large universes (e.g. github/gdrive " "root file trees) need more than the 10GB default.") @@ -48,7 +46,7 @@ @click.option("--env-state-instance-id", default=None, help="Attach against an EXISTING env state instance instead of creating a fresh store " "(its own type selects the provider).") -def deploy(env_id: str, env_version: int | None, ttl_seconds: int, gateway_mode: str, sandbox: str, service_db_env_id: str | None, gateway_env_id: str | None, priority: int, disk_size_gb: float, cpu: float | None, memory_mb: int | None, env_state_type: str | None, env_state_instance_id: str | None): +def deploy(env_id: str, env_version: int | None, ttl_seconds: int, gateway_mode: str, sandbox: str, service_db_env_id: str | None, gateway_env_id: str | None, disk_size_gb: float, cpu: float | None, memory_mb: int | None, env_state_type: str | None, env_state_instance_id: str | None): """Deploy an MCP server environment.""" from agent_env.providers import build_sandbox_provider from agent_env.config import get_config @@ -75,7 +73,7 @@ def deploy(env_id: str, env_version: int | None, ttl_seconds: int, gateway_mode: cpu_note = f", cpu={cpu}" if cpu else "" mem_note = f", memory={memory_mb}MB" if memory_mb else "" click.echo(f"Deploying (ttl={ttl_seconds}s, gateway_mode={mode.value}, disk={disk_size_gb}GB{cpu_note}{mem_note})...") - deploy_kwargs = dict(ttl_seconds=ttl_seconds, gateway_mode=mode, sandbox_type=sandbox, priority=priority, disk_size_gb=disk_size_gb) + deploy_kwargs = dict(ttl_seconds=ttl_seconds, gateway_mode=mode, sandbox_type=sandbox, disk_size_gb=disk_size_gb) if cpu is not None: deploy_kwargs["cpu"] = cpu if memory_mb is not None: diff --git a/src/agent_env/env/envs/mcp_server.py b/src/agent_env/env/envs/mcp_server.py index 856fd988..c9975356 100644 --- a/src/agent_env/env/envs/mcp_server.py +++ b/src/agent_env/env/envs/mcp_server.py @@ -78,11 +78,11 @@ def from_dict(cls, data: dict) -> MCPServerEnv: env_provider_type=data.get("env_provider_type", "gateway"), ) - async def deploy(self, ttl_seconds: int = 10800, disk_size_gb: float = 10, gateway_mode: GatewayMode = GatewayMode.PERFORMANCE, cpu: float | None = None, memory_mb: int | None = None, sandbox_type: str | None = None, priority: Optional[int] = None, env_state_type: str | None = None, env_state_instance_id: str | None = None, *, attribution: Optional[Attribution] = None) -> DeployedEnv: + async def deploy(self, ttl_seconds: int = 10800, disk_size_gb: float = 10, gateway_mode: GatewayMode = GatewayMode.PERFORMANCE, cpu: float | None = None, memory_mb: int | None = None, sandbox_type: str | None = None, env_state_type: str | None = None, env_state_instance_id: str | None = None, *, attribution: Optional[Attribution] = None) -> DeployedEnv: # In container mode the server runs in its own container, so loads stage there, as for a MultiEnv child. return await deploy_through_provider( self, environment_name=self.environment_name, ttl_seconds=ttl_seconds, sandbox_type=sandbox_type, - disk_size_gb=disk_size_gb, gateway_mode=gateway_mode, cpu=cpu, memory_mb=memory_mb, priority=priority, + disk_size_gb=disk_size_gb, gateway_mode=gateway_mode, cpu=cpu, memory_mb=memory_mb, env_state_type=env_state_type, env_state_instance_id=env_state_instance_id, attribution=attribution, ) diff --git a/src/agent_env/env/envs/multi_env.py b/src/agent_env/env/envs/multi_env.py index 1bf7ab88..884c81f9 100644 --- a/src/agent_env/env/envs/multi_env.py +++ b/src/agent_env/env/envs/multi_env.py @@ -87,10 +87,10 @@ def from_dict(cls, data: dict) -> "MultiEnv": return cls(id=data["id"], version=data.get("version"), mcp_server_envs=mcp_server_envs, website_envs=website_envs, metadata=data.get("metadata", {}), name=data.get("name"), env_provider_type=data.get("env_provider_type", "gateway")) - async def deploy(self, ttl_seconds: int = 10800, disk_size_gb: float = 10, gateway_mode: GatewayMode = GatewayMode.PERFORMANCE, cpu: float | None = None, memory_mb: int | None = None, sandbox_type: str | None = None, priority: Optional[int] = None, env_state_type: str | None = None, env_state_instance_id: str | None = None, *, attribution: Optional[Attribution] = None) -> DeployedEnv: + async def deploy(self, ttl_seconds: int = 10800, disk_size_gb: float = 10, gateway_mode: GatewayMode = GatewayMode.PERFORMANCE, cpu: float | None = None, memory_mb: int | None = None, sandbox_type: str | None = None, env_state_type: str | None = None, env_state_instance_id: str | None = None, *, attribution: Optional[Attribution] = None) -> DeployedEnv: deployed_env = await deploy_through_provider( self, environment_name=None, ttl_seconds=ttl_seconds, sandbox_type=sandbox_type, - disk_size_gb=disk_size_gb, gateway_mode=gateway_mode, cpu=cpu, memory_mb=memory_mb, priority=priority, + disk_size_gb=disk_size_gb, gateway_mode=gateway_mode, cpu=cpu, memory_mb=memory_mb, env_state_type=env_state_type, env_state_instance_id=env_state_instance_id, attribution=attribution, ) self._gateway_mode = gateway_mode diff --git a/src/agent_env/env/envs/website.py b/src/agent_env/env/envs/website.py index bfd61da8..f9ed1b02 100644 --- a/src/agent_env/env/envs/website.py +++ b/src/agent_env/env/envs/website.py @@ -94,10 +94,10 @@ def from_dict(cls, data: dict) -> WebsiteEnv: env_provider_type=data.get("env_provider_type", "gateway"), ) - async def deploy(self, ttl_seconds: int = 10800, disk_size_gb: float = 10, gateway_mode: GatewayMode = GatewayMode.PERFORMANCE, cpu: float | None = None, memory_mb: int | None = None, sandbox_type: str | None = None, priority: Optional[int] = None, env_state_type: str | None = None, env_state_instance_id: str | None = None, *, attribution: Optional[Attribution] = None) -> DeployedEnv: + async def deploy(self, ttl_seconds: int = 10800, disk_size_gb: float = 10, gateway_mode: GatewayMode = GatewayMode.PERFORMANCE, cpu: float | None = None, memory_mb: int | None = None, sandbox_type: str | None = None, env_state_type: str | None = None, env_state_instance_id: str | None = None, *, attribution: Optional[Attribution] = None) -> DeployedEnv: return await deploy_through_provider( self, environment_name=self.environment_name, ttl_seconds=ttl_seconds, sandbox_type=sandbox_type, - disk_size_gb=disk_size_gb, gateway_mode=gateway_mode, cpu=cpu, memory_mb=memory_mb, priority=priority, + disk_size_gb=disk_size_gb, gateway_mode=gateway_mode, cpu=cpu, memory_mb=memory_mb, env_state_type=env_state_type, env_state_instance_id=env_state_instance_id, attribution=attribution, ) diff --git a/src/agent_env/explorer/routers/runs.py b/src/agent_env/explorer/routers/runs.py index 37338706..7a5ab8ea 100644 --- a/src/agent_env/explorer/routers/runs.py +++ b/src/agent_env/explorer/routers/runs.py @@ -52,7 +52,6 @@ class RunRequest(BaseModel): step_overrides: Optional[dict] = None overrides: Optional[dict] = None project_id: Optional[str] = None - priority: Optional[int] = None # Accepted but ignored: the local explorer gets models from the [model] config, not a # per-request key; declared so a client that always sends them isn't rejected. litellm_api_key: Optional[str] = None @@ -113,10 +112,8 @@ def _run_metadata(body: "RunRequest") -> dict: # Seed from any user_overrides already in metadata — a re-run inherits the prior # instance's — so the explicit fields merge into them rather than replacing the lot. user_overrides = {**(metadata.get("user_overrides") or {}), **(body.overrides or {})} - for key in ("project_id", "priority"): - value = getattr(body, key) - if value is not None: - user_overrides[key] = value + if body.project_id is not None: + user_overrides["project_id"] = body.project_id # The steps read `step_params` (TaskStep.step_param_overrides); the request field is # named differently. Writing the request name through dropped every override. if body.step_overrides is not None: diff --git a/src/agent_env/explorer/ui/src/components/start-runs-panel.tsx b/src/agent_env/explorer/ui/src/components/start-runs-panel.tsx index e2c582b6..349259b5 100644 --- a/src/agent_env/explorer/ui/src/components/start-runs-panel.tsx +++ b/src/agent_env/explorer/ui/src/components/start-runs-panel.tsx @@ -364,8 +364,8 @@ export function StartRunsPanel({ }, [extraOverridesJson]); const buildOverrides = useCallback((): RunOverrides => { - // priority=0 (interactive): a human watches the live stream. Freeform extras can override (e.g. {"priority":1}); dropdowns win last. - const o = { priority: 0, ...extraOverrides } as RunOverrides; + // Freeform extras first; the dropdowns win. + const o = { ...extraOverrides } as RunOverrides; if (agentModel.trim()) o.agent_model = agentModel.trim(); if (agentArtifactId.trim()) o.agent_artifact_id = agentArtifactId.trim(); if (a2aAgentId.trim()) o.a2a_agent_id = a2aAgentId.trim(); diff --git a/src/agent_env/explorer/ui/src/hooks/useRunGroupPolling.ts b/src/agent_env/explorer/ui/src/hooks/useRunGroupPolling.ts index c55416c7..32d650ef 100644 --- a/src/agent_env/explorer/ui/src/hooks/useRunGroupPolling.ts +++ b/src/agent_env/explorer/ui/src/hooks/useRunGroupPolling.ts @@ -8,9 +8,6 @@ export interface RunOverrides { agent_model?: string; agent_artifact_id?: string; a2a_agent_id?: string; - /** Sandbox scheduling priority (0=interactive, 1=non_interactive), threaded through - * context.metadata.user_overrides to the deploy task steps' sandbox tier. */ - priority?: number; [k: string]: string | number | boolean | null | undefined; } diff --git a/src/agent_env/explorer/ui/src/lib/task-runner-run.smoke.ts b/src/agent_env/explorer/ui/src/lib/task-runner-run.smoke.ts index 7ddfd786..590da1d4 100644 --- a/src/agent_env/explorer/ui/src/lib/task-runner-run.smoke.ts +++ b/src/agent_env/explorer/ui/src/lib/task-runner-run.smoke.ts @@ -59,7 +59,7 @@ async function main(): Promise { // The request a run sends. const body = buildRunBody({ start_step: 2, context_from_instance_id: 'i-1', context_json: { x: 1 } }, 3, ''); - assert(body.version === 3 && body.priority === 0, 'run body: task version, interactive priority'); + assert(body.version === 3, 'run body: task version'); assert(body.start_step === 2, 'run body: start step'); assert(body.context_from_instance_id === 'i-1' && !('context_json' in body), 'run body: instance context wins over inline context'); assert(!('project_id' in body), 'run body: an empty projectId is not sent'); diff --git a/src/agent_env/explorer/ui/src/lib/task-runner-run.ts b/src/agent_env/explorer/ui/src/lib/task-runner-run.ts index d2306e33..d0390d9e 100644 --- a/src/agent_env/explorer/ui/src/lib/task-runner-run.ts +++ b/src/agent_env/explorer/ui/src/lib/task-runner-run.ts @@ -36,8 +36,6 @@ export function buildRunBody( ): Record { const body: Record = {}; body.version = opts?.version ?? taskVersion ?? undefined; - // priority=0 (interactive): a human is waiting. Sent explicitly so intent survives backend default changes. - body.priority = 0; if (opts?.start_step != null) body.start_step = opts.start_step; // Mutually exclusive server-side. if (opts?.context_from_instance_id) diff --git a/src/agent_env/providers/env_providers/env_gateway_provider.py b/src/agent_env/providers/env_providers/env_gateway_provider.py index d5ca45b5..291d4b11 100644 --- a/src/agent_env/providers/env_providers/env_gateway_provider.py +++ b/src/agent_env/providers/env_providers/env_gateway_provider.py @@ -514,7 +514,6 @@ async def deploy( disk_size_gb: float = 10, cpu: float | None = None, memory_mb: int | None = None, - priority: Optional[int] = None, attribution: Optional[Attribution] = None, ) -> DeployedGatewayEnv: """A gateway in front of the env, with the state store it acquires (local Postgres by default); returns the record. @@ -535,7 +534,7 @@ async def deploy( sandbox_provider, env.id, state_instance=state_instance, mcp_servers=topology.mcp_servers, mcp_server_images=topology.mcp_server_images, website_configs=topology.website_configs, website_images=topology.website_images, mcp_server_name=topology.mcp_server_name, gateway_mode=gateway_mode, - ttl_seconds=ttl_seconds, disk_size_gb=disk_size_gb, cpu=cpu, memory_mb=memory_mb, priority=priority, attribution=attribution, + ttl_seconds=ttl_seconds, disk_size_gb=disk_size_gb, cpu=cpu, memory_mb=memory_mb, attribution=attribution, ) return DeployedGatewayEnv( env_id=env.id, @@ -567,7 +566,6 @@ async def create_gateway( disk_size_gb: float = 10, cpu: float | None = None, memory_mb: int | None = None, - priority: Optional[int] = None, existing_sandbox: Sandbox | None = None, env_id: str | None = None, state_instance: "EnvStateInstance | None" = None, @@ -593,7 +591,7 @@ async def create_gateway( sandbox_provider, env_id, state_instance=state_instance, mcp_servers=mcp_servers, mcp_server_images=mcp_server_images, gateway_port=gateway_port, website_configs=website_configs, website_images=website_images, gateway_mode=gateway_mode, ttl_seconds=ttl_seconds, disk_size_gb=disk_size_gb, cpu=cpu, memory_mb=memory_mb, - priority=priority, existing_sandbox=existing_sandbox, sidecars=sidecars, mcp_server_name=mcp_server_name, + existing_sandbox=existing_sandbox, sidecars=sidecars, mcp_server_name=mcp_server_name, attribution=attribution, ) @@ -621,7 +619,6 @@ async def _deploy_via_vm( cpu: float | None = None, memory_mb: int | None = None, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, existing_sandbox: Sandbox | None = None, sidecars: list[SidecarConfig] | None = None, mcp_server_name: str | None = None, @@ -646,7 +643,6 @@ async def _deploy_via_vm( timeout=ttl_seconds, disk_size_gb=disk_size_gb, attribution=attribution, - priority=priority, **vm_kwargs, ) sandbox = self._sandbox @@ -831,7 +827,6 @@ async def _deploy_via_containers( cpu: float | None = None, memory_mb: int | None = None, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, mcp_server_name: str | None = None, ) -> DeployedGateway: from agent_env.env.env import Env @@ -848,7 +843,7 @@ async def _deploy_via_containers( i6pn_kwargs = {"i6pn": True, "region": config.modal_default_region} if isinstance(sandbox_provider, ModalSandboxProvider) else {} deploy = _ContainerDeploy( sandbox_provider=sandbox_provider, cpu=cpu, disk_size_gb=disk_size_gb, ttl_seconds=ttl_seconds, - attribution=attribution, priority=priority, i6pn_kwargs=i6pn_kwargs, + attribution=attribution, i6pn_kwargs=i6pn_kwargs, ) try: @@ -936,7 +931,6 @@ async def _deploy_via_containers( **_size_kwargs(cpu, memory_mb), disk_size_gb=disk_size_gb, timeout=ttl_seconds, attribution=attribution, - priority=priority, **i6pn_kwargs, ) self._container_sandboxes.append(gateway_sb) @@ -1025,7 +1019,6 @@ async def _provision_sidecar(self, deploy: _ContainerDeploy, spec) -> Sandbox: **_size_kwargs(deploy.cpu, None), disk_size_gb=deploy.disk_size_gb, timeout=deploy.ttl_seconds, attribution=deploy.attribution, - priority=deploy.priority, **deploy.i6pn_kwargs, ) @@ -1097,7 +1090,6 @@ async def _stand_up_servicedb(self, deploy: _ContainerDeploy, spec: "LocalPostgr disk_size_gb=deploy.disk_size_gb, timeout=deploy.ttl_seconds, expose_externally=False, attribution=deploy.attribution, - priority=deploy.priority, **deploy.i6pn_kwargs, ) self._container_sandboxes.append(db_sb) @@ -1130,7 +1122,6 @@ async def _provision_mcp( **_size_kwargs(deploy.cpu, None), disk_size_gb=deploy.disk_size_gb, timeout=deploy.ttl_seconds, attribution=deploy.attribution, - priority=deploy.priority, **deploy.i6pn_kwargs, ) return cfg.environment_name, sb @@ -1150,7 +1141,6 @@ async def _deploy_gateway( disk_size_gb: float = 10, cpu: float | None = None, memory_mb: int | None = None, - priority: Optional[int] = None, existing_sandbox: Sandbox | None = None, sidecars: list[SidecarConfig] | None = None, mcp_server_name: str | None = None, @@ -1166,7 +1156,7 @@ async def _deploy_gateway( if state_instance is not None else LocalPostgresStateProvider() ) - deploy_kwargs = {"attribution": dict(attribution or {}), "priority": priority} + deploy_kwargs = {"attribution": dict(attribution or {})} if isinstance(sandbox_provider, ModalSandboxProvider): if existing_sandbox is not None: raise ValueError("existing_sandbox is only supported for VM-mode providers") @@ -1352,5 +1342,4 @@ class _ContainerDeploy: disk_size_gb: float ttl_seconds: int attribution: Optional[Attribution] - priority: Optional[int] i6pn_kwargs: dict diff --git a/src/agent_env/providers/env_providers/env_server_provider.py b/src/agent_env/providers/env_providers/env_server_provider.py index 5ba346e5..b0ee71c5 100644 --- a/src/agent_env/providers/env_providers/env_server_provider.py +++ b/src/agent_env/providers/env_providers/env_server_provider.py @@ -35,7 +35,6 @@ async def deploy( disk_size_gb: float = 10, cpu: float | None = None, memory_mb: int | None = None, - priority: Optional[int] = None, attribution: Optional[Attribution] = None, ) -> DeployedSandboxEnv: """The env's MCP server in its own container; returns the record once it serves its card and its tools.""" @@ -46,7 +45,7 @@ async def deploy( raise TypeError(f"env_provider_type '{self.type}' deploys one MCP server, not a {env.type} env") attempt = functools.partial( self._deploy_server, env, ttl_seconds=ttl_seconds, disk_size_gb=disk_size_gb, - cpu=cpu, memory_mb=memory_mb, priority=priority, attribution=attribution, + cpu=cpu, memory_mb=memory_mb, attribution=attribution, ) return await self._run(sandbox_provider, env.id, attempt) @@ -62,7 +61,6 @@ async def _deploy_server( disk_size_gb: float, cpu: float | None, memory_mb: int | None, - priority: Optional[int], attribution: Optional[Attribution], ) -> DeployedSandboxEnv: """One attempt: the server's container, then its card and tools; returns its record.""" @@ -80,7 +78,6 @@ async def _deploy_server( **_size_kwargs(cpu, memory_mb), disk_size_gb=disk_size_gb, timeout=ttl_seconds, attribution=dict(attribution or {}), - priority=priority, ) self._container_sandboxes.append(server) self._environment_sandboxes[name] = server diff --git a/src/agent_env/providers/env_state/local_postgres.py b/src/agent_env/providers/env_state/local_postgres.py index b324910a..f344a9f2 100644 --- a/src/agent_env/providers/env_state/local_postgres.py +++ b/src/agent_env/providers/env_state/local_postgres.py @@ -59,7 +59,7 @@ class ContainerSpec: """Declarative spec for a store/sidecar container the compute layer provisions (Modal path). The gateway's ``create_container`` loop consumes these and adds its own sandbox - knobs (i6pn, attribution, priority) + knobs (i6pn, attribution) """ name: str diff --git a/src/agent_env/providers/sandbox_providers/e2b/provider.py b/src/agent_env/providers/sandbox_providers/e2b/provider.py index c2aa1df9..9cb554cc 100644 --- a/src/agent_env/providers/sandbox_providers/e2b/provider.py +++ b/src/agent_env/providers/sandbox_providers/e2b/provider.py @@ -114,12 +114,11 @@ async def create_vm( exposed_ports: list[int] | None = None, setup_for_gateway: bool = True, attribution: Attribution | None = None, - priority: int | None = None, network_policy: NetworkPolicy | None = None, ) -> E2BSandbox: """Create an E2B VM using its derived immutable template. - ``boot_mode``, ``disk_size_gb`` and ``priority`` exist for + ``boot_mode`` and ``disk_size_gb`` exist for ``SandboxProvider`` parity only: E2B's sandbox-create API has no corresponding controls. In particular, disk size is never sent to E2B. ``image`` is rejected rather than silently overriding the @@ -130,7 +129,7 @@ async def create_vm( "E2B base_template is immutable and configured by the provider; " "image overrides are unsupported" ) - del boot_mode, priority + del boot_mode # ``10`` is the interface default inherited from SandboxProvider. # Avoid a noisy warning for every existing caller while making any # meaningful disk request explicit: E2B fixes disk capacity in its @@ -216,7 +215,6 @@ async def create_sandbox( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Attribution | None = None, - priority: int | None = None, network_policy: NetworkPolicy | None = None, ) -> E2BSandbox: # Like the other remote VM backends, E2B is a VM backend. The gateway/agent @@ -230,7 +228,6 @@ async def create_sandbox( timeout=timeout, exposed_ports=[port], attribution=attribution, - priority=priority, network_policy=network_policy, ) diff --git a/src/agent_env/providers/sandbox_providers/local_sandbox.py b/src/agent_env/providers/sandbox_providers/local_sandbox.py index 3fb4d5c0..9e80339f 100644 --- a/src/agent_env/providers/sandbox_providers/local_sandbox.py +++ b/src/agent_env/providers/sandbox_providers/local_sandbox.py @@ -311,7 +311,6 @@ async def create_vm( exposed_ports: Optional[list[int]] = None, setup_for_gateway: bool = True, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> LocalSandbox: refuse_unenforceable_policy(self, network_policy) @@ -334,7 +333,6 @@ async def create_container( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> LocalSandbox: sandbox = await super().create_container( @@ -346,7 +344,7 @@ async def create_container( disk_size_gb=disk_size_gb, timeout=timeout, attribution=attribution, - priority=priority, network_policy=network_policy, + network_policy=network_policy, ) # The marker is how a later get_sandbox() (post-run teardown rebuilds the sandbox from disk) # learns this is a container and removes it. If we can't persist it, that reconstructed @@ -387,12 +385,11 @@ async def create_sandbox( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> LocalSandbox: return await self.create_container( image_name=image_name, port=port, env=env, cpu=cpu, memory=memory, disk_size_gb=disk_size_gb, - timeout=timeout, attribution=attribution, priority=priority, network_policy=network_policy, + timeout=timeout, attribution=attribution, network_policy=network_policy, ) async def get_sandbox(self, sandbox_id: str) -> LocalSandbox: diff --git a/src/agent_env/providers/sandbox_providers/modal_sandbox.py b/src/agent_env/providers/sandbox_providers/modal_sandbox.py index 86808e64..f73cd50b 100644 --- a/src/agent_env/providers/sandbox_providers/modal_sandbox.py +++ b/src/agent_env/providers/sandbox_providers/modal_sandbox.py @@ -242,7 +242,6 @@ async def create_container( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, command: list[str] | None = None, i6pn: bool = False, @@ -387,14 +386,13 @@ async def create_sandbox( self, *, image_name: str, port: int, env: dict[str, str], cpu: float = 0.125, memory: int = 8192, disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> Sandbox: return await self.create_container( image_name=image_name, port=port, env=env, cpu=cpu, memory=memory, disk_size_gb=disk_size_gb, timeout=timeout, attribution=attribution, - priority=priority, network_policy=network_policy, + network_policy=network_policy, ) async def get_sandbox(self, sandbox_id: str) -> Sandbox: @@ -433,8 +431,7 @@ def _build_cost_attribution_tags(attribution: Attribution) -> dict[str, str]: Unset dimensions fall back to config.toml ``[sandbox.attribution]``; a dimension with no value anywhere is omitted rather than emitted as a null tag. Returns a flat - ``dict[str, str]`` for ``modal.App.set_tags``. (priority is a scheduling concern, - not attribution, so it is not included here.) + ``dict[str, str]`` for ``modal.App.set_tags``. """ resolved = apply_default_attribution(attribution) return { diff --git a/src/agent_env/providers/sandbox_providers/modal_vm_sandbox.py b/src/agent_env/providers/sandbox_providers/modal_vm_sandbox.py index 91173f4c..17fbca23 100644 --- a/src/agent_env/providers/sandbox_providers/modal_vm_sandbox.py +++ b/src/agent_env/providers/sandbox_providers/modal_vm_sandbox.py @@ -302,10 +302,9 @@ async def create_vm( exposed_ports: Optional[list[int]] = None, setup_for_gateway: bool = True, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> ModalVmSandbox: - # image/boot_mode/disk_size_gb/priority accepted for interface parity but inert here. + # image/boot_mode/disk_size_gb accepted for interface parity but inert here. # disk_size_gb: Modal has no disk-size knob on Sandbox.create; a VM sandbox's rootfs is # fixed at the 512 GiB max. https://modal.com/docs/guide/vm-sandboxes attribution = dict(attribution or {}) @@ -371,7 +370,6 @@ async def create_sandbox( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> ModalVmSandbox: # Like the other VM providers' create_sandbox: return a bare VM (image_name/env are @@ -381,7 +379,7 @@ async def create_sandbox( exposed_ports=[port], cpu=cpu, memory=memory, disk_size_gb=disk_size_gb, timeout=timeout, attribution=attribution, - priority=priority, network_policy=network_policy, + network_policy=network_policy, ) async def get_sandbox(self, sandbox_id: str) -> ModalVmSandbox: diff --git a/src/agent_env/providers/sandbox_providers/sandbox_provider.py b/src/agent_env/providers/sandbox_providers/sandbox_provider.py index bfd46cdb..0a784735 100644 --- a/src/agent_env/providers/sandbox_providers/sandbox_provider.py +++ b/src/agent_env/providers/sandbox_providers/sandbox_provider.py @@ -51,7 +51,6 @@ async def create_sandbox( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> Sandbox: ... @@ -67,7 +66,6 @@ async def create_vm( exposed_ports: Optional[list[int]] = None, setup_for_gateway: bool = True, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> VmSandbox: raise NotImplementedError(f"{type(self).__name__} does not support create_vm") @@ -83,7 +81,6 @@ async def create_container( disk_size_gb: float = 10, timeout: int = 3600 * 2, attribution: Optional[Attribution] = None, - priority: Optional[int] = None, network_policy: Optional[NetworkPolicy] = None, ) -> Sandbox: """Provision a sandbox with the registry image already running as a container. @@ -98,7 +95,7 @@ async def create_container( cpu=cpu, memory=memory, disk_size_gb=disk_size_gb, exposed_ports=[port], timeout=timeout, attribution=attribution, - priority=priority, network_policy=network_policy, + network_policy=network_policy, ) try: from agent_env.config import get_config diff --git a/src/agent_env/task_step/task_steps/deploy_agent.py b/src/agent_env/task_step/task_steps/deploy_agent.py index cf5d4433..3b4e6406 100644 --- a/src/agent_env/task_step/task_steps/deploy_agent.py +++ b/src/agent_env/task_step/task_steps/deploy_agent.py @@ -116,7 +116,6 @@ def __init__( agent_snapshot_files_artifact_id: Optional[str] = None, agent_snapshot_files_artifact_version: Optional[int] = None, agent_snapshot_target_context_id: Optional[str] = None, - priority: Optional[int] = None, network_policy: Optional[dict] = None, role: Optional[str] = None, enable_agent_changelog: bool = False, @@ -148,7 +147,6 @@ def __init__( self.agent_snapshot_files_artifact_id = agent_snapshot_files_artifact_id self.agent_snapshot_files_artifact_version = agent_snapshot_files_artifact_version self.agent_snapshot_target_context_id = agent_snapshot_target_context_id - self.priority = priority self.metadata = metadata or {} self.network_policy = NetworkPolicy.from_dict(network_policy).to_dict() if network_policy else None self.role = role @@ -191,7 +189,6 @@ def to_dict(self) -> dict: base["agent_snapshot_files_artifact_id"] = self.agent_snapshot_files_artifact_id base["agent_snapshot_files_artifact_version"] = self.agent_snapshot_files_artifact_version base["agent_snapshot_target_context_id"] = self.agent_snapshot_target_context_id - base["priority"] = self.priority base["metadata"] = self.metadata base["network_policy"] = self.network_policy base["role"] = self.role @@ -225,7 +222,6 @@ def from_dict(cls, data: dict) -> DeployAgentTaskStep: agent_snapshot_files_artifact_id=data.get("agent_snapshot_files_artifact_id"), agent_snapshot_files_artifact_version=data.get("agent_snapshot_files_artifact_version"), agent_snapshot_target_context_id=data.get("agent_snapshot_target_context_id"), - priority=data.get("priority"), metadata=dict(data.get("metadata") or {}), network_policy=data.get("network_policy"), role=data.get("role"), @@ -320,10 +316,6 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: if self.memory_mb is not None: deploy_kwargs["memory"] = self.memory_mb deploy_kwargs["attribution"] = deploy_attribution(self, context) - _priority_override = user_overrides.get("priority") - resolved_priority = _priority_override if _priority_override is not None else self.priority - if resolved_priority is not None: - deploy_kwargs["priority"] = resolved_priority _policy_override = user_overrides.get("network_policy") resolved_policy = _policy_override if _policy_override is not None else self.network_policy if resolved_policy is not None: diff --git a/src/agent_env/task_step/task_steps/deploy_env.py b/src/agent_env/task_step/task_steps/deploy_env.py index f11c3169..38db9e29 100644 --- a/src/agent_env/task_step/task_steps/deploy_env.py +++ b/src/agent_env/task_step/task_steps/deploy_env.py @@ -32,7 +32,6 @@ def __init__( cpu: Optional[float] = None, memory_mb: Optional[int] = None, sandbox_type: Optional[str] = None, - priority: Optional[int] = None, env_state_type: Optional[str] = None, env_state_instance_id: Optional[str] = None, depends_on: Optional[list[TaskStepDependency]] = None, @@ -51,7 +50,6 @@ def __init__( self.env_state_type = env_state_type # Existing env state instance to attach to; the provider interprets it. self.env_state_instance_id = env_state_instance_id - self.priority = priority self.metadata = metadata or {} def to_dict(self) -> dict: @@ -66,7 +64,6 @@ def to_dict(self) -> dict: base["sandbox_type"] = self.sandbox_type base["env_state_type"] = self.env_state_type base["env_state_instance_id"] = self.env_state_instance_id - base["priority"] = self.priority base["metadata"] = self.metadata return base @@ -84,7 +81,6 @@ def from_dict(cls, data: dict) -> DeployEnvTaskStep: sandbox_type=data.get("sandbox_type"), env_state_type=data.get("env_state_type"), env_state_instance_id=data.get("env_state_instance_id"), - priority=data.get("priority"), metadata=dict(data.get("metadata") or {}), ) @@ -107,7 +103,7 @@ def preflight(self) -> list[str]: # As stored: run-time overrides aren't known at save, and deploy() consumes sandbox_type itself. Every run passes an # attribution, so the check does too, whatever it will hold. refusal = env.deploy_refusal(ttl_seconds=self.ttl_seconds, disk_size_gb=self.disk_size_gb, gateway_mode=self.gateway_mode, cpu=self.cpu, - memory_mb=self.memory_mb, priority=self.priority, env_state_type=self.env_state_type, + memory_mb=self.memory_mb, env_state_type=self.env_state_type, env_state_instance_id=self.env_state_instance_id, attribution={}) except (NotFoundError, ValueError) as e: # missing, or a type or env_provider_type this process can't load return [f"deploy_env '{self.id}': env '{self.env_id}' can't be loaded: {e}"] @@ -127,8 +123,6 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: resolved_env_state_instance_id = ( user_overrides.get("env_state_instance_id") or self.env_state_instance_id ) - _priority_override = user_overrides.get("priority") - resolved_priority = _priority_override if _priority_override is not None else self.priority _ttl_override = user_overrides.get("ttl_seconds") resolved_ttl = _ttl_override if _ttl_override is not None else self.ttl_seconds attribution = deploy_attribution(self, context) @@ -138,7 +132,7 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: f"cpu={self.cpu}, memory_mb={self.memory_mb}, " f"sandbox_type={resolved_sandbox_type}, env_state_type={resolved_env_state_type}, " f"env_state_instance_id={resolved_env_state_instance_id}, " - f"attribution={attribution}, priority={resolved_priority})" + f"attribution={attribution})" ) deploy_kwargs = { "ttl_seconds": resolved_ttl, @@ -146,7 +140,6 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: "gateway_mode": GatewayMode(self.gateway_mode), "cpu": self.cpu, "memory_mb": self.memory_mb, - "priority": resolved_priority, "attribution": attribution, } if resolved_sandbox_type is not None: diff --git a/src/agent_env/task_step/task_steps/deploy_sandbox.py b/src/agent_env/task_step/task_steps/deploy_sandbox.py index cba3a140..46a90237 100644 --- a/src/agent_env/task_step/task_steps/deploy_sandbox.py +++ b/src/agent_env/task_step/task_steps/deploy_sandbox.py @@ -35,7 +35,6 @@ def __init__( port: Optional[int] = None, env_vars: Optional[dict[str, str]] = None, sandbox_type: Optional[str] = None, - priority: Optional[int] = None, network_policy: Optional[dict] = None, depends_on: Optional[list[TaskStepDependency]] = None, fail_task_on_error: bool = True, @@ -56,7 +55,6 @@ def __init__( self.port = port self.env_vars = env_vars self.sandbox_type = sandbox_type - self.priority = priority self.metadata = metadata or {} self.network_policy = NetworkPolicy.from_dict(network_policy).to_dict() if network_policy else None @@ -74,7 +72,6 @@ def to_dict(self) -> dict: base["port"] = self.port base["env_vars"] = self.env_vars base["sandbox_type"] = self.sandbox_type - base["priority"] = self.priority base["metadata"] = self.metadata base["network_policy"] = self.network_policy return base @@ -95,7 +92,6 @@ def from_dict(cls, data: dict) -> DeploySandboxTaskStep: port=data.get("port"), env_vars=data.get("env_vars"), sandbox_type=data.get("sandbox_type"), - priority=data.get("priority"), metadata=dict(data.get("metadata") or {}), network_policy=data.get("network_policy"), ) @@ -139,7 +135,6 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: timeout=resolved_ttl, exposed_ports=self.exposed_ports or [], attribution=attribution, - priority=self.priority, network_policy=policy, ) else: @@ -154,7 +149,6 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: disk_size_gb=self.disk_size_gb, timeout=resolved_ttl, attribution=attribution, - priority=self.priority, network_policy=policy, ) diff --git a/src/agent_env/task_step/task_steps/verifiers/rubrics_verifier.py b/src/agent_env/task_step/task_steps/verifiers/rubrics_verifier.py index 831b40d7..e9738c37 100644 --- a/src/agent_env/task_step/task_steps/verifiers/rubrics_verifier.py +++ b/src/agent_env/task_step/task_steps/verifiers/rubrics_verifier.py @@ -291,7 +291,6 @@ def __init__( use_trajectory: bool = True, judge_a2a_agent_id: Optional[str] = None, judge_sandbox_type: Optional[str] = None, - judge_priority: Optional[int] = None, judge_timeout_seconds: Optional[int] = None, output_format: JudgeOutputFormat | str = JudgeOutputFormat.RUBRIC_BINARY, grading_policy_prompt: Optional[str] = None, @@ -337,7 +336,6 @@ def __init__( self.use_trajectory = use_trajectory self.judge_a2a_agent_id = judge_a2a_agent_id self.judge_sandbox_type = judge_sandbox_type - self.judge_priority = judge_priority self.judge_timeout_seconds = judge_timeout_seconds or self.DEFAULT_JUDGE_TIMEOUT_SECONDS if self.default_model_api_base and self.use_agent_judge: # Agent judges route through their deployed runtime, so this direct-judge @@ -409,7 +407,6 @@ def to_dict(self) -> dict: base["use_trajectory"] = self.use_trajectory base["judge_a2a_agent_id"] = self.judge_a2a_agent_id base["judge_sandbox_type"] = self.judge_sandbox_type - base["judge_priority"] = self.judge_priority base["judge_timeout_seconds"] = self.judge_timeout_seconds base["output_format"] = self.output_format.value base["grading_policy_prompt"] = self.grading_policy_prompt @@ -438,7 +435,6 @@ def from_dict(cls, data: dict) -> RubricsVerifierTaskStep: use_trajectory=data.get("use_trajectory", True), judge_a2a_agent_id=data.get("judge_a2a_agent_id"), judge_sandbox_type=data.get("judge_sandbox_type"), - judge_priority=data.get("judge_priority"), judge_timeout_seconds=data.get("judge_timeout_seconds"), output_format=data.get("output_format", "rubric_binary"), grading_policy_prompt=data.get("grading_policy_prompt"), @@ -588,10 +584,6 @@ async def execute(self, context: TaskStepContext) -> TaskStepContext: resolved_sandbox_type = overrides.get("agent_sandbox") or self.judge_sandbox_type if resolved_sandbox_type: deploy_kwargs["sandbox_type"] = resolved_sandbox_type - _priority_override = overrides.get("priority") - resolved_priority = _priority_override if _priority_override is not None else self.judge_priority - if resolved_priority is not None: - deploy_kwargs["priority"] = resolved_priority auto_deployed_judge = await a2a_agent.deploy(**deploy_kwargs) judge_a2a_url = auto_deployed_judge.a2a_url judge_sandbox_id = auto_deployed_judge.sandbox_id diff --git a/tst/unit/env/envs/test_mcp_server_container_mode.py b/tst/unit/env/envs/test_mcp_server_container_mode.py index 46f96697..620ef715 100644 --- a/tst/unit/env/envs/test_mcp_server_container_mode.py +++ b/tst/unit/env/envs/test_mcp_server_container_mode.py @@ -145,11 +145,11 @@ async def test_a_deploy_hands_the_gateway_its_sizing_state_and_attribution_and_r env, state, seen = _env(), SimpleNamespace(state_type="remote", instance_id="st-ext"), {} record = await _deploy(env, {"gw": _sandbox("gw")}, seen, state, gateway_mode=GatewayMode.CONSISTENT, env_state_type="remote", - ttl_seconds=60, disk_size_gb=20, cpu=2.0, memory_mb=4096, priority=3, attribution={"project_id": "p1"}) + ttl_seconds=60, disk_size_gb=20, cpu=2.0, memory_mb=4096, attribution={"project_id": "p1"}) assert ([c.environment_name for c in seen["mcp_servers"]], seen["mcp_server_images"]) == (["email"], [env.docker_image_artifact]) - assert {k: seen[k] for k in ("ttl_seconds", "disk_size_gb", "cpu", "memory_mb", "priority", "attribution", "gateway_mode")} == { - "ttl_seconds": 60, "disk_size_gb": 20, "cpu": 2.0, "memory_mb": 4096, "priority": 3, "attribution": {"project_id": "p1"}, + assert {k: seen[k] for k in ("ttl_seconds", "disk_size_gb", "cpu", "memory_mb", "attribution", "gateway_mode")} == { + "ttl_seconds": 60, "disk_size_gb": 20, "cpu": 2.0, "memory_mb": 4096, "attribution": {"project_id": "p1"}, "gateway_mode": GatewayMode.CONSISTENT} assert (seen["gateway_port"], seen["website_configs"], seen["website_images"], seen["existing_sandbox"], seen["sidecars"]) == ( 18765, None, None, None, None) @@ -199,9 +199,9 @@ async def test_a_deploy_without_a_gateway_records_the_servers_own_card(): async def test_a_deploy_without_a_gateway_hands_the_server_its_sizing_and_attribution(): seen = {} await _deploy(_env("server"), {"srv": _sandbox("srv")}, seen, gateway_mode=GatewayMode.PERFORMANCE, # the deploy_env step's default - ttl_seconds=60, disk_size_gb=20, cpu=2.0, memory_mb=4096, priority=3, attribution={"project_id": "p1"}) + ttl_seconds=60, disk_size_gb=20, cpu=2.0, memory_mb=4096, attribution={"project_id": "p1"}) - assert seen == {"ttl_seconds": 60, "disk_size_gb": 20, "cpu": 2.0, "memory_mb": 4096, "priority": 3, "attribution": {"project_id": "p1"}} + assert seen == {"ttl_seconds": 60, "disk_size_gb": 20, "cpu": 2.0, "memory_mb": 4096, "attribution": {"project_id": "p1"}} @pytest.mark.asyncio @@ -271,7 +271,7 @@ async def server_path(env, sandbox_provider, **kwargs): [record] = context.deployed_envs assert (record.env_provider_type, record.environment_card_url) == ("server", f"{_SRV}{WELL_KNOWN_PATH}") # the card the gate records assert seen["sandbox_provider"] is default - assert set(seen["options"]) == {"ttl_seconds", "disk_size_gb", "cpu", "memory_mb", "priority", "attribution"} + assert set(seen["options"]) == {"ttl_seconds", "disk_size_gb", "cpu", "memory_mb", "attribution"} def _env(env_provider_type: str = "gateway") -> MCPServerEnv: diff --git a/tst/unit/env/envs/test_mcp_server_plugin_provider.py b/tst/unit/env/envs/test_mcp_server_plugin_provider.py index 553c615a..6905310f 100644 --- a/tst/unit/env/envs/test_mcp_server_plugin_provider.py +++ b/tst/unit/env/envs/test_mcp_server_plugin_provider.py @@ -108,12 +108,12 @@ def test_reading_a_stored_env_looks_up_no_environment_provider(monkeypatch): @pytest.mark.asyncio async def test_a_plugin_provider_gets_every_option_and_its_record_is_registered(): env = _env() - record = await _deploy(env, ttl_seconds=60, cpu=2.0, priority=1, gateway_mode=GatewayMode.CONSISTENT, attribution={"project_id": "p"}) + record = await _deploy(env, ttl_seconds=60, cpu=2.0, gateway_mode=GatewayMode.CONSISTENT, attribution={"project_id": "p"}) [(sandbox_provider, options)] = SEEN["deploys"] assert sandbox_provider == "SANDBOXES" assert options == {"ttl_seconds": 60, "disk_size_gb": 10, "gateway_mode": GatewayMode.CONSISTENT, "cpu": 2.0, "memory_mb": None, - "priority": 1, "env_state_type": None, "env_state_instance_id": None, "attribution": {"project_id": "p"}} + "env_state_type": None, "env_state_instance_id": None, "attribution": {"project_id": "p"}} assert (record.instance_id, env._instance_id, env._deployed, env._sandbox, env._gateway_url) == ("inst-1", "inst-1", record, None, None) diff --git a/tst/unit/env/envs/test_multi_env_plugin_provider.py b/tst/unit/env/envs/test_multi_env_plugin_provider.py index 2a24bf93..504bdff4 100644 --- a/tst/unit/env/envs/test_multi_env_plugin_provider.py +++ b/tst/unit/env/envs/test_multi_env_plugin_provider.py @@ -165,7 +165,7 @@ def register(record, ttl_seconds): [deployed] = context.deployed_envs [(deployed_env, options)] = SEEN["deploys"] - assert deployed_env is env and set(options) == {"ttl_seconds", "disk_size_gb", "gateway_mode", "cpu", "memory_mb", "priority", + assert deployed_env is env and set(options) == {"ttl_seconds", "disk_size_gb", "gateway_mode", "cpu", "memory_mb", "env_state_type", "env_state_instance_id", "attribution"} assert (deployed.instance_id, deployed.mcp_url, env._sandbox, env._deployed) == ("inst-7", f"{_URL}/mcp", None, deployed) for child in [*env.mcp_server_envs, *env.website_envs]: diff --git a/tst/unit/explorer/explorer_app_test.py b/tst/unit/explorer/explorer_app_test.py index 5ddad604..93e9320d 100644 --- a/tst/unit/explorer/explorer_app_test.py +++ b/tst/unit/explorer/explorer_app_test.py @@ -840,15 +840,13 @@ def test_run_metadata_merges_into_inherited_user_overrides(client): from agent_env.explorer.routers.runs import RunRequest, _run_metadata meta = _run_metadata(RunRequest( - metadata={"user_overrides": {"agent_effort": "high", "priority": 1}}, + metadata={"user_overrides": {"agent_effort": "high", "step_params": {"deploy": {"cpu": 1}}}}, step_overrides={"deploy": {"cpu": 4}}, - priority=9, )) overrides = meta["user_overrides"] assert overrides["agent_effort"] == "high", "inherited keys survive" - assert overrides["step_params"] == {"deploy": {"cpu": 4}} - assert overrides["priority"] == 9, "an explicit field wins over the inherited one" + assert overrides["step_params"] == {"deploy": {"cpu": 4}}, "an explicit field wins over the inherited one" def test_bad_inherited_user_overrides_is_rejected(client, monkeypatch): @@ -866,13 +864,13 @@ async def run(self, **kw): for bad in ("oops", [1, 2], 7): resp = client.post( "/api/v1/tasks/t1/run", - json={"metadata": {"user_overrides": bad}, "priority": 1}, + json={"metadata": {"user_overrides": bad}}, ) assert resp.status_code == 422, f"user_overrides={bad!r} should be refused" ok = client.post( "/api/v1/tasks/t1/run", - json={"metadata": {"user_overrides": {"agent_effort": "high"}}, "priority": 1}, + json={"metadata": {"user_overrides": {"agent_effort": "high"}}}, ) assert ok.status_code == 200 diff --git a/tst/unit/providers/env_providers/env_gateway_provider_test.py b/tst/unit/providers/env_providers/env_gateway_provider_test.py index 880abe09..eedb9343 100644 --- a/tst/unit/providers/env_providers/env_gateway_provider_test.py +++ b/tst/unit/providers/env_providers/env_gateway_provider_test.py @@ -1316,14 +1316,14 @@ async def test_create_gateway_hands_the_deploy_path_every_argument(attribution, gp, provider = EnvironmentGatewayProvider(), MagicMock() args = dict(mcp_servers=[MagicMock()], mcp_server_images=[MagicMock()], gateway_port=18999, website_configs=[MagicMock()], website_images=[MagicMock()], gateway_mode=GatewayMode.CONSISTENT, ttl_seconds=61, disk_size_gb=11, cpu=1.5, - memory_mb=3072, priority=7, existing_sandbox=MagicMock(), sidecars=[MagicMock()], mcp_server_name="crm") + memory_mb=3072, existing_sandbox=MagicMock(), sidecars=[MagicMock()], mcp_server_name="crm") with patch.object(gp, "_deploy_via_vm", AsyncMock(return_value=_probed())) as vm, \ patch.object(env_gateway_provider, "_tool_names", AsyncMock(return_value=set())): await gp.create_gateway(sandbox_provider=provider, env_id="crm-env", attribution=attribution, **args) [call] = vm.await_args_list assert call.args == (provider, args.pop("mcp_servers"), args.pop("mcp_server_images")) - assert call.kwargs == {**args, "attribution": forwarded, "priority": 7} + assert call.kwargs == {**args, "attribution": forwarded} assert call.kwargs["attribution"] is not attribution diff --git a/tst/unit/providers/env_providers/env_server_provider_test.py b/tst/unit/providers/env_providers/env_server_provider_test.py index de14edf1..1d8de31f 100644 --- a/tst/unit/providers/env_providers/env_server_provider_test.py +++ b/tst/unit/providers/env_providers/env_server_provider_test.py @@ -53,9 +53,9 @@ async def test_a_deploy_returns_a_sandbox_record_of_the_servers_own_card_and_its @pytest.mark.asyncio async def test_a_deploy_starts_only_the_server_on_sqlite_with_its_sizing(): - run = await _run_server_deploy(cpu=2.0, memory_mb=4096, priority=3, attribution={"project_id": "0123456789abcdef01234567"}) + run = await _run_server_deploy(cpu=2.0, memory_mb=4096, attribution={"project_id": "0123456789abcdef01234567"}) [call] = run.calls - assert (call["image_name"], call["port"], call["cpu"], call["memory"], call["timeout"], call["priority"]) == ("mcp-slack", 18765, 2.0, 4096, 60, 3) + assert (call["image_name"], call["port"], call["cpu"], call["memory"], call["timeout"]) == ("mcp-slack", 18765, 2.0, 4096, 60) assert call["attribution"] == {"project_id": "0123456789abcdef01234567"} and "i6pn" not in call assert call["env"] == {"ENVIRONMENT_NAME": "slack", "MCP_HOST": "0.0.0.0", "DATABASE_URL": "sqlite:////tmp/slack.sqlite"} diff --git a/tst/unit/task/step_journal_test.py b/tst/unit/task/step_journal_test.py index b4b2b12c..04143f7c 100644 --- a/tst/unit/task/step_journal_test.py +++ b/tst/unit/task/step_journal_test.py @@ -205,7 +205,7 @@ def test_completion_that_does_not_land_deletes_its_journal_entry(store, monkeypa # ── replay reproduces the store ─────────────────────────────────────────────── def test_replaying_every_entry_reproduces_the_stored_context(store): - iid = _new(store, seed_md={"base": 1, "user_overrides": {"litellm_api_key": "sk", "priority": 1}}) + iid = _new(store, seed_md={"base": 1, "user_overrides": {"litellm_api_key": "sk", "agent_effort": "high"}}) _record(store, iid, "A", _ops({"base": 1}, {"base": 1, "a": {"k": 1}, "shared": "A", "l": [1]})) _record(store, iid, "B", _ops({"shared": "A", "l": [1]}, {"shared": "B", "l": [1, 2], "gone": None}, agent_model="m")) _record(store, iid, "C", _ops({"l": [1, 2], "gone": None}, {"l": [3, 1]})) # reorder -> wholesale set; key removed diff --git a/tst/unit/task_step/attribution_serialization_test.py b/tst/unit/task_step/attribution_serialization_test.py index a3e9b1a0..57db3056 100644 --- a/tst/unit/task_step/attribution_serialization_test.py +++ b/tst/unit/task_step/attribution_serialization_test.py @@ -4,9 +4,6 @@ rather than assumed because `tasks.steps[]` documents are versioned and immutable, and consumers query them by dotted path: a key that moves returns an empty result set, not an error. - -`priority` is serialized in the same block but is a scheduling concern, not -attribution, so it is not asserted here. """ from unittest.mock import MagicMock, patch diff --git a/tst/unit/task_step/context_ops_journal_test.py b/tst/unit/task_step/context_ops_journal_test.py index 67abd9d7..a84475f7 100644 --- a/tst/unit/task_step/context_ops_journal_test.py +++ b/tst/unit/task_step/context_ops_journal_test.py @@ -47,8 +47,8 @@ def test_nested_list_items_are_redaction_stripped(): def test_regraft_redacted_keys_restores_secrets_into_a_stored_context(): - live = {"user_overrides": {"litellm_api_key": "sk", "priority": 1}, "remote_tokens": "r", "plain": 1} - stored = {"user_overrides": {"priority": 1}, "plain": 1} + live = {"user_overrides": {"litellm_api_key": "sk", "agent_effort": "high"}, "remote_tokens": "r", "plain": 1} + stored = {"user_overrides": {"agent_effort": "high"}, "plain": 1} regraft_redacted_keys(live, stored) assert stored == live @@ -77,9 +77,9 @@ def test_regraft_never_overwrites_a_value_the_rebuild_did_write(): def test_the_judge_key_never_reaches_the_store_but_survives_a_rebuild(): - live = TaskStepContext(metadata={"user_overrides": {"judge_litellm_api_key": "sk-judge", "priority": 1}}) + live = TaskStepContext(metadata={"user_overrides": {"judge_litellm_api_key": "sk-judge", "agent_effort": "high"}}) stored = live.to_safe_dict() - assert stored["metadata"]["user_overrides"] == {"priority": 1} + assert stored["metadata"]["user_overrides"] == {"agent_effort": "high"} assert "sk-judge" not in repr(build_context_update_ops(None, live).to_journal_dict()) _rebuild_context(live, stored) - assert live.metadata["user_overrides"] == {"judge_litellm_api_key": "sk-judge", "priority": 1} + assert live.metadata["user_overrides"] == {"judge_litellm_api_key": "sk-judge", "agent_effort": "high"} diff --git a/tst/unit/task_step/deploy_env_test.py b/tst/unit/task_step/deploy_env_test.py index 1368372e..61009965 100644 --- a/tst/unit/task_step/deploy_env_test.py +++ b/tst/unit/task_step/deploy_env_test.py @@ -258,7 +258,7 @@ def test_preflight_reports_an_option_a_server_env_would_refuse(options, refused) @pytest.mark.parametrize("kind, options", [ - ("server", {"sandbox_type": "modal", "ttl_seconds": 60, "cpu": 2.0, "memory_mb": 4096, "disk_size_gb": 40, "priority": 1}), + ("server", {"sandbox_type": "modal", "ttl_seconds": 60, "cpu": 2.0, "memory_mb": 4096, "disk_size_gb": 40}), ("gateway", {"gateway_mode": "consistent", "env_state_type": "remote_postgres", "env_state_instance_id": "st-1"}), ("other", {"gateway_mode": "consistent", "env_state_type": "remote_postgres"}), ], ids=["server-sizing", "gateway-env", "other-env-type"]) diff --git a/tst/unit/task_step/retry_test.py b/tst/unit/task_step/retry_test.py index 0f28519e..067ca6ac 100644 --- a/tst/unit/task_step/retry_test.py +++ b/tst/unit/task_step/retry_test.py @@ -671,9 +671,9 @@ async def test_secrets_survive_the_rebuild_from_the_stored_context(store): # must graft them back, or the re-dispatched span loses its credentials. deploy = _FakeDeployEnv("s0") flaky = _FlakyPrompt("s1", retry_config=RetryConfig(retry_from_step_id="s0"), fail_times=1) - ctx = TaskStepContext(metadata={"user_overrides": {"litellm_api_key": "SECRET", "priority": 3}}) + ctx = TaskStepContext(metadata={"user_overrides": {"litellm_api_key": "SECRET", "agent_effort": "high"}}) result = await Task(id="t", version=1, steps=[deploy, flaky]).run(context=ctx) - assert result.metadata["user_overrides"] == {"litellm_api_key": "SECRET", "priority": 3} + assert result.metadata["user_overrides"] == {"litellm_api_key": "SECRET", "agent_effort": "high"} assert "SECRET" not in str(_doc(store, ctx.instance_id)) and "SECRET" not in str(_rows(store, ctx.instance_id)) diff --git a/tst/unit/task_step/stored_priority_test.py b/tst/unit/task_step/stored_priority_test.py new file mode 100644 index 00000000..5a9b9cc6 --- /dev/null +++ b/tst/unit/task_step/stored_priority_test.py @@ -0,0 +1,19 @@ +"""Stored step documents written before priority was removed still load, and drop the key.""" + +import pytest + +from agent_env.task_step.task_steps.deploy_agent import DeployAgentTaskStep +from agent_env.task_step.task_steps.deploy_env import DeployEnvTaskStep +from agent_env.task_step.task_steps.deploy_sandbox import DeploySandboxTaskStep +from agent_env.task_step.task_steps.verifiers.rubrics_verifier import RubricsVerifierTaskStep + + +@pytest.mark.parametrize("step, key", [ + (DeployEnvTaskStep(id="d", version=None, env_id="e"), "priority"), + (DeployAgentTaskStep(id="d", version=None), "priority"), + (DeploySandboxTaskStep(id="d", version=None, sandbox_name="sb", sandbox_mode="vm"), "priority"), + (RubricsVerifierTaskStep(id="v", version=None, criteria=[], prompt_id="p"), "judge_priority"), +], ids=["deploy_env", "deploy_agent", "deploy_sandbox", "rubrics_verifier"]) +def test_a_stored_step_with_an_unread_priority_still_loads(step, key): + document = step.to_dict() + assert type(step).from_dict({**document, key: 1}).to_dict() == document