mqtt切换为远程服务器部署,优化简单指令解析时长

This commit is contained in:
Miayui
2026-09-11 10:22:24 +08:00
parent 51ca12b624
commit 3fc6f2c2a4
34 changed files with 4290 additions and 484 deletions
+6 -9
View File
@@ -1101,7 +1101,7 @@ class TestCodexAssistantWebApi:
assert "not-for-mcp" not in serialized_events
assert "模拟编排" in events[-1]["answer"]
def test_structured_plan_crosses_the_internal_bridge_without_replacing_original_text(
def test_explicit_roof_control_uses_local_preview_without_codex(
self,
) -> None:
events = self.post_assistant(
@@ -1112,17 +1112,14 @@ class TestCodexAssistantWebApi:
}
)
assert FAKE_CODEX.bridge_results[-1][0] == 200
call = AssistantApiHandler.service.calls[-1]
assert call["utterance"] == "天幕透光率调到30%"
assert call["provider"] == "local"
forwarded_plan = call["assistant_plan"]
assert forwarded_plan["requests"][0]["capability"] == "roof.set_transmittance"
assert forwarded_plan["requests"][0]["parameters"] == [
{"name": "transmittance_pct", "value": 30}
]
assert forwarded_plan["requests"][0]["reason"] == "原始用户请求的结构化候选动作。"
assert "instruction" not in call
assert "assistant_plan" not in call
assert not FAKE_CODEX.turn_calls
assert not FAKE_CODEX.bridge_results
assert events[0]["route"] == "vehicle_control"
assert events[0]["engine"] == "n7web-control-router"
assert events[-1]["type"] == "answer.completed"
def test_assistant_returns_named_mode_draft_without_saving_it(self) -> None:
+151 -18
View File
@@ -13,6 +13,7 @@ from pathlib import Path
from types import SimpleNamespace
from unittest.mock import patch
from cognitive_agent.application.codex_assistant import CodexAssistantService
from cognitive_agent.application.mode_profile import ModeProfileRegistry
from cognitive_agent.application.seat_service import REPOSITORY_ROOT, SeatDemoService
from cognitive_agent.application.self_extension import (
@@ -438,6 +439,12 @@ operations:
}
)
try:
with self.opener.open(
f"{self.base_url}/api/vehicle-display-sync", timeout=3
) as response:
display_before_compile = json.loads(
response.read().decode("utf-8")
)
generate_request = urllib.request.Request(
f"{self.base_url}/api/requests/preview",
method="POST",
@@ -457,6 +464,16 @@ operations:
)
with self.opener.open(generate_request, timeout=3) as response:
generated = json.loads(response.read().decode("utf-8"))
with self.opener.open(
f"{self.base_url}/api/vehicle-display-sync", timeout=3
) as response:
display_after_compile = json.loads(
response.read().decode("utf-8")
)
self.assertEqual(
display_after_compile["task"],
display_before_compile["task"],
)
save_request = urllib.request.Request(
f"{self.base_url}/api/mode-profiles/office",
@@ -650,18 +667,18 @@ operations:
def test_static_console_and_runtime_endpoint(self) -> None:
with self.opener.open(f"{self.base_url}/", timeout=3) as response:
html = response.read().decode("utf-8")
with self.opener.open(f"{self.base_url}/app.js?v=dual-seat-130", timeout=3) as response:
with self.opener.open(f"{self.base_url}/app.js?v=dual-seat-131", timeout=3) as response:
app_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/gesture-control.js?v=android-pad-9", timeout=3
) as response:
gesture_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/console-v2.js?v=delivery-state-62", timeout=3
f"{self.base_url}/console-v2.js?v=local-first-66", timeout=3
) as response:
console_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/console-v2.css?v=delivery-state-66", timeout=3
f"{self.base_url}/console-v2.css?v=delivery-state-68", timeout=3
) as response:
console_styles = response.read().decode("utf-8")
with self.opener.open(
@@ -685,7 +702,7 @@ operations:
) as response:
extension_styles = response.read().decode("utf-8").replace("\r\n", "\n")
with self.opener.open(
f"{self.base_url}/assistant-chat.js?v=codex-assistant-26", timeout=3
f"{self.base_url}/assistant-chat.js?v=codex-assistant-27", timeout=3
) as response:
assistant_script = response.read().decode("utf-8")
with self.opener.open(
@@ -726,12 +743,12 @@ operations:
self.assertIn("CMD 0x431 · FB 0x41A · CH1", html)
self.assertIn("CMD 0x431 · FB 0x388 · CH1", html)
self.assertNotIn("透明车体 · 实体设备", html)
self.assertIn('src="/app.js?v=dual-seat-130"', html)
self.assertIn('src="/app.js?v=dual-seat-131"', html)
self.assertIn('href="/styles.css?v=dual-seat-23"', html)
self.assertIn('src="/gesture-control.js?v=android-pad-9"', html)
self.assertNotIn('class="vehicle-system-hud"', html)
self.assertIn('src="/console-v2.js?v=delivery-state-62"', html)
self.assertIn('href="/console-v2.css?v=delivery-state-66"', html)
self.assertIn('src="/console-v2.js?v=local-first-66"', html)
self.assertIn('href="/console-v2.css?v=delivery-state-68"', html)
self.assertIn('src="/speech-input.js?v=sensevoice-13"', html)
self.assertIn('href="/speech-input.css?v=sensevoice-7"', html)
self.assertIn('id="speechDictationButton"', html)
@@ -748,7 +765,7 @@ operations:
self.assertIn('aria-label="发送消息"', html)
self.assertIn('id="assistantTranscript"', html)
self.assertIn('href="/assistant-chat.css?v=codex-assistant-26"', html)
self.assertIn('src="/assistant-chat.js?v=codex-assistant-26"', html)
self.assertIn('src="/assistant-chat.js?v=codex-assistant-27"', html)
self.assertIn('href="/energy-monitor.css?v=energy-monitor-4"', html)
self.assertIn('src="/energy-monitor.js?v=energy-monitor-4"', html)
self.assertNotIn('"admin"', console_script)
@@ -931,7 +948,12 @@ operations:
self.assertNotIn('data-mode-command="seat driver vent low"', app_script)
self.assertIn("CH0 副驾座椅与 CH1 主驾座椅独立收发、独立反馈", app_script)
self.assertIn("CH1 主驾实车测试不启用无闭环的座椅位置手势", app_script)
self.assertIn("车端 CAN 未启用,其他领域保持虚拟执行", app_script)
self.assertNotIn("车端 CAN 未启用,其他领域保持虚拟执行", app_script)
self.assertNotIn('id="hardwareNote"', html)
self.assertNotIn('id="hardwareAliasNote"', html)
self.assertNotIn('id="vehicleTransportNote"', html)
self.assertIn("下发控制指令", console_script)
self.assertIn('new Set(["mode_editor_compile"])', console_script)
self.assertIn("function extractReferenceWindowPanes", app_script)
self.assertIn("function collectReferenceFrontLampMeshes", app_script)
self.assertIn("function emphasizeReferenceWindowPanes", app_script)
@@ -1021,14 +1043,14 @@ operations:
self.assertIn("CAN 指令已提交,等待车辆状态确认", console_script)
self.assertIn('canvas.addEventListener("webglcontextlost"', app_script)
self.assertIn('"cognitive-agent:module-change"', app_script)
self.assertIn('const CACHE_VERSION = "cognitive-agent-pad-v277"', service_worker)
self.assertIn('/console-v2.css?v=delivery-state-66', service_worker)
self.assertIn('/console-v2.js?v=delivery-state-62', service_worker)
self.assertIn('const CACHE_VERSION = "cognitive-agent-pad-v282"', service_worker)
self.assertIn('/console-v2.css?v=delivery-state-68', service_worker)
self.assertIn('/console-v2.js?v=local-first-66', service_worker)
self.assertIn('/assistant-chat.css?v=codex-assistant-26', service_worker)
self.assertIn('/assistant-chat.js?v=codex-assistant-26', service_worker)
self.assertIn('/assistant-chat.js?v=codex-assistant-27', service_worker)
self.assertIn('/energy-monitor.css?v=energy-monitor-4', service_worker)
self.assertIn('/energy-monitor.js?v=energy-monitor-4', service_worker)
self.assertIn('"/app.js?v=dual-seat-130"', service_worker)
self.assertIn('"/app.js?v=dual-seat-131"', service_worker)
self.assertIn('"/speech-input.js?v=sensevoice-13"', service_worker)
self.assertIn('"/speech-input.css?v=sensevoice-7"', service_worker)
self.assertIn('"/speech-audio-worklet.js?v=sensevoice-5"', service_worker)
@@ -1485,7 +1507,7 @@ operations:
) as response:
extension_script = response.read().decode("utf-8")
with self.opener.open(
f"{self.base_url}/app.js?v=dual-seat-130", timeout=3
f"{self.base_url}/app.js?v=dual-seat-131", timeout=3
) as response:
app_script = response.read().decode("utf-8")
@@ -2134,7 +2156,7 @@ operations:
},
data=json.dumps(
{
"utterance": "打开闪烁灯,颜色切换到红色,打开空调",
"utterance": "空调温度设置到23度,打开闪烁灯",
"provider": "local",
"conversation_id": "conv-mixed-nfc-can",
"execution_mode": "dry_run",
@@ -2160,6 +2182,14 @@ operations:
self.assertEqual(synced["learned_count"], 2)
self.assertEqual(events[-1]["type"], "result")
self.assertTrue(any(item["type"] == "validated_commands" for item in events))
self.assertLess(
next(
index
for index, item in enumerate(events)
if item["type"] == "validated_commands"
),
len(events) - 1,
)
validated_payloads = [
item["payload"]
for item in events
@@ -2168,15 +2198,118 @@ operations:
self.assertTrue(validated_payloads)
self.assertTrue(
all(
"self_extension" in payload["function_configs"]
{"native_climate", "self_extension"}.issubset(
payload["function_configs"]
)
for payload in validated_payloads
)
)
first_validated = validated_payloads[0]
self.assertTrue(
{"native_climate", "self_extension"}.issubset(
first_validated["command_plans"]
)
)
validated_operations = [
operation
for configuration in first_validated["function_configs"].values()
for operation in configuration["spec"].get("operations", [])
]
self.assertEqual(
{operation["capability"] for operation in validated_operations},
{"climate.set_temperature", "infrared.emit"},
)
self.assertTrue(
all(
operation.get("parse_source") == "local_rule"
for operation in validated_operations
)
)
validated_commands = [
command
for plan in first_validated["command_plans"].values()
for command in plan["spec"].get("commands", [])
]
climate_command = next(
command
for command in validated_commands
if command.get("signals", {}).get("debug_command")
== "ac temp driver 23"
)
self.assertEqual(climate_command["signals"]["frame_id"], "0x1DE")
self.assertEqual(
climate_command["signals"]["data_hex"],
"00 00 00 00 17 00 00 00",
)
infrared_command = next(
command
for command in validated_commands
if command.get("message") == "infrared.emit"
)
self.assertEqual(infrared_command["signals"]["slot"], 1)
assistant_projection = CodexAssistantService._validated_control_payload(
first_validated
)
self.assertIsNotNone(assistant_projection)
projected_commands = assistant_projection["validated_control_commands"]
projected_by_capability = {
item["operation"]["capability"]: item for item in projected_commands
}
self.assertEqual(
projected_by_capability["climate.set_temperature"]["actual_command"],
"ac temp driver 23",
)
self.assertEqual(
projected_by_capability["climate.set_temperature"]["frames"][0][
"value"
],
"0x1DE · 00 00 00 00 17 00 00 00",
)
self.assertEqual(
projected_by_capability["infrared.emit"]["actual_command"],
"infrared emit 1",
)
serialized_projection = json.dumps(
assistant_projection, ensure_ascii=False
)
self.assertNotIn("command_plans", serialized_projection)
self.assertNotIn("data_hex", serialized_projection)
compile_trace = next(
event
for event in first_validated["trace_events"]
if event["stage"] == "compile"
)
validated_traces = first_validated["trace_events"][
: first_validated["trace_events"].index(compile_trace) + 1
]
required_validation_stages = {
"intent_parse",
"context_resolve",
"domain_route",
"function_generate",
"schema_validate",
"compile",
}
actual_validation_stages = {
event["stage"] for event in validated_traces
}
self.assertTrue(
required_validation_stages.issubset(actual_validation_stages),
sorted(actual_validation_stages),
)
self.assertTrue(
all(
isinstance(event.get("duration_ms"), int)
and event["duration_ms"] >= 0
for event in validated_traces
)
)
self.assertEqual(result["status"], "succeeded")
self.assertEqual(result["orchestration_route"], "unified_can_infrared")
self.assertEqual(
[item["slot"] for item in result["infrared_actions"]], [1, 3]
result["provider_used"], "local_rules+infrared_local_rules"
)
self.assertEqual([item["slot"] for item in result["infrared_actions"]], [1])
self.assertEqual(
result["infrared_actions"][0]["parse_source"], "local_rule"
)