do_memory_core/episode/
validation.rs1use super::structs::{Episode, ExecutionStep};
6use crate::types::ExecutionResult;
7
8impl ExecutionStep {
9 pub fn validate(&self) -> Result<(), String> {
11 if self.step_number == 0 {
12 return Err("Step number must be greater than 0".to_string());
13 }
14 if self.tool.is_empty() {
15 return Err("Tool name cannot be empty".to_string());
16 }
17 if self.action.is_empty() {
18 return Err("Action description cannot be empty".to_string());
19 }
20 Ok(())
21 }
22
23 pub fn validate_result(&self) -> Result<(), String> {
25 if let Some(ref result) = self.result {
26 match result {
27 ExecutionResult::Success { output } if output.is_empty() => {
28 Err("Success result must have non-empty output".to_string())
29 }
30 ExecutionResult::Error { message } if message.is_empty() => {
31 Err("Error result must have non-empty message".to_string())
32 }
33 _ => Ok(()),
34 }
35 } else {
36 Ok(())
37 }
38 }
39}
40
41impl Episode {
42 pub fn validate(&self) -> Result<(), String> {
44 if self.task_description.is_empty() {
45 return Err("Task description cannot be empty".to_string());
46 }
47 if self.context.domain.is_empty() {
48 return Err("Task domain cannot be empty".to_string());
49 }
50 Ok(())
51 }
52
53 pub fn validate_for_completion(&self) -> Result<(), String> {
55 self.validate()?;
56
57 if self.steps.is_empty() {
58 return Err("Episode must have at least one step before completion".to_string());
59 }
60
61 for step in &self.steps {
62 step.validate()?;
63 }
64
65 Ok(())
66 }
67
68 #[must_use]
70 pub fn summary(&self) -> String {
71 format!(
72 "Episode {}: {} ({} steps, {})",
73 self.episode_id,
74 self.task_description,
75 self.steps.len(),
76 match &self.outcome {
77 Some(o) => o.to_string(),
78 None => "in progress".to_string(),
79 }
80 )
81 }
82}