mockforge_core/voice/
hook_transpiler.rs1use crate::intelligent_behavior::{
23 config::IntelligentBehaviorConfig, llm_client::LlmClient, types::LlmGenerationRequest,
24};
25use crate::Result;
26type Hook = serde_json::Value;
29type Condition = serde_json::Value;
30type HookAction = serde_json::Value;
31type HookType = serde_json::Value;
32type LogLevel = serde_json::Value;
33use serde::{Deserialize, Serialize};
34use serde_json::Value as JsonValue;
35
36pub struct HookTranspiler {
38 llm_client: LlmClient,
40 config: IntelligentBehaviorConfig,
42}
43
44impl HookTranspiler {
45 pub fn new(config: IntelligentBehaviorConfig) -> Self {
47 let behavior_model = config.behavior_model.clone();
48 let llm_client = LlmClient::new(behavior_model);
49
50 Self { llm_client, config }
51 }
52
53 pub async fn transpile(&self, description: &str) -> Result<Hook> {
65 let system_prompt = r#"You are an expert at parsing natural language descriptions of hook logic
67and converting them to structured hook configurations.
68
69A hook consists of:
701. **Name**: A descriptive name for the hook
712. **Hook Type**: When the hook executes (pre_step, post_step, pre_orchestration, post_orchestration)
723. **Condition**: Optional condition that must be met for the hook to execute
734. **Actions**: List of actions to perform when the hook executes
74
75Available hook types:
76- pre_step: Execute before a step
77- post_step: Execute after a step
78- pre_orchestration: Execute before orchestration starts
79- post_orchestration: Execute after orchestration completes
80
81Available conditions:
82- equals: Variable equals value
83- not_equals: Variable not equals value
84- greater_than: Variable greater than numeric value
85- less_than: Variable less than numeric value
86- exists: Variable exists
87- and: All conditions must be true
88- or: At least one condition must be true
89- not: Condition must be false
90
91Available actions:
92- set_variable: Set a variable to a value
93- log: Log a message at a level (trace, debug, info, warn, error)
94- http_request: Make an HTTP request (webhook)
95- command: Execute a command
96- record_metric: Record a metric value
97
98For probability-based failures (e.g., "fail 5% of the time"), you should:
991. Use a condition that checks a random variable or metric
1002. Use set_variable to set a failure flag
1013. The actual failure injection should be handled by the chaos configuration
102
103For timing constraints (e.g., "instantly", "with delay"), use appropriate hook types or add delay actions.
104
105Return your response as a JSON object with this structure:
106{
107 "name": "string (descriptive hook name)",
108 "hook_type": "pre_step | post_step | pre_orchestration | post_orchestration",
109 "condition": {
110 "type": "condition type",
111 ...condition-specific fields
112 } or null,
113 "actions": [
114 {
115 "type": "action type",
116 ...action-specific fields
117 }
118 ]
119}
120
121Be specific and extract all details from the description. If timing is mentioned (instantly, with delay),
122choose the appropriate hook_type. If conditions are mentioned (for users flagged as VIP), create
123appropriate condition structures."#;
124
125 let user_prompt = format!(
127 "Parse this hook description and convert it to a hook configuration:\n\n{}",
128 description
129 );
130
131 let llm_request = LlmGenerationRequest {
133 system_prompt: system_prompt.to_string(),
134 user_prompt,
135 temperature: 0.2, max_tokens: 2000,
137 schema: None,
138 };
139
140 let response = self.llm_client.generate(&llm_request).await?;
142
143 if !response.is_object() {
146 return Err(crate::Error::generic(format!(
147 "LLM response is not a JSON object. Response: {}",
148 serde_json::to_string(&response).unwrap_or_default()
149 )));
150 }
151
152 Ok(response)
153 }
154
155 }