de9bd7eb83
Operators can now declare:
agent_provider:
template: claude
auth_token: BOT_BOTTLE_CLAUDE_OAUTH_TOKEN
and the provisioner injects a provider-owned api.anthropic.com egress
route (Bearer, tls_passthrough) rather than requiring a manually
declared route with the former claude_code_oauth role.
Changes:
- Add auth_token field to AgentProvider; validate claude-only.
- Remove claude_code_oauth from EGRESS_ROLES / PROVIDER_EGRESS_ROLES.
Manifests that declare the role now fail at parse time with "unknown
role" — the provisioner owns the route.
- agent_provision_plan: replace manifest_egress_routes/has_provider_auth
with auth_token; Claude branch injects the api.anthropic.com route,
placeholder env, and nonessential-traffic flags when auth_token is set.
- Add hidden_env_names: frozenset[str] to AgentProvisionPlan; Claude
branch populates it with CLAUDE_CODE_OAUTH_TOKEN.
- Remove auth_role from AgentProviderRuntime and placeholder_env_for().
- print_util.visible_agent_env_names: accept hidden_env_names from the
plan instead of dispatching on agent_provider_template.
- Both backends: drop manifest_egress_routes call, pass auth_token.
- PRD 0029 rescoped to cover both Codex and Claude provider auth.
Assisted-by: Claude Code
42 lines
1.4 KiB
Python
42 lines
1.4 KiB
Python
"""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}")
|
|
|
|
|
|
def visible_agent_env_names(
|
|
env_names: Sequence[str], *, hidden_env_names: frozenset[str],
|
|
) -> list[str]:
|
|
"""Env names worth showing in launch summaries.
|
|
|
|
Provider-injected placeholder env vars are implementation details:
|
|
they are non-secret dummy values that satisfy provider CLIs while
|
|
egress injects the real Authorization header. The plan's
|
|
`hidden_env_names` carries exactly which names to suppress.
|
|
"""
|
|
return sorted({name for name in env_names if name and name not in hidden_env_names})
|