test_sqlite_store.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. from agent_lab.domain.messages import ChatMessage, TokenUsage
  2. from agent_lab.infrastructure.sqlite_store import SQLiteSessionStore
  3. def test_sqlite_store_persists_session_messages_audit_and_usage(tmp_path):
  4. store = SQLiteSessionStore(tmp_path / "agent_lab.sqlite3")
  5. session_id = store.create_session(
  6. title="Debug first turn",
  7. config={"chat_agent": {"model": "chat-model"}},
  8. )
  9. store.start_turn(session_id, turn_index=1, user_message="debug this")
  10. store.append_message(
  11. session_id,
  12. turn_index=1,
  13. message=ChatMessage(role="user", content="debug this"),
  14. )
  15. store.append_message(
  16. session_id,
  17. turn_index=1,
  18. message=ChatMessage(role="assistant", content="answer"),
  19. )
  20. store.append_audit(
  21. session_id,
  22. event="chat_agent_request",
  23. details={"model": "chat-model"},
  24. turn_index=1,
  25. round_index=1,
  26. )
  27. store.append_usage(
  28. session_id,
  29. turn_index=1,
  30. round_index=1,
  31. usage=TokenUsage(
  32. prompt_tokens=3,
  33. completion_tokens=7,
  34. total_tokens=10,
  35. cached_tokens=2,
  36. ),
  37. ttft_ms=120,
  38. elapsed_ms=450,
  39. )
  40. store.complete_turn(session_id, turn_index=1)
  41. sessions = store.list_sessions()
  42. assert sessions == [
  43. {
  44. "id": session_id,
  45. "title": "Debug first turn",
  46. "created_at": sessions[0]["created_at"],
  47. "updated_at": sessions[0]["updated_at"],
  48. "turn_count": 1,
  49. "total_tokens": 10,
  50. }
  51. ]
  52. assert store.get_session(session_id)["config"]["chat_agent"]["model"] == "chat-model"
  53. assert [message["content"] for message in store.list_messages(session_id)] == [
  54. "debug this",
  55. "answer",
  56. ]
  57. assert store.list_audit_logs(session_id)[0]["event"] == "chat_agent_request"
  58. usage = store.usage_summary(session_id)
  59. assert usage["calls"][0]["total_tokens"] == 10
  60. assert usage["turns"] == [
  61. {
  62. "turn_index": 1,
  63. "prompt_tokens": 3,
  64. "completion_tokens": 7,
  65. "total_tokens": 10,
  66. "cached_tokens": 2,
  67. "elapsed_ms": 450,
  68. }
  69. ]
  70. assert usage["session"]["total_tokens"] == 10
  71. def test_sqlite_store_session_list_totals_are_not_multiplied_by_turns(tmp_path):
  72. store = SQLiteSessionStore(tmp_path / "agent_lab.sqlite3")
  73. session_id = store.create_session(title="two turns", config={})
  74. for turn_index, tokens in [(1, 2), (2, 4)]:
  75. store.start_turn(
  76. session_id,
  77. turn_index=turn_index,
  78. user_message=f"turn {turn_index}",
  79. )
  80. store.append_usage(
  81. session_id,
  82. turn_index=turn_index,
  83. round_index=1,
  84. usage=TokenUsage(total_tokens=tokens),
  85. ttft_ms=None,
  86. elapsed_ms=10,
  87. )
  88. assert store.list_sessions()[0]["turn_count"] == 2
  89. assert store.list_sessions()[0]["total_tokens"] == 6