use super::filter::{RawTriple, RecalledDrawer};
use super::{EMPTY_PLACEHOLDER, PALACE_KG_ALL_PATH, PALACE_RECALL_PATH, PROMPT_CONTEXT_PATH};
use serde_json::Value;
pub(super) async fn fetch_global_prompt_context(
client: &reqwest::Client,
base: &str,
) -> Option<String> {
let url = format!("{base}{PROMPT_CONTEXT_PATH}");
let resp = client.get(&url).send().await.ok()?;
if !resp.status().is_success() {
return None;
}
let body = resp.text().await.ok()?;
let trimmed = body.trim();
if trimmed.is_empty() || trimmed == EMPTY_PLACEHOLDER {
None
} else {
Some(body)
}
}
pub(super) async fn fetch_palace_recall(
client: &reqwest::Client,
base: &str,
palace: &str,
prompt: &str,
top_k: usize,
) -> Vec<RecalledDrawer> {
if prompt.is_empty() {
return Vec::new();
}
let path = PALACE_RECALL_PATH.replace("{slug}", palace);
let url = format!("{base}{path}");
let resp = match client
.get(&url)
.query(&[("q", prompt.to_string()), ("top_k", top_k.to_string())])
.send()
.await
{
Ok(r) => r,
Err(_) => return Vec::new(),
};
if !resp.status().is_success() {
return Vec::new();
}
let body: Value = match resp.json().await {
Ok(b) => b,
Err(_) => return Vec::new(),
};
let Some(arr) = body.as_array() else {
return Vec::new();
};
arr.iter()
.filter_map(RecalledDrawer::from_recall_entry)
.filter(|d| d.layer.unwrap_or(0) > 0)
.take(top_k)
.collect()
}
pub(super) async fn fetch_palace_kg_triples(
client: &reqwest::Client,
base: &str,
palace: &str,
) -> Vec<RawTriple> {
let path = PALACE_KG_ALL_PATH.replace("{slug}", palace);
let url = format!("{base}{path}");
let resp = match client.get(&url).query(&[("limit", "200")]).send().await {
Ok(r) => r,
Err(_) => return Vec::new(),
};
if !resp.status().is_success() {
return Vec::new();
}
let body: Value = match resp.json().await {
Ok(b) => b,
Err(_) => return Vec::new(),
};
let Some(arr) = body.as_array() else {
return Vec::new();
};
arr.iter().filter_map(RawTriple::from_value).collect()
}