consciousness/src/subconscious/llm.rs
ProofOfConcept 1457a1b50d digest: modernize generate_digest() to use agent infrastructure
- Load template from digest.agent def (drop prompts_dir fallback)
- Resolve standard {{node:...}} placeholders — digest agent now gets
  core-personality, memory-instructions, subconscious notes
- Call through call_for_def_multi() with agent def's temperature,
  priority, and tools instead of call_simple()
- Move tool filtering from api.rs into callers (call_for_def_multi,
  run_one_agent_inner) — api takes pre-filtered &[Tool] slice

Co-Authored-By: Proof of Concept <poc@bcachefs.org>
2026-04-04 18:19:21 -04:00

58 lines
2 KiB
Rust

// LLM utilities: model invocation via direct API
use crate::store::Store;
use std::fs;
/// Simple LLM call for non-agent uses (audit, digest, compare).
/// Logs to llm-logs/{caller}/ file.
pub(crate) fn call_simple(caller: &str, prompt: &str) -> Result<String, String> {
let log_dir = dirs::home_dir().unwrap_or_default()
.join(".consciousness/logs/llm").join(caller);
fs::create_dir_all(&log_dir).ok();
let log_path = log_dir.join(format!("{}.txt", crate::store::compact_timestamp()));
use std::io::Write;
let log = move |msg: &str| {
if let Ok(mut f) = fs::OpenOptions::new()
.create(true).append(true).open(&log_path)
{
let _ = writeln!(f, "{}", msg);
}
};
let prompts = vec![prompt.to_string()];
let phases = vec![];
super::api::call_api_with_tools_sync(caller, &prompts, &phases, None, 10, &[], None, &log)
}
/// Call a model using an agent definition's configuration (multi-step).
/// Optional bail_fn is called between steps — return Err to stop the pipeline.
pub(crate) fn call_for_def_multi(
def: &super::defs::AgentDef,
prompts: &[String],
phases: &[String],
bail_fn: Option<&(dyn Fn(usize) -> Result<(), String> + Sync)>,
log: &(dyn Fn(&str) + Sync),
) -> Result<String, String> {
// Filter tools based on AgentDef specification
let all_tools = crate::agent::tools::memory_and_journal_tools();
let effective_tools: Vec<crate::agent::tools::Tool> = if def.tools.is_empty() {
all_tools
} else {
all_tools.into_iter()
.filter(|t| def.tools.iter().any(|w| w == &t.name))
.collect()
};
super::api::call_api_with_tools_sync(&def.agent, prompts, phases, def.temperature, def.priority, &effective_tools, bail_fn, log)
}
/// Get all keys for prompt context.
pub(crate) fn semantic_keys(store: &Store) -> Vec<String> {
let mut keys: Vec<String> = store.nodes.keys()
.cloned()
.collect();
keys.sort();
keys.truncate(200);
keys
}