fix: _extract_skill_json crashes on a truthy non-string teacher response (#1630)

This commit is contained in:
Afonso Coutinho
2026-06-03 00:59:36 +01:00
committed by GitHub
parent 6b2618dab4
commit d818117d4c
2 changed files with 20 additions and 1 deletions

View File

@@ -327,7 +327,7 @@ def _extract_skill_json(teacher_response: str) -> Optional[Dict[str, Any]]:
treated as "teacher declined to write a skill", per the prompt treated as "teacher declined to write a skill", per the prompt
contract. contract.
""" """
if not teacher_response: if not isinstance(teacher_response, str) or not teacher_response:
return None return None
import json import json
m = re.search(r"```(?:json)?\s*\n(\{[\s\S]*?\})\s*\n```", teacher_response) m = re.search(r"```(?:json)?\s*\n(\{[\s\S]*?\})\s*\n```", teacher_response)

View File

@@ -0,0 +1,19 @@
"""Regression: _extract_skill_json must tolerate a non-string response.
The `if not teacher_response` guard only handled falsy values; a truthy
non-string (e.g. a number or list from an unexpected LLM client) reached
`re.search(..., teacher_response)` and raised TypeError. Non-strings now
return None (treated as "no skill"), matching the documented contract.
"""
from src.teacher_escalation import _extract_skill_json
def test_non_string_returns_none():
assert _extract_skill_json(123) is None
assert _extract_skill_json(["x"]) is None
assert _extract_skill_json(None) is None
def test_valid_json_block_parsed():
resp = "sure:\n```json\n{\"name\": \"x\"}\n```\n"
assert _extract_skill_json(resp) == {"name": "x"}