166 lines
6.3 KiB
Python
166 lines
6.3 KiB
Python
from __future__ import annotations
|
|
|
|
import tempfile
|
|
import unittest
|
|
from datetime import datetime
|
|
from pathlib import Path
|
|
|
|
from opc.core.models import AgentMessage, ExternalSession
|
|
from opc.database.store import OPCStore
|
|
|
|
|
|
class CliRuntimeStoreHelperTests(unittest.IsolatedAsyncioTestCase):
|
|
async def asyncSetUp(self) -> None:
|
|
self._tmpdir = tempfile.TemporaryDirectory()
|
|
self.store = OPCStore(Path(self._tmpdir.name) / "store.db")
|
|
await self.store.initialize()
|
|
|
|
async def asyncTearDown(self) -> None:
|
|
await self.store.close()
|
|
self._tmpdir.cleanup()
|
|
|
|
async def test_runtime_event_and_session_filters(self) -> None:
|
|
await self.store.save_runtime_session(
|
|
runtime_session_id="rt-1",
|
|
project_id="proj1",
|
|
session_id="sess-1",
|
|
task_id="task-1",
|
|
status="running",
|
|
metadata={"summary": "active"},
|
|
)
|
|
await self.store.save_runtime_session(
|
|
runtime_session_id="rt-2",
|
|
project_id="proj1",
|
|
session_id="sess-2",
|
|
task_id="task-2",
|
|
status="completed",
|
|
metadata={"summary": "done"},
|
|
)
|
|
await self.store.save_runtime_event("rt-1", "tool_started", {"tool_name": "shell_exec"})
|
|
await self.store.save_runtime_event("rt-1", "tool_completed", {"result_summary": "ok"})
|
|
|
|
by_project = await self.store.list_runtime_sessions(project_id="proj1", limit=10)
|
|
by_task = await self.store.list_runtime_sessions(project_id="proj1", task_id="task-1", limit=10)
|
|
by_session = await self.store.list_runtime_sessions(project_id="proj1", session_id="sess-2", limit=10)
|
|
events = await self.store.list_runtime_events("rt-1", limit=10)
|
|
|
|
self.assertEqual({row["runtime_session_id"] for row in by_project}, {"rt-1", "rt-2"})
|
|
self.assertEqual([row["runtime_session_id"] for row in by_task], ["rt-1"])
|
|
self.assertEqual([row["runtime_session_id"] for row in by_session], ["rt-2"])
|
|
self.assertEqual([event["event_type"] for event in events], ["tool_started", "tool_completed"])
|
|
self.assertEqual(events[0]["payload"]["tool_name"], "shell_exec")
|
|
|
|
async def test_external_session_filters(self) -> None:
|
|
await self.store.save_external_session(
|
|
ExternalSession(
|
|
agent_type="codex",
|
|
project_id="proj1",
|
|
session_id="provider-1",
|
|
opc_session_id="sess-1",
|
|
task_id="task-1",
|
|
workspace_path="workspace",
|
|
run_mode="interactive",
|
|
status="running",
|
|
updated_at=datetime.now(),
|
|
)
|
|
)
|
|
await self.store.save_external_session(
|
|
ExternalSession(
|
|
agent_type="claude_code",
|
|
project_id="proj1",
|
|
session_id="provider-2",
|
|
opc_session_id="sess-2",
|
|
task_id="task-2",
|
|
status="completed",
|
|
updated_at=datetime.now(),
|
|
)
|
|
)
|
|
|
|
running = await self.store.list_external_sessions(project_id="proj1", status="running")
|
|
by_task = await self.store.list_external_sessions(project_id="proj1", task_id="task-2")
|
|
by_opc_session = await self.store.list_external_sessions(project_id="proj1", opc_session_id="sess-1")
|
|
|
|
self.assertEqual([item.agent_type for item in running], ["codex"])
|
|
self.assertEqual([item.session_id for item in by_task], ["provider-2"])
|
|
self.assertEqual([item.task_id for item in by_opc_session], ["task-1"])
|
|
|
|
async def test_external_session_done_closes_replaced_working_placeholder(self) -> None:
|
|
await self.store.save_external_session(
|
|
ExternalSession(
|
|
agent_type="codex",
|
|
project_id="proj1",
|
|
session_id="codex:proj1:task-1",
|
|
opc_session_id="role-session-1",
|
|
task_id="task-1",
|
|
status="working",
|
|
updated_at=datetime.now(),
|
|
)
|
|
)
|
|
await self.store.save_external_session(
|
|
ExternalSession(
|
|
agent_type="codex",
|
|
project_id="proj1",
|
|
session_id="codex:proj1:task-1",
|
|
opc_session_id="other-role-session",
|
|
task_id="task-1",
|
|
status="working",
|
|
updated_at=datetime.now(),
|
|
)
|
|
)
|
|
|
|
await self.store.save_external_session(
|
|
ExternalSession(
|
|
agent_type="codex",
|
|
project_id="proj1",
|
|
session_id="provider-session-1",
|
|
opc_session_id="role-session-1",
|
|
task_id="task-1",
|
|
status="done",
|
|
updated_at=datetime.now(),
|
|
)
|
|
)
|
|
|
|
role_rows = await self.store.list_external_sessions(
|
|
project_id="proj1",
|
|
task_id="task-1",
|
|
opc_session_id="role-session-1",
|
|
)
|
|
other_role_rows = await self.store.list_external_sessions(
|
|
project_id="proj1",
|
|
task_id="task-1",
|
|
opc_session_id="other-role-session",
|
|
)
|
|
|
|
self.assertEqual({item.status for item in role_rows}, {"done"})
|
|
self.assertEqual({item.session_id for item in role_rows}, {"codex:proj1:task-1", "provider-session-1"})
|
|
self.assertEqual([item.status for item in other_role_rows], ["working"])
|
|
|
|
async def test_agent_messages_for_task_scope(self) -> None:
|
|
await self.store.save_message(
|
|
AgentMessage(
|
|
msg_id="msg-1",
|
|
msg_type="request_review",
|
|
from_agent="founder",
|
|
to_agents=["reviewer"],
|
|
subject="Review",
|
|
body="Please review.",
|
|
task_id="task-1",
|
|
)
|
|
)
|
|
await self.store.save_message(
|
|
AgentMessage(
|
|
msg_id="msg-2",
|
|
msg_type="inform",
|
|
from_agent="reviewer",
|
|
to_agents=["founder"],
|
|
subject="Other",
|
|
body="Other task.",
|
|
task_id="task-2",
|
|
)
|
|
)
|
|
|
|
messages = await self.store.list_agent_messages_for_tasks(["task-1"], limit=10)
|
|
|
|
self.assertEqual([message.msg_id for message in messages], ["msg-1"])
|
|
self.assertEqual(messages[0].subject, "Review")
|