"""Configuration resolution for the opencode-bridge extension. Priority order (highest to lowest): 1. jupyter settings dict (from schema/plugin.json) 2. Environment variables (OPENCODE_BRIDGE_URL, _USER, _PASSWORD) 3. Built-in defaults """ from __future__ import annotations import os from typing import NamedTuple, Optional, Tuple ENV_URL = "OPENCODE_BRIDGE_URL" ENV_USER = "OPENCODE_BRIDGE_USER" ENV_PASSWORD = "OPENCODE_BRIDGE_PASSWORD" DEFAULT_URL = "http://127.0.0.1:4096" DEFAULT_USER = "opencode" DEFAULT_REQUEST_TIMEOUT = 120 class OpenCodeConfig(NamedTuple): url: str user: str password: str request_timeout_seconds: int = DEFAULT_REQUEST_TIMEOUT @property def auth(self) -> Optional[Tuple[str, str]]: """Return (user, password) for HTTP Basic Auth, or None if no password set.""" if not self.password: return None return (self.user, self.password) def resolve_config(jupyter_settings: dict) -> OpenCodeConfig: """Resolve OpenCode connection config from jupyter settings + env + defaults.""" bridge = jupyter_settings.get("opencode_bridge", {}) or {} return OpenCodeConfig( url=bridge.get("opencodeServerUrl") or os.environ.get(ENV_URL) or DEFAULT_URL, user=bridge.get("opencodeServerUser") or os.environ.get(ENV_USER) or DEFAULT_USER, password=( bridge.get("opencodeServerPassword") or os.environ.get(ENV_PASSWORD) or "" ), request_timeout_seconds=int( bridge.get("requestTimeoutSeconds", DEFAULT_REQUEST_TIMEOUT) ), )