Skip to main content

mockforge_core/openapi/
response_trace.rs

1//! Response generation trace instrumentation
2//!
3//! This module provides helpers to instrument response generation
4//! and collect trace data for debugging and observability.
5
6use crate::openapi::response::ResponseGenerator;
7use crate::openapi::response_selection::ResponseSelectionMode;
8use crate::openapi::OpenApiSpec;
9use crate::reality_continuum::response_trace::ResponseGenerationTrace;
10use crate::Result;
11use openapiv3::Operation;
12use serde_json::Value;
13use std::time::Instant;
14
15/// Generate a response with trace collection
16///
17/// This function wraps the response generation and collects trace data
18/// about how the response was generated.
19///
20/// # Arguments
21/// * `spec` - The OpenAPI specification
22/// * `operation` - The operation to generate a response for
23/// * `status_code` - The HTTP status code
24/// * `content_type` - Optional content type
25/// * `expand_tokens` - Whether to expand template tokens
26/// * `scenario` - Optional scenario name
27/// * `selection_mode` - Response selection mode
28/// * `selector` - Optional response selector
29/// * `persona` - Optional persona for data generation
30///
31/// # Returns
32/// A tuple of (response_value, trace_data)
33#[allow(clippy::too_many_arguments)]
34pub fn generate_response_with_trace(
35    spec: &OpenApiSpec,
36    operation: &Operation,
37    status_code: u16,
38    content_type: Option<&str>,
39    expand_tokens: bool,
40    scenario: Option<&str>,
41    selection_mode: Option<ResponseSelectionMode>,
42    selector: Option<&crate::openapi::response_selection::ResponseSelector>,
43    persona: Option<&crate::intelligent_behavior::config::Persona>,
44) -> Result<(Value, ResponseGenerationTrace)> {
45    let start_time = Instant::now();
46    let mut trace = ResponseGenerationTrace::new();
47
48    // Record selection mode
49    let actual_mode = selection_mode.unwrap_or(ResponseSelectionMode::First);
50    trace.response_selection_mode = actual_mode;
51
52    // Record scenario if provided
53    if let Some(scenario_name) = scenario {
54        trace.selected_example = Some(scenario_name.to_string());
55    }
56
57    // Record template expansion setting
58    trace.add_metadata("expand_tokens".to_string(), serde_json::json!(expand_tokens));
59
60    // Record persona if provided
61    if let Some(p) = persona {
62        trace.add_metadata("persona_name".to_string(), serde_json::json!(p.name));
63    }
64
65    // Generate the response
66    let response = ResponseGenerator::generate_response_with_scenario_and_mode_and_persona(
67        spec,
68        operation,
69        status_code,
70        content_type,
71        expand_tokens,
72        scenario,
73        selection_mode,
74        selector,
75        persona,
76    )?;
77
78    // Record final payload
79    trace.set_final_payload(response.clone());
80
81    // Record generation time
82    let generation_time_ms = start_time.elapsed().as_millis() as u64;
83    trace.add_metadata("generation_time_ms".to_string(), serde_json::json!(generation_time_ms));
84
85    // Record operation ID if available
86    if let Some(operation_id) = &operation.operation_id {
87        trace.add_metadata("operation_id".to_string(), serde_json::json!(operation_id));
88    }
89
90    // Record status code
91    trace.add_metadata("status_code".to_string(), serde_json::json!(status_code));
92
93    // Try to determine which example was selected
94    // This is a simplified version - full implementation would need to
95    // instrument the actual selection logic
96    if let Some(sel) = selector {
97        if actual_mode == ResponseSelectionMode::Sequential {
98            let seq_index = sel.get_sequential_index();
99            trace.add_metadata("sequential_index".to_string(), serde_json::json!(seq_index));
100        }
101    }
102
103    // Record content type
104    if let Some(ct) = content_type {
105        trace.add_metadata("content_type".to_string(), serde_json::json!(ct));
106    }
107
108    Ok((response, trace))
109}