feat: integrate production cockpit AI assistant

This commit is contained in:
vee
2026-09-08 17:46:07 +08:00
parent 5e228e12ae
commit 93103c2579
66 changed files with 11046 additions and 374 deletions
+120
View File
@@ -2,6 +2,7 @@ from __future__ import annotations
import json
import sys
import time
import tomllib
import traceback
from pathlib import Path
@@ -11,6 +12,7 @@ import pytest
from cognitive_agent.infrastructure.codex.app_server import (
CodexAppServerClient,
CodexAppServerProtocolError,
CodexAppServerTimeout,
CodexAppServerUnavailable,
CodexTurnHandle,
)
@@ -47,6 +49,21 @@ def _events_until_completed(handle: CodexTurnHandle) -> list[dict[str, object]]:
return events
def _wait_for_wire_method(trace_path: Path, method: str) -> list[dict[str, object]]:
deadline = time.monotonic() + 2
messages: list[dict[str, object]] = []
while time.monotonic() < deadline:
if trace_path.exists():
messages = [
json.loads(line)
for line in trace_path.read_text(encoding="utf-8").splitlines()
]
if any(message.get("method") == method for message in messages):
return messages
time.sleep(0.01)
raise AssertionError(f"timed out waiting for {method}: {messages}")
def test_real_stdio_adapter_handshake_stream_and_transport_overrides(tmp_path: Path) -> None:
client, trace_path = _client(tmp_path)
try:
@@ -124,6 +141,102 @@ def test_interrupt_is_sent_and_waits_for_authoritative_terminal_event(tmp_path:
assert terminal["status"] == "interrupted"
def test_late_thread_start_response_is_unsubscribed_after_rpc_timeout(
tmp_path: Path,
) -> None:
client, trace_path = _client(tmp_path)
try:
client.start(CALLBACK_URL, CALLBACK_TOKEN)
with pytest.raises(CodexAppServerTimeout):
client.start_thread(
developer_instructions="DELAY_THREAD_START",
ephemeral=True,
timeout=0.02,
)
wire = _wait_for_wire_method(trace_path, "thread/unsubscribe")
finally:
client.close()
start = next(item for item in wire if item.get("method") == "thread/start")
unsubscribe = next(
item for item in wire if item.get("method") == "thread/unsubscribe"
)
assert start["id"] != unsubscribe["id"]
assert unsubscribe["params"] == {"threadId": "thread-1"}
def test_late_structured_turn_response_is_interrupted_without_backlog_leak(
tmp_path: Path,
) -> None:
client, trace_path = _client(tmp_path)
try:
client.start(CALLBACK_URL, CALLBACK_TOKEN)
thread_id = client.start_thread(developer_instructions="Test", ephemeral=True)
with pytest.raises(CodexAppServerTimeout):
client.start_structured_turn(
thread_id,
"DELAY_TURN_START",
application_context={"capabilities": []},
output_schema={
"type": "object",
"additionalProperties": False,
"required": [],
"properties": {},
},
timeout=0.02,
)
wire = _wait_for_wire_method(trace_path, "turn/interrupt")
_wait_for_wire_method(trace_path, "thread/unsubscribe")
deadline = time.monotonic() + 1
while time.monotonic() < deadline:
with client._lock:
if not client._turns and not client._event_backlog:
break
time.sleep(0.01)
with client._lock:
assert client._turns == {}
assert client._event_backlog == {}
finally:
client.close()
interrupt = next(item for item in wire if item.get("method") == "turn/interrupt")
assert interrupt["params"] == {"threadId": thread_id, "turnId": "turn-1"}
def test_abandon_turn_releases_handle_and_discards_all_late_events(tmp_path: Path) -> None:
client, _trace_path = _client(tmp_path)
handle = CodexTurnHandle(thread_id="thread-abandoned", turn_id="turn-abandoned")
key = (handle.thread_id, handle.turn_id)
with client._lock:
client._turns[key] = handle
client.abandon_turn(handle)
client._dispatch(
{
"method": "item/agentMessage/delta",
"params": {
"threadId": handle.thread_id,
"turnId": handle.turn_id,
"delta": "late",
},
}
)
client._dispatch(
{
"method": "turn/completed",
"params": {
"threadId": handle.thread_id,
"turn": {"id": handle.turn_id, "status": "interrupted"},
},
}
)
with client._lock:
assert key not in client._turns
assert key not in client._event_backlog
assert key in client._abandoned_turns
def test_startup_bootstraps_missing_builtin_account_from_api_key_without_leaking_it(
tmp_path: Path,
monkeypatch: pytest.MonkeyPatch,
@@ -642,15 +755,22 @@ def test_client_can_restart_with_a_fresh_isolated_workspace(
)
first_workspace = client._cwd
client.start(CALLBACK_URL, CALLBACK_TOKEN)
first_cleanup_executor = client._late_cleanup_executor
assert first_cleanup_executor is not None
assert first_cleanup_executor._max_workers == 4
client.close()
assert not first_workspace.exists()
assert client._late_cleanup_executor is None
client.start(CALLBACK_URL, CALLBACK_TOKEN)
second_workspace = client._cwd
try:
assert client.available is True
assert second_workspace != first_workspace
assert second_workspace.is_dir()
assert client._late_cleanup_executor is not first_cleanup_executor
assert client._late_cleanup_executor is not None
assert client._late_cleanup_executor._max_workers == 4
finally:
client.close()
assert not second_workspace.exists()