feat(admin): add Fireworks API key and proxy to admin manifest

Registers FIREWORKS_API_KEY / FIREWORKS_PROXY in api/admin_config FIELDS so the UI can set credentials and provider status stays accurate.

Adds admin apply test and contract guards linking PROVIDER_CATALOG to FIELD_BY_KEY; updates .env.example.
This commit is contained in:
Alishahryar1
2026-05-20 20:57:11 -07:00
parent 54a9dc4e34
commit fe98abf675
4 changed files with 117 additions and 1 deletions
+7 -1
View File
@@ -26,6 +26,10 @@ OPENCODE_API_KEY=""
ZAI_API_KEY=""
# Fireworks AI Config (OpenAI-compatible Chat Completions at api.fireworks.ai/inference/v1)
FIREWORKS_API_KEY=""
# LM Studio Config (local provider, no API key required)
LM_STUDIO_BASE_URL="http://localhost:1234/v1"
@@ -40,7 +44,7 @@ OLLAMA_BASE_URL="http://localhost:11434"
# All Claude model requests are mapped to these models, plain model is fallback
# Format: provider_type/model/name
# Valid providers: "nvidia_nim" | "open_router" | "deepseek" | "lmstudio" | "llamacpp" | "ollama" | "kimi" | "wafer" | "opencode" | "zai"
# Valid providers: "nvidia_nim" | "open_router" | "deepseek" | "lmstudio" | "llamacpp" | "ollama" | "kimi" | "wafer" | "opencode" | "zai" | "fireworks"
MODEL_OPUS=
MODEL_SONNET=
MODEL_HAIKU=
@@ -59,6 +63,7 @@ FCC_SMOKE_MODEL_KIMI=
FCC_SMOKE_MODEL_WAFER=
FCC_SMOKE_MODEL_OPENCODE=
FCC_SMOKE_MODEL_ZAI=
FCC_SMOKE_MODEL_FIREWORKS=
FCC_SMOKE_NIM_MODELS=
FCC_SMOKE_NIM_EXTRA_MODELS=
FCC_SMOKE_OPENROUTER_FREE_MODELS=
@@ -84,6 +89,7 @@ KIMI_PROXY=""
WAFER_PROXY=""
OPENCODE_PROXY=""
ZAI_PROXY=""
FIREWORKS_PROXY=""
PROVIDER_RATE_LIMIT=1
PROVIDER_RATE_WINDOW=3
+18
View File
@@ -176,6 +176,15 @@ FIELDS: tuple[ConfigFieldSpec, ...] = (
secret=True,
description="Z.ai Coding Plan API key.",
),
ConfigFieldSpec(
"FIREWORKS_API_KEY",
"Fireworks API Key",
"providers",
"secret",
settings_attr="fireworks_api_key",
secret=True,
description="Fireworks AI inference API key.",
),
ConfigFieldSpec(
"LM_STUDIO_BASE_URL",
"LM Studio Base URL",
@@ -269,6 +278,15 @@ FIELDS: tuple[ConfigFieldSpec, ...] = (
secret=True,
advanced=True,
),
ConfigFieldSpec(
"FIREWORKS_PROXY",
"Fireworks Proxy",
"providers",
"secret",
settings_attr="fireworks_proxy",
secret=True,
advanced=True,
),
ConfigFieldSpec(
"MODEL",
"Default Model",
+26
View File
@@ -102,6 +102,7 @@ def test_admin_config_masks_secrets_and_exposes_manifest(monkeypatch, tmp_path):
keys = {field["key"] for field in body["fields"]}
assert "ANTHROPIC_AUTH_TOKEN" in keys
assert "OPENROUTER_API_KEY" in keys
assert "FIREWORKS_API_KEY" in keys
assert "ZAI_BASE_URL" not in keys
assert "CLAUDE_WORKSPACE" not in keys
assert "CLAUDE_CLI_BIN" not in keys
@@ -181,6 +182,31 @@ def test_admin_apply_writes_complete_managed_env_and_masks_preview(
}
def test_admin_apply_writes_fireworks_key_and_masks_preview(monkeypatch, tmp_path):
_set_home(monkeypatch, tmp_path)
_clear_process_config(monkeypatch)
app = create_app(lifespan_enabled=False)
response = _local_client(app).post(
"/admin/api/config/apply",
json={
"values": {
"MODEL": "fireworks/test-model",
"FIREWORKS_API_KEY": "fw-secret",
}
},
)
assert response.status_code == 200
body = response.json()
assert body["applied"] is True
assert "FIREWORKS_API_KEY=********" in body["env_preview"]
env_file = tmp_path / ".fcc" / ".env"
text = env_file.read_text(encoding="utf-8")
assert "MODEL=fireworks/test-model" in text
assert "FIREWORKS_API_KEY=fw-secret" in text
def test_admin_apply_preserves_hidden_diagnostics_and_smoke_values(
monkeypatch, tmp_path
):
@@ -0,0 +1,66 @@
"""Ensure admin UI manifest exposes every catalog credential/proxy binding."""
from __future__ import annotations
from api.admin_config import FIELD_BY_KEY
from config.provider_catalog import PROVIDER_CATALOG
from config.settings import Settings
def test_provider_catalog_remote_credentials_in_admin_manifest() -> None:
missing: list[str] = []
wrong_attr: list[str] = []
for provider_id, desc in PROVIDER_CATALOG.items():
if desc.credential_env is None:
continue
if desc.credential_attr is None:
missing.append(
f"{provider_id}: credential_env set but credential_attr missing"
)
continue
entry = FIELD_BY_KEY.get(desc.credential_env)
if entry is None:
missing.append(
f"{provider_id}: {desc.credential_env} not in admin FIELD_BY_KEY"
)
continue
if entry.settings_attr != desc.credential_attr:
wrong_attr.append(
f"{provider_id}: {desc.credential_env} maps settings_attr="
f"{entry.settings_attr!r}, catalog expects "
f"{desc.credential_attr!r}"
)
assert not missing and not wrong_attr, "\n".join(missing + wrong_attr)
def test_provider_catalog_proxy_attrs_in_admin_manifest() -> None:
missing_key: list[str] = []
wrong_attr: list[str] = []
for provider_id, desc in PROVIDER_CATALOG.items():
if desc.proxy_attr is None:
continue
mf = Settings.model_fields[desc.proxy_attr]
alias = mf.validation_alias
if alias is None:
missing_key.append(
f"{provider_id}: {desc.proxy_attr} has no validation_alias "
"(admin manifest expects env-backed proxy)"
)
continue
env_key = str(alias)
entry = FIELD_BY_KEY.get(env_key)
if entry is None:
missing_key.append(
f"{provider_id}: proxy env {env_key} not in FIELD_BY_KEY"
)
continue
if entry.settings_attr != desc.proxy_attr:
wrong_attr.append(
f"{provider_id}: {env_key} maps settings_attr="
f"{entry.settings_attr!r}, catalog expects {desc.proxy_attr!r}"
)
assert not missing_key and not wrong_attr, "\n".join(missing_key + wrong_attr)