feat(smolmachines): backend skeleton + Smolfile/gvproxy renderers (PRD 0023 chunk 1) #62

Merged
didericis merged 2 commits from prd-0023-chunk-1-skeleton into main 2026-05-27 03:18:48 -04:00
3 changed files with 51 additions and 37 deletions
Showing only changes of commit 2aca9e609a - Show all commits
+5 -16
View File
@@ -17,6 +17,7 @@ from ...log import info
from ...pipelock import PipelockProxyPlan
from ...supervise import SupervisePlan
from .. import BottlePlan
from ..print_util import print_multi
@dataclass(frozen=True)
@@ -70,22 +71,10 @@ class DockerBottlePlan(BottlePlan):
# from the agent to the proxy is needed.
env_names = sorted(set(bottle.env.keys()) | set(self.forwarded_env.keys()))
def _multi(label: str, values: list[str]) -> None:
"""Print a label with N continuation-indented values. Used
for env / skills / git-gate / egress where one item
per line keeps the summary scannable."""
if not values:
info(f"{label}: (none)")
return
info(f"{label}: {values[0]}")
indent = " " * (len(label) + 2)
for v_ in values[1:]:
info(f"{indent}{v_}")
print(file=sys.stderr)
info(f"agent : {spec.agent_name}")
_multi("env ", env_names)
_multi("skills ", list(agent.skills))
print_multi("env ", env_names)
print_multi("skills ", list(agent.skills))
info(f"bottle : {agent.bottle}")
git_lines = [
@@ -93,13 +82,13 @@ class DockerBottlePlan(BottlePlan):
for u in self.git_gate_plan.upstreams
]
if git_lines:
_multi(" git gate ", git_lines)
print_multi(" git gate ", git_lines)
if self.egress_plan.routes:
egress_lines = []
for r in self.egress_plan.routes:
auth = f" [auth:{r.auth_scheme}]" if r.auth_scheme else ""
egress_lines.append(f"{r.host}{auth}")
_multi(" egress ", egress_lines)
print_multi(" egress ", egress_lines)
print(file=sys.stderr)
+28
View File
@@ -0,0 +1,28 @@
"""Shared print helpers for BottlePlan.print implementations.
Lifts the multi-value label printer out of DockerBottlePlan so the
smolmachines backend (and any future backend) renders the same
two-column scannable preflight without duplicating the indent
math."""
from __future__ import annotations
from typing import Sequence
from ..log import info
def print_multi(label: str, values: Sequence[str]) -> None:
"""Print `label: <value>` with continuation lines indented to
align under the first value. Empty `values` renders `(none)`.
Used by every backend's `BottlePlan.print` for env / skills /
git / egress — one item per line keeps the preflight summary
scannable when an agent has many of any of these."""
if not values:
info(f"{label}: (none)")
return
info(f"{label}: {values[0]}")
indent = " " * (len(label) + 2)
for v in values[1:]:
info(f"{indent}{v}")
@@ -8,11 +8,13 @@ launch flow grows."""
from __future__ import annotations
import sys
from dataclasses import dataclass
from pathlib import Path
from ...log import info
from .. import BottlePlan
from ..print_util import print_multi
@dataclass(frozen=True)
@@ -33,32 +35,27 @@ class SmolmachinesBottlePlan(BottlePlan):
host_port_map: dict[str, int]
def print(self, *, remote_control: bool) -> None:
"""Compact y/N preflight for the smolmachines path. Mirrors
the docker preflight's layout so operators don't have to
learn two formats."""
"""Compact y/N preflight. Same shape as the Docker
backend's so operators see one format across backends."""
del remote_control # not surfaced in the compact summary
spec = self.spec
manifest = spec.manifest
agent = manifest.agents[spec.agent_name]
bottle = manifest.bottle_for(spec.agent_name)
info(f"backend: smolmachines")
info(f"agent: {spec.agent_name}")
info(f"bottle: {agent.bottle}")
info(f"slug: {self.slug}")
info(f"gvproxy: {self.gvproxy_gateway} on {self.gvproxy_subnet}")
env_names = sorted(bottle.env.keys())
skills = list(agent.skills)
upstreams = [g.Name for g in bottle.git]
upstreams = [
f"{g.Name}{g.Upstream}" for g in bottle.git
]
routes = [r.host for r in bottle.egress.routes]
info(f"env: {', '.join(env_names) if env_names else '(none)'}")
info(f"skills: {', '.join(skills) if skills else '(none)'}")
info(f"git: {', '.join(upstreams) if upstreams else '(none)'}")
info(f"routes: {', '.join(routes) if routes else '(none)'}")
info(f"smolfile: {self.smolfile_path}")
info(f"gvproxy config: {self.gvproxy_config_path}")
info(
"(chunk 1 of PRD 0023: prepare-only — launch is "
"not yet implemented)"
)
print(file=sys.stderr)
info(f"agent : {spec.agent_name}")
print_multi("env ", env_names)
print_multi("skills ", list(agent.skills))
info(f"bottle : {agent.bottle}")
if upstreams:
print_multi(" git gate ", upstreams)
if routes:
print_multi(" egress ", routes)
print(file=sys.stderr)