use tracing::warn;
use crate::ilink::types::HubExt;
use crate::store::Store;
use super::super::*;
pub async fn resolve_vctx_for_message(
state: &HubState,
real_ctx: &str,
peer_user_id: &str,
group_id: Option<&str>,
_client_scope: Option<&str>,
) -> String {
match state
.store
.find_or_create_vctx(peer_user_id, group_id, real_ctx)
.await
{
Ok(vctx) => vctx,
Err(e) => {
warn!(error = %e, "find_or_create_vctx failed, generating ephemeral vctx");
format!("vctx_{}", uuid::Uuid::new_v4().simple())
}
}
}
pub async fn build_hub_ext_for_vctx(
store: &Store,
vctx: &str,
vtoken: &str,
session_override: Option<String>,
) -> Option<HubExt> {
if let Some(name) = session_override.filter(|n| !n.is_empty()) {
let session_id = match tokio::time::timeout(
std::time::Duration::from_secs(5),
store.get_backend_session(vctx, vtoken, &name),
)
.await
{
Ok(Ok(Some(s))) => {
let t = s.trim().to_string();
(!t.is_empty()).then_some(t)
}
Ok(Ok(None)) => None,
Ok(Err(e)) => {
warn!("Failed to get backend session from DB for {vctx}/{name}: {e}");
None
}
Err(_) => {
warn!("Timeout getting backend session from DB for {vctx}/{name}");
None
}
};
return Some(HubExt {
session_id,
session_name: Some(name),
cli_session_id: None,
a2a_call_id: None,
a2a_depth: None,
usage: None,
});
}
let (session_name, session_id) = match tokio::time::timeout(
std::time::Duration::from_secs(5),
store.get_hub_ext_single(vctx, vtoken),
)
.await
{
Ok(Ok(pair)) => pair,
Ok(Err(e)) => {
warn!("Failed to get hub ext from DB for {vctx}: {e}");
("default".to_string(), None)
}
Err(_) => {
warn!("Timeout getting hub ext from DB for {vctx}");
("default".to_string(), None)
}
};
Some(HubExt {
session_id,
session_name: Some(session_name),
cli_session_id: None,
a2a_call_id: None,
a2a_depth: None,
usage: None,
})
}
pub(super) fn build_no_backend_reply(user_text: Option<&str>) -> String {
let is_command = user_text
.map(|t| t.trim().starts_with('/'))
.unwrap_or(false);
if is_command {
return messages::UNRECOGNIZED_COMMAND.to_string();
}
messages::NO_BACKEND_ONLINE.to_string()
}