config: agent_panel block (enabled/surfaces/min_quality/daily budget)

New optional config.json block for the upcoming LLM agent-panel feature:
enabled, telegram, dashboard (per-surface toggles), min_quality,
max_panels_per_day, reuse_ttl_seconds. Absent block → {} → feature dark.
Validation mirrors the deepseek block. Module 23 opened with parse +
reject tests.

Claude-Session: https://claude.ai/code/session_01SisdfkxnXNL9iZsXxN3T15
This commit is contained in:
Harwinder Sekhon
2026-08-07 22:26:43 -04:00
parent 250078c987
commit 0b604f1ad0
3 changed files with 75 additions and 1 deletions
+36
View File
@@ -6943,6 +6943,42 @@ def _():
assert "must be > 0" in str(e)
print("\n═══ Module 23: LLM agent panel ═══")
@test("app_config: agent_panel block parses; absent block → {}")
def _():
app = load_app_config(_write_json({"agent_panel": {
"enabled": True, "telegram": True, "dashboard": False,
"min_quality": "A", "max_panels_per_day": 10,
"reuse_ttl_seconds": 600}}))
assert app.agent_panel_settings["enabled"] is True
assert app.agent_panel_settings["min_quality"] == "A"
assert app.agent_panel_settings["max_panels_per_day"] == 10
assert load_app_config(_write_json({})).agent_panel_settings == {}
assert AppConfig().agent_panel_settings == {}
@test("app_config: agent_panel rejects unknown keys and bad types")
def _():
for payload in (
{"agent_panel": {"enabld": True}}, # unknown key
{"agent_panel": {"enabled": "yes"}}, # not a bool
{"agent_panel": {"telegram": 1}}, # not a bool
{"agent_panel": {"dashboard": "no"}}, # not a bool
{"agent_panel": {"min_quality": "Z"}}, # invalid grade
{"agent_panel": {"max_panels_per_day": 0}}, # not positive
{"agent_panel": {"max_panels_per_day": True}}, # bool is not an int
{"agent_panel": {"reuse_ttl_seconds": -5}}, # negative
{"agent_panel": "oops"}, # not an object
):
try:
load_app_config(_write_json(payload))
assert False, f"should have raised for {payload}"
except AppConfigError:
pass
# ══════════════════════════════════════════════════════════════════════
# SUMMARY
# ══════════════════════════════════════════════════════════════════════