config

package
v0.0.10 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 5, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package config holds the wsproxy runtime configuration. All env-var defaults and flag registrations are centralised here so the rest of the codebase is free of os.Getenv calls.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ParseModelList added in v0.0.10

func ParseModelList(spec string) []agentsv1alpha1.ManagedAgentModel

ParseModelList reads a model dropdown from one flag value.

Entries are comma-separated and each is "id", "id|Display Name" or "id|Display Name|nonreasoning". A model id may not contain a comma, so the two separators cannot collide.

The nonreasoning marker is not decoration: it is what makes a model eligible to back the topic classifier, and a reasoning model there spends its whole completion budget on the chain of thought and returns empty content, which reads as "same topic" every single time.

Types

type Config

type Config struct {
	// ListenAddr is the address the terminal WebSocket proxy listens on.
	// Flag: --listen-addr  Env: WSPROXY_LISTEN_ADDR  Default: :9003
	ListenAddr string

	// InternalAddr is the address the internal management API listens on.
	// Only used when SyncToken is non-empty.
	// Flag: --internal-addr  Env: WSPROXY_INTERNAL_ADDR  Default: :9004
	InternalAddr string

	// ClustersFilePath is the path to clusters.yaml consumed by cluster.Store.
	// Flag: --clusters-config  Env: CLUSTERS_CONFIG_PATH
	ClustersFilePath string

	// Secret is the single shared secret used for:
	//   - dialling Worker /v1/ws/sync endpoints (AGENTBOX-SYNC-TOKEN header);
	//   - gating the legacy /internal/* routes (static token check);
	//   - verifying Bearer JWTs issued by the BFF (HS256).
	// When empty the sync manager is disabled and JWT auth is off.
	// Flag: --secret  Env: AGENTBOX_SECRET
	Secret string

	// AdminKey is the shared admin API key used by the internal API auth
	// middleware to recognise admin callers via AGENTBOX-API-KEY header.
	// When empty the internal API runs in dev mode (anonymous admin).
	// Flag: --admin-key  Env: AGENTBOX_ADMIN_KEY
	AdminKey string

	// MaxKeysPerUser is the per-(namespace, user) API key count limit.
	// 0 means unlimited.
	// Flag: --max-keys-per-user  Env: AGENTBOX_MAX_KEYS_PER_USER
	MaxKeysPerUser int

	// APIKeyNamespace is the Kubernetes namespace where API key Secrets are stored.
	// Flag: --apikey-namespace  Env: AGENTBOX_APIKEY_NAMESPACE  Default: agentbox-system
	APIKeyNamespace string

	// ImagesCatalogConfigMap is the name of the ConfigMap that holds the images
	// catalog. It is stored in APIKeyNamespace.
	// Flag: --images-catalog-configmap  Env: AGENTBOX_IMAGES_CATALOG_CONFIGMAP
	// Default: agentbox-images-catalog
	ImagesCatalogConfigMap string

	// ManagedAgentEnabled starts the ManagedAgent controller alongside the
	// proxy. It lives here rather than in the worker binary because a
	// ManagedAgent is a control-plane object: the worker chart installs on
	// every cluster, so reconciling it there would run one controller per
	// cluster for a single set of resources.
	// Flag: --managed-agent  Env: AGENTBOX_MANAGED_AGENT_ENABLED  Default: false
	ManagedAgentEnabled bool

	// ManagedAgentGatewayAddr is the listener that serves published agents to
	// callers outside the cluster. It is separate from the internal API because
	// that one trusts a manager token: an ingress may only be pointed at a port
	// where every request carries its own credential. Empty disables publishing.
	ManagedAgentGatewayAddr string

	// ManagedAgentPublicBaseURL is the shared route published agents answer on,
	// e.g. "https://console.example.com/agentbox/api/managed-agents". It is
	// configuration rather than something the controller can derive: only the
	// chart knows the hostname and base path the ingress was created with.
	ManagedAgentPublicBaseURL string

	// ManagedAgentProxyService is this process as in-cluster callers address it,
	// "<service>.<namespace>:<port>". Reported as status.endpoint so nothing
	// hands out the Brain's own unauthenticated address.
	ManagedAgentProxyService string

	// ManagedAgentNamespace restricts the controller's cache and watches to one
	// namespace. Empty watches all namespaces, which needs cluster-wide RBAC.
	// Flag: --managed-agent-namespace  Env: AGENTBOX_MANAGED_AGENT_NAMESPACE
	ManagedAgentNamespace string

	// ManagedAgentBrainImage is the Brain image an agent gets when it names none.
	//
	// This is what lets an agent be created from a prompt alone: requiring the
	// caller to name an image means knowing which one ships a gateway compatible
	// with this control plane, and that is the deployment's business rather than
	// the tenant's.
	//
	// Empty keeps the image required, which is correct for a deployment that has
	// not published one — inventing a reference would surface much later as an
	// ImagePullBackOff, a long way from the cause.
	// Flag: --managed-agent-brain-image  Env: AGENTBOX_MANAGED_AGENT_BRAIN_IMAGE
	ManagedAgentBrainImage string

	// ManagedAgentBrainImageTag is the tag paired with the repository above.
	// Kept separate so the chart can carry `image.repository` and `image.tag` as
	// two values, the way every other image in it is expressed.
	// Flag: --managed-agent-brain-image-tag
	// Env: AGENTBOX_MANAGED_AGENT_BRAIN_IMAGE_TAG
	ManagedAgentBrainImageTag string

	// ManagedAgentBrainPullSecrets names imagePullSecrets for the default Brain
	// image, comma-separated. A private registry needs them, and an agent created
	// from a prompt alone has no place to declare them.
	// Flag: --managed-agent-brain-pull-secrets
	// Env: AGENTBOX_MANAGED_AGENT_BRAIN_PULL_SECRETS
	ManagedAgentBrainPullSecrets string

	// ── Default sandbox supply ────────────────────────────────────────────────
	//
	// Together these describe one E2B-compatible sandbox service an agent is given
	// when it declares no hands of its own. It is the other half of creating an
	// agent from a prompt alone: the three sandbox branches all ask the caller
	// which cluster, which environment and which image, and the image in
	// particular fails silently — a sandbox started from a pool's default image
	// comes up and then refuses every command.
	//
	// The credential is named, not carried: the pod that reads it is the Brain, in
	// the agent's namespace, so what this process needs is a Secret reference to
	// render rather than the key itself. Nothing here ever holds the value.
	//
	// HandsAPIURL empty disables the default entirely.
	// Flag: --managed-agent-hands-api-url
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_API_URL
	ManagedAgentHandsAPIURL string

	// ManagedAgentHandsDomain is the data-plane gateway, host plus any ingress
	// path. Omitting the path is the usual cause of "the sandbox exists but no
	// port answers".
	// Flag: --managed-agent-hands-domain
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_DOMAIN
	ManagedAgentHandsDomain string

	// ManagedAgentHandsHTTPS selects https for the data plane. Default true.
	// Flag: --managed-agent-hands-https
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_HTTPS
	ManagedAgentHandsHTTPS bool

	// ManagedAgentHandsEnvName is the environment to launch sandboxes from,
	// written verbatim: a bare name ("navix") or one scoped to a cluster
	// ("cluster::navix").
	// Flag: --managed-agent-hands-env-name
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_ENV_NAME
	ManagedAgentHandsEnvName string

	// ManagedAgentHandsImage overrides the sandbox main-container image.
	// Effectively required: a member pool's default image does not run the sandbox
	// command endpoint, so leaving it empty yields sandboxes that start and then
	// answer every command with a 502, with nothing wrong on the control plane.
	// Flag: --managed-agent-hands-image
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_IMAGE
	ManagedAgentHandsImage string

	// ManagedAgentHandsScalingGroup pins the default's sandboxes to one member
	// pool. Empty lets the environment route them.
	// Flag: --managed-agent-hands-scaling-group
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_SCALING_GROUP
	ManagedAgentHandsScalingGroup string

	// ManagedAgentHandsSecretName and ...Key name the Secret holding the sandbox
	// API key for the default supply. It must exist in the namespace the agents
	// run in, since it is the Brain's kubelet that resolves it.
	//
	// This credential is the platform's own, deliberately not the caller's: the
	// default environment belongs to the deployment, and an agent using it must
	// not need — or receive — a sandbox key of its own.
	// Flag: --managed-agent-hands-secret-name
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_SECRET_NAME
	ManagedAgentHandsSecretName string
	// Flag: --managed-agent-hands-secret-key
	// Env: AGENTBOX_MANAGED_AGENT_HANDS_SECRET_KEY
	ManagedAgentHandsSecretKey string

	// ── Default model provider ────────────────────────────────────────────────
	//
	// Address and model list only. The key stays per agent: this publishes where
	// the deployment's models live so a caller does not have to know, and the
	// console prefills a create form from it.
	// Flag: --managed-agent-model-base-url
	// Env: AGENTBOX_MANAGED_AGENT_MODEL_BASE_URL
	ManagedAgentModelBaseURL string

	// ManagedAgentModels is the model dropdown a new agent starts with, as
	// comma-separated entries of "id", "id|Display Name" or
	// "id|Display Name|nonreasoning". The list is the only source of that
	// dropdown — no endpoint is queried for it — so a deployment that publishes
	// none leaves the caller to type them.
	// Flag: --managed-agent-models  Env: AGENTBOX_MANAGED_AGENT_MODELS
	ManagedAgentModels string

	// ManagedAgentModelDefault is the model a new agent starts on, and
	// ManagedAgentModelSmall backs a harness's own side tasks (titles and the
	// like).
	// Flag: --managed-agent-model-default
	// Env: AGENTBOX_MANAGED_AGENT_MODEL_DEFAULT
	ManagedAgentModelDefault string
	// Flag: --managed-agent-model-small
	// Env: AGENTBOX_MANAGED_AGENT_MODEL_SMALL
	ManagedAgentModelSmall string

	// ManagedAgentModelSecretName and ...Key name the Secret holding the model
	// credential every agent gets when it declares no harness of its own.
	//
	// Both set is what turns the published endpoint into a usable default: without
	// a credential the Brain comes up healthy and reports every harness
	// unavailable, which is legible but is still an agent that cannot answer.
	//
	// Configuring it is a deliberate trade a deployment makes, not an oversight to
	// fix. One shared key is one quota, one revocation and one audit trail for
	// every agent; a deployment that needs those separate leaves this unset and
	// each agent brings its own key. Only the REFERENCE is held here — the Brain
	// resolves it in the agents' namespace and this process never reads the value.
	// Flag: --managed-agent-model-secret-name
	// Env: AGENTBOX_MANAGED_AGENT_MODEL_SECRET_NAME
	ManagedAgentModelSecretName string
	// Flag: --managed-agent-model-secret-key
	// Env: AGENTBOX_MANAGED_AGENT_MODEL_SECRET_KEY
	ManagedAgentModelSecretKey string

	// NotificationConfigMap is the name of the ConfigMap that holds the
	// notification service's config + runtime state. Stored in APIKeyNamespace.
	// Flag: --notification-configmap  Env: AGENTBOX_NOTIFICATION_CONFIGMAP
	// Default: agentbox-notifications
	NotificationConfigMap string

	// FeishuWebhookURL is the Feishu (Lark) bot webhook the notification
	// service posts daily reports and idle alerts to. Empty disables sending.
	// Flag: --feishu-webhook-url  Env: FEISHU_WEBHOOK_URL
	FeishuWebhookURL string

	// PrometheusURL is the base query URL of the Prometheus-compatible metrics
	// store the notification service reads sandbox-create counters from.
	// Empty disables the daily report and idle alert (no data source).
	// Flag: --prometheus-url  Env: PROMETHEUS_URL
	PrometheusURL string

	// PrometheusToken is the bearer token sent with every PrometheusURL query.
	// Flag: --prometheus-token  Env: PROMETHEUS_TOKEN
	PrometheusToken string
}

Config holds all wsproxy runtime settings. Each field maps 1:1 to a CLI flag whose default value is the matching environment variable (or a hard-coded default when the env var is absent).

func FromFlags

func FromFlags(fs *flag.FlagSet) *Config

FromFlags registers all wsproxy flags on fs and returns a *Config whose fields point to the registered flag values. Call flag.Parse() (or fs.Parse()) after this to populate the fields.

Each flag's default is the corresponding environment variable, falling back to the built-in default when the env var is absent.

func (*Config) DefaultBrainImage added in v0.0.10

func (c *Config) DefaultBrainImage() agentsv1alpha1.ManagedAgentImage

DefaultBrainImage is the Brain image an agent gets when it names none.

An empty repository is passed through as empty rather than defaulted to something: the renderer treats that as "this deployment has no default" and keeps spec.image.repository required, which fails with a readable message. Substituting a guess here would instead produce a Deployment that reconciles cleanly and then sits in ImagePullBackOff.

func (*Config) DefaultHands added in v0.0.10

func (c *Config) DefaultHands() *agentsv1alpha1.ManagedAgentHands

DefaultHands is the sandbox supply an agent gets when it declares no branch.

Nil when no API URL is configured. That is the whole switch: a deployment either names a sandbox service its agents may use by default or it does not, and a half-configured default — an endpoint with no environment name, say — would create sandboxes that fail at the first tool call, so the missing pieces are reported by the agent's HandsReady condition rather than guessed at here.

The credential is a reference, never a value. The pod that reads it is the Brain, in the agents' namespace, and this process only has to render the pointer; the key itself is not held here and does not pass through the API.

func (*Config) DefaultModelProvider added in v0.0.10

func (c *Config) DefaultModelProvider() ModelProviderDefaults

DefaultModelProvider is the model endpoint and dropdown a new agent starts with.

func (*Config) DefaultRuntime added in v0.0.10

func (c *Config) DefaultRuntime() *agentsv1alpha1.ManagedAgentRuntime

DefaultRuntime is the harness configuration an agent gets when it declares none of its own.

Nil unless BOTH an endpoint and a credential reference are configured. A half-configured default is worse than none: an endpoint with no key produces an agent whose Brain is healthy and whose every harness reports itself unavailable, which reads as a broken platform rather than as configuration a deployment chose not to supply.

Rendered as Claude Code because it is the harness whose sandbox confinement is verified by a driven session; the OpenCode override mechanism is still an open question against 1.18.16. An agent that wants OpenCode configures its own runtime, which suppresses this default entirely.

func (*Config) SyncEnabled

func (c *Config) SyncEnabled() bool

SyncEnabled reports whether the sync manager (and internal API) should be started. It is true when Secret is non-empty.

func (*Config) Validate

func (c *Config) Validate() error

Validate checks that the Config is consistent. It does not require Secret to be set — an empty Secret simply disables the sync manager and internal API.

type ModelProviderDefaults added in v0.0.10

type ModelProviderDefaults struct {
	BaseURL      string
	Models       []agentsv1alpha1.ManagedAgentModel
	DefaultModel string
	SmallModel   string
}

ModelProviderDefaults is the model endpoint a new agent starts with.

There is no credential here, and there is not meant to be: publishing an address and a model list saves a caller from knowing them, while a key that the platform handed to every agent would make one agent's quota and one agent's revocation everyone's.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL