97 lines
3.5 KiB
Python
97 lines
3.5 KiB
Python
"""SmolmachinesBottlePlan — concrete BottlePlan for the smolmachines
|
|
backend (PRD 0023).
|
|
|
|
Slug + legacy bundle network coordinates + smolvm machine name +
|
|
agent `.smolmachine` artifact + per-bottle guest env."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from pathlib import Path
|
|
|
|
from ...agent_provider import PromptMode
|
|
from .. import BottlePlan
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class SmolmachinesBottlePlan(BottlePlan):
|
|
"""Resolved fields the launch step needs to bring up the bottle.
|
|
|
|
Inherits `spec`, `stage_dir`, `git_gate_plan`, `egress_plan`,
|
|
`supervise_plan`, and `agent_provision` from BottlePlan."""
|
|
|
|
slug: str
|
|
# Legacy per-bottle bundle network coordinates. These remain on
|
|
# the plan while BundleLaunchSpec still carries the original shape,
|
|
# but the smolmachines launch path exposes the sidecar VM through
|
|
# host-loopback forwarders instead of a Docker bridge IP.
|
|
bundle_subnet: str
|
|
bundle_gateway: str
|
|
bundle_ip: str
|
|
# In-guest env vars (HTTPS_PROXY etc) — IP-literal URLs since
|
|
# the guest has no DNS resolver inside the TSI allowlist.
|
|
# Passed to `smolvm machine create` as `-e K=V` flags.
|
|
# Smolfile-rendering is gone (smolvm 0.8.0's
|
|
# `--smolfile` is mutually exclusive with `--from`, and
|
|
# `--from` is the path that avoids the registry-pull race).
|
|
guest_env: dict[str, str]
|
|
# Agent-side endpoints. Empty at prepare time; launch populates
|
|
# these after sidecar VM bringup via `dataclasses.replace`.
|
|
# Format: a `host:port` for git-gate (insteadOf URL prefix) +
|
|
# full URLs for proxy / supervise.
|
|
agent_proxy_url: str = ""
|
|
agent_git_gate_host: str = ""
|
|
agent_supervise_url: str = ""
|
|
|
|
@property
|
|
def machine_name(self) -> str:
|
|
"""smolvm machine name. `machine_create` boots from a packed
|
|
`.smolmachine` artifact (pre-baked at prepare time via
|
|
`smolvm pack create`); using `--from` instead of `--image`
|
|
avoids the registry-pull race we hit when machine_start tried
|
|
to fetch on-demand and the libkrun agent's network attempt
|
|
got refused by macOS."""
|
|
return self.agent_provision.instance_name
|
|
|
|
@property
|
|
def agent_image(self) -> str:
|
|
"""Agent image ref (docker tag). `launch` runs the
|
|
build → save → registry push → smolvm pack pipeline against
|
|
this and feeds the resulting `.smolmachine` artifact to
|
|
`machine_create --from`. The pipeline runs at launch time
|
|
(not prepare time) so the docker build output doesn't garble
|
|
the dashboard's preflight modal."""
|
|
return self.agent_provision.image
|
|
|
|
@property
|
|
def prompt_file(self) -> Path:
|
|
"""Path to the agent's prompt file on the host. Always written
|
|
(mode 0o600) so the in-VM path always exists; the file is
|
|
empty when the agent has no prompt — claude-code reads it
|
|
via --append-system-prompt-file only when non-empty."""
|
|
return self.agent_provision.prompt_file
|
|
|
|
@property
|
|
def git_gate_insteadof_host(self) -> str:
|
|
return self.agent_git_gate_host
|
|
|
|
@property
|
|
def git_gate_insteadof_scheme(self) -> str:
|
|
return "http"
|
|
|
|
@property
|
|
def agent_command(self) -> str:
|
|
return self.agent_provision.command
|
|
|
|
@property
|
|
def agent_prompt_mode(self) -> PromptMode:
|
|
return self.agent_provision.prompt_mode
|
|
|
|
@property
|
|
def agent_provider_template(self) -> str:
|
|
return self.agent_provision.template
|
|
|
|
@property
|
|
def agent_dockerfile_path(self) -> str:
|
|
return self.agent_provision.dockerfile
|