修复:CI 部署环境与 ref 错配、迁移碎片化、图片意图 source_span、章节物化脏版式、会话历史与本地语音不一致

新增:TTS 上传 COS 与分片、章节 reading_segments 物化与快照、markdown 清洗、会话消息 repository、语音 store 重构与相关测试
This commit is contained in:
Kevin
2026-03-20 16:36:42 +08:00
parent 7317bf10cd
commit 8af37e5e8e
65 changed files with 1704 additions and 504 deletions

View File

@@ -3,7 +3,11 @@ from datetime import datetime, timezone
from app.features.conversation.models import Conversation
from app.features.conversation import router as conversations_router
from app.features.conversation.service import (
_build_messages_from_history,
_latest_message_time_ms,
_message_timestamp_ms,
)
class ConversationMessagesHistoryTest(unittest.TestCase):
@@ -37,7 +41,7 @@ class ConversationMessagesHistoryTest(unittest.TestCase):
},
]
messages = conversations_router._build_messages_from_history(
messages = _build_messages_from_history(
conversation_id="conv-1",
history=history,
fallback_timestamp=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
@@ -55,6 +59,7 @@ class ConversationMessagesHistoryTest(unittest.TestCase):
],
)
self.assertEqual(messages[0]["timestamp"], 1773489601000)
self.assertEqual(messages[0]["voiceSessionId"], "voice-1")
self.assertEqual(messages[1]["timestamp"], 1773489602000)
self.assertEqual(messages[2]["timestamp"], 1773489604000)
@@ -76,7 +81,7 @@ class ConversationMessagesHistoryTest(unittest.TestCase):
},
]
messages = conversations_router._build_messages_from_history(
messages = _build_messages_from_history(
conversation_id="conv-1",
history=history,
fallback_timestamp=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
@@ -85,8 +90,29 @@ class ConversationMessagesHistoryTest(unittest.TestCase):
self.assertEqual(len(messages), 2)
self.assertEqual(messages[0]["messageType"], "audio")
self.assertEqual(messages[0]["content"], "第一次录音")
self.assertEqual(messages[0]["voiceSessionId"], "voice-1")
self.assertEqual(messages[1]["messageType"], "audio")
self.assertEqual(messages[1]["content"], "第二次录音")
self.assertEqual(messages[1]["voiceSessionId"], "voice-2")
def test_build_messages_includes_duration_seconds_from_history(self):
history = [
{
"role": "human",
"content": "你好",
"messageType": "audio",
"voiceSessionId": "vs-a",
"durationSeconds": 8,
"timestamp": "2026-03-14T12:00:01+00:00",
},
]
messages = _build_messages_from_history(
conversation_id="conv-1",
history=history,
fallback_timestamp=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
)
self.assertEqual(len(messages), 1)
self.assertEqual(messages[0]["durationSeconds"], 8)
def test_latest_message_time_prefers_conversation_last_message_at(self):
conversation = Conversation(
@@ -104,9 +130,7 @@ class ConversationMessagesHistoryTest(unittest.TestCase):
}
]
latest_message_time = conversations_router._latest_message_time_ms(
conversation, history
)
latest_message_time = _latest_message_time_ms(conversation, history)
self.assertEqual(latest_message_time, 1773489605000)
@@ -117,8 +141,6 @@ class ConversationMessagesHistoryTest(unittest.TestCase):
started_at=datetime(2026, 3, 14, 12, 0, 0, tzinfo=timezone.utc),
)
timestamp = conversations_router._message_timestamp_ms(
{}, conversation.started_at
)
timestamp = _message_timestamp_ms({}, conversation.started_at)
self.assertEqual(timestamp, 1773489600000)