reasoninglayer 0.2.1

Rust client SDK for the Reasoning Layer API
Documentation
//! Conversation DTOs (chat-style interaction with OSF/QL execution).

use std::collections::BTreeMap;

use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ConversationMessageRequest {
    pub message: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub conversation_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub session_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub current_sort_context: Option<String>,
    #[serde(default)]
    pub generate_certificate: bool,
}

/// Free-form value returned by OSF/QL queries — backend uses
/// `OsfqlValueDto` (tagged enum). Kept as `serde_json::Value` here so the
/// SDK doesn't have to track the OSF/QL value enum's evolution.
pub type OsfqlValueDto = serde_json::Value;

/// Recursive proof trace node. Children may nest arbitrarily — left as
/// `serde_json::Value` to avoid forcing a recursive type definition for an
/// area that is still evolving.
pub type ProofTraceNodeDto = serde_json::Value;

/// UI customisation hint emitted by the conversation engine.
pub type UICustomizationDto = serde_json::Value;

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ClaimAnnotationDto {
    /// `[start, end]` byte offsets into the assistant message.
    pub span: (u64, u64),
    pub claim_text: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub provenance: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub confidence: Option<f64>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct CognitiveStrategyDto {
    pub name: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    #[serde(default)]
    pub parameters: BTreeMap<String, serde_json::Value>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ConversationMessageResponse {
    pub assistant_message: String,
    pub conversation_id: String,
    pub intent: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub osfql_executed: Option<String>,
    #[serde(default)]
    pub query_results: Vec<BTreeMap<String, OsfqlValueDto>>,
    #[serde(default)]
    pub produced_term_ids: Vec<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub ui_sort_id: Option<String>,
    #[serde(default)]
    pub suggestions: Vec<String>,
    #[serde(default)]
    pub ui_customizations: Vec<UICustomizationDto>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub proof_trace: Option<ProofTraceNodeDto>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub validity_certificate_id: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub validity_certificate_hash: Option<String>,
    #[serde(default)]
    pub claim_annotations: Vec<ClaimAnnotationDto>,
    #[serde(default)]
    pub matched_templates: Vec<QueryTemplateDto>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub cognitive_strategy: Option<CognitiveStrategyDto>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub system_prompt: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub llm_context: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ConversationTurnDto {
    pub id: String,
    pub role: String,
    pub content: String,
    /// ISO-8601 timestamp.
    pub timestamp: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub intent: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub osfql: Option<String>,
    #[serde(default)]
    pub claim_annotations: Vec<ClaimAnnotationDto>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ConversationTurnsResponse {
    pub conversation_id: String,
    #[serde(default)]
    pub turns: Vec<ConversationTurnDto>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct QueryTemplateDto {
    pub id: String,
    pub sort_name: String,
    pub intent: String,
    pub osfql_pattern: String,
    pub usage_count: u32,
    pub is_user_created: bool,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
    /// ISO-8601 timestamp, if any.
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub last_used: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct ListTemplatesResponse {
    #[serde(default)]
    pub templates: Vec<QueryTemplateDto>,
}

#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateTemplateRequest {
    pub sort_name: String,
    pub intent: String,
    pub osfql_pattern: String,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
}

#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct UpdateTemplateRequest {
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub osfql_pattern: Option<String>,
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub description: Option<String>,
}