Files
2026-07-13 13:12:33 +08:00

141 lines
5.7 KiB
Python

"""Wire-contract freeze for the ``config.effective`` provenance view.
``config.effective`` returns the effective LLM routing fields with per-field
provenance. Clients (Web UI config screens, ``opensquilla config``) script
against the envelope, the per-field record keys, the dotted field paths, and
the source vocabulary, so all four are public protocol contracts (CLAUDE.md:
public RPC field names are stable).
Unlike ``config.get`` (superset-friendly), this view is a curated allowlist:
every path it emits was individually chosen to be non-secret, so the tests
below use EXACT-set assertions. Adding a field here is itself a wire-contract
change: update the list below together with the resolver as a conscious
decision — an unexpected extra path failing this test is the alarm working,
not test friction.
Only synthetic credentials appear (``sk-test-000`` etc.); the environment is
already provider-key-free via tests/conftest.py.
"""
from __future__ import annotations
import pytest
from opensquilla.gateway.config import GatewayConfig, LlmProviderConfig
from opensquilla.gateway.rpc import RpcContext
from opensquilla.gateway.rpc_config import _handle_config_effective
# The full response envelope. Exactly one key: provenance data must never be
# merged with other config surfaces without a new contract decision.
ENVELOPE_KEYS = frozenset({"fields"})
# Every per-field record carries exactly these keys. A {path, value, source}
# triple was deliberately rejected (it defeats key-name redaction); the path
# is the dict key instead.
FIELD_RECORD_KEYS = frozenset({"value", "source"})
# The provenance vocabulary. "session" is reserved (no field emits it yet)
# but is part of the contract so clients can pre-wire rendering for it.
ALLOWED_SOURCES = frozenset({"default", "catalog", "preset", "config", "session"})
# Exact field-path set for a default config (the curated tokenrhythm default
# ladder: text tiers c0-c3 plus the packaged image tier). Tier paths follow
# whichever tiers the config actually carries; an image_model tier emits its
# provider/model paths when present. Conscious decision required to change:
# each entry is an individually vetted non-secret path — renames, removals,
# AND additions are contract changes that must update clients and this list
# together.
EXPECTED_FIELD_PATHS = frozenset(
{
"llm.provider",
"llm.model",
"llm.base_url",
"llm.max_tokens",
"llm.context_window",
"llm_ensemble.enabled",
"llm_ensemble.selection_mode",
"squilla_router.tiers.c0.provider",
"squilla_router.tiers.c0.model",
"squilla_router.tiers.c1.provider",
"squilla_router.tiers.c1.model",
"squilla_router.tiers.c2.provider",
"squilla_router.tiers.c2.model",
"squilla_router.tiers.c3.provider",
"squilla_router.tiers.c3.model",
"squilla_router.tiers.image_model.provider",
"squilla_router.tiers.image_model.model",
}
)
SYNTHETIC_SECRET = "sk-test-000" # synthetic; never a real credential
@pytest.fixture()
def default_config(tmp_path, monkeypatch: pytest.MonkeyPatch) -> GatewayConfig:
monkeypatch.setenv("OPENSQUILLA_STATE_DIR", str(tmp_path / "state"))
return GatewayConfig(config_path=str(tmp_path / "opensquilla.toml"))
async def _effective(config: GatewayConfig) -> dict:
return await _handle_config_effective(None, RpcContext(conn_id="test", config=config))
async def test_envelope_is_exactly_fields(default_config: GatewayConfig) -> None:
result = await _effective(default_config)
assert set(result) == ENVELOPE_KEYS
async def test_field_paths_are_frozen_exact_set(default_config: GatewayConfig) -> None:
result = await _effective(default_config)
assert set(result["fields"]) == EXPECTED_FIELD_PATHS
async def test_field_records_and_sources_are_frozen(default_config: GatewayConfig) -> None:
result = await _effective(default_config)
for path, record in result["fields"].items():
assert set(record) == FIELD_RECORD_KEYS, path
assert record["source"] in ALLOWED_SOURCES, path
async def test_no_secret_value_ever_reaches_the_wire(
tmp_path, monkeypatch: pytest.MonkeyPatch
) -> None:
# A config carrying explicit secrets across every secret-bearing surface
# the resolver walks near: the response must not contain the marker
# anywhere, in any key or value, at any nesting depth.
monkeypatch.setenv("OPENSQUILLA_STATE_DIR", str(tmp_path / "state"))
cfg = GatewayConfig(
config_path=str(tmp_path / "opensquilla.toml"),
# provider named explicitly: a bare api_key would resolve to the
# legacy openrouter default, whose curated ladder adds image_model
# paths beyond EXPECTED_FIELD_PATHS.
llm=LlmProviderConfig(provider="tokenrhythm", api_key=SYNTHETIC_SECRET),
channels={
"channels": [
{
"name": "feishu-main",
"type": "feishu",
"app_id": "cli_dummy_0000",
"app_secret": SYNTHETIC_SECRET,
"encrypt_key": SYNTHETIC_SECRET,
"verification_token": SYNTHETIC_SECRET,
},
{
"name": "wecom-main",
"type": "wecom",
"connection_mode": "webhook",
"corp_id": "ww_dummy_0000",
"corp_secret": SYNTHETIC_SECRET,
"agent_id_int": 1000002,
"token": SYNTHETIC_SECRET,
"encoding_aes_key": SYNTHETIC_SECRET,
},
]
},
)
result = await _effective(cfg)
assert set(result["fields"]) == EXPECTED_FIELD_PATHS
assert SYNTHETIC_SECRET not in repr(result)