Skip to main content

codetether_rlm/engine/
run.rs

1//! Engine entry point.
2
3use anyhow::Result;
4use std::time::Instant;
5use uuid::Uuid;
6
7use crate::config::RlmConfig;
8use crate::result::RlmResult;
9use crate::router::CrateAutoProcessContext;
10
11use super::{complete, deterministic, evidence, file, query, semantic};
12
13/// Run the evidence-first engine.
14pub async fn process(
15    content: &str,
16    ctx: &CrateAutoProcessContext<'_>,
17    config: &RlmConfig,
18) -> Result<Option<RlmResult>> {
19    if config.mode == "off" || content.trim().is_empty() {
20        return Ok(None);
21    }
22    let start = Instant::now();
23    let query = query::extract(ctx);
24    let source = file::source_label(ctx);
25    let trace_id = ctx.trace_id.unwrap_or_else(Uuid::new_v4);
26    let input_tokens = crate::RlmChunker::estimate_tokens(content);
27
28    if let Some(answer) = deterministic::answer(content, &query, source.clone(), ctx)? {
29        return Ok(Some(complete::finish(
30            ctx,
31            answer,
32            input_tokens,
33            start,
34            trace_id,
35            None,
36        )));
37    }
38
39    let evidence = evidence::collect(content, &query, &source, config);
40    let answer = semantic::synthesize(ctx, &query, &evidence).await?;
41    Ok(Some(complete::finish(
42        ctx,
43        answer,
44        evidence.input_tokens,
45        start,
46        trace_id,
47        Some(&evidence),
48    )))
49}