use objectiveai_sdk::agent::InlineAgentBaseWithFallbacksOrRemoteCommitOptional;
use sqlx::Row as _;
use super::super::{Error, Pool};
#[derive(Debug, Clone)]
pub struct SessionLookup {
pub agent: InlineAgentBaseWithFallbacksOrRemoteCommitOptional,
pub continuation: Option<String>,
}
pub async fn lookup_session(
pool: &Pool,
agent_instance_hierarchy: &str,
) -> Result<Option<SessionLookup>, Error> {
let row = sqlx::query(
"SELECT refs.remote AS remote, refs.inline AS inline, \
cont.continuation AS continuation \
FROM objectiveai.agent_refs refs \
LEFT JOIN objectiveai.agent_continuations cont \
ON cont.agent_instance_hierarchy = refs.agent_instance_hierarchy \
WHERE refs.agent_instance_hierarchy = $1",
)
.bind(agent_instance_hierarchy)
.fetch_optional(&**pool)
.await?;
let Some(row) = row else {
return lookup_session_from_request_blob(pool, agent_instance_hierarchy)
.await;
};
let remote: Option<String> = row.try_get("remote")?;
let inline: Option<serde_json::Value> = row.try_get("inline")?;
let continuation: Option<String> = row.try_get("continuation")?;
let agent_value = match (remote, inline) {
(Some(remote), _) => serde_json::Value::String(remote),
(None, Some(inline)) => inline,
(None, None) => {
return Err(Error::InvalidData(format!(
"agent_refs row for {agent_instance_hierarchy} has neither \
remote nor inline",
)));
}
};
let agent: InlineAgentBaseWithFallbacksOrRemoteCommitOptional =
serde_json::from_value(agent_value)?;
Ok(Some(SessionLookup { agent, continuation }))
}
async fn lookup_session_from_request_blob(
pool: &Pool,
agent_instance_hierarchy: &str,
) -> Result<Option<SessionLookup>, Error> {
let Some((_, response_id)) = agent_instance_hierarchy.rsplit_once('-') else {
return Ok(None);
};
let row = sqlx::query(
"SELECT req.body AS request_body, cont.continuation AS continuation \
FROM objectiveai.agent_completion_requests req \
LEFT JOIN objectiveai.agent_continuations cont \
ON cont.agent_instance_hierarchy = $2 \
WHERE req.response_id = $1",
)
.bind(response_id)
.bind(agent_instance_hierarchy)
.fetch_optional(&**pool)
.await?;
let Some(row) = row else { return Ok(None) };
let request_body: serde_json::Value = row.try_get("request_body")?;
let continuation: Option<String> = row.try_get("continuation")?;
let agent_value = request_body.get("agent").cloned().ok_or_else(|| {
Error::InvalidData(format!(
"agent_completion_requests.body missing `agent` field for response_id {response_id}",
))
})?;
let agent: InlineAgentBaseWithFallbacksOrRemoteCommitOptional =
serde_json::from_value(agent_value)?;
Ok(Some(SessionLookup { agent, continuation }))
}