mockforge_foundation/
response_generation_trace.rs1use crate::response_selection::ResponseSelectionMode;
8use crate::schema_diff::ValidationError;
9use serde::{Deserialize, Serialize};
10use serde_json::Value;
11use std::collections::HashMap;
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct ResponseGenerationTrace {
19 #[serde(skip_serializing_if = "Option::is_none")]
21 pub template_path: Option<String>,
22
23 #[serde(skip_serializing_if = "Option::is_none")]
25 pub fixture_path: Option<String>,
26
27 pub response_selection_mode: ResponseSelectionMode,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub selected_example: Option<String>,
33
34 #[serde(default)]
36 pub persona_graph_nodes: Vec<PersonaGraphNodeUsage>,
37
38 #[serde(default)]
40 pub rules_executed: Vec<RuleExecution>,
41
42 #[serde(default)]
44 pub template_expansions: Vec<TemplateExpansion>,
45
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub blending_decision: Option<BlendingDecision>,
49
50 #[serde(skip_serializing_if = "Option::is_none")]
56 pub final_payload: Option<Value>,
57
58 #[serde(skip_serializing_if = "Option::is_none")]
64 pub schema_validation_diff: Option<Vec<ValidationError>>,
65
66 #[serde(default)]
68 pub metadata: HashMap<String, Value>,
69}
70
71impl Default for ResponseGenerationTrace {
72 fn default() -> Self {
73 Self {
74 template_path: None,
75 fixture_path: None,
76 response_selection_mode: ResponseSelectionMode::First,
77 selected_example: None,
78 persona_graph_nodes: Vec::new(),
79 rules_executed: Vec::new(),
80 template_expansions: Vec::new(),
81 blending_decision: None,
82 final_payload: None,
83 schema_validation_diff: None,
84 metadata: HashMap::new(),
85 }
86 }
87}
88
89#[derive(Debug, Clone, Serialize, Deserialize)]
91pub struct PersonaGraphNodeUsage {
92 pub persona_id: String,
94
95 pub entity_type: String,
97
98 pub usage_type: String,
100
101 #[serde(skip_serializing_if = "Option::is_none")]
103 pub relationship_path: Option<Vec<String>>,
104}
105
106#[derive(Debug, Clone, Serialize, Deserialize)]
108pub struct RuleExecution {
109 pub name: String,
111
112 pub rule_type: String,
114
115 pub condition_matched: bool,
117
118 #[serde(default)]
120 pub actions_executed: Vec<String>,
121
122 #[serde(skip_serializing_if = "Option::is_none")]
124 pub execution_time_ms: Option<u64>,
125
126 #[serde(skip_serializing_if = "Option::is_none")]
128 pub error: Option<String>,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct TemplateExpansion {
134 pub template: String,
136
137 pub value: Value,
139
140 pub source: String,
142
143 pub step: usize,
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct BlendingDecision {
150 pub blend_ratio: f64,
152
153 pub ratio_source: String,
155
156 pub blended: bool,
158
159 #[serde(skip_serializing_if = "Option::is_none")]
161 pub merge_strategy: Option<String>,
162
163 #[serde(default)]
165 pub field_decisions: Vec<FieldBlendingDecision>,
166}
167
168#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct FieldBlendingDecision {
171 pub field_path: String,
173
174 pub field_ratio: f64,
176
177 pub value_source: String,
179}
180
181impl ResponseGenerationTrace {
182 pub fn new() -> Self {
184 Self::default()
185 }
186
187 pub fn add_persona_node(&mut self, usage: PersonaGraphNodeUsage) {
189 self.persona_graph_nodes.push(usage);
190 }
191
192 pub fn add_rule_execution(&mut self, execution: RuleExecution) {
194 self.rules_executed.push(execution);
195 }
196
197 pub fn add_template_expansion(&mut self, expansion: TemplateExpansion) {
199 self.template_expansions.push(expansion);
200 }
201
202 pub fn set_blending_decision(&mut self, decision: BlendingDecision) {
204 self.blending_decision = Some(decision);
205 }
206
207 pub fn add_metadata(&mut self, key: String, value: Value) {
209 self.metadata.insert(key, value);
210 }
211
212 pub fn set_final_payload(&mut self, payload: Value) {
214 self.final_payload = Some(payload);
215 }
216
217 pub fn set_schema_validation_diff(&mut self, diff: Vec<ValidationError>) {
219 self.schema_validation_diff = Some(diff);
220 }
221}