Coverage for agentos/tests/test_conversation.py: 0%
102 statements
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-06 10:59 +0800
« prev ^ index » next coverage.py v7.14.3, created at 2026-07-06 10:59 +0800
1"""Tests for agentos.conversation.conversation."""
3from __future__ import annotations
5import pytest
6from agentos.conversation.conversation import (
7 ConversationManager,
8 ConversationConfig,
9 MessageRole,
10 TrimStrategy,
11)
14@pytest.fixture
15def conv():
16 return ConversationManager(ConversationConfig(max_messages=10, max_tokens=100000))
19def test_add_message(conv):
20 """添加单条消息。"""
21 msg = conv.add("user", "Hello")
22 assert msg.role == MessageRole.USER
23 assert msg.content == "Hello"
24 assert conv.message_count == 1
27def test_add_many(conv):
28 """批量添加消息。"""
29 msgs = conv.add_many([("user", "Hi"), ("assistant", "Hello there")])
30 assert len(msgs) == 2
31 assert conv.message_count == 2
34def test_get_context(conv):
35 """获取 OpenAI 兼容上下文。"""
36 conv.add("system", "You are helpful.")
37 conv.add("user", "Question?")
38 ctx = conv.get_context()
39 assert len(ctx) == 2
40 assert ctx[0]["role"] == "system"
41 assert ctx[1]["role"] == "user"
44def test_fifo_trim(conv):
45 """FIFO 裁剪:超出 max_messages 时移除最旧消息。"""
46 conv.config.max_messages = 5
47 conv.config.preserve_last_n = 2
48 for i in range(10):
49 conv.add("user", f"msg{i}")
50 assert conv.message_count <= 5
53def test_preserve_system(conv):
54 """裁剪时保留 system 消息。"""
55 conv.config.max_messages = 4
56 conv.config.preserve_last_n = 1
57 conv.config.preserve_system = True
58 conv.add("system", "System prompt")
59 for i in range(8):
60 conv.add("user", f"msg{i}")
61 system_msgs = [m for m in conv._messages if m.role == MessageRole.SYSTEM]
62 assert len(system_msgs) >= 1
63 assert system_msgs[0].content == "System prompt"
66def test_token_tracking(conv):
67 """token 统计。"""
68 conv.add("user", "A" * 300)
69 assert conv.token_count > 50
72def test_fork_and_switch(conv):
73 """对话分支:fork -> switch -> 验证。"""
74 conv.add("user", "msg1")
75 conv.add("assistant", "reply1")
76 snapshot = conv.fork("test-branch")
77 assert snapshot.label == "test-branch"
79 conv.add("user", "msg2")
80 assert conv.message_count == 3
82 conv.switch_branch(snapshot.snapshot_id)
83 assert conv.message_count == 2
86def test_fork_branch_not_found(conv):
87 """切换不存在分支抛出 KeyError。"""
88 with pytest.raises(KeyError):
89 conv.switch_branch("nonexistent")
92def test_merge_branch_append(conv):
93 """合并分支(追加模式)。"""
94 conv.add("user", "msg1")
95 snapshot = conv.fork("side")
96 conv.add("user", "msg2")
97 conv.add("user", "msg3")
98 conv.merge_branch(snapshot.snapshot_id, strategy="append")
99 assert conv.message_count >= 3
102def test_clear(conv):
103 """清空对话。"""
104 conv.add_many([("user", "a"), ("assistant", "b"), ("user", "c")])
105 conv.clear()
106 assert conv.message_count == 0
107 assert conv.token_count == 0
110def test_clear_keep_system(conv):
111 """清空但保留 system 消息。"""
112 conv.add("system", "sys")
113 conv.add("user", "q")
114 conv.add("assistant", "a")
115 conv.clear(keep_system=True)
116 assert conv.message_count == 1
117 assert conv._messages[0].content == "sys"
120def test_stats_tracking(conv):
121 """统计数据正确累加。"""
122 conv.add("user", "hello world")
123 conv.add("assistant", "hi there")
124 assert conv.stats.total_messages == 2
125 assert conv.stats.total_tokens > 0
126 assert conv.stats.oldest_timestamp > 0
129def test_message_id_unique(conv):
130 """每条消息 ID 唯一。"""
131 msgs = conv.add_many([("user", f"msg{i}") for i in range(5)])
132 ids = {m.message_id for m in msgs}
133 assert len(ids) == 5
136def test_empty_context(conv):
137 """空对话上下文。"""
138 ctx = conv.get_context()
139 assert ctx == []
142def test_get_system_prompt(conv):
143 """提取 system prompt。"""
144 conv.add("system", "Be concise.")
145 conv.add("user", "Q")
146 assert conv.get_system_prompt() == "Be concise."
149def test_importance_weighted_trim():
150 """重要性加权裁剪。"""
151 cfg = ConversationConfig(max_messages=5, trim_strategy=TrimStrategy.IMPORTANCE_WEIGHTED, preserve_last_n=2)
152 c = ConversationManager(cfg)
153 for i in range(10):
154 m = c.add("user", f"msg{i}")
155 m.importance = float(i % 3)
156 assert c.message_count <= 5
159def test_trim_stats_increment(conv):
160 """裁剪后 trim_count 递增。"""
161 conv.config.max_messages = 3
162 conv.config.preserve_last_n = 1
163 for i in range(8):
164 conv.add("user", f"msg{i}")
165 assert conv.stats.trim_count > 0