Files
life-echo/api/app/features/conversation/session_history.py
2026-03-20 15:15:35 +08:00

64 lines
2.0 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
会话 transcript 与 Redis 历史条目的纯映射(无 I/O
仅由 ConversationService 使用:对齐 ChatOrchestrator 经 save_message 写入 Redis 的字段形状,
不属于 Agent 层 —— 多 Agent 模块只消费已就绪的 history不负责从 DB 重建。
"""
from __future__ import annotations
from datetime import timezone
from typing import Any, Dict, List
from app.features.conversation.models import Segment
def _voice_session_id_from_audio_url(audio_url: str | None) -> str | None:
if not audio_url:
return None
prefix = "audio-segment:"
if not audio_url.startswith(prefix):
return None
payload = audio_url[len(prefix) :]
voice_session_id_raw, sep, _ = payload.rpartition(":")
if sep and voice_session_id_raw:
return voice_session_id_raw
return None
def _segment_timestamp_iso(seg: Segment) -> str | None:
if not seg.created_at:
return None
dt = seg.created_at
if dt.tzinfo is None:
dt = dt.replace(tzinfo=timezone.utc)
return dt.isoformat()
def segments_to_redis_history(segments: List[Segment]) -> List[Dict[str, Any]]:
"""Segment 行 → Redis conversation history 项(与 ChatOrchestrator 写入格式一致)。"""
history: List[Dict[str, Any]] = []
for seg in segments:
ts = _segment_timestamp_iso(seg)
is_voice = bool(seg.audio_url)
human: Dict[str, Any] = {
"role": "human",
"content": seg.transcript_text or "",
"messageType": "audio" if is_voice else "text",
"timestamp": ts,
}
vsid = _voice_session_id_from_audio_url(seg.audio_url)
if vsid:
human["voiceSessionId"] = vsid
history.append(human)
if seg.agent_response and seg.agent_response.strip():
history.append(
{
"role": "ai",
"content": seg.agent_response.strip(),
"messageType": "text",
"timestamp": ts,
}
)
return history