refactor: move guest_home onto AgentProvisionPlan as source of truth
guest_home is now a field on AgentProvisionPlan (set by each provider's provision_plan() method). BottlePlan.guest_home becomes a read-only property delegating to agent_provision.guest_home so existing callers (provision_git, provision_skills, provision_prompt) are unchanged. Both resolve_plan.py files drop guest_home from the plan constructor call; the local variable still exists as an intermediary for the workspace_plan call that precedes agent_provision_plan.
This commit is contained in:
@@ -103,6 +103,7 @@ class AgentProvisionPlan:
|
|||||||
prompt_mode: PromptMode
|
prompt_mode: PromptMode
|
||||||
image: str
|
image: str
|
||||||
dockerfile: str
|
dockerfile: str
|
||||||
|
guest_home: str
|
||||||
guest_env: dict[str, str]
|
guest_env: dict[str, str]
|
||||||
env_vars: dict[str, str] = field(default_factory=dict)
|
env_vars: dict[str, str] = field(default_factory=dict)
|
||||||
dirs: tuple[AgentProvisionDir, ...] = ()
|
dirs: tuple[AgentProvisionDir, ...] = ()
|
||||||
|
|||||||
@@ -78,9 +78,12 @@ class BottlePlan(ABC):
|
|||||||
|
|
||||||
spec: BottleSpec
|
spec: BottleSpec
|
||||||
stage_dir: Path
|
stage_dir: Path
|
||||||
guest_home: str
|
|
||||||
git_gate_plan: GitGatePlan
|
git_gate_plan: GitGatePlan
|
||||||
|
|
||||||
|
@property
|
||||||
|
def guest_home(self) -> str:
|
||||||
|
return self.agent_provision.guest_home
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def git_gate_insteadof_host(self) -> str:
|
def git_gate_insteadof_host(self) -> str:
|
||||||
"""Host (and optional port) used in git-gate insteadOf URLs.
|
"""Host (and optional port) used in git-gate insteadOf URLs.
|
||||||
|
|||||||
@@ -169,7 +169,6 @@ def resolve_plan(
|
|||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage_dir,
|
stage_dir=stage_dir,
|
||||||
guest_home=guest_home,
|
|
||||||
slug=slug,
|
slug=slug,
|
||||||
container_name=container_name,
|
container_name=container_name,
|
||||||
container_name_pinned=container_name_pinned,
|
container_name_pinned=container_name_pinned,
|
||||||
|
|||||||
@@ -114,7 +114,6 @@ def resolve_plan(
|
|||||||
return SmolmachinesBottlePlan(
|
return SmolmachinesBottlePlan(
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage_dir,
|
stage_dir=stage_dir,
|
||||||
guest_home=guest_home,
|
|
||||||
slug=slug,
|
slug=slug,
|
||||||
bundle_subnet=subnet,
|
bundle_subnet=subnet,
|
||||||
bundle_gateway=gateway,
|
bundle_gateway=gateway,
|
||||||
|
|||||||
@@ -110,6 +110,7 @@ class ClaudeAgentProvider(AgentProvider):
|
|||||||
prompt_mode=_RUNTIME.prompt_mode,
|
prompt_mode=_RUNTIME.prompt_mode,
|
||||||
image=_RUNTIME.image,
|
image=_RUNTIME.image,
|
||||||
dockerfile=dockerfile,
|
dockerfile=dockerfile,
|
||||||
|
guest_home=guest_home,
|
||||||
env_vars=env_vars,
|
env_vars=env_vars,
|
||||||
guest_env=resolved_guest_env,
|
guest_env=resolved_guest_env,
|
||||||
files=files,
|
files=files,
|
||||||
|
|||||||
@@ -147,6 +147,7 @@ class CodexAgentProvider(AgentProvider):
|
|||||||
prompt_mode=_RUNTIME.prompt_mode,
|
prompt_mode=_RUNTIME.prompt_mode,
|
||||||
image=_RUNTIME.image,
|
image=_RUNTIME.image,
|
||||||
dockerfile=dockerfile,
|
dockerfile=dockerfile,
|
||||||
|
guest_home=guest_home,
|
||||||
env_vars=env_vars,
|
env_vars=env_vars,
|
||||||
guest_env=resolved_guest_env,
|
guest_env=resolved_guest_env,
|
||||||
dirs=tuple(dirs),
|
dirs=tuple(dirs),
|
||||||
|
|||||||
@@ -149,7 +149,6 @@ def _plan(
|
|||||||
|
|
||||||
spec = _spec(supervise=supervise, with_git=with_git, with_egress=with_egress)
|
spec = _spec(supervise=supervise, with_git=with_git, with_egress=with_egress)
|
||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=STAGE,
|
stage_dir=STAGE,
|
||||||
slug=SLUG,
|
slug=SLUG,
|
||||||
@@ -172,6 +171,7 @@ def _plan(
|
|||||||
prompt_mode="append_file",
|
prompt_mode="append_file",
|
||||||
image="bot-bottle-claude:latest",
|
image="bot-bottle-claude:latest",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env={},
|
guest_env={},
|
||||||
),
|
),
|
||||||
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
||||||
@@ -252,6 +252,7 @@ class TestAgentAlwaysPresent(unittest.TestCase):
|
|||||||
prompt_mode="read_prompt_file",
|
prompt_mode="read_prompt_file",
|
||||||
image="bot-bottle-codex:latest",
|
image="bot-bottle-codex:latest",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env={"CODEX_HOME": "/home/node/.codex"},
|
guest_env={"CODEX_HOME": "/home/node/.codex"},
|
||||||
)
|
)
|
||||||
plan = type(plan)(**{**vars(plan), "agent_provision": provision}) # type: ignore
|
plan = type(plan)(**{**vars(plan), "agent_provision": provision}) # type: ignore
|
||||||
|
|||||||
@@ -76,7 +76,6 @@ def _plan(
|
|||||||
current_config_dir=Path("/tmp/current-config"),
|
current_config_dir=Path("/tmp/current-config"),
|
||||||
)
|
)
|
||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=Path("/tmp/stage"),
|
stage_dir=Path("/tmp/stage"),
|
||||||
slug="demo-abc12",
|
slug="demo-abc12",
|
||||||
@@ -106,7 +105,7 @@ def _plan(
|
|||||||
use_runsc=False,
|
use_runsc=False,
|
||||||
agent_provision=agent_provision or AgentProvisionPlan(
|
agent_provision=agent_provision or AgentProvisionPlan(
|
||||||
template="claude", command="claude", prompt_mode="append_file",
|
template="claude", command="claude", prompt_mode="append_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
),
|
),
|
||||||
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
||||||
)
|
)
|
||||||
@@ -211,7 +210,7 @@ class TestClaudeProvision(unittest.TestCase):
|
|||||||
def test_copies_files_and_chowns(self):
|
def test_copies_files_and_chowns(self):
|
||||||
provision = AgentProvisionPlan(
|
provision = AgentProvisionPlan(
|
||||||
template="claude", command="claude", prompt_mode="append_file",
|
template="claude", command="claude", prompt_mode="append_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
files=(AgentProvisionFile(
|
files=(AgentProvisionFile(
|
||||||
Path("/tmp/claude.json"), "/home/node/.claude.json",
|
Path("/tmp/claude.json"), "/home/node/.claude.json",
|
||||||
),),
|
),),
|
||||||
@@ -234,7 +233,7 @@ class TestClaudeProvision(unittest.TestCase):
|
|||||||
def test_dies_when_file_chown_fails(self):
|
def test_dies_when_file_chown_fails(self):
|
||||||
provision = AgentProvisionPlan(
|
provision = AgentProvisionPlan(
|
||||||
template="claude", command="claude", prompt_mode="append_file",
|
template="claude", command="claude", prompt_mode="append_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
files=(AgentProvisionFile(
|
files=(AgentProvisionFile(
|
||||||
Path("/tmp/claude.json"), "/home/node/.claude.json",
|
Path("/tmp/claude.json"), "/home/node/.claude.json",
|
||||||
),),
|
),),
|
||||||
@@ -250,7 +249,7 @@ class TestClaudeProvision(unittest.TestCase):
|
|||||||
def test_runs_verify_commands(self):
|
def test_runs_verify_commands(self):
|
||||||
provision = AgentProvisionPlan(
|
provision = AgentProvisionPlan(
|
||||||
template="claude", command="claude", prompt_mode="append_file",
|
template="claude", command="claude", prompt_mode="append_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
verify=(AgentProvisionCommand(
|
verify=(AgentProvisionCommand(
|
||||||
("/usr/bin/true",), "verify failed",
|
("/usr/bin/true",), "verify failed",
|
||||||
),),
|
),),
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ def _plan(
|
|||||||
current_config_dir=Path("/tmp/current-config"),
|
current_config_dir=Path("/tmp/current-config"),
|
||||||
)
|
)
|
||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=Path("/tmp/stage"),
|
stage_dir=Path("/tmp/stage"),
|
||||||
slug="demo-abc12",
|
slug="demo-abc12",
|
||||||
@@ -107,7 +106,7 @@ def _plan(
|
|||||||
use_runsc=False,
|
use_runsc=False,
|
||||||
agent_provision=agent_provision or AgentProvisionPlan(
|
agent_provision=agent_provision or AgentProvisionPlan(
|
||||||
template="codex", command="codex", prompt_mode="read_prompt_file",
|
template="codex", command="codex", prompt_mode="read_prompt_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
),
|
),
|
||||||
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
||||||
)
|
)
|
||||||
@@ -177,7 +176,7 @@ class TestCodexProvision(unittest.TestCase):
|
|||||||
provision = AgentProvisionPlan(
|
provision = AgentProvisionPlan(
|
||||||
template="codex", command="codex",
|
template="codex", command="codex",
|
||||||
prompt_mode="read_prompt_file",
|
prompt_mode="read_prompt_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
dirs=(AgentProvisionDir("/home/node/.codex"),),
|
dirs=(AgentProvisionDir("/home/node/.codex"),),
|
||||||
files=(AgentProvisionFile(
|
files=(AgentProvisionFile(
|
||||||
Path("/tmp/codex-config.toml"),
|
Path("/tmp/codex-config.toml"),
|
||||||
@@ -201,7 +200,7 @@ class TestCodexProvision(unittest.TestCase):
|
|||||||
provision = AgentProvisionPlan(
|
provision = AgentProvisionPlan(
|
||||||
template="codex", command="codex",
|
template="codex", command="codex",
|
||||||
prompt_mode="read_prompt_file",
|
prompt_mode="read_prompt_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
pre_copy=(AgentProvisionCommand(
|
pre_copy=(AgentProvisionCommand(
|
||||||
("find", "/home/node/.codex", "-name", "*.sqlite", "-delete"),
|
("find", "/home/node/.codex", "-name", "*.sqlite", "-delete"),
|
||||||
"could not reset runtime db files",
|
"could not reset runtime db files",
|
||||||
@@ -223,7 +222,7 @@ class TestCodexProvision(unittest.TestCase):
|
|||||||
provision = AgentProvisionPlan(
|
provision = AgentProvisionPlan(
|
||||||
template="codex", command="codex",
|
template="codex", command="codex",
|
||||||
prompt_mode="read_prompt_file",
|
prompt_mode="read_prompt_file",
|
||||||
image="", dockerfile="", guest_env={},
|
image="", dockerfile="", guest_home="/home/node", guest_env={},
|
||||||
dirs=(AgentProvisionDir("/home/node/.codex"),),
|
dirs=(AgentProvisionDir("/home/node/.codex"),),
|
||||||
)
|
)
|
||||||
bottle = _make_bottle(exec_result=ExecResult(1, "", "mkdir: nope\n"))
|
bottle = _make_bottle(exec_result=ExecResult(1, "", "mkdir: nope\n"))
|
||||||
|
|||||||
@@ -43,7 +43,6 @@ def _plan(tmp: str) -> DockerBottlePlan:
|
|||||||
identity="test-teardown-00001",
|
identity="test-teardown-00001",
|
||||||
)
|
)
|
||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage,
|
stage_dir=stage,
|
||||||
git_gate_plan=GitGatePlan(
|
git_gate_plan=GitGatePlan(
|
||||||
@@ -66,6 +65,7 @@ def _plan(tmp: str) -> DockerBottlePlan:
|
|||||||
prompt_mode="append_file",
|
prompt_mode="append_file",
|
||||||
image="",
|
image="",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env={},
|
guest_env={},
|
||||||
),
|
),
|
||||||
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ def _plan(*, git_user: dict | None = None, # type: ignore
|
|||||||
copy_cwd=copy_cwd, user_cwd=user_cwd,
|
copy_cwd=copy_cwd, user_cwd=user_cwd,
|
||||||
)
|
)
|
||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage_dir or Path("/tmp/stage"),
|
stage_dir=stage_dir or Path("/tmp/stage"),
|
||||||
slug="demo-abc12",
|
slug="demo-abc12",
|
||||||
@@ -95,6 +94,7 @@ def _plan(*, git_user: dict | None = None, # type: ignore
|
|||||||
prompt_mode="append_file",
|
prompt_mode="append_file",
|
||||||
image="bot-bottle-claude:latest",
|
image="bot-bottle-claude:latest",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env={},
|
guest_env={},
|
||||||
),
|
),
|
||||||
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
workspace_plan=workspace_plan(spec, guest_home="/home/node"),
|
||||||
|
|||||||
@@ -86,6 +86,7 @@ def _agent_provision() -> AgentProvisionPlan:
|
|||||||
prompt_mode="append_file",
|
prompt_mode="append_file",
|
||||||
image="",
|
image="",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env={"HTTPS_PROXY": "http://127.0.0.1:9999"},
|
guest_env={"HTTPS_PROXY": "http://127.0.0.1:9999"},
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -93,7 +94,6 @@ def _agent_provision() -> AgentProvisionPlan:
|
|||||||
def _docker_plan(spec: BottleSpec, tmp: str) -> DockerBottlePlan:
|
def _docker_plan(spec: BottleSpec, tmp: str) -> DockerBottlePlan:
|
||||||
stage = Path(tmp)
|
stage = Path(tmp)
|
||||||
return DockerBottlePlan(
|
return DockerBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage,
|
stage_dir=stage,
|
||||||
git_gate_plan=_git_gate_plan(tmp),
|
git_gate_plan=_git_gate_plan(tmp),
|
||||||
@@ -118,7 +118,6 @@ def _docker_plan(spec: BottleSpec, tmp: str) -> DockerBottlePlan:
|
|||||||
def _smolmachines_plan(spec: BottleSpec, tmp: str) -> SmolmachinesBottlePlan:
|
def _smolmachines_plan(spec: BottleSpec, tmp: str) -> SmolmachinesBottlePlan:
|
||||||
stage = Path(tmp)
|
stage = Path(tmp)
|
||||||
return SmolmachinesBottlePlan(
|
return SmolmachinesBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage,
|
stage_dir=stage,
|
||||||
git_gate_plan=_git_gate_plan(tmp),
|
git_gate_plan=_git_gate_plan(tmp),
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ class TestSmolmachinesResolveEnv(unittest.TestCase):
|
|||||||
prompt_mode="append_file",
|
prompt_mode="append_file",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
image="bot-bottle-claude:latest",
|
image="bot-bottle-claude:latest",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env=dict(kwargs.get("guest_env") or {}),
|
guest_env=dict(kwargs.get("guest_env") or {}),
|
||||||
)
|
)
|
||||||
mock_app.side_effect = lambda **kw: _make_provision(**kw) # type: ignore
|
mock_app.side_effect = lambda **kw: _make_provision(**kw) # type: ignore
|
||||||
|
|||||||
@@ -140,7 +140,6 @@ def _plan(
|
|||||||
current_config_dir=Path("/tmp/current-config"),
|
current_config_dir=Path("/tmp/current-config"),
|
||||||
)
|
)
|
||||||
return SmolmachinesBottlePlan(
|
return SmolmachinesBottlePlan(
|
||||||
guest_home="/home/node",
|
|
||||||
spec=spec,
|
spec=spec,
|
||||||
stage_dir=stage_dir or Path("/tmp/stage"),
|
stage_dir=stage_dir or Path("/tmp/stage"),
|
||||||
slug="demo-abc12",
|
slug="demo-abc12",
|
||||||
@@ -190,6 +189,7 @@ def _agent_provision(
|
|||||||
prompt_mode="append_file",
|
prompt_mode="append_file",
|
||||||
image="",
|
image="",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env=dict(guest_env or {}),
|
guest_env=dict(guest_env or {}),
|
||||||
)
|
)
|
||||||
auth_dir = (guest_env or {}).get("CODEX_HOME", "/home/node/.codex")
|
auth_dir = (guest_env or {}).get("CODEX_HOME", "/home/node/.codex")
|
||||||
@@ -227,6 +227,7 @@ def _agent_provision(
|
|||||||
prompt_mode="read_prompt_file",
|
prompt_mode="read_prompt_file",
|
||||||
image="bot-bottle-codex:latest",
|
image="bot-bottle-codex:latest",
|
||||||
dockerfile="",
|
dockerfile="",
|
||||||
|
guest_home="/home/node",
|
||||||
guest_env=dict(guest_env or {}),
|
guest_env=dict(guest_env or {}),
|
||||||
dirs=(AgentProvisionDir(auth_dir),),
|
dirs=(AgentProvisionDir(auth_dir),),
|
||||||
files=tuple(files),
|
files=tuple(files),
|
||||||
|
|||||||
Reference in New Issue
Block a user