103 lines
3.9 KiB
Python
103 lines
3.9 KiB
Python
from __future__ import annotations
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
from unittest.mock import patch
|
|
|
|
from cognitive_agent.application.assistant_capabilities import AssistantCapabilityCatalog
|
|
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.infrastructure.codex.app_server import CodexAppServerClient
|
|
|
|
FAKE_SERVER = REPOSITORY_ROOT / "tests" / "fixtures" / "fake_codex_app_server.py"
|
|
MCP_SERVER = (
|
|
REPOSITORY_ROOT / "src/cognitive_agent/infrastructure/codex/vehicle_mcp_server.py"
|
|
)
|
|
CALLBACK_URL = "http://127.0.0.1:8765/api/internal/codex/vehicle-control"
|
|
|
|
|
|
def test_structured_scene_turn_reaches_the_complete_local_dry_run_pipeline(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
service = SeatDemoService(REPOSITORY_ROOT)
|
|
service.artifact_root = tmp_path / "runs"
|
|
service.mode_profiles = ModeProfileRegistry(
|
|
REPOSITORY_ROOT / "config" / "modes",
|
|
user_root=tmp_path / "user-modes",
|
|
)
|
|
client = CodexAppServerClient(
|
|
cwd=tmp_path / "codex-workspace",
|
|
codex_command=[sys.executable, "-u", str(FAKE_SERVER)],
|
|
model="gpt-test-fast",
|
|
reasoning_effort="low",
|
|
request_timeout=2,
|
|
startup_timeout=2,
|
|
environment={"OPENAI_BASE_URL": "https://api.openai.com/v1"},
|
|
mcp_server_path=MCP_SERVER,
|
|
)
|
|
assistant = CodexAssistantService(client)
|
|
catalog = AssistantCapabilityCatalog(service)
|
|
snapshot = catalog.snapshot()
|
|
events: list[dict[str, object]] = []
|
|
|
|
def execute_control(
|
|
instruction: str,
|
|
progress: object,
|
|
assistant_plan: object,
|
|
) -> dict[str, object]:
|
|
assert isinstance(assistant_plan, dict)
|
|
return service.preview_native_can(
|
|
instruction,
|
|
provider="local",
|
|
conversation_id="conv-scene-e2e-pipeline",
|
|
execution_mode="hardware",
|
|
vehicle_id="denza_n7",
|
|
on_commands_validated=progress if callable(progress) else None,
|
|
assistant_plan=assistant_plan,
|
|
)
|
|
|
|
try:
|
|
assistant.start(CALLBACK_URL)
|
|
with patch.object(
|
|
service.hardware_execution,
|
|
"reserve",
|
|
side_effect=AssertionError("scene preview must never reserve hardware"),
|
|
):
|
|
response = assistant.stream(
|
|
"构建一个星夜模式",
|
|
conversation_id="conv-scene-e2e-pipeline",
|
|
principal="scene-e2e-user",
|
|
history=[],
|
|
emit=lambda event: events.append(event) or True,
|
|
execute_control=execute_control,
|
|
capability_snapshot=snapshot,
|
|
capability_context=catalog.compact_context(snapshot),
|
|
scene_capability_context=catalog.scene_composition_context(snapshot),
|
|
control_terms=catalog.control_terms(snapshot),
|
|
)
|
|
finally:
|
|
assistant.close()
|
|
|
|
result = response["result"]
|
|
draft = result["mode_profile_draft"]
|
|
assert response["route"] == "scene_composer"
|
|
assert response["success"] is True
|
|
assert result["status"] == "succeeded"
|
|
assert result["execution_mode"] == "dry_run"
|
|
assert result["hardware_execution_allowed"] is False
|
|
assert result["orchestration_route"] == "mode_profile_create_preview"
|
|
assert draft["name"] == "星夜模式"
|
|
assert draft["generation_source"] == "codex_scene_composition"
|
|
assert draft["operation_count"] == 2
|
|
capabilities = {
|
|
action["capability"] for action in result["actions"]
|
|
}
|
|
assert capabilities == {
|
|
"climate.set_temperature",
|
|
"roof.set_shade_position",
|
|
}
|
|
assert not list((tmp_path / "user-modes").rglob("*.yaml"))
|
|
assert any(event.get("type") == "action.completed" for event in events)
|
|
assert all("request_token" not in str(event) for event in events)
|