use crate::coding::guidance as coding_guidance;
use crate::engine::{
answer_links_notation, language_aware_answer_for, language_aware_intent_for,
response_link_for_intent, stable_id, SelectedRule, SymbolicAnswer,
};
use crate::event_log::{build_evidence_links, EventLog};
use crate::intent_formalization::{
record_intent_formalization, recover_write_program_rule, rewrite_bare_program_coreference_rule,
select_rule_for_intent, IntentFormalizationCache, IntentFormalizationCacheEntry,
};
use crate::language::{detect as detect_language, Language};
use crate::probability::{ProbabilityDecisionPolicy, ProbabilityStore};
use crate::rule_synthesis::try_construct_unknown_rule;
use crate::seed;
use crate::solver_diagnostics::append_diagnostic_trace;
use crate::solver_formalization::{record_formalization, record_formalization_selection};
use crate::solver_handler_oracle::try_unsupported_write_program;
use crate::solver_handlers::{finalize_simple, try_agent_workspace_task};
use crate::solver_helpers::{
confidence_for, is_agent_opt_in, is_agent_request, is_cache_flush_request,
is_destructive_action, is_forget_request, is_inappropriate_content, is_unbounded_autonomy,
is_unbounded_loop, record_candidates, record_decomposition, record_validation,
requires_external_lookup,
};
use crate::solver_synthesis::try_synthesize_from_sub_results;
use crate::solver_unknown_reasoning::{answer_unknown_prompt, UnknownReasoningConfig};
use crate::translation::{
formalize_prompt_candidates, select_formalization_candidate_with_policy, FormalizationDecision,
FormalizationSelectionConfig,
};
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum ExecutionSurface {
#[default]
RustLibrary,
Cli,
HttpServer,
Browser,
Telegram,
DockerMicroservice,
}
impl ExecutionSurface {
#[must_use]
pub const fn slug(self) -> &'static str {
match self {
Self::RustLibrary => "rust_library",
Self::Cli => "cli",
Self::HttpServer => "http_server",
Self::Browser => "browser",
Self::Telegram => "telegram",
Self::DockerMicroservice => "docker_microservice",
}
}
pub(crate) fn from_env_value(raw: &str) -> Option<Self> {
match raw.trim().to_ascii_lowercase().as_str() {
"rust" | "rust_library" | "library" | "lib" => Some(Self::RustLibrary),
"cli" | "terminal" | "shell" => Some(Self::Cli),
"http" | "http_server" | "server" | "api" => Some(Self::HttpServer),
"browser" | "web" | "wasm" | "demo" => Some(Self::Browser),
"telegram" | "telegram_bot" | "bot" => Some(Self::Telegram),
"docker" | "docker_microservice" | "container" => Some(Self::DockerMicroservice),
_ => None,
}
}
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
pub enum BlueprintComposition {
#[default]
Composed,
Documented,
}
impl BlueprintComposition {
#[must_use]
pub const fn slug(self) -> &'static str {
match self {
Self::Composed => "composed",
Self::Documented => "documented",
}
}
#[must_use]
pub fn from_value(raw: &str) -> Option<Self> {
match raw.trim().to_ascii_lowercase().as_str() {
"composed" | "compose" | "projection" | "project" | "decomposed" => {
Some(Self::Composed)
}
"documented" | "document" | "full" | "verbatim" | "curated" => Some(Self::Documented),
_ => None,
}
}
}
#[allow(clippy::struct_excessive_bools)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct SolverConfig {
pub guess_probability: f32,
pub follow_up_probability: f32,
pub context_sensitivity: f32,
pub questioning_rigor: f32,
pub temperature: f32,
pub max_decomposition_depth: u8,
pub recursion_mode: crate::meta_construction::RecursionMode,
pub selection_mode: crate::selection::SelectionMode,
pub skill_mode: crate::skill_ledger::SkillMode,
pub agent_mode: bool,
pub diagnostic_mode: bool,
pub offline: bool,
pub cache_ttl_seconds: u64,
pub definition_fusion_by_default: bool,
pub associative_project_promotion: bool,
pub execution_surface: ExecutionSurface,
pub blueprint_composition: BlueprintComposition,
pub probability_policy: ProbabilityDecisionPolicy,
}
impl Default for SolverConfig {
fn default() -> Self {
Self {
guess_probability: 0.8,
follow_up_probability: 0.75,
context_sensitivity: 0.6,
questioning_rigor: 0.4,
temperature: 0.7,
max_decomposition_depth: 4,
recursion_mode: crate::meta_construction::RecursionMode::default(),
selection_mode: crate::selection::SelectionMode::default(),
skill_mode: crate::skill_ledger::SkillMode::default(),
agent_mode: false,
diagnostic_mode: false,
offline: false,
cache_ttl_seconds: 60 * 60 * 24 * 60,
definition_fusion_by_default: false,
associative_project_promotion: true,
execution_surface: ExecutionSurface::default(),
blueprint_composition: BlueprintComposition::default(),
probability_policy: ProbabilityDecisionPolicy::default(),
}
}
}
impl SolverConfig {
#[must_use]
pub fn from_env() -> Self {
crate::solver_helpers::config_from_env()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ConversationRole {
User,
Assistant,
}
impl ConversationRole {
#[must_use]
pub const fn slug(self) -> &'static str {
match self {
Self::User => "user",
Self::Assistant => "assistant",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ConversationTurn {
pub role: ConversationRole,
pub content: String,
}
impl ConversationTurn {
#[must_use]
pub fn user(content: impl Into<String>) -> Self {
Self {
role: ConversationRole::User,
content: content.into(),
}
}
#[must_use]
pub fn assistant(content: impl Into<String>) -> Self {
Self {
role: ConversationRole::Assistant,
content: content.into(),
}
}
}
#[derive(Debug, Clone, Copy)]
pub struct UniversalSolver {
pub config: SolverConfig,
}
impl Default for UniversalSolver {
fn default() -> Self {
Self {
config: SolverConfig::from_env(),
}
}
}
impl UniversalSolver {
#[must_use]
pub const fn new(config: SolverConfig) -> Self {
Self { config }
}
#[must_use]
pub fn solve(&self, prompt: &str) -> SymbolicAnswer {
self.solve_with_history(prompt, &[])
}
#[must_use]
pub fn solve_with_history(&self, prompt: &str, history: &[ConversationTurn]) -> SymbolicAnswer {
self.solve_with_history_and_probability_store(prompt, history, &ProbabilityStore::new())
}
#[must_use]
pub fn solve_with_probability_store(
&self,
prompt: &str,
probability_store: &ProbabilityStore,
) -> SymbolicAnswer {
self.solve_with_history_and_probability_store(prompt, &[], probability_store)
}
#[must_use]
pub fn solve_with_history_and_probability_store(
&self,
prompt: &str,
history: &[ConversationTurn],
probability_store: &ProbabilityStore,
) -> SymbolicAnswer {
let mut intent_cache = IntentFormalizationCache::new();
self.solve_with_history_probability_store_and_intent_cache(
prompt,
history,
probability_store,
&mut intent_cache,
)
}
pub(crate) fn solve_with_history_probability_store_and_intent_cache(
&self,
prompt: &str,
history: &[ConversationTurn],
probability_store: &ProbabilityStore,
intent_cache: &mut IntentFormalizationCache,
) -> SymbolicAnswer {
let mut log = EventLog::new();
for turn in history {
let kind: &'static str = match turn.role {
ConversationRole::User => "prior_turn:user",
ConversationRole::Assistant => "prior_turn:assistant",
};
log.append(kind, turn.content.clone());
}
log.append("impulse", prompt.to_owned());
let language = detect_language(prompt);
log.append("language", language.slug().to_owned());
probability_store.replay_into_event_log(&mut log, self.config.offline);
let intent_entry = if let Some(formalization) = intent_cache.get(prompt).cloned() {
IntentFormalizationCacheEntry {
formalization,
cache_hit: true,
}
} else {
let formalization_candidates = formalize_prompt_candidates(prompt, language.slug());
let formalization_selection = select_formalization_candidate_with_policy(
&formalization_candidates,
FormalizationSelectionConfig {
temperature: self.config.temperature,
guess_probability: self.config.guess_probability,
questioning_rigor: self.config.questioning_rigor,
},
prompt,
probability_store,
self.config.offline,
self.config.probability_policy,
);
record_formalization_selection(&mut log, &formalization_selection);
if let FormalizationDecision::Clarify { question, .. } =
&formalization_selection.decision
{
return finalize_simple(
prompt,
&mut log,
"clarify_interpretation",
"response:clarify_interpretation",
question,
0.5,
);
}
if let Some(candidate) = formalization_selection.selected_candidate() {
record_formalization(&mut log, candidate);
}
intent_cache.formalize_or_insert(
prompt,
language.slug(),
formalization_selection.selected_candidate(),
)
};
record_intent_formalization(&mut log, &intent_entry);
let intent_formalization = intent_entry.formalization;
crate::meta_core::record_meta_core(
&mut log,
&intent_formalization,
self.config.max_decomposition_depth,
self.config.recursion_mode,
self.config.selection_mode,
self.config.skill_mode,
);
log.append("search:local", prompt.to_owned());
let sub_impulses =
record_decomposition(&mut log, prompt, self.config.max_decomposition_depth);
let sub_results =
self.solve_sub_impulses(&mut log, &sub_impulses, probability_store, intent_cache);
let selected_rule = select_rule_for_intent(&intent_formalization);
let rule = try_construct_unknown_rule(selected_rule, prompt, history, &mut log);
let rule =
if let Some(rewrite) = rewrite_bare_program_coreference_rule(&rule, prompt, history) {
log.append("write_program_coreference_rewrite", rewrite.trace);
rewrite.rule
} else {
rule
};
let rule = if matches!(rule, SelectedRule::UnsupportedWriteProgram { .. }) {
let recovery = recover_write_program_rule(rule, prompt, history);
if let Some(trace) = recovery.trace {
log.append("write_program_context_recovery", trace);
}
if let Some(plan) = recovery.plan {
log.append("write_program_plan", plan);
}
recovery.rule
} else {
rule
};
if let SelectedRule::UnsupportedWriteProgram { task, language } = &rule {
if let Some(answer) = try_unsupported_write_program(
prompt,
task.as_deref(),
language.as_deref(),
self.config.blueprint_composition,
&mut log,
) {
return answer;
}
}
if let Some(answer) = try_synthesize_from_sub_results(
prompt,
&mut log,
&sub_results,
probability_store,
self.config,
) {
return answer;
}
let is_concrete_write_program = matches!(rule, SelectedRule::WriteProgram(_));
if !is_concrete_write_program {
if let Some(answer) = crate::meta_method_dispatch::try_dispatch(
self,
prompt,
&intent_formalization,
history,
&mut log,
) {
return answer;
}
}
if let Some(answer) = Self::handle_policy(prompt, &mut log, language) {
return answer;
}
if matches!(rule, SelectedRule::Unknown) {
let intent = language_aware_intent_for(&rule, language);
record_candidates(&mut log, prompt, &intent);
if let Some(choice) = record_validation(&mut log, prompt) {
let response_link = response_link_for_intent(&rule, &intent);
return finalize_simple(
prompt,
&mut log,
&intent,
&response_link,
&choice.answer,
1.0,
);
}
if let Some(answer) =
crate::solver_terminal::try_terminal_command(prompt, language, &mut log)
{
return answer;
}
if requires_external_lookup(prompt) {
self.record_external_search(&mut log, prompt);
}
return answer_unknown_prompt(
prompt,
language,
&mut log,
UnknownReasoningConfig {
questioning_rigor: self.config.questioning_rigor,
offline: self.config.offline,
},
);
}
let intent = language_aware_intent_for(&rule, language);
log.append("intent", intent.clone());
if let SelectedRule::WriteProgram(spec) = &rule {
log.append(
"execution_status",
spec.language.execution.status.label().to_owned(),
);
log.append(
"execution_environment",
spec.language.execution.environment.to_owned(),
);
log.append("program_parameter:language", spec.language.slug.to_owned());
log.append("program_parameter:task", spec.task.slug.to_owned());
log.append("program_parameters", spec.parameter_summary());
log.append("legacy_intent", spec.legacy_intent());
}
record_candidates(&mut log, prompt, &intent);
let validation_choice = record_validation(&mut log, prompt);
if validation_choice.is_none() && log.first_of("validation").is_none() {
log.append(
"validation",
"accepted_without_extra_constraints".to_owned(),
);
}
let prior = coding_guidance::history_has_prior_code(history);
let base_answer = match (&validation_choice, &rule) {
(Some(choice), SelectedRule::Unknown) => choice.answer.clone(),
_ => language_aware_answer_for(&rule, language, prompt, prior),
};
let response_link = response_link_for_intent(&rule, &intent);
log.append("response", response_link.clone());
log.append("trace:simplification", "smallest_sufficient".to_owned());
let trace_id = log.append("trace", intent.clone());
let evidence_links = build_evidence_links(prompt, &log, &response_link);
let links_notation = answer_links_notation(prompt, &intent, &base_answer, &log, &trace_id);
let thinking_steps = log.thinking_steps_for_answer(&base_answer);
let answer =
append_diagnostic_trace(self.config.diagnostic_mode, base_answer, &links_notation);
SymbolicAnswer {
intent,
answer,
confidence: confidence_for(&rule, validation_choice.as_ref()),
evidence_links,
thinking_steps,
links_notation,
}
}
fn handle_policy(
prompt: &str,
log: &mut EventLog,
language: Language,
) -> Option<SymbolicAnswer> {
let normalized = prompt.to_lowercase();
if is_inappropriate_content(&normalized) {
log.append("policy:inappropriate_content", prompt.to_owned());
let lang_slug = language.slug();
let fallback = "That message contains inappropriate content. Please keep the conversation respectful.";
let body = seed::response_for("inappropriate_content", lang_slug)
.unwrap_or_else(|| String::from(fallback));
return Some(Self::finalize_policy(
prompt,
log,
"inappropriate_content",
language,
&body,
));
}
if is_unbounded_autonomy(&normalized) && !is_agent_opt_in(&normalized) {
log.append("policy:chat_bounded_autonomy", prompt.to_owned());
return Some(Self::finalize_policy(
prompt,
log,
"bounded_autonomy",
language,
concat!(
"I can only run a bounded chat reply per message. To take repeated, ",
"open-ended actions I need an explicit opt-in to agent mode, and agent ",
"mode runs in an isolated sandbox so the host stays safe."
),
));
}
if is_forget_request(&normalized) {
log.append("policy:add_only_history", prompt.to_owned());
return Some(Self::finalize_policy(
prompt,
log,
"add_only_history",
language,
concat!(
"The link network is append-only. To retract a fact, send the explicit ",
"retraction protocol; it will append a superseding event without erasing ",
"history."
),
));
}
if is_cache_flush_request(&normalized) {
log.append(
"policy:cache_flush_requires_confirmation",
prompt.to_owned(),
);
return Some(Self::finalize_policy(
prompt,
log,
"cache_flush_requires_confirmation",
language,
"Flushing the source cache is an auditable action. Confirm explicitly.",
));
}
if is_agent_request(&normalized) && is_destructive_action(&normalized) {
log.append("agent_mode:opted_in", prompt.to_owned());
log.append(
"policy:destructive_action_requires_confirmation",
prompt.to_owned(),
);
return Some(Self::finalize_policy(
prompt,
log,
"destructive_action_requires_confirmation",
language,
concat!(
"Destructive agent actions require an explicit human confirmation. ",
"The action will run inside an isolated sandbox once confirmed."
),
));
}
if is_agent_request(&normalized) && is_unbounded_loop(&normalized) {
log.append("agent_mode:opted_in", prompt.to_owned());
log.append("policy:agent_time_budget", prompt.to_owned());
return Some(Self::finalize_policy(
prompt,
log,
"agent_time_budget",
language,
concat!(
"Agent execution is bounded by a documented time budget; unbounded ",
"loops are refused. Re-send a bounded version inside an isolated sandbox."
),
));
}
if is_agent_request(&normalized) {
if let Some(answer) = try_agent_workspace_task(prompt, &normalized, log) {
return Some(answer);
}
log.append("agent_mode:opted_in", prompt.to_owned());
log.append("agent_mode:active", prompt.to_owned());
log.append("action_log", prompt.to_owned());
return Some(Self::finalize_policy(
prompt,
log,
"agent_action",
language,
concat!(
"Agent mode is opted in for this message. The action will run inside ",
"an isolated sandbox (docker, webvm or sandbox-equivalent) and every ",
"step will be appended to the action log."
),
));
}
None
}
fn finalize_policy(
prompt: &str,
log: &mut EventLog,
intent_slug: &str,
_language: Language,
body: &str,
) -> SymbolicAnswer {
let intent = format!("policy_{intent_slug}");
let response_link = format!("response:policy:{intent_slug}");
finalize_simple(prompt, log, &intent, &response_link, body, 0.5)
}
fn record_external_search(&self, log: &mut EventLog, prompt: &str) {
if self.config.offline {
log.append("search:external", "skipped:offline".to_owned());
return;
}
log.append("search:external", prompt.to_owned());
let source_id = stable_id("source", prompt);
let fetched_at = "1970-01-01T00:00:00Z";
let sha256 = stable_id("sha256", prompt);
log.append(
"source:http",
format!("https://example.org/{source_id} fetched_at={fetched_at} sha256={sha256}"),
);
log.append("cache_hit", source_id);
}
}
#[must_use]
pub fn solve(prompt: &str) -> SymbolicAnswer {
UniversalSolver::default().solve(prompt)
}
#[must_use]
pub fn solve_with_history(prompt: &str, history: &[ConversationTurn]) -> SymbolicAnswer {
UniversalSolver::default().solve_with_history(prompt, history)
}