swarm-engine-core 0.1.6

Core types and orchestration for SwarmEngine
Documentation
//! DependencyGraphRecord - DependencyGraph 推論の記録

use serde::{Deserialize, Serialize};

use crate::events::LearningEvent;
use crate::util::epoch_millis;

/// DependencyGraph 推論の記録
///
/// LLM による DependencyGraph 生成時の prompt/response と結果を記録。
/// 学習データとして使用され、正しい推論パターンを LoRA で学習可能にする。
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DependencyGraphRecord {
    /// 推論に使用した prompt
    pub prompt: String,
    /// LLM の response(生テキスト)
    pub response: String,
    /// 利用可能なアクション一覧
    pub available_actions: Vec<String>,
    /// 推論結果: discover 順序(NodeExpand アクション)
    pub discover_order: Vec<String>,
    /// 推論結果: not_discover 順序(NodeStateChange アクション)
    pub not_discover_order: Vec<String>,
    /// タイムスタンプ(Unix epoch ms)
    pub timestamp_ms: u64,
    /// LLM モデル名
    pub model: String,
    /// エンドポイント
    pub endpoint: String,
    /// LoRA アダプター名(あれば)
    pub lora: Option<String>,
    /// レイテンシ(ミリ秒)
    pub latency_ms: u64,
    /// エラー(あれば)
    pub error: Option<String>,
}

impl DependencyGraphRecord {
    /// 新しい DependencyGraphRecord を作成
    pub fn new(model: impl Into<String>) -> Self {
        Self {
            prompt: String::new(),
            response: String::new(),
            available_actions: Vec::new(),
            discover_order: Vec::new(),
            not_discover_order: Vec::new(),
            timestamp_ms: epoch_millis(),
            model: model.into(),
            endpoint: String::new(),
            lora: None,
            latency_ms: 0,
            error: None,
        }
    }

    /// Builder: prompt を設定
    pub fn prompt(mut self, prompt: impl Into<String>) -> Self {
        self.prompt = prompt.into();
        self
    }

    /// Builder: response を設定
    pub fn response(mut self, response: impl Into<String>) -> Self {
        self.response = response.into();
        self
    }

    /// Builder: available_actions を設定
    pub fn available_actions(mut self, actions: Vec<String>) -> Self {
        self.available_actions = actions;
        self
    }

    /// Builder: discover_order を設定
    pub fn discover_order(mut self, order: Vec<String>) -> Self {
        self.discover_order = order;
        self
    }

    /// Builder: not_discover_order を設定
    pub fn not_discover_order(mut self, order: Vec<String>) -> Self {
        self.not_discover_order = order;
        self
    }

    /// Builder: endpoint を設定
    pub fn endpoint(mut self, endpoint: impl Into<String>) -> Self {
        self.endpoint = endpoint.into();
        self
    }

    /// Builder: lora を設定
    pub fn lora(mut self, lora: impl Into<String>) -> Self {
        self.lora = Some(lora.into());
        self
    }

    /// Builder: latency_ms を設定
    pub fn latency_ms(mut self, latency: u64) -> Self {
        self.latency_ms = latency;
        self
    }

    /// Builder: error を設定
    pub fn error(mut self, error: impl Into<String>) -> Self {
        self.error = Some(error.into());
        self
    }

    /// 成功したか(エラーがなく、結果がある)
    pub fn is_success(&self) -> bool {
        self.error.is_none() && !self.discover_order.is_empty()
    }
}

impl From<&LearningEvent> for DependencyGraphRecord {
    fn from(event: &LearningEvent) -> Self {
        match event {
            LearningEvent::DependencyGraphInference {
                timestamp_ms,
                prompt,
                response,
                available_actions,
                discover_order,
                not_discover_order,
                model,
                endpoint,
                lora,
                latency_ms,
                error,
                ..
            } => Self {
                prompt: prompt.clone(),
                response: response.clone(),
                available_actions: available_actions.clone(),
                discover_order: discover_order.clone(),
                not_discover_order: not_discover_order.clone(),
                timestamp_ms: *timestamp_ms,
                model: model.clone(),
                endpoint: endpoint.clone(),
                lora: lora.clone(),
                latency_ms: *latency_ms,
                error: error.clone(),
            },
            _ => Self::new("unknown"),
        }
    }
}