feat(opencode): multi-provider support with local provider for qwen3.8-27b
This commit is contained in:
+34
-14
@@ -389,12 +389,26 @@ def sanitize_workdir(workdir: str) -> list[str]:
|
||||
|
||||
|
||||
def install_config(src: str, dst: str) -> bool:
|
||||
"""Copy `opencode.json` from src to dst, substituting the model endpoint.
|
||||
"""Copy `opencode.json` from src to dst, substituting per-provider endpoint
|
||||
+ API key.
|
||||
|
||||
The committed `opencode.json` carries a neutral placeholder for the model
|
||||
provider's `baseURL`, so the repo can be public without publishing the
|
||||
address of a private network. The real endpoint is supplied at runtime by
|
||||
`PRAGENT_MODEL_BASE_URL` and patched in here.
|
||||
The committed `opencode.json` carries neutral placeholders for every
|
||||
provider's `baseURL`/`apiKey` so the repo can be public without leaking
|
||||
private-network addresses. Real values are supplied at runtime and patched
|
||||
in here.
|
||||
|
||||
Env var convention (case-sensitive provider name — `headroom`, `local`):
|
||||
|
||||
PRAGENT_<NAME>_BASE_URL — per-provider endpoint override
|
||||
PRAGENT_<NAME>_API_KEY — per-provider API key override
|
||||
PRAGENT_MODEL_BASE_URL — legacy catchall, applies to every provider
|
||||
when the per-provider var is unset
|
||||
PRAGENT_MODEL_API_KEY — legacy catchall (same)
|
||||
|
||||
Per-provider wins over the catchall. The first 2 win when the operator
|
||||
needs a different endpoint per upstream (e.g. headroom → MiniMax, local →
|
||||
ai-workstation). The catchall keeps the single-provider deploys from
|
||||
needing any env config.
|
||||
|
||||
This is done in Python rather than with opencode's own `{env:VAR}` config
|
||||
templating because the reviewer subprocess runs with an allow-listed
|
||||
@@ -405,20 +419,26 @@ def install_config(src: str, dst: str) -> bool:
|
||||
"""
|
||||
if not os.path.isfile(src):
|
||||
return False
|
||||
base_url = os.environ.get("PRAGENT_MODEL_BASE_URL", "").strip()
|
||||
api_key = os.environ.get("PRAGENT_MODEL_API_KEY", "").strip()
|
||||
if not base_url and not api_key:
|
||||
default_url = os.environ.get("PRAGENT_MODEL_BASE_URL", "").strip()
|
||||
default_key = os.environ.get("PRAGENT_MODEL_API_KEY", "").strip()
|
||||
if not default_url and not default_key:
|
||||
# Fast path: no env at all → commit copy is fine, no rewrite needed.
|
||||
shutil.copy2(src, dst)
|
||||
return True
|
||||
try:
|
||||
with open(src, encoding="utf-8") as f:
|
||||
cfg = json.load(f)
|
||||
for prov in (cfg.get("provider") or {}).values():
|
||||
if isinstance(prov, dict) and isinstance(prov.get("options"), dict):
|
||||
if base_url:
|
||||
prov["options"]["baseURL"] = base_url
|
||||
if api_key:
|
||||
prov["options"]["apiKey"] = api_key
|
||||
for name, prov in (cfg.get("provider") or {}).items():
|
||||
if not isinstance(prov, dict) or not isinstance(prov.get("options"), dict):
|
||||
continue
|
||||
per_url = os.environ.get(f"PRAGENT_{name.upper()}_BASE_URL", "").strip()
|
||||
per_key = os.environ.get(f"PRAGENT_{name.upper()}_API_KEY", "").strip()
|
||||
url = per_url or default_url
|
||||
key = per_key or default_key
|
||||
if url:
|
||||
prov["options"]["baseURL"] = url
|
||||
if key:
|
||||
prov["options"]["apiKey"] = key
|
||||
with open(dst, "w", encoding="utf-8") as f:
|
||||
json.dump(cfg, f, indent=2)
|
||||
except (OSError, ValueError, AttributeError):
|
||||
|
||||
Reference in New Issue
Block a user