Skip to main content

forge_engine/runtime/
compiler.rs

1use std::collections::BTreeMap;
2
3use crate::config::ForgeConfig;
4use crate::error::ForgeResult;
5use crate::runtime::mindstate::{EvidenceItem, MindState, OrderedFloat, TraceRef};
6use crate::store::ForgeStore;
7
8/// Compile a MindState from inputs using a BasisVersion.
9///
10/// Pulls evidence from semantic-memory handle (read-only).
11/// Injects answer traces for novelty context.
12pub fn compile_mindstate(
13    request: &str,
14    repo_context: &str,
15    basis_version_id: &str,
16    evidence: Vec<EvidenceItem>,
17    store: &ForgeStore,
18    config: &ForgeConfig,
19    config_overrides: BTreeMap<String, String>,
20) -> ForgeResult<MindState> {
21    // Compute question signature for trace lookup
22    let question_sig = compute_question_sig(request, repo_context);
23
24    // Retrieve recent answer traces for this question
25    let trace_rows = store.get_recent_traces_for_question(
26        &question_sig,
27        config.novelty.min_traces_for_orthogonality,
28    )?;
29
30    let traces: Vec<TraceRef> = trace_rows
31        .into_iter()
32        .map(|row| {
33            let tags: Vec<String> =
34                serde_json::from_str(&row.strategy_tags_json).unwrap_or_default();
35            let score: f64 = serde_json::from_str::<serde_json::Value>(&row.score_json)
36                .ok()
37                .and_then(|v| v.get("weighted_total").and_then(|w| w.as_f64()))
38                .unwrap_or(0.0);
39            TraceRef {
40                question_sig: row.question_sig,
41                strategy_tags: tags,
42                score: OrderedFloat(score),
43            }
44        })
45        .collect();
46
47    // Budget evidence
48    let budgeted_evidence =
49        mindstate_core::budget_evidence(evidence, config.mindstate.evidence_budget);
50
51    Ok(MindState {
52        request: request.to_string(),
53        repo_context: repo_context.to_string(),
54        evidence: budgeted_evidence,
55        traces,
56        basis_version_id: basis_version_id.to_string(),
57        config_overrides,
58    })
59}
60
61/// Compute a stable question signature from request + repo context.
62pub fn compute_question_sig(request: &str, repo_context: &str) -> String {
63    mindstate_core::compute_question_sig(request, repo_context)
64}