use serde::Serialize;
use super::{Error, Pool};
pub enum AgentRefValue {
Remote(String),
Inline(serde_json::Value),
}
impl AgentRefValue {
pub fn remote<T: Serialize>(remote: &T) -> Option<Self> {
match serde_json::to_value(remote).ok()? {
serde_json::Value::String(s) => Some(Self::Remote(s)),
other => Some(Self::Remote(other.to_string())),
}
}
pub fn inline<T: Serialize>(spec: &T) -> Option<Self> {
serde_json::to_value(spec).ok().map(Self::Inline)
}
}
fn now_seconds() -> i64 {
use std::time::{SystemTime, UNIX_EPOCH};
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map(|d| d.as_secs() as i64)
.unwrap_or(0)
}
pub async fn upsert(
pool: &Pool,
agent_instance_hierarchy: &str,
value: AgentRefValue,
) -> Result<(), Error> {
let (remote, inline) = match value {
AgentRefValue::Remote(remote) => (Some(remote), None),
AgentRefValue::Inline(inline) => (None, Some(inline)),
};
sqlx::query(
"INSERT INTO objectiveai.agent_refs \
(agent_instance_hierarchy, remote, inline, updated_at) \
VALUES ($1, $2, $3, $4) \
ON CONFLICT (agent_instance_hierarchy) DO UPDATE SET \
remote = EXCLUDED.remote, \
inline = EXCLUDED.inline, \
updated_at = EXCLUDED.updated_at",
)
.bind(agent_instance_hierarchy)
.bind(remote)
.bind(inline)
.bind(now_seconds())
.execute(&**pool)
.await?;
Ok(())
}