use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use super::chunk::ChunkPolicy;
use super::insights::CompilationInsights;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum ContextAction {
Preserve,
Abstract,
Retrieve,
Drop,
Cache,
}
#[derive(
Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema,
)]
#[serde(rename_all = "lowercase")]
pub enum FidelityRisk {
#[default]
Low,
Medium,
High,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct MediaRef {
pub mime: String,
pub bytes_b64: String,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ContextSource {
pub content: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub media: Option<MediaRef>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct ContextFragment {
#[serde(
default,
skip_serializing_if = "Option::is_none",
deserialize_with = "super::wire::deserialize_optional_id"
)]
pub id: Option<u64>,
pub content: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub kind: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub priority: Option<u8>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub metadata: Option<Map<String, Value>>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub media: Option<MediaRef>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct MemoryScope {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub project: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub k: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub hops: Option<usize>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub graph_boost: Option<f64>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
pub struct ImportanceWeights {
pub confidence: f64,
pub recency: f64,
#[serde(skip_serializing_if = "Option::is_none")]
pub recency_field: Option<String>,
}
impl Default for ImportanceWeights {
fn default() -> Self {
Self {
confidence: 0.2,
recency: 0.1,
recency_field: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[serde(default)]
#[schemars(transform = crate::schema::strip_int_formats)]
#[allow(clippy::struct_excessive_bools)]
pub struct CompilePolicy {
pub response_reserve_tokens: u64,
pub near_dup_dedup: bool,
pub disabled_rules: Vec<String>,
pub chunk: ChunkPolicy,
pub record_events: bool,
pub store_sources: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_ttl_seconds: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_ttl_seconds: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub pricing: Option<super::insights::PricingTable>,
pub importance: ImportanceWeights,
pub normalize_log_timestamps: bool,
pub ids_as_strings: bool,
}
impl Default for CompilePolicy {
fn default() -> Self {
Self {
response_reserve_tokens: 0,
near_dup_dedup: true,
disabled_rules: Vec::new(),
chunk: ChunkPolicy::default(),
record_events: true,
store_sources: true,
source_ttl_seconds: None,
event_ttl_seconds: None,
pricing: None,
importance: ImportanceWeights::default(),
normalize_log_timestamps: false,
ids_as_strings: false,
}
}
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct ContextSavings {
pub events: u64,
pub tokens_in: u64,
pub tokens_out: u64,
pub tokens_saved: u64,
pub cost_saved_micros_by_currency: std::collections::BTreeMap<String, u64>,
pub truncated: bool,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct CompileRequest {
pub query: String,
pub fragments: Vec<ContextFragment>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub project: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub target_model: Option<String>,
pub token_budget: u64,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory_scope: Option<MemoryScope>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub policy: Option<CompilePolicy>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum SectionKind {
Cache,
Body,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct CompiledSection {
pub kind: SectionKind,
pub content: String,
pub fragment_ids: Vec<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct SourceReference {
pub fragment_id: u64,
pub handle: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory_id: Option<u64>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct RetrievalHandle {
pub handle: String,
pub fragment_id: u64,
pub estimated_tokens: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct ContextDecision {
pub fragment_id: u64,
pub content_hash: u64,
pub action: ContextAction,
pub rule_id: String,
pub relevance: f32,
pub risk: FidelityRisk,
pub reason: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub memory_id: Option<u64>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub handle: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct CompiledContext {
pub content: String,
pub sections: Vec<CompiledSection>,
pub decisions: Vec<ContextDecision>,
pub sources: Vec<SourceReference>,
pub retrieval_handles: Vec<RetrievalHandle>,
pub insights: CompilationInsights,
pub risk: FidelityRisk,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
pub struct ContextFact {
pub text: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub source: Option<SourceReference>,
}
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(transform = crate::schema::strip_int_formats)]
pub struct ContextDecisionRef {
pub fragment_id: u64,
pub rule_id: String,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize, JsonSchema)]
pub struct WorkingContext {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub goal: Option<String>,
#[serde(default)]
pub active_constraints: Vec<ContextFact>,
#[serde(default)]
pub verified_facts: Vec<ContextFact>,
#[serde(default)]
pub open_hypotheses: Vec<ContextFact>,
#[serde(default)]
pub decisions: Vec<ContextDecisionRef>,
#[serde(default)]
pub exact_evidence: Vec<SourceReference>,
#[serde(default)]
pub pending_actions: Vec<String>,
}