refactor(agent): surface provider env defaults

This commit is contained in:
2026-06-01 22:32:03 +00:00
committed by didericis
parent e808e81b87
commit c8ab0c67a8
4 changed files with 20 additions and 24 deletions
+7 -5
View File
@@ -8,7 +8,7 @@ command, default image, and prompt/auth behavior.
from __future__ import annotations from __future__ import annotations
import os import os
from dataclasses import dataclass from dataclasses import dataclass, field
from pathlib import Path from pathlib import Path
from typing import Literal from typing import Literal
@@ -71,6 +71,7 @@ class AgentProvisionPlan:
image: str image: str
dockerfile: str dockerfile: str
guest_env: dict[str, str] guest_env: dict[str, str]
env_vars: dict[str, str] = field(default_factory=dict)
dirs: tuple[AgentProvisionDir, ...] = () dirs: tuple[AgentProvisionDir, ...] = ()
files: tuple[AgentProvisionFile, ...] = () files: tuple[AgentProvisionFile, ...] = ()
pre_copy: tuple[AgentProvisionCommand, ...] = () pre_copy: tuple[AgentProvisionCommand, ...] = ()
@@ -124,17 +125,17 @@ def agent_provision_plan(
) -> AgentProvisionPlan: ) -> AgentProvisionPlan:
runtime = runtime_for(template) runtime = runtime_for(template)
resolved_guest_env = dict(guest_env or {}) resolved_guest_env = dict(guest_env or {})
env_vars: dict[str, str] = {}
dirs: list[AgentProvisionDir] = [] dirs: list[AgentProvisionDir] = []
files: list[AgentProvisionFile] = [] files: list[AgentProvisionFile] = []
pre_copy: list[AgentProvisionCommand] = [] pre_copy: list[AgentProvisionCommand] = []
verify: list[AgentProvisionCommand] = [] verify: list[AgentProvisionCommand] = []
if template == PROVIDER_CODEX: if template == PROVIDER_CODEX:
resolved_guest_env.setdefault( env_vars["CODEX_CA_CERTIFICATE"] = "/etc/ssl/certs/ca-certificates.crt"
"CODEX_CA_CERTIFICATE",
"/etc/ssl/certs/ca-certificates.crt",
)
auth_dir = resolved_guest_env.get("CODEX_HOME", f"{guest_home}/.codex") auth_dir = resolved_guest_env.get("CODEX_HOME", f"{guest_home}/.codex")
if forward_host_credentials:
env_vars["CODEX_HOME"] = auth_dir
dirs.append(AgentProvisionDir(auth_dir)) dirs.append(AgentProvisionDir(auth_dir))
config_path = f"{auth_dir}/config.toml" config_path = f"{auth_dir}/config.toml"
config_file = state_dir / "codex-config.toml" config_file = state_dir / "codex-config.toml"
@@ -177,6 +178,7 @@ def agent_provision_plan(
prompt_mode=runtime.prompt_mode, prompt_mode=runtime.prompt_mode,
image=runtime.image, image=runtime.image,
dockerfile=dockerfile, dockerfile=dockerfile,
env_vars=env_vars,
guest_env=resolved_guest_env, guest_env=resolved_guest_env,
dirs=tuple(dirs), dirs=tuple(dirs),
files=tuple(files), files=tuple(files),
+5
View File
@@ -12,6 +12,7 @@ from __future__ import annotations
import os import os
from datetime import datetime, timezone from datetime import datetime, timezone
from dataclasses import replace
from pathlib import Path from pathlib import Path
from ...agent_provider import agent_provision_plan, runtime_for from ...agent_provider import agent_provision_plan, runtime_for
@@ -231,6 +232,10 @@ def resolve_plan(
forward_host_credentials=provider.forward_host_credentials, forward_host_credentials=provider.forward_host_credentials,
host_env=dict(os.environ), host_env=dict(os.environ),
) )
guest_env = dict(agent_provision.guest_env)
for key, val in agent_provision.env_vars.items():
guest_env.setdefault(key, val)
agent_provision = replace(agent_provision, guest_env=guest_env)
return DockerBottlePlan( return DockerBottlePlan(
spec=spec, spec=spec,
+5 -18
View File
@@ -12,6 +12,7 @@ from __future__ import annotations
import os import os
from datetime import datetime, timezone from datetime import datetime, timezone
from dataclasses import replace
from pathlib import Path from pathlib import Path
from ...agent_provider import agent_provision_plan, runtime_for from ...agent_provider import agent_provision_plan, runtime_for
@@ -128,24 +129,6 @@ def resolve_plan(
if provider.template == "claude" and has_provider_auth: if provider.template == "claude" and has_provider_auth:
guest_env.setdefault("CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC", "1") guest_env.setdefault("CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC", "1")
guest_env.setdefault("DISABLE_ERROR_REPORTING", "1") guest_env.setdefault("DISABLE_ERROR_REPORTING", "1")
if provider.template == "codex":
# Codex is a Rust/rustls client: unlike the Node agents it does
# NOT consult the system trust store or honor NODE_EXTRA_CA_CERTS.
# It reads CODEX_CA_CERTIFICATE (falling back to SSL_CERT_FILE)
# for custom roots, across HTTPS *and* the wss responses channel.
# Point it at the bundle update-ca-certificates rebuilt with the
# egress MITM CA so Codex trusts the proxy and egress can inject
# the host bearer — without this, codex bottles need
# pipelock tls_passthrough, which disables auth injection.
guest_env["CODEX_CA_CERTIFICATE"] = (
"/etc/ssl/certs/ca-certificates.crt"
)
if provider.template == "codex" and provider.forward_host_credentials:
# Smolvm exec process trees do not reliably inherit the image
# user's login environment. Pin CODEX_HOME to the same path
# provision_provider_auth writes so Codex never falls back to a
# root or unset home and shows the sign-in picker.
guest_env["CODEX_HOME"] = "/home/node/.codex"
supervise_plan = None supervise_plan = None
if bottle.supervise: if bottle.supervise:
@@ -189,6 +172,10 @@ def resolve_plan(
forward_host_credentials=provider.forward_host_credentials, forward_host_credentials=provider.forward_host_credentials,
host_env=dict(os.environ), host_env=dict(os.environ),
) )
merged_guest_env = dict(agent_provision.guest_env)
for key, val in agent_provision.env_vars.items():
merged_guest_env.setdefault(key, val)
agent_provision = replace(agent_provision, guest_env=merged_guest_env)
return SmolmachinesBottlePlan( return SmolmachinesBottlePlan(
spec=spec, spec=spec,
+3 -1
View File
@@ -42,8 +42,9 @@ class TestAgentProviderRuntime(unittest.TestCase):
self.assertEqual("/tmp/Dockerfile.codex", plan.dockerfile) self.assertEqual("/tmp/Dockerfile.codex", plan.dockerfile)
self.assertEqual( self.assertEqual(
"/etc/ssl/certs/ca-certificates.crt", "/etc/ssl/certs/ca-certificates.crt",
plan.guest_env["CODEX_CA_CERTIFICATE"], plan.env_vars["CODEX_CA_CERTIFICATE"],
) )
self.assertEqual({}, plan.guest_env)
self.assertEqual(("/home/node/.codex",), tuple(d.guest_path for d in plan.dirs)) self.assertEqual(("/home/node/.codex",), tuple(d.guest_path for d in plan.dirs))
self.assertEqual( self.assertEqual(
("/home/node/.codex/config.toml",), ("/home/node/.codex/config.toml",),
@@ -70,6 +71,7 @@ class TestAgentProviderRuntime(unittest.TestCase):
"/run/codex-home/auth.json", "/run/codex-home/auth.json",
{f.guest_path for f in plan.files}, {f.guest_path for f in plan.files},
) )
self.assertEqual("/run/codex-home", plan.env_vars["CODEX_HOME"])
self.assertEqual(1, len(plan.pre_copy)) self.assertEqual(1, len(plan.pre_copy))
self.assertEqual(1, len(plan.verify)) self.assertEqual(1, len(plan.verify))
self.assertIn("CODEX_HOME=/run/codex-home", plan.verify[0].argv) self.assertIn("CODEX_HOME=/run/codex-home", plan.verify[0].argv)