Files
opensquilla--opensquilla/tests/test_meta_skill_parser_label_progress_emits.py
2026-07-13 13:12:33 +08:00

153 lines
4.8 KiB
Python

"""MetaStep 暴露 label 与 progress_emits,默认安全回退。"""
from dataclasses import dataclass, field
from typing import Any
import pytest
from opensquilla.skills.meta.parser import MetaPlanError, parse_meta_plan
from opensquilla.skills.meta.types import MetaStep
def test_meta_step_default_label_empty():
s = MetaStep(id="intake", skill="intake")
assert s.label == ""
assert s.progress_emits is True
def test_meta_step_explicit_label():
s = MetaStep(id="intake", skill="intake", label="意图提取")
assert s.label == "意图提取"
def test_meta_step_progress_emits_off():
s = MetaStep(id="tool", skill="tool", kind="tool_call",
tool="memory_save", progress_emits=False)
assert s.progress_emits is False
@dataclass
class _FakeSpec:
name: str = "fake-meta"
kind: str = "meta"
composition_raw: dict[str, Any] = field(default_factory=dict)
triggers: list[str] = field(default_factory=list)
meta_priority: int = 0
content: str = ""
final_text_mode: str = "auto"
request_template: dict[str, Any] | None = None
output_contract: dict[str, Any] | None = None
eval_prompts: list[dict[str, Any]] = field(default_factory=list)
preference_keys: list[str] = field(default_factory=list)
policy_tags: list[str] = field(default_factory=list)
def _spec_with(steps):
return _FakeSpec(composition_raw={"steps": steps})
def test_parser_reads_label():
plan = parse_meta_plan(_spec_with([
{"id": "intake", "kind": "llm_chat", "label": "意图提取"},
]))
assert plan is not None
assert plan.steps[0].label == "意图提取"
def test_parser_reads_progress_emits_false():
plan = parse_meta_plan(_spec_with([
{"id": "tool", "kind": "tool_call", "tool": "memory_save",
"progress_emits": False},
]))
assert plan is not None
assert plan.steps[0].progress_emits is False
def test_parser_defaults_tool_call_progress_emits_false():
plan = parse_meta_plan(_spec_with([
{"id": "tool", "kind": "tool_call", "tool": "memory_save"},
]))
assert plan is not None
assert plan.steps[0].progress_emits is False
def test_parser_label_must_be_string():
with pytest.raises(MetaPlanError, match="label"):
parse_meta_plan(_spec_with([
{"id": "intake", "kind": "llm_chat", "label": 123},
]))
def test_parser_progress_emits_must_be_bool():
with pytest.raises(MetaPlanError, match="progress_emits"):
parse_meta_plan(_spec_with([
{"id": "intake", "kind": "llm_chat", "progress_emits": "yes"},
]))
def test_parser_label_optional_uses_readable_step_id_fallback():
plan = parse_meta_plan(_spec_with([
{"id": "source_digest", "kind": "llm_chat"},
]))
assert plan is not None
assert plan.steps[0].label == "Source Digest"
assert plan.steps[0].label_by_language["en"] == "Source Digest"
def test_parser_reads_request_template_from_spec():
spec = _spec_with([
{"id": "intake", "kind": "llm_chat"},
])
spec.request_template = {
"outcome": "Decision memo",
"fields": [
{"name": "decision_criteria", "required": True},
{"name": "time_window", "required": False, "default": "next 30 days"},
],
"assumptions": ["Use public evidence only"],
}
plan = parse_meta_plan(spec)
assert plan is not None
assert plan.request_template["outcome"] == "Decision memo"
assert plan.request_template["fields"][0]["name"] == "decision_criteria"
def test_parser_reads_output_contract_from_spec():
spec = _spec_with([
{"id": "final", "kind": "llm_chat"},
])
spec.output_contract = {
"required_sections": ["Recommendation", "Evidence"],
"assumptions": ["Criteria inferred from request"],
"unverified": ["Pricing may change"],
"artifacts": [{"name": "decision_memo.md", "required": False}],
}
plan = parse_meta_plan(spec)
assert plan is not None
assert plan.output_contract["required_sections"] == ["Recommendation", "Evidence"]
assert plan.output_contract["artifacts"][0]["name"] == "decision_memo.md"
def test_parser_reads_eval_preference_and_policy_metadata_from_spec():
spec = _spec_with([
{"id": "final", "kind": "llm_chat"},
])
spec.eval_prompts = [{
"name": "happy-path",
"prompt": "Write a decision memo for project X",
"rubric": ["Recommendation", "Evidence"],
}]
spec.preference_keys = ["preferred_language", "briefing_depth"]
spec.policy_tags = ["public-data-only", "no-pii"]
plan = parse_meta_plan(spec)
assert plan is not None
assert plan.eval_prompts[0]["name"] == "happy-path"
assert plan.preference_keys == ("preferred_language", "briefing_depth")
assert plan.policy_tags == ("public-data-only", "no-pii")