daat-locus 0.1.1

A long-running local agent runtime with memory, workflows, apps, and sleep-time self-improvement.
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::reasoning::{ir::PromptIR, program::Program, signature::Signature};

const WORKFLOW_CANDIDATE_ROLLOUT_EVALUATOR_SYSTEM_PROMPT: &str = r#"You are responsible for single-case rollout evaluation of a workflow frontier candidate.
The candidate may be a patch or a merge. You will see:
- target workflow spec after rollout
- rollout result summary
- target reflection
- a concrete target rollout case containing flushed run record, executed steps, and boundary events
- for merges, source workflow spec, source reflection, and one source rollout case
- the candidate itself

Your task is to judge:
- whether the candidate may outperform the current baseline on this concrete case
- whether there is obvious regression risk

Output requirements:
- `score`: overall score for this case
- `accepted_case`: whether this case supports keeping the candidate
- `improves_upon_baseline`: whether it improves upon the current baseline
- `regression_risk`: whether there is obvious regression risk
- `reason`: rationale based on this case"#;

pub struct WorkflowCandidateRolloutEvaluatorProgram;

#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct WorkflowCandidateRolloutEvaluatorOutput {
    pub score: f64,
    pub accepted_case: bool,
    pub improves_upon_baseline: bool,
    pub regression_risk: bool,
    pub reason: String,
}

impl Program for WorkflowCandidateRolloutEvaluatorProgram {
    type Output = WorkflowCandidateRolloutEvaluatorOutput;

    fn name(&self) -> &'static str {
        "workflow_candidate_rollout_evaluator"
    }

    fn description(&self) -> &'static str {
        "Evaluate a workflow frontier candidate against a single workflow rollout case."
    }

    fn signature(&self) -> Signature {
        Signature::new("Perform single-case rollout evaluation for a workflow frontier candidate.")
            .input("candidate kind", "patch or merge.")
            .input(
                "rollout target workflow spec",
                "Target workflow spec after the candidate was actually applied.",
            )
            .input(
                "rollout result",
                "Summary of the candidate's actual application result in an isolated workflow store.",
            )
            .input("target reflection", "Target workflow reflection.")
            .input(
                "target rollout case",
                "A concrete target workflow rollout case containing run record, executed steps, and boundary events.",
            )
            .input(
                "source workflow spec",
                "Source workflow spec for merges; otherwise none.",
            )
            .input(
                "source reflection",
                "Source reflection for merges; otherwise none.",
            )
            .input(
                "source rollout case",
                "Source rollout case for merges; otherwise none. It also contains run record, executed steps, and boundary events.",
            )
            .input("candidate", "Patch or merge candidate to evaluate.")
            .output("score", "Overall score for this case.")
            .output("accepted_case", "Whether this case supports keeping the candidate.")
            .output("improves_upon_baseline", "Whether it improves upon the current baseline.")
            .output("regression_risk", "Whether there is obvious regression risk.")
            .output("reason", "Rationale based on the case.")
            .rule("A patch candidate must improve a concrete weakness shown by this case.")
            .rule("A merge candidate must preserve compatible task boundaries and process skeleton on this case.")
    }
}

impl WorkflowCandidateRolloutEvaluatorProgram {
    #[allow(clippy::too_many_arguments)]
    pub fn dataset_ir(
        &self,
        candidate_kind: String,
        rollout_target_workflow_spec: String,
        rollout_result: String,
        target_reflection_json: String,
        target_rollout_case_json: String,
        source_workflow_spec: String,
        source_reflection_json: String,
        source_rollout_case_json: String,
        candidate_json: String,
    ) -> PromptIR {
        let mut ir = PromptIR::with_system(WORKFLOW_CANDIDATE_ROLLOUT_EVALUATOR_SYSTEM_PROMPT);
        ir.push_instruction(
            "The goal is to evaluate candidate behavior on a concrete rollout case; rollout target workflow spec is the real result after applying the candidate.",
        );
        ir.push_section("candidate kind", candidate_kind);
        ir.push_section("rollout target workflow spec", rollout_target_workflow_spec);
        ir.push_section("rollout result", rollout_result);
        ir.push_section("target reflection", target_reflection_json);
        ir.push_section("target rollout case", target_rollout_case_json);
        ir.push_section("source workflow spec", source_workflow_spec);
        ir.push_section("source reflection", source_reflection_json);
        ir.push_section("source rollout case", source_rollout_case_json);
        ir.push_section("candidate", candidate_json);
        ir
    }
}