Files
agentic-mobile-control/tests/test_skill_synthesis.py
T

114 lines
3.2 KiB
Python

from __future__ import annotations
from skills_learning.models import FlowStep, FlowTemplateSkill, SkillMetadata
from skills_learning.store import SkillStore
from skills_learning.synthesis import extract_tool_calls, synthesize_flow_skill
def _record(
action: str,
args: dict[str, object] | None = None,
*,
result: dict[str, object] | None = None,
) -> dict[str, object]:
return {
"tool_call": {
"action": action,
"args": args or {},
},
"result": result or {},
}
def test_extract_tool_calls_filters_read_only_tools_in_order() -> None:
records = [
_record("describe_screen"),
_record("launch_app", {"app_id": "com.example"}),
_record("screenshot"),
_record("tap", {"x": 1, "y": 2}),
_record("find_text", {"query": "Send"}),
_record("input_text", {"text": "coffee"}),
]
steps = extract_tool_calls("", records)
assert steps == [
FlowStep("launch_app", {"app_id": "com.example"}),
FlowStep("tap", {"x": 1, "y": 2}),
FlowStep("input_text", {"text": "coffee"}),
]
def test_first_time_synthesis_has_literal_steps_and_no_parameters() -> None:
skill = synthesize_flow_skill(
"search coffee",
[_record("input_text", {"text": "coffee"})],
)
assert skill.name == "search coffee"
assert skill.steps == [FlowStep("input_text", {"text": "coffee"})]
assert skill.parameters == {}
def test_second_execution_promotes_differing_argument_to_parameter() -> None:
store = SkillStore()
store.create_version(
FlowTemplateSkill(
metadata=SkillMetadata(
name="search",
description="Learned search",
originating_goal="search coffee",
),
steps=[FlowStep("input_text", {"text": "coffee"})],
parameters={},
)
)
records = [
_record(
"input_text",
{"text": "tea"},
result={
"semantic_scene": {
"page": "Search",
"intents": ["search"],
"widgets": [
{
"element_id": "search-input",
"purpose": "search field",
}
],
}
},
)
]
skill = synthesize_flow_skill("search tea", records, store=store)
assert skill.name == "search"
assert skill.steps == [FlowStep("input_text", {"text": "{search_field}"})]
assert "search_field" in skill.parameters
def test_identical_repeat_does_not_add_parameters() -> None:
store = SkillStore()
store.create_version(
FlowTemplateSkill(
metadata=SkillMetadata(
name="search",
description="Learned search",
originating_goal="search coffee",
),
steps=[FlowStep("input_text", {"text": "coffee"})],
parameters={},
)
)
skill = synthesize_flow_skill(
"search coffee again",
[_record("input_text", {"text": "coffee"})],
store=store,
)
assert skill.steps == [FlowStep("input_text", {"text": "coffee"})]
assert skill.parameters == {}