generated from coulomb/repo-seed
Forward instruction schemas to llm-connect
This commit is contained in:
@@ -180,7 +180,10 @@ def _llm_run_config(instr: Any) -> dict[str, Any]:
|
|||||||
value = getattr(instr, field, None)
|
value = getattr(instr, field, None)
|
||||||
if value is not None:
|
if value is not None:
|
||||||
config[field] = value
|
config[field] = value
|
||||||
model_params = getattr(instr, "model_params", None)
|
model_params = dict(getattr(instr, "model_params", None) or {})
|
||||||
|
schema = _load_output_schema(getattr(instr, "output_schema", ""))
|
||||||
|
if schema is not None:
|
||||||
|
model_params.setdefault("json_schema", schema)
|
||||||
if model_params:
|
if model_params:
|
||||||
config["model_params"] = model_params
|
config["model_params"] = model_params
|
||||||
return config
|
return config
|
||||||
@@ -263,16 +266,33 @@ def _validate_against_schema(data: Any, schema_path: str) -> str | None:
|
|||||||
if not schema_path:
|
if not schema_path:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
schema = _load_output_schema(schema_path)
|
||||||
|
except (OSError, json.JSONDecodeError, TypeError) as exc:
|
||||||
|
return f"could not read output schema: {exc}"
|
||||||
|
if schema is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
return _validate_schema_node(data, schema, "$")
|
||||||
|
|
||||||
|
|
||||||
|
def _load_output_schema(schema_path: str) -> dict[str, Any] | None:
|
||||||
|
"""Load a JSON schema file when present.
|
||||||
|
|
||||||
|
Missing schema files are intentionally tolerated for backward
|
||||||
|
compatibility with existing tests and definitions.
|
||||||
|
"""
|
||||||
|
if not schema_path:
|
||||||
|
return None
|
||||||
|
|
||||||
path = Path(schema_path)
|
path = Path(schema_path)
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
schema = json.loads(path.read_text(encoding="utf-8"))
|
||||||
schema = json.loads(path.read_text(encoding="utf-8"))
|
if not isinstance(schema, dict):
|
||||||
except (OSError, json.JSONDecodeError) as exc:
|
raise TypeError("output schema must be a JSON object")
|
||||||
return f"could not read output schema: {exc}"
|
return schema
|
||||||
|
|
||||||
return _validate_schema_node(data, schema, "$")
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_schema_node(data: Any, schema: dict[str, Any], path: str) -> str | None:
|
def _validate_schema_node(data: Any, schema: dict[str, Any], path: str) -> str | None:
|
||||||
|
|||||||
@@ -275,6 +275,46 @@ def test_execute_instruction_forwards_llm_connect_run_config():
|
|||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def test_execute_instruction_forwards_output_schema_to_llm_connect(tmp_path, monkeypatch):
|
||||||
|
schema_dir = tmp_path / "schemas"
|
||||||
|
schema_dir.mkdir()
|
||||||
|
schema_path = schema_dir / "daily-triage-report.json"
|
||||||
|
schema = {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["summary", "recommendations"],
|
||||||
|
"properties": {
|
||||||
|
"summary": {"type": "string"},
|
||||||
|
"recommendations": {"type": "array", "items": {"type": "object"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
schema_path.write_text(json.dumps(schema), encoding="utf-8")
|
||||||
|
monkeypatch.chdir(tmp_path)
|
||||||
|
|
||||||
|
llm = _CountingLLM([
|
||||||
|
json.dumps({"summary": "Review open work.", "recommendations": []})
|
||||||
|
])
|
||||||
|
instr = _instr(
|
||||||
|
id="daily-triage-report",
|
||||||
|
prompt="Report.",
|
||||||
|
trusted_fields=[],
|
||||||
|
output_schema="schemas/daily-triage-report.json",
|
||||||
|
model_params={"reasoning_effort": "medium"},
|
||||||
|
)
|
||||||
|
|
||||||
|
result = execute_instruction_with_audit(instr, _Event(), {}, llm)
|
||||||
|
|
||||||
|
assert result.output_validated is True
|
||||||
|
assert llm.calls == [
|
||||||
|
{
|
||||||
|
"model_name": "claude-sonnet-4-6",
|
||||||
|
"model_params": {
|
||||||
|
"reasoning_effort": "medium",
|
||||||
|
"json_schema": schema,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def test_execute_instruction_with_audit_accepts_report_payload():
|
def test_execute_instruction_with_audit_accepts_report_payload():
|
||||||
report_data = {
|
report_data = {
|
||||||
"summary": "State Hub has loose ends.",
|
"summary": "State Hub has loose ends.",
|
||||||
|
|||||||
@@ -157,5 +157,18 @@ async def test_evaluate_instructions_forwards_llm_connect_depth_config(monkeypat
|
|||||||
"temperature": 0.2,
|
"temperature": 0.2,
|
||||||
"max_tokens": 1200,
|
"max_tokens": 1200,
|
||||||
"max_depth": 2,
|
"max_depth": 2,
|
||||||
"model_params": {"reasoning_effort": "medium"},
|
"model_params": {
|
||||||
|
"reasoning_effort": "medium",
|
||||||
|
"json_schema": {
|
||||||
|
"type": "object",
|
||||||
|
"required": ["summary", "recommendations"],
|
||||||
|
"properties": {
|
||||||
|
"summary": {"type": "string"},
|
||||||
|
"recommendations": {
|
||||||
|
"type": "array",
|
||||||
|
"items": {"type": "object"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user