use super::*;
use super::prompts;
use super::scan;
use super::queue;
use crate::errors::AppError;
use std::path::Path;
pub(crate) fn call_claude(
binary: &Path,
prompt: &str,
json_schema: &str,
input_text: &str,
model: Option<&str>,
timeout_secs: u64,
) -> Result<(serde_json::Value, f64, bool), AppError> {
let result = crate::commands::claude_runner::run_claude(
binary,
prompt,
json_schema,
input_text,
model,
timeout_secs,
7,
)?;
Ok((result.value, result.cost_usd, result.is_oauth))
}
pub(crate) struct OpenRouterFailureDiagnostics {
pub(crate) retry_class: crate::retry::AttemptOutcome,
pub(crate) finish_reason: Option<String>,
pub(crate) prompt_tokens: Option<i64>,
pub(crate) completion_tokens: Option<i64>,
}
thread_local! {
static LAST_OPENROUTER_FAILURE: std::cell::RefCell<Option<OpenRouterFailureDiagnostics>> =
const { std::cell::RefCell::new(None) };
}
pub(crate) fn take_last_openrouter_failure() -> Option<OpenRouterFailureDiagnostics> {
LAST_OPENROUTER_FAILURE.with(|cell| cell.borrow_mut().take())
}
pub(crate) fn call_openrouter(
prompt: &str,
json_schema: &str,
input_text: &str,
model: Option<&str>,
timeout_secs: u64,
) -> Result<(serde_json::Value, f64, bool), AppError> {
let _ = (model, timeout_secs);
let client = crate::embedder::openrouter_chat_client().ok_or_else(|| {
AppError::Validation(
"OpenRouter chat client not initialised before dispatch (internal error)".into(),
)
})?;
let runtime = crate::embedder::shared_runtime()?;
match runtime.block_on(client.complete(
prompt,
input_text,
json_schema,
Some(crate::constants::ENRICH_INITIAL_MAX_TOKENS),
)) {
Ok(completion) => Ok((completion.value, completion.cost_usd, false)),
Err(chat_err) => {
LAST_OPENROUTER_FAILURE.with(|cell| {
*cell.borrow_mut() = Some(OpenRouterFailureDiagnostics {
retry_class: chat_err.retry_class,
finish_reason: chat_err.finish_reason.clone(),
prompt_tokens: chat_err.prompt_tokens.map(i64::from),
completion_tokens: chat_err.completion_tokens.map(i64::from),
});
});
Err(chat_err.source)
}
}
}
pub(crate) enum EnrichItemResult {
Done {
memory_id: Option<i64>,
entity_id: Option<i64>,
entities: usize,
rels: usize,
chars_before: Option<usize>,
chars_after: Option<usize>,
cost: f64,
is_oauth: bool,
},
Skipped {
reason: String,
},
PreservationFailed {
score: f64,
threshold: f64,
chars_before: usize,
chars_after: usize,
},
}
#[path = "extraction_ops_a.rs"]
mod ops_a;
#[path = "extraction_ops_b.rs"]
mod ops_b;
#[path = "extraction_ops_c.rs"]
mod ops_c;
#[path = "extraction_providers.rs"]
mod providers;
pub(super) use ops_a::*;
pub(super) use ops_b::*;
pub(super) use ops_c::*;
pub(super) use providers::*;
#[cfg(test)]
#[path = "extraction_tests.rs"]
mod tests;