feat: make mode creation preview-only and cache-safe
This commit is contained in:
@@ -138,7 +138,7 @@ function ndjsonResponse(events) {
|
||||
};
|
||||
}
|
||||
|
||||
function createHarness(events) {
|
||||
function createHarness(events, executionMode = "dry_run") {
|
||||
const document = new MockEventTarget();
|
||||
const windowEvents = new MockEventTarget();
|
||||
const body = new MockElement("body");
|
||||
@@ -209,7 +209,7 @@ function createHarness(events) {
|
||||
sandbox.removeEventListener = windowEvents.removeEventListener.bind(windowEvents);
|
||||
sandbox.dispatchEvent = windowEvents.dispatchEvent.bind(windowEvents);
|
||||
sandbox.CognitiveAgentConsole = {
|
||||
getExecutionMode: () => "dry_run",
|
||||
getExecutionMode: () => executionMode,
|
||||
async refreshModeProfiles(modeProfileId) {
|
||||
refreshedModeProfiles.push(modeProfileId);
|
||||
},
|
||||
@@ -367,6 +367,10 @@ test("assistant bridges request start and validated local controls to the consol
|
||||
const cards = assistantArticle.querySelectorAll(".assistant-dispatched-controls");
|
||||
assert.equal(cards.length, 1);
|
||||
assert.equal(cards[0].open, true);
|
||||
assert.equal(
|
||||
cards[0].children[0].children[1].textContent,
|
||||
"控制指令预览(未下发)",
|
||||
);
|
||||
assert.equal(
|
||||
cards[0].querySelector(".assistant-dispatched-controls-count").textContent,
|
||||
"3",
|
||||
@@ -381,6 +385,7 @@ test("assistant bridges request start and validated local controls to the consol
|
||||
["23°C", "关闭", "关闭"],
|
||||
);
|
||||
assert.match(rows[0].title, /实际控制指令:ac temp driver 23/);
|
||||
assert.match(rows[0].title, /下发状态:仅预览 · 未下发/);
|
||||
});
|
||||
|
||||
test("unsupported-control suggestions render once and click through as a new command", async () => {
|
||||
@@ -544,6 +549,17 @@ function modeDraftEvents(sourceRequestId, temperatureC) {
|
||||
];
|
||||
}
|
||||
|
||||
test("mode creation always requests dry-run even while the console is in hardware mode", async () => {
|
||||
const harness = createHarness(modeDraftEvents("req-draft-hardware-safe", 24), "hardware");
|
||||
harness.input.value = "创建一个午休模式";
|
||||
|
||||
await harness.sandbox.CognitiveAgentAssistant.submit();
|
||||
|
||||
const request = JSON.parse(harness.requestCalls[0].options.body);
|
||||
assert.equal(request.execution_mode, "dry_run");
|
||||
assert.equal(Object.hasOwn(request, "hardware_client_id"), false);
|
||||
});
|
||||
|
||||
test("a follow-up turn carries only the active authoritative draft reference", async () => {
|
||||
const events = modeDraftEvents("req-draft-one", 24);
|
||||
const harness = createHarness(events);
|
||||
|
||||
@@ -21,17 +21,17 @@ def test_console_contains_ai_assistant_surface():
|
||||
assert 'placeholder="向 AI助手提问或交代工作"' in template
|
||||
assert 'aria-label="发送消息"' in template
|
||||
assert 'import "../assistant-chat.css";' in vite_entry
|
||||
assert 'src="/assistant-chat.js?v=codex-assistant-34"' in html
|
||||
assert 'src="/assistant-chat.js?v=codex-assistant-35"' in html
|
||||
|
||||
|
||||
def test_codex_assistant_assets_are_versioned_together_in_the_service_worker():
|
||||
service_worker = (ROOT / "apps/web-console/service-worker.js").read_text(encoding="utf-8")
|
||||
assert (
|
||||
'const CACHE_VERSION = "cognitive-agent-pad-v328-nfc-mqtt"'
|
||||
'const CACHE_VERSION = "cognitive-agent-pad-v329-mode-preview"'
|
||||
in service_worker
|
||||
)
|
||||
assert '"/assistant-chat.css?v=codex-assistant-29"' in service_worker
|
||||
assert '"/assistant-chat.js?v=codex-assistant-34"' in service_worker
|
||||
assert '"/assistant-chat.css?v=codex-assistant-30"' in service_worker
|
||||
assert '"/assistant-chat.js?v=codex-assistant-35"' in service_worker
|
||||
|
||||
|
||||
def test_codex_frontend_uses_one_streaming_endpoint_and_agent_work_events():
|
||||
@@ -91,7 +91,7 @@ def test_validated_controls_are_mirrored_into_a_compact_assistant_card():
|
||||
assert "window.CognitiveAgentConsoleV2?.getParsedCanCommands?.(result)" in script
|
||||
assert "fallbackAssistantControlCommands(result)" in script
|
||||
assert 'card.className = "assistant-dispatched-controls"' in script
|
||||
assert 'heading.textContent = "下发控制指令"' in script
|
||||
assert 'const headingText = previewOnly ? "控制指令预览(未下发)" : "下发控制指令"' in script
|
||||
assert 'count.className = "assistant-dispatched-controls-count"' in script
|
||||
assert 'list.className = "assistant-dispatched-controls-list"' in script
|
||||
assert "value.textContent = assistantControlValue(item)" in script
|
||||
@@ -186,6 +186,7 @@ def test_codex_request_keeps_trusted_vehicle_context_without_legacy_model_routin
|
||||
assert "history" not in request_body
|
||||
assert "provider" not in request_body
|
||||
assert "reasoning_effort" not in request_body
|
||||
assert 'const executionMode = modeConfigurationPreview ? "dry_run"' in request_body
|
||||
|
||||
|
||||
def test_starting_a_new_codex_conversation_rotates_the_conversation_id():
|
||||
@@ -239,7 +240,9 @@ def test_assistant_mode_creation_previews_then_saves_to_the_compact_mode_strip()
|
||||
assert 'event.payload.orchestration_route === "mode_profile_create_preview"' in assistant
|
||||
assert "appendModeDraftState(" in assistant
|
||||
assert "保存为功能模式" in assistant
|
||||
assert "先试运行" in assistant
|
||||
assert "重新校验(不下发)" in assistant
|
||||
assert "创建阶段仅生成并校验控制方案,不会向 CAN 或红外外设发送指令" in assistant
|
||||
assert 'label = String(action?.target?.name || action?.target?.device || "红外外设")' in assistant
|
||||
|
||||
save_flow = assistant.split(
|
||||
"async function saveModeProfileDraft", 1
|
||||
|
||||
@@ -175,3 +175,35 @@ def test_climate_control_circulation_and_outlet_are_not_conflated(render_rows):
|
||||
("空调出风模式", "吹面 / 吹脚"),
|
||||
("空调风量", "2档"),
|
||||
]
|
||||
|
||||
|
||||
def test_mode_preview_localizes_external_device_name_and_action_parameters(render_rows):
|
||||
rows = render_rows([
|
||||
{
|
||||
"domain": "self_extension",
|
||||
"capability": "infrared.emit",
|
||||
"target": {"device": "flashing-light", "name": "闪烁灯"},
|
||||
"parameters": {"action": "打开", "slot": 7},
|
||||
},
|
||||
])
|
||||
|
||||
assert [(row["label"], row["value"]) for row in rows] == [
|
||||
("闪烁灯", "动作:打开"),
|
||||
]
|
||||
assert "infrared.emit" not in json.dumps(rows, ensure_ascii=False)
|
||||
|
||||
|
||||
def test_default_bundle_rows_show_power_window_and_grouped_passenger_comfort(render_rows):
|
||||
rows = render_rows([
|
||||
action("climate.set_power", {"state": "on"}, "vehicle"),
|
||||
action("window.set_position", {"position_pct": 0}, "front_left"),
|
||||
action("seat.set_ventilation", {"state": "on", "level": 1}, "passenger"),
|
||||
action("seat.set_backrest_recline", {"position_pct": 45}, "passenger"),
|
||||
action("seat.set_legrest_height", {"position_pct": 35}, "passenger"),
|
||||
])
|
||||
|
||||
assert [(row["label"], row["value"]) for row in rows] == [
|
||||
("空调电源", "开启"),
|
||||
("主驾车窗", "完全关闭(目标开度 0%)"),
|
||||
("副驾座椅舒适模式", "通风开启 1档 · 靠背 45% · 腿托 35%"),
|
||||
]
|
||||
|
||||
@@ -37,11 +37,11 @@ def test_energy_monitor_assets_are_versioned_and_cached() -> None:
|
||||
assert f'"{asset}"' in service_worker
|
||||
assert 'import "../energy-monitor.css";' in vite_entry
|
||||
assert "/energy-monitor.js?v=energy-monitor-5-performance" in html
|
||||
assert html.index("/assistant-chat.js?v=codex-assistant-34") < html.index(
|
||||
assert html.index("/assistant-chat.js?v=codex-assistant-35") < html.index(
|
||||
"/energy-monitor.js?v=energy-monitor-5-performance"
|
||||
)
|
||||
assert (
|
||||
'const CACHE_VERSION = "cognitive-agent-pad-v328-nfc-mqtt"'
|
||||
'const CACHE_VERSION = "cognitive-agent-pad-v329-mode-preview"'
|
||||
in service_worker
|
||||
)
|
||||
|
||||
|
||||
@@ -99,5 +99,5 @@ def test_performance_assets_have_a_new_cache_generation() -> None:
|
||||
):
|
||||
assert asset in html
|
||||
assert f'"{asset}"' in worker
|
||||
assert 'const CACHE_VERSION = "cognitive-agent-pad-v328-nfc-mqtt"' in worker
|
||||
assert 'const CACHE_VERSION = "cognitive-agent-pad-v329-mode-preview"' in worker
|
||||
assert '"/codepen-glass-theme.css?v=creative-cloud-6-performance"' in worker
|
||||
|
||||
@@ -54,7 +54,7 @@ def test_theme_asset_versions_are_consistent_with_the_pwa_shell() -> None:
|
||||
assert source_asset in main
|
||||
assert f'"{cached_asset}"' in service_worker
|
||||
assert 'import "./styles/design-system.css"' in main
|
||||
assert 'const CACHE_VERSION = "cognitive-agent-pad-v328-nfc-mqtt"' in service_worker
|
||||
assert 'const CACHE_VERSION = "cognitive-agent-pad-v329-mode-preview"' in service_worker
|
||||
|
||||
|
||||
def test_reference_glass_theme_covers_the_complete_workspace() -> None:
|
||||
|
||||
@@ -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": [],
|
||||
|
||||
@@ -11,6 +11,8 @@ from cognitive_agent.application.assistant_capabilities import AssistantCapabili
|
||||
from cognitive_agent.application.scene_composer import (
|
||||
build_scene_output_schema,
|
||||
normalize_scene_output,
|
||||
scene_has_explicit_control_object,
|
||||
scene_required_native_fallbacks,
|
||||
scene_required_peripheral_refs,
|
||||
scene_semantic_guidance,
|
||||
)
|
||||
@@ -464,7 +466,7 @@ def test_learning_mode_is_grounded_as_free_semantic_composition() -> None:
|
||||
|
||||
|
||||
@pytest.mark.parametrize("mode_name", ("浪漫模式", "中秋欢快模式"))
|
||||
def test_romantic_and_mid_autumn_require_flashing_light_actions(
|
||||
def test_romantic_and_mid_autumn_require_decorative_light_actions(
|
||||
mode_name: str,
|
||||
) -> None:
|
||||
context = _context()
|
||||
@@ -490,6 +492,27 @@ def test_romantic_and_mid_autumn_require_flashing_light_actions(
|
||||
"action_label": "关闭",
|
||||
"action_names": ["关闭", "熄灭"],
|
||||
},
|
||||
{
|
||||
"ref": "ir:strip-open",
|
||||
"device_label": "灯带",
|
||||
"object_names": ["灯带", "LED 灯条"],
|
||||
"action_label": "打开",
|
||||
"action_names": ["打开", "开启"],
|
||||
},
|
||||
{
|
||||
"ref": "ir:strip-red",
|
||||
"device_label": "灯带",
|
||||
"object_names": ["灯带", "LED 灯条"],
|
||||
"action_label": "切换为红色",
|
||||
"action_names": ["切换为红色", "设置为红色"],
|
||||
},
|
||||
{
|
||||
"ref": "ir:ambient-open",
|
||||
"device_label": "外设氛围灯",
|
||||
"object_names": ["外设氛围灯", "氛围灯"],
|
||||
"action_label": "打开",
|
||||
"action_names": ["打开", "开启"],
|
||||
},
|
||||
]
|
||||
required = scene_required_peripheral_refs(mode_name, context)
|
||||
semantics = scene_semantic_guidance(mode_name)
|
||||
@@ -497,7 +520,109 @@ def test_romantic_and_mid_autumn_require_flashing_light_actions(
|
||||
context["scene_semantics"] = semantics
|
||||
schema = build_scene_output_schema(context)
|
||||
|
||||
assert required == ["ir:flash-open", "ir:flash-red"]
|
||||
assert schema["properties"]["requests"]["maxItems"] == 10
|
||||
assert required == [
|
||||
"ir:flash-open",
|
||||
"ir:strip-open",
|
||||
]
|
||||
assert scene_required_peripheral_refs(
|
||||
mode_name,
|
||||
context,
|
||||
include_default_bundle=True,
|
||||
) == [
|
||||
"ir:flash-open",
|
||||
"ir:ambient-open",
|
||||
"ir:strip-open",
|
||||
]
|
||||
assert schema["properties"]["requests"]["maxItems"] == 18
|
||||
if "中秋" in mode_name:
|
||||
assert semantics["family"] == "festival_celebration"
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("mode_name", "expected_shade"),
|
||||
(("浪漫模式", 0), ("中秋欢快模式", 100)),
|
||||
)
|
||||
def test_required_native_fallbacks_cover_climate_ambient_and_shade(
|
||||
mode_name: str,
|
||||
expected_shade: int,
|
||||
) -> None:
|
||||
context = _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,
|
||||
}
|
||||
],
|
||||
}
|
||||
)
|
||||
|
||||
fallbacks = scene_required_native_fallbacks(mode_name, context)
|
||||
|
||||
assert [item["domain"] for item in fallbacks] == [
|
||||
"climate",
|
||||
"ambient_light",
|
||||
"roof",
|
||||
]
|
||||
assert fallbacks[0]["capability"] == "climate.set_temperature"
|
||||
assert fallbacks[1]["capability"] == "ambient_light.set_power"
|
||||
assert fallbacks[2]["capability"] == "roof.set_shade_position"
|
||||
assert fallbacks[2]["parameters"] == [
|
||||
{"name": "position_pct", "value": expected_shade}
|
||||
]
|
||||
|
||||
|
||||
def test_name_only_scene_default_bundle_covers_all_required_native_controls() -> None:
|
||||
service = SeatDemoService()
|
||||
catalog = AssistantCapabilityCatalog(service)
|
||||
context = catalog.scene_composition_context(catalog.snapshot())
|
||||
|
||||
fallbacks = scene_required_native_fallbacks(
|
||||
"星夜模式",
|
||||
context,
|
||||
include_default_bundle=True,
|
||||
)
|
||||
semantics = scene_semantic_guidance("星夜模式")
|
||||
semantics["native_fallback_requests"] = fallbacks
|
||||
semantics["peripheral_policy"] = {"required_refs": []}
|
||||
context["scene_semantics"] = semantics
|
||||
|
||||
assert [(item["capability"], item["target_scope"]) for item in fallbacks] == [
|
||||
("climate.set_power", "vehicle"),
|
||||
("climate.set_temperature", "vehicle"),
|
||||
("climate.set_fan_level", "vehicle"),
|
||||
("climate.set_cycle_mode", "vehicle"),
|
||||
("window.set_position", "front_left"),
|
||||
("window.set_position", "front_right"),
|
||||
("window.set_position", "rear_left"),
|
||||
("window.set_position", "rear_right"),
|
||||
("roof.set_shade_position", "vehicle"),
|
||||
("seat.set_ventilation", "passenger"),
|
||||
("seat.set_backrest_recline", "passenger"),
|
||||
("seat.set_legrest_height", "passenger"),
|
||||
("ambient_light.set_power", "vehicle"),
|
||||
]
|
||||
assert build_scene_output_schema(context)["properties"]["requests"]["maxItems"] == 7
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("message", "expected"),
|
||||
(
|
||||
("创建浪漫中秋模式", False),
|
||||
("创建浪漫中秋模式,空调温度设置为25度", True),
|
||||
("创建灯光主题模式", True),
|
||||
("创建主驾浪漫模式", True),
|
||||
("创建节日模式", False),
|
||||
),
|
||||
)
|
||||
def test_scene_detects_whether_user_named_a_concrete_control_object(
|
||||
message: str,
|
||||
expected: bool,
|
||||
) -> None:
|
||||
assert scene_has_explicit_control_object(message, _context()) is expected
|
||||
|
||||
@@ -111,7 +111,7 @@ def test_initialize_and_tool_catalog_expose_only_safe_arguments() -> None:
|
||||
properties = tools[1]["inputSchema"]["properties"]
|
||||
assert set(properties) == {"request_token", "plan"}
|
||||
assert properties["plan"]["additionalProperties"] is False
|
||||
assert properties["plan"]["properties"]["requests"]["maxItems"] == 12
|
||||
assert properties["plan"]["properties"]["requests"]["maxItems"] == 20
|
||||
assert not {
|
||||
"approval_token",
|
||||
"hardware_access_bypass",
|
||||
@@ -149,7 +149,7 @@ def test_structured_plan_is_validated_and_forwarded_without_freeform_instruction
|
||||
"plan",
|
||||
[
|
||||
{"requests": []},
|
||||
{**_sample_plan(), "requests": _sample_plan()["requests"] * 13},
|
||||
{**_sample_plan(), "requests": _sample_plan()["requests"] * 21},
|
||||
{
|
||||
**_sample_plan(),
|
||||
"requests": [{**_sample_plan()["requests"][0], "raw_can": "01 02 03"}],
|
||||
|
||||
@@ -31,7 +31,10 @@ def test_vue_vite_application_is_the_primary_frontend_entry() -> None:
|
||||
assert package["scripts"]["build"] == "vite build"
|
||||
assert 'import vue from "@vitejs/plugin-vue"' in vite
|
||||
assert 'outDir: outputRoot' in vite
|
||||
assert 'const CACHE_VERSION = "cognitive-agent-pad-v328-nfc-mqtt"' in service_worker
|
||||
assert 'const CACHE_VERSION = "cognitive-agent-pad-v329-mode-preview"' in service_worker
|
||||
assert 'createHash("sha256")' in vite
|
||||
assert 'runtime-assets.json' in vite
|
||||
assert 'rewriteRuntimeReferences' in vite
|
||||
assert "unpkg.com" not in html
|
||||
assert "cdn.jsdelivr.net" not in html
|
||||
|
||||
|
||||
Reference in New Issue
Block a user