use lingshu_state::SessionDb;
use std::sync::Arc;
pub async fn mirror_to_session(
db: &Arc<SessionDb>,
platform: &str,
chat_id: &str,
message_text: &str,
source_label: &str,
thread_id: Option<&str>,
) -> bool {
let session_id = match find_session_id(db, platform, chat_id, thread_id).await {
Some(id) => id,
None => {
tracing::debug!(platform, chat_id, thread_id, "mirror: no session found");
return false;
}
};
let msg = lingshu_types::Message {
role: lingshu_types::message::Role::Assistant,
content: Some(lingshu_types::message::Content::Text(format!(
"[mirror from {source_label}] {message_text}"
))),
tool_calls: None,
tool_call_id: None,
name: None,
reasoning: None,
finish_reason: None,
};
match db.save_message(&session_id, &msg).await {
Ok(()) => {
tracing::debug!(session_id, source_label, "mirror: wrote to session");
true
}
Err(e) => {
tracing::debug!(error = %e, "mirror: failed to write");
false
}
}
}
async fn find_session_id(
db: &Arc<SessionDb>,
platform: &str,
chat_id: &str,
thread_id: Option<&str>,
) -> Option<String> {
let sessions = db.list_sessions(100).await.ok()?;
let platform_lower = platform.to_lowercase();
let exact_routing_key = match thread_id {
Some(thread_id) if !thread_id.is_empty() => format!("{chat_id}:{thread_id}"),
_ => chat_id.to_string(),
};
let mut best_match: Option<(String, f64)> = None;
for session in sessions {
let source = session.source.to_lowercase();
if source != platform_lower {
continue;
}
let record = match db.get_session(&session.id).await {
Ok(Some(record)) => record,
_ => continue,
};
let Some(session_chat_id) = record.user_id.as_deref() else {
continue;
};
if session_chat_id != exact_routing_key && session_chat_id != chat_id {
continue;
}
let started = session.started_at;
match &best_match {
Some((_, best_time)) if started > *best_time => {
best_match = Some((session.id, started));
}
None => {
best_match = Some((session.id, started));
}
_ => {}
}
}
best_match.map(|(id, _)| id)
}
#[cfg(test)]
mod tests {
use super::*;
}