feat: make mode creation preview-only and cache-safe

This commit is contained in:
Miayui
2026-09-20 19:32:03 +08:00
parent bfff1b515c
commit 89707a42e2
28 changed files with 1375 additions and 165 deletions
+71 -7
View File
@@ -15,7 +15,10 @@ from cognitive_agent.application.codex_assistant import (
CodexAssistantService,
_mode_profile_create_parts,
)
from cognitive_agent.application.scene_composer import scene_semantic_guidance
from cognitive_agent.application.scene_composer import (
scene_required_native_fallbacks,
scene_semantic_guidance,
)
CONTROL_TERMS = ("空调", "座椅", "车窗", "遮阳帘", "氛围灯", "阅读灯", "出风口")
@@ -563,6 +566,21 @@ def test_exact_scene_template_keeps_native_base_and_adds_only_selected_ir_ref()
def _scene_context_with_flashing_light() -> dict[str, object]:
context = _scene_context()
context["capabilities"].append(
{
"id": "ambient_light.set_power",
"domain": "ambient_light",
"target_scopes": ["vehicle"],
"parameters": [
{
"name": "state",
"type": "string",
"allowed_values": ["on", "off"],
"required": True,
}
],
}
)
context["peripheral_actions"] = [
{
"ref": "ir:flash-open-000000000001",
@@ -588,6 +606,30 @@ def _scene_context_with_flashing_light() -> dict[str, object]:
"action_names": ["关闭", "熄灭"],
"semantic_tags": ["闪烁灯", "灯光"],
},
{
"ref": "ir:strip-open-000000000001",
"device_label": "灯带",
"object_names": ["灯带", "LED 灯条"],
"action_label": "打开",
"action_names": ["打开", "开启"],
"semantic_tags": ["灯带", "灯光"],
},
{
"ref": "ir:strip-red-0000000000002",
"device_label": "灯带",
"object_names": ["灯带", "LED 灯条"],
"action_label": "切换为红色",
"action_names": ["切换为红色", "设置为红色"],
"semantic_tags": ["灯带", "红色", "灯光"],
},
{
"ref": "ir:ambient-open-0000000001",
"device_label": "外设氛围灯",
"object_names": ["外设氛围灯", "氛围灯"],
"action_label": "打开",
"action_names": ["打开", "开启"],
"semantic_tags": ["氛围灯", "灯光"],
},
]
context["device_inventory"] = [
{
@@ -612,7 +654,7 @@ def _peripheral_refs(plan: Mapping[str, object]) -> list[str]:
]
def test_romantic_template_always_adds_authorized_flashing_light() -> None:
def test_romantic_template_always_adds_authorized_decorative_lights() -> None:
client = StructuredSceneClient()
client.structured_answers.put(
json.dumps(
@@ -647,14 +689,19 @@ def test_romantic_template_always_adds_authorized_flashing_light() -> None:
assert result["success"] is True
assert observed[0]["requests"][:2] == template["plan"]["requests"]
assert any(
request.get("domain") == "ambient_light"
for request in observed[0]["requests"]
)
assert _peripheral_refs(observed[0]) == [
"ir:flash-open-000000000001",
"ir:flash-red-0000000000002",
"ir:ambient-open-0000000001",
"ir:strip-open-000000000001",
]
assert "ir:flash-close-00000000003" not in _peripheral_refs(observed[0])
def test_mid_autumn_cloud_composition_receives_all_abilities_and_adds_flashing_light() -> None:
def test_mid_autumn_cloud_composition_adds_required_native_and_external_controls() -> None:
client = StructuredSceneClient()
assistant = CodexAssistantService(client)
observed: list[dict[str, object]] = []
@@ -681,18 +728,20 @@ def test_mid_autumn_cloud_composition_receives_all_abilities_and_adds_flashing_l
assert result["route"] == "scene_composer"
call_context = client.structured_calls[0]["application_context"]
assert len(call_context["capabilities"]) == len(scene_context["capabilities"])
assert len(call_context["peripheral_actions"]) == 3
assert len(call_context["peripheral_actions"]) == 6
assert call_context["scene_semantics"]["family"] == "festival_celebration"
assert call_context["scene_semantics"]["peripheral_policy"][
"required_refs"
] == [
"ir:flash-open-000000000001",
"ir:flash-red-0000000000002",
"ir:ambient-open-0000000001",
"ir:strip-open-000000000001",
]
assert "as many relevant" in client.thread_instructions[0]
assert _peripheral_refs(observed[0]) == [
"ir:flash-open-000000000001",
"ir:flash-red-0000000000002",
"ir:ambient-open-0000000001",
"ir:strip-open-000000000001",
]
@@ -1103,6 +1152,21 @@ def test_unknown_mode_uses_one_structured_turn_then_local_dry_run() -> None:
"cloud_input_utterance": "构建一个星夜模式",
}
expected_semantics = scene_semantic_guidance("星夜模式")
required_native = scene_required_native_fallbacks(
"星夜模式",
expected_context,
include_default_bundle=True,
)
expected_semantics["required_native_domains"] = ["climate", "roof"]
expected_semantics["required_native_controls"] = [
{
"capability": str(item["capability"]),
"target_scope": str(item["target_scope"]),
}
for item in required_native
]
expected_semantics["native_fallback_requests"] = required_native
expected_semantics["default_control_bundle_applied"] = True
expected_semantics["peripheral_policy"] = {
"available_action_count": 0,
"required_refs": [],