deterministically execute create_skill from create_category, execute skill after creation
This commit is contained in:
@@ -206,4 +206,32 @@ def test_create_skill_empty_category_does_not_wedge(tmp_path):
|
||||
|
||||
status, detail = scheduler.submit("tell me if my package was delivered")
|
||||
print(f"[{status}] {detail}")
|
||||
assert scheduler.current is None
|
||||
assert scheduler.current is None
|
||||
|
||||
|
||||
def test_create_category_chain_runs_new_skill(tmp_path):
|
||||
"""A request that needs a brand-new category must end with a skill run.
|
||||
|
||||
Deterministic chain: create_category -> create_skill in the new category ->
|
||||
run that skill (the leaf answers the request, not the category stub). Slow:
|
||||
uses real codegen (~7 min). Run in the background.
|
||||
"""
|
||||
config = load_config()
|
||||
require_real(config)
|
||||
config["log"] = str(tmp_path / "decisions.jsonl")
|
||||
config["trace"] = str(tmp_path / "runs.jsonl")
|
||||
config["category_registry"] = str(tmp_path / "categories.json")
|
||||
config["skill_bodies"] = str(tmp_path / "skills")
|
||||
scheduler, config = build_scheduler(config)
|
||||
scheduler.tree = {}
|
||||
|
||||
status, detail = scheduler.submit("track my drone delivery in real time")
|
||||
print(f"[{status}] {detail}")
|
||||
|
||||
rows = scheduler.trace.read()
|
||||
kinds = [e["kind"] for e in rows]
|
||||
assert "category_created" in kinds, "category stub must be authored first"
|
||||
created = next(e for e in rows if e["kind"] == "skill_created")
|
||||
assert created["written"] is True, "codegen must produce a runnable body"
|
||||
assessed = next(e for e in rows if e["kind"] == "assessed")
|
||||
assert assessed["skill"] == created["skill"], "the created skill must run"
|
||||
+25
-1
@@ -9,7 +9,9 @@ import pytest
|
||||
|
||||
from semif_agent.decisions import Request
|
||||
from semif_agent.engine import EngineConfig, EngineUnavailable, SemIfEngine
|
||||
from semif_agent.llm import LLMClient
|
||||
from semif_agent.log import DecisionLog
|
||||
from semif_agent.scheduler import Scheduler
|
||||
from semif_agent.skills import (
|
||||
CategoryDraft,
|
||||
CategoryRegistry,
|
||||
@@ -198,4 +200,26 @@ def test_navigate_empty_tree_short_circuits(tmp_path):
|
||||
result = navigate(None, log, trace, Request("anything"), {})
|
||||
assert isinstance(result, CreateCategory)
|
||||
assert log.read() == []
|
||||
assert any(e["kind"] == "create_category" for e in trace.read())
|
||||
assert any(e["kind"] == "create_category" for e in trace.read())
|
||||
|
||||
|
||||
def test_dispatch_create_category_without_engine_returns_error(tmp_path):
|
||||
"""An empty tree short-circuits to CreateCategory; without an engine the
|
||||
category authoring fails gracefully instead of leaving the scheduler wedged."""
|
||||
log = DecisionLog(str(tmp_path / "decisions.jsonl"))
|
||||
trace = TraceLog(str(tmp_path / "runs.jsonl"))
|
||||
scheduler = Scheduler(
|
||||
engine=SemIfEngine(EngineConfig()),
|
||||
llm=LLMClient(base_url="http://localhost:1/v1", model="test"),
|
||||
log=log,
|
||||
config={
|
||||
"skills": {},
|
||||
"category_registry": str(tmp_path / "categories.json"),
|
||||
"skill_bodies": str(tmp_path / "skills"),
|
||||
},
|
||||
trace=trace,
|
||||
)
|
||||
scheduler.tree = {}
|
||||
result = scheduler._dispatch(Request("anything"))
|
||||
assert result.kind == "error"
|
||||
assert "create_category failed" in result.summary
|
||||
Reference in New Issue
Block a user