from __future__ import annotations from pathlib import Path from fastapi.testclient import TestClient from beaver.engine.session import SessionManager from beaver.interfaces.web.app import create_app from beaver.services.agent_service import AgentService def test_archived_sessions_can_be_hidden_from_default_web_list(tmp_path: Path) -> None: manager = SessionManager(tmp_path) manager.ensure_session("web:keep", source="web") manager.ensure_session("web:archived", source="web") manager.end_session("web:archived", "archived") visible = manager.list_sessions_rich(exclude_end_reasons=["archived"]) visible_ids = {row["id"] for row in visible} assert "web:keep" in visible_ids assert "web:archived" not in visible_ids assert manager.get_session("web:archived")["end_reason"] == "archived" def test_archived_sessions_remain_available_to_history_search(tmp_path: Path) -> None: manager = SessionManager(tmp_path) manager.ensure_session("web:archived", source="web") manager.end_session("web:archived", "archived") all_sessions = manager.list_sessions_rich() assert {row["id"] for row in all_sessions} == {"web:archived"} def test_visible_history_excludes_error_and_incomplete_runs(tmp_path: Path) -> None: manager = SessionManager(tmp_path) manager.ensure_session("web:history", source="web") manager.append_message("web:history", run_id="ok-run", role="user", content="hello") manager.append_message("web:history", run_id="ok-run", role="assistant", content="hi", finish_reason="stop") manager.append_message( "web:history", run_id="ok-run", role="assistant", content=None, tool_calls=[{"id": "call-1", "type": "function", "function": {"name": "echo", "arguments": "{}"}}], ) manager.append_message( "web:history", run_id="ok-run", role="tool", content="tool result", tool_call_id="call-1", ) manager.append_message( "web:history", run_id="ok-run", role="system", event_type="run_completed", content="hi", context_visible=False, ) manager.append_message("web:history", run_id="error-run", role="user", content="bad") manager.append_message( "web:history", run_id="error-run", role="assistant", content="Error: provider failed", finish_reason="error", ) manager.append_message( "web:history", run_id="error-run", role="system", event_type="run_completed", content="Error: provider failed", finish_reason="error", context_visible=False, ) manager.append_message("web:history", run_id="pending-run", role="user", content="pending") history = manager.get_visible_history("web:history") assert [(message["role"], message["content"]) for message in history] == [ ("user", "hello"), ("assistant", "hi"), ] def test_web_archive_route_does_not_create_archive_suffix_session(tmp_path: Path) -> None: service = AgentService(workspace=tmp_path) app = create_app(service=service, manage_service_lifecycle=False) with TestClient(app) as client: create_response = client.post("/api/sessions/web:alpha") archive_response = client.post("/api/sessions/web:alpha/archive") sessions_response = client.get("/api/sessions") assert create_response.status_code == 200 assert archive_response.status_code == 200 assert archive_response.json() == {"ok": True, "archived": True} assert sessions_response.status_code == 200 loaded = service.create_loop().boot() assert loaded.session_manager.get_session("web:alpha")["end_reason"] == "archived" # type: ignore[union-attr] assert loaded.session_manager.get_session("web:alpha/archive") is None # type: ignore[union-attr] assert sessions_response.json() == [] def test_web_session_list_hides_skill_replay_evaluation_sessions(tmp_path: Path) -> None: service = AgentService(workspace=tmp_path) loaded = service.create_loop().boot() loaded.session_manager.ensure_session("eval-session", source="skill_replay_eval") # type: ignore[union-attr] loaded.session_manager.ensure_session("web:visible", source="web") # type: ignore[union-attr] app = create_app(service=service, manage_service_lifecycle=False) with TestClient(app) as client: response = client.get("/api/sessions") assert response.status_code == 200 assert [item["key"] for item in response.json()] == ["web:visible"] def test_get_missing_session_returns_404_without_creating_it(tmp_path: Path) -> None: service = AgentService(workspace=tmp_path) app = create_app(service=service, manage_service_lifecycle=False) with TestClient(app) as client: response = client.get("/api/sessions/missing-session") assert response.status_code == 404 loaded = service.create_loop().boot() assert loaded.session_manager.get_session("missing-session") is None # type: ignore[union-attr]