From 4eda6d1bc6447826b0930dcd910b8a526a756568 Mon Sep 17 00:00:00 2001 From: grimmjoww578 Date: Fri, 24 Jul 2026 07:29:20 -0400 Subject: [PATCH 1/2] fix(config): wire prm.temperature from config.yaml to PRMScorer The prm_temperature field existed on SkillClawConfig but was never populated from the prm section of config.yaml, so PRM scoring always sent the hard default 0.6 upstream. Models with sampling constraints (e.g. kimi k3, which only accepts temperature=1) rejected every PRM vote with HTTP 400, silently disabling PRM scoring. Map prm.temperature (already settable via 'skillclaw config prm.temperature ') through to SkillClawConfig, keeping 0.6 as the default when unset. --- skillclaw/config_store.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/skillclaw/config_store.py b/skillclaw/config_store.py index b2aa7c9..ff7f5d0 100644 --- a/skillclaw/config_store.py +++ b/skillclaw/config_store.py @@ -337,6 +337,7 @@ def to_skillclaw_config(self) -> SkillClawConfig: prm_url = str(prm.get("url", "") or llm_api_base) prm_model = str(prm.get("model", "") or llm_model_id or "gpt-5.2") prm_api_key = str(prm.get("api_key", "") or llm_api_key) + prm_temperature = float(prm.get("temperature", 0.6) or 0.6) skills_dir = resolve_skills_dir( skills.get("dir", str(_DEFAULT_SKILLS_DIR)), @@ -377,6 +378,7 @@ def to_skillclaw_config(self) -> SkillClawConfig: prm_url=prm_url, prm_model=prm_model, prm_api_key=prm_api_key, + prm_temperature=prm_temperature, # Model model_name=llm.get("model_id") or "Qwen/Qwen3-4B", # Claw From cd99bb26ae2041cf6496997bdcc07e88807e58fa Mon Sep 17 00:00:00 2001 From: grimmjoww578 Date: Fri, 24 Jul 2026 07:37:04 -0400 Subject: [PATCH 2/2] fix(config): honor explicit prm temperature 0, document key in defaults MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review feedback on the initial wiring: float(prm.get('temperature', 0.6) or 0.6) silently rewrote an explicit temperature: 0 to 0.6 — the same 'user setting ignored' defect class this PR exists to fix. Use a None-check guard instead, and add temperature to the defaults dict so the key is self-documenting in seeded configs. Adds tests/test_prm_temperature_config.py pinning: configured values pass through (1, 0.2), explicit 0 is honored, absent key defaults to 0.6. 4/4 passing. --- skillclaw/config_store.py | 4 ++- tests/test_prm_temperature_config.py | 49 ++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 tests/test_prm_temperature_config.py diff --git a/skillclaw/config_store.py b/skillclaw/config_store.py index ff7f5d0..c37ee02 100644 --- a/skillclaw/config_store.py +++ b/skillclaw/config_store.py @@ -61,6 +61,7 @@ "url": "", "model": "", "api_key": "", + "temperature": 0.6, }, "sharing": { "enabled": False, @@ -337,7 +338,8 @@ def to_skillclaw_config(self) -> SkillClawConfig: prm_url = str(prm.get("url", "") or llm_api_base) prm_model = str(prm.get("model", "") or llm_model_id or "gpt-5.2") prm_api_key = str(prm.get("api_key", "") or llm_api_key) - prm_temperature = float(prm.get("temperature", 0.6) or 0.6) + _prm_temperature = prm.get("temperature") + prm_temperature = float(_prm_temperature) if _prm_temperature is not None else 0.6 skills_dir = resolve_skills_dir( skills.get("dir", str(_DEFAULT_SKILLS_DIR)), diff --git a/tests/test_prm_temperature_config.py b/tests/test_prm_temperature_config.py new file mode 100644 index 0000000..b9900d5 --- /dev/null +++ b/tests/test_prm_temperature_config.py @@ -0,0 +1,49 @@ +"""``prm.temperature`` in config.yaml must reach ``SkillClawConfig.prm_temperature``. + +Regression coverage for the config bridge: the field existed but was never +wired from YAML, and the first wiring attempt silently rewrote an explicit +``temperature: 0`` to the default via an ``or``-guard. These cases pin the +correct behavior: configured values pass through (including falsy-but-valid +0), and the default only applies when the key is absent. +""" +from __future__ import annotations + +from pathlib import Path + +import yaml + +from skillclaw.config_store import ConfigStore + + +def _store(tmp_path: Path, prm: dict) -> ConfigStore: + cfg = tmp_path / "config.yaml" + cfg.write_text( + yaml.safe_dump( + { + "llm": {"provider": "openai", "model_id": "k3", "api_base": "https://example.invalid/v1"}, + "prm": prm, + } + ) + ) + return ConfigStore(cfg) + + +def test_prm_temperature_from_config(tmp_path): + store = _store(tmp_path, {"enabled": True, "model": "k3", "temperature": 1}) + assert store.to_skillclaw_config().prm_temperature == 1 + + +def test_prm_temperature_fractional_value(tmp_path): + store = _store(tmp_path, {"enabled": True, "model": "gpt-5.2", "temperature": 0.2}) + assert store.to_skillclaw_config().prm_temperature == 0.2 + + +def test_prm_temperature_zero_is_honored(tmp_path): + """An explicit 0 (deterministic scoring) must not be rewritten to 0.6.""" + store = _store(tmp_path, {"enabled": True, "model": "gpt-5.2", "temperature": 0}) + assert store.to_skillclaw_config().prm_temperature == 0 + + +def test_prm_temperature_default_when_unset(tmp_path): + store = _store(tmp_path, {"enabled": True, "model": "gpt-5.2"}) + assert store.to_skillclaw_config().prm_temperature == 0.6