main
py 84 lines 2.53 KB
Raw
1 from datetime import datetime, timedelta, timezone
2 import json
3 from pathlib import Path
4 import sys
5 import threading
6
7 import pytest
8
9 PROJECT_ROOT = Path(__file__).resolve().parents[1]
10 if str(PROJECT_ROOT) not in sys.path:
11 sys.path.insert(0, str(PROJECT_ROOT))
12
13 from agent import AgentContext
14 from initialize import initialize_agent
15
16
17 class _CompletedTask:
18 async def result(self):
19 return "ok"
20
21
22 @pytest.mark.asyncio
23 async def test_api_message_persists_lifetime_hours_in_context_data(monkeypatch):
24 from api.api_message import ApiMessage
25 from helpers import persist_chat
26
27 monkeypatch.setattr(AgentContext, "communicate", lambda self, msg: _CompletedTask())
28
29 handler = ApiMessage(app=None, thread_lock=threading.RLock()) # type: ignore[arg-type]
30 output = await handler.process(
31 {
32 "message": "hello",
33 "lifetime_hours": 1,
34 },
35 request=None, # type: ignore[arg-type]
36 )
37
38 context_id = output["context_id"] # type: ignore[index]
39 context = AgentContext.get(context_id)
40 restored = None
41 try:
42 assert context is not None
43 assert context.get_data("lifetime_hours") == 1.0
44
45 serialized = json.loads(persist_chat.export_json_chat(context))
46 assert serialized["data"]["lifetime_hours"] == 1.0
47
48 AgentContext.remove(context_id)
49 restored = persist_chat._deserialize_context(serialized)
50 assert restored.get_data("lifetime_hours") == 1.0
51 finally:
52 AgentContext.remove(context_id)
53 if restored:
54 AgentContext.remove(restored.id)
55
56
57 @pytest.mark.asyncio
58 async def test_job_loop_removes_expired_lifetime_chat(monkeypatch):
59 from extensions.python.job_loop._20_cleanup_expired_api_chats import (
60 CleanupExpiredApiChats,
61 )
62 import extensions.python.job_loop._20_cleanup_expired_api_chats as cleanup_module
63
64 removed_chats = []
65 dirty_reasons = []
66 monkeypatch.setattr(cleanup_module.persist_chat, "remove_chat", removed_chats.append)
67 monkeypatch.setattr(
68 cleanup_module,
69 "mark_dirty_all",
70 lambda reason: dirty_reasons.append(reason),
71 )
72
73 context = AgentContext(
74 config=initialize_agent(),
75 last_message=datetime.now(timezone.utc) - timedelta(hours=2),
76 )
77 context.set_data("lifetime_hours", 1)
78 CleanupExpiredApiChats._last_check = None
79
80 await CleanupExpiredApiChats(agent=None).execute()
81
82 assert AgentContext.get(context.id) is None
83 assert removed_chats == [context.id]
84 assert dirty_reasons == ["job_loop.CleanupExpiredApiChats"]