Skip to main content

modular_agent_core/
value.rs

1use std::sync::Arc;
2
3#[cfg(feature = "image")]
4use photon_rs::PhotonImage;
5
6use im::{HashMap, Vector};
7use serde::{
8    Deserialize, Deserializer, Serialize, Serializer,
9    ser::{SerializeMap, SerializeSeq},
10};
11
12use crate::error::AgentError;
13use crate::llm::Message;
14
15#[cfg(feature = "image")]
16const IMAGE_BASE64_PREFIX: &str = "data:image/png;base64,";
17
18/// The value type passed between agents.
19///
20/// Supports multiple data types with immutable data structures for efficient cloning.
21/// Large data (String, Image, Tensor, etc.) is wrapped in `Arc` for reference-counted sharing.
22#[derive(Debug, Clone)]
23pub enum AgentValue {
24    /// Empty value. Used as a trigger signal.
25    Unit,
26
27    /// Boolean value.
28    Boolean(bool),
29
30    /// 64-bit signed integer.
31    Integer(i64),
32
33    /// 64-bit floating point number.
34    Number(f64),
35
36    /// UTF-8 string wrapped in `Arc` for efficient cloning.
37    String(Arc<String>),
38
39    /// Image data (requires `image` feature).
40    #[cfg(feature = "image")]
41    Image(Arc<PhotonImage>),
42
43    /// Ordered array of values.
44    Array(Vector<AgentValue>),
45
46    /// Key-value map.
47    Object(HashMap<String, AgentValue>),
48
49    /// Tensor data for embeddings, etc.
50    Tensor(Arc<Vec<f32>>),
51
52    /// LLM chat message.
53    Message(Arc<Message>),
54
55    /// Error value for propagating errors through the workflow.
56    Error(Arc<AgentError>),
57}
58
59/// Type alias for key-value maps used in `AgentValue::Object`.
60pub type AgentValueMap<S, T> = HashMap<S, T>;
61
62impl AgentValue {
63    /// Creates a `Unit` value.
64    pub fn unit() -> Self {
65        AgentValue::Unit
66    }
67
68    /// Creates a `Boolean` value.
69    pub fn boolean(value: bool) -> Self {
70        AgentValue::Boolean(value)
71    }
72
73    /// Creates an `Integer` value.
74    pub fn integer(value: i64) -> Self {
75        AgentValue::Integer(value)
76    }
77
78    /// Creates a `Number` value.
79    pub fn number(value: f64) -> Self {
80        AgentValue::Number(value)
81    }
82
83    /// Creates a `String` value.
84    pub fn string(value: impl Into<String>) -> Self {
85        AgentValue::String(Arc::new(value.into()))
86    }
87
88    /// Creates an `Image` value from a `PhotonImage`.
89    #[cfg(feature = "image")]
90    pub fn image(value: PhotonImage) -> Self {
91        AgentValue::Image(Arc::new(value))
92    }
93
94    /// Creates an `Image` value from an `Arc<PhotonImage>`.
95    #[cfg(feature = "image")]
96    pub fn image_arc(value: Arc<PhotonImage>) -> Self {
97        AgentValue::Image(value)
98    }
99
100    /// Creates an `Array` value.
101    pub fn array(value: Vector<AgentValue>) -> Self {
102        AgentValue::Array(value)
103    }
104
105    /// Creates an `Object` value.
106    pub fn object(value: AgentValueMap<String, AgentValue>) -> Self {
107        AgentValue::Object(value)
108    }
109
110    /// Creates a `Tensor` value from a `Vec<f32>`.
111    pub fn tensor(value: Vec<f32>) -> Self {
112        AgentValue::Tensor(Arc::new(value))
113    }
114
115    /// Creates a `Message` value.
116    pub fn message(value: Message) -> Self {
117        AgentValue::Message(Arc::new(value))
118    }
119
120    /// Creates a default `Boolean` value (`false`).
121    pub fn boolean_default() -> Self {
122        AgentValue::Boolean(false)
123    }
124
125    /// Creates a default `Integer` value (`0`).
126    pub fn integer_default() -> Self {
127        AgentValue::Integer(0)
128    }
129
130    /// Creates a default `Number` value (`0.0`).
131    pub fn number_default() -> Self {
132        AgentValue::Number(0.0)
133    }
134
135    /// Creates a default `String` value (empty string).
136    pub fn string_default() -> Self {
137        AgentValue::String(Arc::new(String::new()))
138    }
139
140    /// Creates a default `Image` value (1x1 transparent pixel).
141    #[cfg(feature = "image")]
142    pub fn image_default() -> Self {
143        AgentValue::Image(Arc::new(PhotonImage::new(vec![0u8, 0u8, 0u8, 0u8], 1, 1)))
144    }
145
146    /// Creates a default `Array` value (empty array).
147    pub fn array_default() -> Self {
148        AgentValue::Array(Vector::new())
149    }
150
151    /// Creates a default `Object` value (empty object).
152    pub fn object_default() -> Self {
153        AgentValue::Object(HashMap::new())
154    }
155
156    /// Creates a default `Tensor` value (empty vector).
157    pub fn tensor_default() -> Self {
158        AgentValue::Tensor(Arc::new(Vec::new()))
159    }
160
161    /// Creates an `AgentValue` from a `serde_json::Value`.
162    ///
163    /// # Errors
164    ///
165    /// Returns `InvalidValue` if the JSON value cannot be converted.
166    pub fn from_json(value: serde_json::Value) -> Result<Self, AgentError> {
167        match value {
168            serde_json::Value::Null => Ok(AgentValue::Unit),
169            serde_json::Value::Bool(b) => Ok(AgentValue::Boolean(b)),
170            serde_json::Value::Number(n) => {
171                if let Some(i) = n.as_i64() {
172                    Ok(AgentValue::Integer(i))
173                } else if let Some(f) = n.as_f64() {
174                    Ok(AgentValue::Number(f))
175                } else {
176                    Err(AgentError::InvalidValue(
177                        "Invalid numeric value for AgentValue".into(),
178                    ))
179                }
180            }
181            serde_json::Value::String(s) => {
182                #[cfg(feature = "image")]
183                if s.starts_with(IMAGE_BASE64_PREFIX) {
184                    let img =
185                        PhotonImage::new_from_base64(&s.trim_start_matches(IMAGE_BASE64_PREFIX));
186                    Ok(AgentValue::Image(Arc::new(img)))
187                } else {
188                    Ok(AgentValue::String(Arc::new(s)))
189                }
190                #[cfg(not(feature = "image"))]
191                Ok(AgentValue::String(Arc::new(s)))
192            }
193            serde_json::Value::Array(arr) => {
194                let agent_arr: Vector<AgentValue> = arr
195                    .into_iter()
196                    .map(AgentValue::from_json)
197                    .collect::<Result<_, _>>()?;
198                Ok(AgentValue::Array(agent_arr))
199            }
200            serde_json::Value::Object(obj) => {
201                let map: HashMap<String, AgentValue> = obj
202                    .into_iter()
203                    .map(|(k, v)| Ok((k, AgentValue::from_json(v)?)))
204                    .collect::<Result<_, AgentError>>()?;
205                Ok(AgentValue::Object(map))
206            }
207        }
208    }
209
210    /// Converts to a `serde_json::Value`.
211    pub fn to_json(&self) -> serde_json::Value {
212        match self {
213            AgentValue::Unit => serde_json::Value::Null,
214            AgentValue::Boolean(b) => (*b).into(),
215            AgentValue::Integer(i) => (*i).into(),
216            AgentValue::Number(n) => (*n).into(),
217            AgentValue::String(s) => s.as_str().into(),
218            #[cfg(feature = "image")]
219            AgentValue::Image(img) => img.get_base64().into(),
220            AgentValue::Array(a) => {
221                let arr: Vec<serde_json::Value> = a.iter().map(|v| v.to_json()).collect();
222                serde_json::Value::Array(arr)
223            }
224            AgentValue::Object(o) => {
225                let mut map = serde_json::Map::new();
226                let mut entries: Vec<_> = o.iter().collect();
227                entries.sort_by(|a, b| a.0.cmp(b.0));
228
229                for (k, v) in entries {
230                    map.insert(k.clone(), v.to_json());
231                }
232                serde_json::Value::Object(map)
233            }
234            AgentValue::Tensor(t) => {
235                let arr: Vec<serde_json::Value> = t
236                    .iter()
237                    .map(|&v| {
238                        serde_json::Value::Number(
239                            serde_json::Number::from_f64(v as f64)
240                                .unwrap_or_else(|| serde_json::Number::from(0)),
241                        )
242                    })
243                    .collect();
244                serde_json::Value::Array(arr)
245            }
246            AgentValue::Message(m) => serde_json::to_value(&**m).unwrap_or(serde_json::Value::Null),
247            AgentValue::Error(_) => serde_json::Value::Null, // Errors are not serializable
248        }
249    }
250
251    /// Create AgentValue from Serialize
252    pub fn from_serialize<T: Serialize>(value: &T) -> Result<Self, AgentError> {
253        let json_value = serde_json::to_value(value)
254            .map_err(|e| AgentError::InvalidValue(format!("Failed to serialize: {}", e)))?;
255        Self::from_json(json_value)
256    }
257
258    /// Convert AgentValue to a Deserialize
259    pub fn to_deserialize<T: for<'de> Deserialize<'de>>(&self) -> Result<T, AgentError> {
260        let json_value = self.to_json();
261        serde_json::from_value(json_value)
262            .map_err(|e| AgentError::InvalidValue(format!("Failed to deserialize: {}", e)))
263    }
264
265    // Type check helpers
266
267    /// Returns `true` if this is a `Unit` value.
268    pub fn is_unit(&self) -> bool {
269        matches!(self, AgentValue::Unit)
270    }
271
272    /// Returns `true` if this is a `Boolean` value.
273    pub fn is_boolean(&self) -> bool {
274        matches!(self, AgentValue::Boolean(_))
275    }
276
277    /// Returns `true` if this is an `Integer` value.
278    pub fn is_integer(&self) -> bool {
279        matches!(self, AgentValue::Integer(_))
280    }
281
282    /// Returns `true` if this is a `Number` value.
283    pub fn is_number(&self) -> bool {
284        matches!(self, AgentValue::Number(_))
285    }
286
287    /// Returns `true` if this is a `String` value.
288    pub fn is_string(&self) -> bool {
289        matches!(self, AgentValue::String(_))
290    }
291
292    /// Returns `true` if this is an `Image` value.
293    #[cfg(feature = "image")]
294    pub fn is_image(&self) -> bool {
295        matches!(self, AgentValue::Image(_))
296    }
297
298    /// Returns `true` if this is an `Array` value.
299    pub fn is_array(&self) -> bool {
300        matches!(self, AgentValue::Array(_))
301    }
302
303    /// Returns `true` if this is an `Object` value.
304    pub fn is_object(&self) -> bool {
305        matches!(self, AgentValue::Object(_))
306    }
307
308    /// Returns `true` if this is a `Tensor` value.
309    pub fn is_tensor(&self) -> bool {
310        matches!(self, AgentValue::Tensor(_))
311    }
312
313    /// Returns `true` if this is a `Message` value.
314    pub fn is_message(&self) -> bool {
315        matches!(self, AgentValue::Message(_))
316    }
317
318    // Cast helpers
319
320    /// Returns the inner boolean value if this is a `Boolean`, otherwise `None`.
321    pub fn as_bool(&self) -> Option<bool> {
322        match self {
323            AgentValue::Boolean(b) => Some(*b),
324            _ => None,
325        }
326    }
327
328    /// Returns the value as `i64` if this is an `Integer` or `Number`, otherwise `None`.
329    pub fn as_i64(&self) -> Option<i64> {
330        match self {
331            AgentValue::Integer(i) => Some(*i),
332            AgentValue::Number(n) => Some(*n as i64),
333            _ => None,
334        }
335    }
336
337    /// Returns the value as `f64` if this is an `Integer` or `Number`, otherwise `None`.
338    pub fn as_f64(&self) -> Option<f64> {
339        match self {
340            AgentValue::Integer(i) => Some(*i as f64),
341            AgentValue::Number(n) => Some(*n),
342            _ => None,
343        }
344    }
345
346    /// Returns a reference to the inner string if this is a `String`, otherwise `None`.
347    pub fn as_str(&self) -> Option<&str> {
348        match self {
349            AgentValue::String(s) => Some(s),
350            _ => None,
351        }
352    }
353
354    /// Returns a reference to the inner image if this is an `Image`, otherwise `None`.
355    #[cfg(feature = "image")]
356    pub fn as_image(&self) -> Option<&PhotonImage> {
357        match self {
358            AgentValue::Image(img) => Some(img),
359            _ => None,
360        }
361    }
362
363    /// Returns a mutable reference to the inner image if this is an `Image`, otherwise `None`.
364    #[cfg(feature = "image")]
365    pub fn as_image_mut(&mut self) -> Option<&mut PhotonImage> {
366        match self {
367            AgentValue::Image(img) => Some(Arc::make_mut(img)),
368            _ => None,
369        }
370    }
371
372    /// Extracts the inner `Arc<PhotonImage>` if this is an `Image`, consuming self.
373    #[cfg(feature = "image")]
374    pub fn into_image(self) -> Option<Arc<PhotonImage>> {
375        match self {
376            AgentValue::Image(img) => Some(img),
377            _ => None,
378        }
379    }
380
381    /// Returns a reference to the inner message if this is a `Message`, otherwise `None`.
382    pub fn as_message(&self) -> Option<&Message> {
383        match self {
384            AgentValue::Message(m) => Some(m),
385            _ => None,
386        }
387    }
388
389    /// Returns a mutable reference to the inner message if this is a `Message`, otherwise `None`.
390    pub fn as_message_mut(&mut self) -> Option<&mut Message> {
391        match self {
392            AgentValue::Message(m) => Some(Arc::make_mut(m)),
393            _ => None,
394        }
395    }
396
397    /// Extracts the inner `Arc<Message>` if this is a `Message`, consuming self.
398    pub fn into_message(self) -> Option<Arc<Message>> {
399        match self {
400            AgentValue::Message(m) => Some(m),
401            _ => None,
402        }
403    }
404
405    /// Converts to a boolean with type coercion.
406    ///
407    /// Conversion rules:
408    /// - `Boolean`: returns the value
409    /// - `Integer`: `0` → `false`, otherwise `true`
410    /// - `Number`: `0.0` → `false`, otherwise `true`
411    /// - `String`: parses "true"/"false"
412    pub fn to_boolean(&self) -> Option<bool> {
413        match self {
414            AgentValue::Boolean(b) => Some(*b),
415            AgentValue::Integer(i) => Some(*i != 0),
416            AgentValue::Number(n) => Some(*n != 0.0),
417            AgentValue::String(s) => s.parse().ok(),
418            _ => None,
419        }
420    }
421
422    /// Converts to `AgentValue::Boolean` or `AgentValue::Array` of booleans.
423    pub fn to_boolean_value(&self) -> Option<AgentValue> {
424        match self {
425            AgentValue::Boolean(_) => Some(self.clone()),
426            AgentValue::Array(arr) => {
427                if arr.iter().all(|v| v.is_boolean()) {
428                    return Some(self.clone());
429                }
430                let mut new_arr = Vector::new();
431                for item in arr {
432                    new_arr.push_back(item.to_boolean_value()?);
433                }
434                Some(AgentValue::Array(new_arr))
435            }
436            _ => self.to_boolean().map(AgentValue::boolean),
437        }
438    }
439
440    /// Converts to an integer (i64) with type coercion.
441    pub fn to_integer(&self) -> Option<i64> {
442        match self {
443            AgentValue::Integer(i) => Some(*i),
444            AgentValue::Boolean(b) => Some(if *b { 1 } else { 0 }),
445            AgentValue::Number(n) => Some(*n as i64),
446            AgentValue::String(s) => s.parse().ok(),
447            _ => None,
448        }
449    }
450
451    /// Converts to `AgentValue::Integer` or `AgentValue::Array` of integers.
452    pub fn to_integer_value(&self) -> Option<AgentValue> {
453        match self {
454            AgentValue::Integer(_) => Some(self.clone()),
455            AgentValue::Array(arr) => {
456                if arr.iter().all(|v| v.is_integer()) {
457                    return Some(self.clone());
458                }
459                let mut new_arr = Vector::new();
460                for item in arr {
461                    new_arr.push_back(item.to_integer_value()?);
462                }
463                Some(AgentValue::Array(new_arr))
464            }
465            _ => self.to_integer().map(AgentValue::integer),
466        }
467    }
468
469    /// Converts to a number (f64) with type coercion.
470    pub fn to_number(&self) -> Option<f64> {
471        match self {
472            AgentValue::Number(n) => Some(*n),
473            AgentValue::Boolean(b) => Some(if *b { 1.0 } else { 0.0 }),
474            AgentValue::Integer(i) => Some(*i as f64),
475            AgentValue::String(s) => s.parse().ok(),
476            _ => None,
477        }
478    }
479
480    /// Converts to `AgentValue::Number` or `AgentValue::Array` of numbers.
481    pub fn to_number_value(&self) -> Option<AgentValue> {
482        match self {
483            AgentValue::Number(_) => Some(self.clone()),
484            AgentValue::Array(arr) => {
485                if arr.iter().all(|v| v.is_number()) {
486                    return Some(self.clone());
487                }
488                let mut new_arr = Vector::new();
489                for item in arr {
490                    new_arr.push_back(item.to_number_value()?);
491                }
492                Some(AgentValue::Array(new_arr))
493            }
494            _ => self.to_number().map(AgentValue::number),
495        }
496    }
497
498    /// Converts to a string with type coercion.
499    pub fn to_string(&self) -> Option<String> {
500        match self {
501            AgentValue::String(s) => Some(s.as_ref().clone()),
502            AgentValue::Boolean(b) => Some(b.to_string()),
503            AgentValue::Integer(i) => Some(i.to_string()),
504            AgentValue::Number(n) => Some(n.to_string()),
505            AgentValue::Message(m) => Some(m.content.clone()),
506            _ => None,
507        }
508    }
509
510    /// Converts to `AgentValue::String` or `AgentValue::Array` of strings.
511    pub fn to_string_value(&self) -> Option<AgentValue> {
512        match self {
513            AgentValue::String(_) => Some(self.clone()),
514            AgentValue::Array(arr) => {
515                if arr.iter().all(|v| v.is_string()) {
516                    return Some(self.clone());
517                }
518                let mut new_arr = Vector::new();
519                for item in arr {
520                    new_arr.push_back(item.to_string_value()?);
521                }
522                Some(AgentValue::Array(new_arr))
523            }
524            _ => self.to_string().map(AgentValue::string),
525        }
526    }
527
528    /// Converts to a `Message`.
529    pub fn to_message(&self) -> Option<Message> {
530        Message::try_from(self.clone()).ok()
531    }
532
533    /// Converts to `AgentValue::Message` or `AgentValue::Array` of messages.
534    /// 
535    /// If the value is an array, it recursively converts its elements.
536    pub fn to_message_value(&self) -> Option<AgentValue> {
537        match self {
538            AgentValue::Message(_) => Some(self.clone()),
539            AgentValue::Array(arr) => {
540                if arr.iter().all(|v| v.is_message()) {
541                    return Some(self.clone());
542                }
543                let mut new_arr = Vector::new();
544                for item in arr {
545                    new_arr.push_back(item.to_message_value()?);
546                }
547                Some(AgentValue::Array(new_arr))
548            }
549            _ => Message::try_from(self.clone())
550                .ok()
551                .map(|m| AgentValue::message(m)),
552        }
553    }
554
555    /// Returns a reference to the inner object map if this is an `Object`, otherwise `None`.
556    pub fn as_object(&self) -> Option<&AgentValueMap<String, AgentValue>> {
557        match self {
558            AgentValue::Object(o) => Some(o),
559            _ => None,
560        }
561    }
562
563    /// Returns a mutable reference to the inner object map if this is an `Object`, otherwise `None`.
564    pub fn as_object_mut(&mut self) -> Option<&mut AgentValueMap<String, AgentValue>> {
565        match self {
566            AgentValue::Object(o) => Some(o),
567            _ => None,
568        }
569    }
570
571    /// Extracts the inner `HashMap` if this is an `Object`, consuming self.
572    pub fn into_object(self) -> Option<AgentValueMap<String, AgentValue>> {
573        match self {
574            AgentValue::Object(o) => Some(o),
575            _ => None,
576        }
577    }
578
579    /// Returns a reference to the inner array if this is an `Array`, otherwise `None`.
580    pub fn as_array(&self) -> Option<&Vector<AgentValue>> {
581        match self {
582            AgentValue::Array(a) => Some(a),
583            _ => None,
584        }
585    }
586
587    /// Returns a mutable reference to the inner array if this is an `Array`, otherwise `None`.
588    pub fn as_array_mut(&mut self) -> Option<&mut Vector<AgentValue>> {
589        match self {
590            AgentValue::Array(a) => Some(a),
591            _ => None,
592        }
593    }
594
595    /// Extracts the inner `Vector` if this is an `Array`, consuming self.
596    pub fn into_array(self) -> Option<Vector<AgentValue>> {
597        match self {
598            AgentValue::Array(a) => Some(a),
599            _ => None,
600        }
601    }
602
603    /// Returns a reference to the inner tensor if this is a `Tensor`, otherwise `None`.
604    pub fn as_tensor(&self) -> Option<&Vec<f32>> {
605        match self {
606            AgentValue::Tensor(t) => Some(t),
607            _ => None,
608        }
609    }
610
611    /// Returns a mutable reference to the inner tensor if this is a `Tensor`, otherwise `None`.
612    pub fn as_tensor_mut(&mut self) -> Option<&mut Vec<f32>> {
613        match self {
614            AgentValue::Tensor(t) => Some(Arc::make_mut(t)),
615            _ => None,
616        }
617    }
618
619    /// Extracts the inner `Arc<Vec<f32>>` if this is a `Tensor`, consuming self.
620    pub fn into_tensor(self) -> Option<Arc<Vec<f32>>> {
621        match self {
622            AgentValue::Tensor(t) => Some(t),
623            _ => None,
624        }
625    }
626
627    /// Extracts the inner `Vec<f32>` if this is a `Tensor`, consuming self.
628    /// Possibly O(n) copy.
629    pub fn into_tensor_vec(self) -> Option<Vec<f32>> {
630        match self {
631            AgentValue::Tensor(t) => Some(Arc::unwrap_or_clone(t)),
632            _ => None,
633        }
634    }
635
636    // Getters by key
637    // These methods only work on `Object` values.
638
639    /// Gets a value by key from an `Object`.
640    pub fn get(&self, key: &str) -> Option<&AgentValue> {
641        self.as_object().and_then(|o| o.get(key))
642    }
643
644    /// Gets a mutable reference to a value by key from an `Object`.
645    pub fn get_mut(&mut self, key: &str) -> Option<&mut AgentValue> {
646        self.as_object_mut().and_then(|o| o.get_mut(key))
647    }
648
649    /// Gets a boolean value by key from an `Object`.
650    pub fn get_bool(&self, key: &str) -> Option<bool> {
651        self.get(key).and_then(|v| v.as_bool())
652    }
653
654    /// Gets an i64 value by key from an `Object`.
655    pub fn get_i64(&self, key: &str) -> Option<i64> {
656        self.get(key).and_then(|v| v.as_i64())
657    }
658
659    /// Gets an f64 value by key from an `Object`.
660    pub fn get_f64(&self, key: &str) -> Option<f64> {
661        self.get(key).and_then(|v| v.as_f64())
662    }
663
664    /// Gets a string reference by key from an `Object`.
665    pub fn get_str(&self, key: &str) -> Option<&str> {
666        self.get(key).and_then(|v| v.as_str())
667    }
668
669    /// Gets an image reference by key from an `Object`.
670    #[cfg(feature = "image")]
671    pub fn get_image(&self, key: &str) -> Option<&PhotonImage> {
672        self.get(key).and_then(|v| v.as_image())
673    }
674
675    /// Gets a mutable image reference by key from an `Object`.
676    #[cfg(feature = "image")]
677    pub fn get_image_mut(&mut self, key: &str) -> Option<&mut PhotonImage> {
678        self.get_mut(key).and_then(|v| v.as_image_mut())
679    }
680
681    /// Gets an object reference by key from an `Object`.
682    pub fn get_object(&self, key: &str) -> Option<&AgentValueMap<String, AgentValue>> {
683        self.get(key).and_then(|v| v.as_object())
684    }
685
686    /// Gets a mutable object reference by key from an `Object`.
687    pub fn get_object_mut(&mut self, key: &str) -> Option<&mut AgentValueMap<String, AgentValue>> {
688        self.get_mut(key).and_then(|v| v.as_object_mut())
689    }
690
691    /// Gets an array reference by key from an `Object`.
692    pub fn get_array(&self, key: &str) -> Option<&Vector<AgentValue>> {
693        self.get(key).and_then(|v| v.as_array())
694    }
695
696    /// Gets a mutable array reference by key from an `Object`.
697    pub fn get_array_mut(&mut self, key: &str) -> Option<&mut Vector<AgentValue>> {
698        self.get_mut(key).and_then(|v| v.as_array_mut())
699    }
700
701    /// Gets a tensor reference by key from an `Object`.
702    pub fn get_tensor(&self, key: &str) -> Option<&Vec<f32>> {
703        self.get(key).and_then(|v| v.as_tensor())
704    }
705
706    /// Gets a mutable tensor reference by key from an `Object`.
707    pub fn get_tensor_mut(&mut self, key: &str) -> Option<&mut Vec<f32>> {
708        self.get_mut(key).and_then(|v| v.as_tensor_mut())
709    }
710
711    /// Gets a message reference by key from an `Object`.
712    pub fn get_message(&self, key: &str) -> Option<&Message> {
713        self.get(key).and_then(|v| v.as_message())
714    }
715
716    /// Gets a mutable message reference by key from an `Object`.
717    pub fn get_message_mut(&mut self, key: &str) -> Option<&mut Message> {
718        self.get_mut(key).and_then(|v| v.as_message_mut())
719    }
720
721    // Setter by key
722
723    /// Sets a value by key in an `Object`.
724    ///
725    /// # Errors
726    ///
727    /// Returns `InvalidValue` if this is not an `Object`.
728    pub fn set(&mut self, key: String, value: AgentValue) -> Result<(), AgentError> {
729        if let Some(obj) = self.as_object_mut() {
730            obj.insert(key, value);
731            Ok(())
732        } else {
733            Err(AgentError::InvalidValue(
734                "set can only be called on Object AgentValue".into(),
735            ))
736        }
737    }
738}
739
740impl Default for AgentValue {
741    fn default() -> Self {
742        AgentValue::Unit
743    }
744}
745
746impl PartialEq for AgentValue {
747    fn eq(&self, other: &Self) -> bool {
748        match (self, other) {
749            (AgentValue::Unit, AgentValue::Unit) => true,
750            (AgentValue::Boolean(b1), AgentValue::Boolean(b2)) => b1 == b2,
751            (AgentValue::Integer(i1), AgentValue::Integer(i2)) => i1 == i2,
752            (AgentValue::Number(n1), AgentValue::Number(n2)) => n1 == n2,
753            (AgentValue::String(s1), AgentValue::String(s2)) => s1 == s2,
754            #[cfg(feature = "image")]
755            (AgentValue::Image(i1), AgentValue::Image(i2)) => {
756                i1.get_width() == i2.get_width()
757                    && i1.get_height() == i2.get_height()
758                    && i1.get_raw_pixels() == i2.get_raw_pixels()
759            }
760            (AgentValue::Array(a1), AgentValue::Array(a2)) => a1 == a2,
761            (AgentValue::Object(o1), AgentValue::Object(o2)) => o1 == o2,
762            (AgentValue::Tensor(t1), AgentValue::Tensor(t2)) => t1 == t2,
763            (AgentValue::Message(m1), AgentValue::Message(m2)) => m1 == m2,
764            _ => false,
765        }
766    }
767}
768
769impl Serialize for AgentValue {
770    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
771    where
772        S: Serializer,
773    {
774        match self {
775            AgentValue::Unit => serializer.serialize_none(),
776            AgentValue::Boolean(b) => serializer.serialize_bool(*b),
777            AgentValue::Integer(i) => serializer.serialize_i64(*i),
778            AgentValue::Number(n) => serializer.serialize_f64(*n),
779            AgentValue::String(s) => serializer.serialize_str(s),
780            #[cfg(feature = "image")]
781            AgentValue::Image(img) => serializer.serialize_str(&img.get_base64()),
782            AgentValue::Array(a) => {
783                let mut seq = serializer.serialize_seq(Some(a.len()))?;
784                for e in a.iter() {
785                    seq.serialize_element(e)?;
786                }
787                seq.end()
788            }
789            AgentValue::Object(o) => {
790                let mut map = serializer.serialize_map(Some(o.len()))?;
791                // Sort the entries to ensure stable JSON output.
792                let mut entries: Vec<_> = o.iter().collect();
793                entries.sort_by(|a, b| a.0.cmp(b.0));
794
795                for (k, v) in entries {
796                    map.serialize_entry(k, v)?;
797                }
798                map.end()
799            }
800            AgentValue::Tensor(t) => {
801                let mut seq = serializer.serialize_seq(Some(t.len()))?;
802                for e in t.iter() {
803                    seq.serialize_element(e)?;
804                }
805                seq.end()
806            }
807            AgentValue::Message(m) => m.serialize(serializer),
808            AgentValue::Error(_) => serializer.serialize_none(), // Errors are not serializable
809        }
810    }
811}
812
813impl<'de> Deserialize<'de> for AgentValue {
814    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
815    where
816        D: Deserializer<'de>,
817    {
818        let value = serde_json::Value::deserialize(deserializer)?;
819        AgentValue::from_json(value).map_err(|e| {
820            serde::de::Error::custom(format!("Failed to deserialize AgentValue: {}", e))
821        })
822    }
823}
824
825impl From<()> for AgentValue {
826    fn from(_: ()) -> Self {
827        AgentValue::unit()
828    }
829}
830
831impl From<bool> for AgentValue {
832    fn from(value: bool) -> Self {
833        AgentValue::boolean(value)
834    }
835}
836
837impl From<i32> for AgentValue {
838    fn from(value: i32) -> Self {
839        AgentValue::integer(value as i64)
840    }
841}
842
843impl From<i64> for AgentValue {
844    fn from(value: i64) -> Self {
845        AgentValue::integer(value)
846    }
847}
848
849impl From<usize> for AgentValue {
850    fn from(value: usize) -> Self {
851        AgentValue::Integer(value as i64)
852    }
853}
854
855impl From<u64> for AgentValue {
856    fn from(value: u64) -> Self {
857        AgentValue::Integer(value as i64)
858    }
859}
860
861impl From<f32> for AgentValue {
862    fn from(value: f32) -> Self {
863        AgentValue::Number(value as f64)
864    }
865}
866
867impl From<f64> for AgentValue {
868    fn from(value: f64) -> Self {
869        AgentValue::number(value)
870    }
871}
872
873impl From<String> for AgentValue {
874    fn from(value: String) -> Self {
875        AgentValue::string(value)
876    }
877}
878
879impl From<&str> for AgentValue {
880    fn from(value: &str) -> Self {
881        AgentValue::string(value)
882    }
883}
884
885impl From<Vector<AgentValue>> for AgentValue {
886    fn from(value: Vector<AgentValue>) -> Self {
887        AgentValue::Array(value)
888    }
889}
890
891impl From<HashMap<String, AgentValue>> for AgentValue {
892    fn from(value: HashMap<String, AgentValue>) -> Self {
893        AgentValue::Object(value)
894    }
895}
896
897// Tensor support
898impl From<Vec<f32>> for AgentValue {
899    fn from(value: Vec<f32>) -> Self {
900        AgentValue::Tensor(Arc::new(value))
901    }
902}
903impl From<Arc<Vec<f32>>> for AgentValue {
904    fn from(value: Arc<Vec<f32>>) -> Self {
905        AgentValue::Tensor(value)
906    }
907}
908
909// Standard Collections support
910impl From<Vec<AgentValue>> for AgentValue {
911    fn from(value: Vec<AgentValue>) -> Self {
912        AgentValue::Array(Vector::from(value))
913    }
914}
915impl From<std::collections::HashMap<String, AgentValue>> for AgentValue {
916    fn from(value: std::collections::HashMap<String, AgentValue>) -> Self {
917        AgentValue::Object(HashMap::from(value))
918    }
919}
920
921// Error support
922impl From<AgentError> for AgentValue {
923    fn from(value: AgentError) -> Self {
924        AgentValue::Error(Arc::new(value))
925    }
926}
927
928// Option support
929impl From<Option<AgentValue>> for AgentValue {
930    fn from(value: Option<AgentValue>) -> Self {
931        value.unwrap_or(AgentValue::Unit)
932    }
933}
934
935#[cfg(test)]
936mod tests {
937    use super::*;
938    use im::{hashmap, vector};
939    use serde_json::json;
940
941    #[test]
942    fn test_partial_eq() {
943        // Test PartialEq implementation
944        let unit1 = AgentValue::unit();
945        let unit2 = AgentValue::unit();
946        assert_eq!(unit1, unit2);
947
948        let boolean1 = AgentValue::boolean(true);
949        let boolean2 = AgentValue::boolean(true);
950        assert_eq!(boolean1, boolean2);
951
952        let integer1 = AgentValue::integer(42);
953        let integer2 = AgentValue::integer(42);
954        assert_eq!(integer1, integer2);
955        let different = AgentValue::integer(100);
956        assert_ne!(integer1, different);
957
958        let number1 = AgentValue::number(3.14);
959        let number2 = AgentValue::number(3.14);
960        assert_eq!(number1, number2);
961
962        let string1 = AgentValue::string("hello");
963        let string2 = AgentValue::string("hello");
964        assert_eq!(string1, string2);
965
966        #[cfg(feature = "image")]
967        {
968            let image1 = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
969            let image2 = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
970            assert_eq!(image1, image2);
971        }
972
973        let obj1 = AgentValue::object(hashmap! {
974                "key1".into() => AgentValue::string("value1"),
975                "key2".into() => AgentValue::integer(2),
976        });
977        let obj2 = AgentValue::object(hashmap! {
978                "key1".to_string() => AgentValue::string("value1"),
979                "key2".to_string() => AgentValue::integer(2),
980        });
981        assert_eq!(obj1, obj2);
982
983        let arr1 = AgentValue::array(vector![
984            AgentValue::integer(1),
985            AgentValue::string("two"),
986            AgentValue::boolean(true),
987        ]);
988        let arr2 = AgentValue::array(vector![
989            AgentValue::integer(1),
990            AgentValue::string("two"),
991            AgentValue::boolean(true),
992        ]);
993        assert_eq!(arr1, arr2);
994
995        let mixed_types_1 = AgentValue::boolean(true);
996        let mixed_types_2 = AgentValue::integer(1);
997        assert_ne!(mixed_types_1, mixed_types_2);
998
999        let msg1 = AgentValue::message(Message::user("hello".to_string()));
1000        let msg2 = AgentValue::message(Message::user("hello".to_string()));
1001        assert_eq!(msg1, msg2);
1002    }
1003
1004    #[test]
1005    fn test_agent_value_constructors() {
1006        // Test AgentValue constructors
1007        let unit = AgentValue::unit();
1008        assert_eq!(unit, AgentValue::Unit);
1009
1010        let boolean = AgentValue::boolean(true);
1011        assert_eq!(boolean, AgentValue::Boolean(true));
1012
1013        let integer = AgentValue::integer(42);
1014        assert_eq!(integer, AgentValue::Integer(42));
1015
1016        let number = AgentValue::number(3.14);
1017        assert!(matches!(number, AgentValue::Number(_)));
1018        if let AgentValue::Number(num) = number {
1019            assert!((num - 3.14).abs() < f64::EPSILON);
1020        }
1021
1022        let string = AgentValue::string("hello");
1023        assert!(matches!(string, AgentValue::String(_)));
1024        assert_eq!(string.as_str().unwrap(), "hello");
1025
1026        let text = AgentValue::string("multiline\ntext");
1027        assert!(matches!(text, AgentValue::String(_)));
1028        assert_eq!(text.as_str().unwrap(), "multiline\ntext");
1029
1030        let array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(2)]);
1031        assert!(matches!(array, AgentValue::Array(_)));
1032        if let AgentValue::Array(arr) = array {
1033            assert_eq!(arr.len(), 2);
1034            assert_eq!(arr[0].as_i64().unwrap(), 1);
1035            assert_eq!(arr[1].as_i64().unwrap(), 2);
1036        }
1037
1038        let obj = AgentValue::object(hashmap! {
1039                "key1".to_string() => AgentValue::string("string1"),
1040                "key2".to_string() => AgentValue::integer(2),
1041        });
1042        assert!(matches!(obj, AgentValue::Object(_)));
1043        if let AgentValue::Object(obj) = obj {
1044            assert_eq!(obj.get("key1").and_then(|v| v.as_str()), Some("string1"));
1045            assert_eq!(obj.get("key2").and_then(|v| v.as_i64()), Some(2));
1046        } else {
1047            panic!("Object was not deserialized correctly");
1048        }
1049
1050        let msg = AgentValue::message(Message::user("hello".to_string()));
1051        assert!(matches!(msg, AgentValue::Message(_)));
1052    }
1053
1054    #[test]
1055    fn test_agent_value_from_json_value() {
1056        // Test converting from JSON value to AgentValue
1057        let null = AgentValue::from_json(json!(null)).unwrap();
1058        assert_eq!(null, AgentValue::Unit);
1059
1060        let boolean = AgentValue::from_json(json!(true)).unwrap();
1061        assert_eq!(boolean, AgentValue::Boolean(true));
1062
1063        let integer = AgentValue::from_json(json!(42)).unwrap();
1064        assert_eq!(integer, AgentValue::Integer(42));
1065
1066        let number = AgentValue::from_json(json!(3.14)).unwrap();
1067        assert!(matches!(number, AgentValue::Number(_)));
1068        if let AgentValue::Number(num) = number {
1069            assert!((num - 3.14).abs() < f64::EPSILON);
1070        }
1071
1072        let string = AgentValue::from_json(json!("hello")).unwrap();
1073        assert!(matches!(string, AgentValue::String(_)));
1074        if let AgentValue::String(s) = string {
1075            assert_eq!(*s, "hello");
1076        } else {
1077            panic!("Expected string value");
1078        }
1079
1080        let array = AgentValue::from_json(json!([1, "test", true])).unwrap();
1081        assert!(matches!(array, AgentValue::Array(_)));
1082        if let AgentValue::Array(arr) = array {
1083            assert_eq!(arr.len(), 3);
1084            assert_eq!(arr[0], AgentValue::Integer(1));
1085            assert!(matches!(&arr[1], AgentValue::String(_)));
1086            if let AgentValue::String(s) = &arr[1] {
1087                assert_eq!(**s, "test");
1088            } else {
1089                panic!("Expected string value");
1090            }
1091            assert_eq!(arr[2], AgentValue::Boolean(true));
1092        }
1093
1094        let object = AgentValue::from_json(json!({"key1": "string1", "key2": 2})).unwrap();
1095        assert!(matches!(object, AgentValue::Object(_)));
1096        if let AgentValue::Object(obj) = object {
1097            assert_eq!(obj.get("key1").and_then(|v| v.as_str()), Some("string1"));
1098            assert_eq!(obj.get("key2").and_then(|v| v.as_i64()), Some(2));
1099        } else {
1100            panic!("Object was not deserialized correctly");
1101        }
1102    }
1103
1104    #[test]
1105    fn test_agent_value_test_methods() {
1106        // Test test methods on AgentValue
1107        let unit = AgentValue::unit();
1108        assert_eq!(unit.is_unit(), true);
1109        assert_eq!(unit.is_boolean(), false);
1110        assert_eq!(unit.is_integer(), false);
1111        assert_eq!(unit.is_number(), false);
1112        assert_eq!(unit.is_string(), false);
1113        assert_eq!(unit.is_array(), false);
1114        assert_eq!(unit.is_object(), false);
1115        #[cfg(feature = "image")]
1116        assert_eq!(unit.is_image(), false);
1117
1118        let boolean = AgentValue::boolean(true);
1119        assert_eq!(boolean.is_unit(), false);
1120        assert_eq!(boolean.is_boolean(), true);
1121        assert_eq!(boolean.is_integer(), false);
1122        assert_eq!(boolean.is_number(), false);
1123        assert_eq!(boolean.is_string(), false);
1124        assert_eq!(boolean.is_array(), false);
1125        assert_eq!(boolean.is_object(), false);
1126        #[cfg(feature = "image")]
1127        assert_eq!(boolean.is_image(), false);
1128
1129        let integer = AgentValue::integer(42);
1130        assert_eq!(integer.is_unit(), false);
1131        assert_eq!(integer.is_boolean(), false);
1132        assert_eq!(integer.is_integer(), true);
1133        assert_eq!(integer.is_number(), false);
1134        assert_eq!(integer.is_string(), false);
1135        assert_eq!(integer.is_array(), false);
1136        assert_eq!(integer.is_object(), false);
1137        #[cfg(feature = "image")]
1138        assert_eq!(integer.is_image(), false);
1139
1140        let number = AgentValue::number(3.14);
1141        assert_eq!(number.is_unit(), false);
1142        assert_eq!(number.is_boolean(), false);
1143        assert_eq!(number.is_integer(), false);
1144        assert_eq!(number.is_number(), true);
1145        assert_eq!(number.is_string(), false);
1146        assert_eq!(number.is_array(), false);
1147        assert_eq!(number.is_object(), false);
1148        #[cfg(feature = "image")]
1149        assert_eq!(number.is_image(), false);
1150
1151        let string = AgentValue::string("hello");
1152        assert_eq!(string.is_unit(), false);
1153        assert_eq!(string.is_boolean(), false);
1154        assert_eq!(string.is_integer(), false);
1155        assert_eq!(string.is_number(), false);
1156        assert_eq!(string.is_string(), true);
1157        assert_eq!(string.is_array(), false);
1158        assert_eq!(string.is_object(), false);
1159        #[cfg(feature = "image")]
1160        assert_eq!(string.is_image(), false);
1161
1162        let array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(2)]);
1163        assert_eq!(array.is_unit(), false);
1164        assert_eq!(array.is_boolean(), false);
1165        assert_eq!(array.is_integer(), false);
1166        assert_eq!(array.is_number(), false);
1167        assert_eq!(array.is_string(), false);
1168        assert_eq!(array.is_array(), true);
1169        assert_eq!(array.is_object(), false);
1170        #[cfg(feature = "image")]
1171        assert_eq!(array.is_image(), false);
1172
1173        let obj = AgentValue::object(hashmap! {
1174                "key1".to_string() => AgentValue::string("string1"),
1175                "key2".to_string() => AgentValue::integer(2),
1176        });
1177        assert_eq!(obj.is_unit(), false);
1178        assert_eq!(obj.is_boolean(), false);
1179        assert_eq!(obj.is_integer(), false);
1180        assert_eq!(obj.is_number(), false);
1181        assert_eq!(obj.is_string(), false);
1182        assert_eq!(obj.is_array(), false);
1183        assert_eq!(obj.is_object(), true);
1184        #[cfg(feature = "image")]
1185        assert_eq!(obj.is_image(), false);
1186
1187        #[cfg(feature = "image")]
1188        {
1189            let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
1190            assert_eq!(img.is_unit(), false);
1191            assert_eq!(img.is_boolean(), false);
1192            assert_eq!(img.is_integer(), false);
1193            assert_eq!(img.is_number(), false);
1194            assert_eq!(img.is_string(), false);
1195            assert_eq!(img.is_array(), false);
1196            assert_eq!(img.is_object(), false);
1197            assert_eq!(img.is_image(), true);
1198        }
1199
1200        let msg = AgentValue::message(Message::user("hello".to_string()));
1201        assert_eq!(msg.is_unit(), false);
1202        assert_eq!(msg.is_boolean(), false);
1203        assert_eq!(msg.is_integer(), false);
1204        assert_eq!(msg.is_number(), false);
1205        assert_eq!(msg.is_string(), false);
1206        assert_eq!(msg.is_array(), false);
1207        assert_eq!(msg.is_object(), false);
1208        #[cfg(feature = "image")]
1209        assert_eq!(msg.is_image(), false);
1210        assert_eq!(msg.is_message(), true);
1211    }
1212
1213    #[test]
1214    fn test_agent_value_as_methods() {
1215        // Test accessor methods on AgentValue
1216        let boolean = AgentValue::boolean(true);
1217        assert_eq!(boolean.as_bool(), Some(true));
1218        assert_eq!(boolean.as_i64(), None);
1219        assert_eq!(boolean.as_f64(), None);
1220        assert_eq!(boolean.as_str(), None);
1221        assert!(boolean.as_array().is_none());
1222        assert_eq!(boolean.as_object(), None);
1223        #[cfg(feature = "image")]
1224        assert!(boolean.as_image().is_none());
1225
1226        let integer = AgentValue::integer(42);
1227        assert_eq!(integer.as_bool(), None);
1228        assert_eq!(integer.as_i64(), Some(42));
1229        assert_eq!(integer.as_f64(), Some(42.0));
1230        assert_eq!(integer.as_str(), None);
1231        assert!(integer.as_array().is_none());
1232        assert_eq!(integer.as_object(), None);
1233        #[cfg(feature = "image")]
1234        assert!(integer.as_image().is_none());
1235
1236        let number = AgentValue::number(3.14);
1237        assert_eq!(number.as_bool(), None);
1238        assert_eq!(number.as_i64(), Some(3)); // truncated
1239        assert_eq!(number.as_f64().unwrap(), 3.14);
1240        assert_eq!(number.as_str(), None);
1241        assert!(number.as_array().is_none());
1242        assert_eq!(number.as_object(), None);
1243        #[cfg(feature = "image")]
1244        assert!(number.as_image().is_none());
1245
1246        let string = AgentValue::string("hello");
1247        assert_eq!(string.as_bool(), None);
1248        assert_eq!(string.as_i64(), None);
1249        assert_eq!(string.as_f64(), None);
1250        assert_eq!(string.as_str(), Some("hello"));
1251        assert!(string.as_array().is_none());
1252        assert_eq!(string.as_object(), None);
1253        #[cfg(feature = "image")]
1254        assert!(string.as_image().is_none());
1255
1256        let array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(2)]);
1257        assert_eq!(array.as_bool(), None);
1258        assert_eq!(array.as_i64(), None);
1259        assert_eq!(array.as_f64(), None);
1260        assert_eq!(array.as_str(), None);
1261        assert!(array.as_array().is_some());
1262        if let Some(arr) = array.as_array() {
1263            assert_eq!(arr.len(), 2);
1264            assert_eq!(arr[0].as_i64().unwrap(), 1);
1265            assert_eq!(arr[1].as_i64().unwrap(), 2);
1266        }
1267        assert_eq!(array.as_object(), None);
1268        #[cfg(feature = "image")]
1269        assert!(array.as_image().is_none());
1270
1271        let mut array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(2)]);
1272        if let Some(arr) = array.as_array_mut() {
1273            arr.push_back(AgentValue::integer(3));
1274        }
1275
1276        let obj = AgentValue::object(hashmap! {
1277                "key1".to_string() => AgentValue::string("string1"),
1278                "key2".to_string() => AgentValue::integer(2),
1279        });
1280        assert_eq!(obj.as_bool(), None);
1281        assert_eq!(obj.as_i64(), None);
1282        assert_eq!(obj.as_f64(), None);
1283        assert_eq!(obj.as_str(), None);
1284        assert!(obj.as_array().is_none());
1285        assert!(obj.as_object().is_some());
1286        if let Some(value) = obj.as_object() {
1287            assert_eq!(value.get("key1").and_then(|v| v.as_str()), Some("string1"));
1288            assert_eq!(value.get("key2").and_then(|v| v.as_i64()), Some(2));
1289        }
1290        #[cfg(feature = "image")]
1291        assert!(obj.as_image().is_none());
1292
1293        let mut obj = AgentValue::object(hashmap! {
1294                "key1".to_string() => AgentValue::string("string1"),
1295                "key2".to_string() => AgentValue::integer(2),
1296        });
1297        if let Some(value) = obj.as_object_mut() {
1298            value.insert("key3".to_string(), AgentValue::boolean(true));
1299        }
1300
1301        #[cfg(feature = "image")]
1302        {
1303            let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
1304            assert_eq!(img.as_bool(), None);
1305            assert_eq!(img.as_i64(), None);
1306            assert_eq!(img.as_f64(), None);
1307            assert_eq!(img.as_str(), None);
1308            assert!(img.as_array().is_none());
1309            assert_eq!(img.as_object(), None);
1310            assert!(img.as_image().is_some());
1311        }
1312
1313        let mut msg = AgentValue::message(Message::user("hello".to_string()));
1314        assert!(msg.as_message().is_some());
1315        assert_eq!(msg.as_message().unwrap().content, "hello");
1316        assert!(msg.as_message_mut().is_some());
1317        if let Some(m) = msg.as_message_mut() {
1318            m.content = "world".to_string();
1319        }
1320        assert_eq!(msg.as_message().unwrap().content, "world");
1321        assert!(msg.into_message().is_some());
1322    }
1323
1324    #[test]
1325    fn test_agent_value_get_methods() {
1326        // Test get methods on AgentValue
1327        const KEY: &str = "key";
1328
1329        let boolean = AgentValue::boolean(true);
1330        assert_eq!(boolean.get(KEY), None);
1331
1332        let integer = AgentValue::integer(42);
1333        assert_eq!(integer.get(KEY), None);
1334
1335        let number = AgentValue::number(3.14);
1336        assert_eq!(number.get(KEY), None);
1337
1338        let string = AgentValue::string("hello");
1339        assert_eq!(string.get(KEY), None);
1340
1341        let array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(2)]);
1342        assert_eq!(array.get(KEY), None);
1343
1344        let mut array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(2)]);
1345        assert_eq!(array.get_mut(KEY), None);
1346
1347        let mut obj = AgentValue::object(hashmap! {
1348                "k_boolean".to_string() => AgentValue::boolean(true),
1349                "k_integer".to_string() => AgentValue::integer(42),
1350                "k_number".to_string() => AgentValue::number(3.14),
1351                "k_string".to_string() => AgentValue::string("string1"),
1352                "k_array".to_string() => AgentValue::array(vector![AgentValue::integer(1)]),
1353                "k_object".to_string() => AgentValue::object(hashmap! {
1354                        "inner_key".to_string() => AgentValue::integer(100),
1355                }),
1356                #[cfg(feature = "image")]
1357                "k_image".to_string() => AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1)),
1358                "k_message".to_string() => AgentValue::message(Message::user("hello".to_string())),
1359        });
1360        assert_eq!(obj.get(KEY), None);
1361        assert_eq!(obj.get_bool("k_boolean"), Some(true));
1362        assert_eq!(obj.get_i64("k_integer"), Some(42));
1363        assert_eq!(obj.get_f64("k_number"), Some(3.14));
1364        assert_eq!(obj.get_str("k_string"), Some("string1"));
1365        assert!(obj.get_array("k_array").is_some());
1366        assert!(obj.get_array_mut("k_array").is_some());
1367        assert!(obj.get_object("k_object").is_some());
1368        assert!(obj.get_object_mut("k_object").is_some());
1369        #[cfg(feature = "image")]
1370        assert!(obj.get_image("k_image").is_some());
1371        assert!(obj.get_message("k_message").is_some());
1372        assert!(obj.get_message_mut("k_message").is_some());
1373
1374        #[cfg(feature = "image")]
1375        {
1376            let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
1377            assert_eq!(img.get(KEY), None);
1378        }
1379    }
1380
1381    #[test]
1382    fn test_agent_value_set() {
1383        // Test set method on AgentValue
1384        let mut obj = AgentValue::object(AgentValueMap::new());
1385        assert!(obj.set("key1".to_string(), AgentValue::integer(42)).is_ok());
1386        assert_eq!(obj.get_i64("key1"), Some(42));
1387
1388        let mut not_obj = AgentValue::integer(10);
1389        assert!(
1390            not_obj
1391                .set("key1".to_string(), AgentValue::integer(42))
1392                .is_err()
1393        );
1394    }
1395
1396    #[test]
1397    fn test_agent_value_default() {
1398        assert_eq!(AgentValue::default(), AgentValue::Unit);
1399
1400        assert_eq!(AgentValue::boolean_default(), AgentValue::Boolean(false));
1401        assert_eq!(AgentValue::integer_default(), AgentValue::Integer(0));
1402        assert_eq!(AgentValue::number_default(), AgentValue::Number(0.0));
1403        assert_eq!(
1404            AgentValue::string_default(),
1405            AgentValue::String(Arc::new(String::new()))
1406        );
1407        assert_eq!(
1408            AgentValue::array_default(),
1409            AgentValue::Array(Vector::new())
1410        );
1411        assert_eq!(
1412            AgentValue::object_default(),
1413            AgentValue::Object(AgentValueMap::new())
1414        );
1415
1416        #[cfg(feature = "image")]
1417        {
1418            assert_eq!(
1419                AgentValue::image_default(),
1420                AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1))
1421            );
1422        }
1423    }
1424
1425    #[test]
1426    fn test_to_json() {
1427        // Test to_json
1428        let unit = AgentValue::unit();
1429        assert_eq!(unit.to_json(), json!(null));
1430
1431        let boolean = AgentValue::boolean(true);
1432        assert_eq!(boolean.to_json(), json!(true));
1433
1434        let integer = AgentValue::integer(42);
1435        assert_eq!(integer.to_json(), json!(42));
1436
1437        let number = AgentValue::number(3.14);
1438        assert_eq!(number.to_json(), json!(3.14));
1439
1440        let string = AgentValue::string("hello");
1441        assert_eq!(string.to_json(), json!("hello"));
1442
1443        let array = AgentValue::array(vector![AgentValue::integer(1), AgentValue::string("test")]);
1444        assert_eq!(array.to_json(), json!([1, "test"]));
1445
1446        let obj = AgentValue::object(hashmap! {
1447                "key1".to_string() => AgentValue::string("string1"),
1448                "key2".to_string() => AgentValue::integer(2),
1449        });
1450        assert_eq!(obj.to_json(), json!({"key1": "string1", "key2": 2}));
1451
1452        #[cfg(feature = "image")]
1453        {
1454            let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
1455            assert_eq!(
1456                img.to_json(),
1457                json!(
1458                    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg=="
1459                )
1460            );
1461        }
1462
1463        let msg = AgentValue::message(Message::user("hello".to_string()));
1464        assert_eq!(
1465            msg.to_json(),
1466            json!({
1467                "role": "user",
1468                "content": "hello",
1469            })
1470        );
1471    }
1472
1473    #[test]
1474    fn test_agent_value_serialization() {
1475        // Test Null serialization
1476        {
1477            let null = AgentValue::Unit;
1478            assert_eq!(serde_json::to_string(&null).unwrap(), "null");
1479        }
1480
1481        // Test Boolean serialization
1482        {
1483            let boolean_t = AgentValue::boolean(true);
1484            assert_eq!(serde_json::to_string(&boolean_t).unwrap(), "true");
1485
1486            let boolean_f = AgentValue::boolean(false);
1487            assert_eq!(serde_json::to_string(&boolean_f).unwrap(), "false");
1488        }
1489
1490        // Test Integer serialization
1491        {
1492            let integer = AgentValue::integer(42);
1493            assert_eq!(serde_json::to_string(&integer).unwrap(), "42");
1494        }
1495
1496        // Test Number serialization
1497        {
1498            let num = AgentValue::number(3.14);
1499            assert_eq!(serde_json::to_string(&num).unwrap(), "3.14");
1500
1501            let num = AgentValue::number(3.0);
1502            assert_eq!(serde_json::to_string(&num).unwrap(), "3.0");
1503        }
1504
1505        // Test String serialization
1506        {
1507            let s = AgentValue::string("Hello, world!");
1508            assert_eq!(serde_json::to_string(&s).unwrap(), "\"Hello, world!\"");
1509
1510            let s = AgentValue::string("hello\nworld\n\n");
1511            assert_eq!(serde_json::to_string(&s).unwrap(), r#""hello\nworld\n\n""#);
1512        }
1513
1514        // Test Image serialization
1515        #[cfg(feature = "image")]
1516        {
1517            let img = AgentValue::image(PhotonImage::new(vec![0u8; 4], 1, 1));
1518            assert_eq!(
1519                serde_json::to_string(&img).unwrap(),
1520                r#""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg==""#
1521            );
1522        }
1523
1524        // Test Arc Image serialization
1525        #[cfg(feature = "image")]
1526        {
1527            let img = AgentValue::image_arc(Arc::new(PhotonImage::new(vec![0u8; 4], 1, 1)));
1528            assert_eq!(
1529                serde_json::to_string(&img).unwrap(),
1530                r#""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg==""#
1531            );
1532        }
1533
1534        // Test Array serialization
1535        {
1536            let array = AgentValue::array(vector![
1537                AgentValue::integer(1),
1538                AgentValue::string("test"),
1539                AgentValue::object(hashmap! {
1540                        "key1".to_string() => AgentValue::string("test"),
1541                        "key2".to_string() => AgentValue::integer(2),
1542                }),
1543            ]);
1544            assert_eq!(
1545                serde_json::to_string(&array).unwrap(),
1546                r#"[1,"test",{"key1":"test","key2":2}]"#
1547            );
1548        }
1549
1550        // Test Object serialization
1551        {
1552            let obj = AgentValue::object(hashmap! {
1553                    "key1".to_string() => AgentValue::string("test"),
1554                    "key2".to_string() => AgentValue::integer(3),
1555            });
1556            assert_eq!(
1557                serde_json::to_string(&obj).unwrap(),
1558                r#"{"key1":"test","key2":3}"#
1559            );
1560        }
1561    }
1562
1563    #[test]
1564    fn test_agent_value_deserialization() {
1565        // Test Null deserialization
1566        {
1567            let deserialized: AgentValue = serde_json::from_str("null").unwrap();
1568            assert_eq!(deserialized, AgentValue::Unit);
1569        }
1570
1571        // Test Boolean deserialization
1572        {
1573            let deserialized: AgentValue = serde_json::from_str("false").unwrap();
1574            assert_eq!(deserialized, AgentValue::boolean(false));
1575
1576            let deserialized: AgentValue = serde_json::from_str("true").unwrap();
1577            assert_eq!(deserialized, AgentValue::boolean(true));
1578        }
1579
1580        // Test Integer deserialization
1581        {
1582            let deserialized: AgentValue = serde_json::from_str("123").unwrap();
1583            assert_eq!(deserialized, AgentValue::integer(123));
1584        }
1585
1586        // Test Number deserialization
1587        {
1588            let deserialized: AgentValue = serde_json::from_str("3.14").unwrap();
1589            assert_eq!(deserialized, AgentValue::number(3.14));
1590
1591            let deserialized: AgentValue = serde_json::from_str("3.0").unwrap();
1592            assert_eq!(deserialized, AgentValue::number(3.0));
1593        }
1594
1595        // Test String deserialization
1596        {
1597            let deserialized: AgentValue = serde_json::from_str("\"Hello, world!\"").unwrap();
1598            assert_eq!(deserialized, AgentValue::string("Hello, world!"));
1599
1600            let deserialized: AgentValue = serde_json::from_str(r#""hello\nworld\n\n""#).unwrap();
1601            assert_eq!(deserialized, AgentValue::string("hello\nworld\n\n"));
1602        }
1603
1604        // Test Image deserialization
1605        #[cfg(feature = "image")]
1606        {
1607            let deserialized: AgentValue = serde_json::from_str(
1608                r#""data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAEElEQVR4AQEFAPr/AAAAAAAABQABZHiVOAAAAABJRU5ErkJggg==""#,
1609            )
1610            .unwrap();
1611            assert!(matches!(deserialized, AgentValue::Image(_)));
1612        }
1613
1614        // Test Array deserialization
1615        {
1616            let deserialized: AgentValue =
1617                serde_json::from_str(r#"[1,"test",{"key1":"test","key2":2}]"#).unwrap();
1618            assert!(matches!(deserialized, AgentValue::Array(_)));
1619            if let AgentValue::Array(arr) = deserialized {
1620                assert_eq!(arr.len(), 3, "Array length mismatch after serialization");
1621                assert_eq!(arr[0], AgentValue::integer(1));
1622                assert_eq!(arr[1], AgentValue::string("test"));
1623                assert_eq!(
1624                    arr[2],
1625                    AgentValue::object(hashmap! {
1626                            "key1".to_string() => AgentValue::string("test"),
1627                            "key2".to_string() => AgentValue::integer(2),
1628                    })
1629                );
1630            }
1631        }
1632
1633        // Test Object deserialization
1634        {
1635            let deserialized: AgentValue =
1636                serde_json::from_str(r#"{"key1":"test","key2":3}"#).unwrap();
1637            assert_eq!(
1638                deserialized,
1639                AgentValue::object(hashmap! {
1640                        "key1".to_string() => AgentValue::string("test"),
1641                        "key2".to_string() => AgentValue::integer(3),
1642                })
1643            );
1644        }
1645    }
1646
1647    #[test]
1648    fn test_agent_value_into() {
1649        // Test From implementations for AgentValue
1650        let from_unit: AgentValue = ().into();
1651        assert_eq!(from_unit, AgentValue::Unit);
1652
1653        let from_bool: AgentValue = true.into();
1654        assert_eq!(from_bool, AgentValue::Boolean(true));
1655
1656        let from_i32: AgentValue = 42i32.into();
1657        assert_eq!(from_i32, AgentValue::Integer(42));
1658
1659        let from_i64: AgentValue = 100i64.into();
1660        assert_eq!(from_i64, AgentValue::Integer(100));
1661
1662        let from_f64: AgentValue = 3.14f64.into();
1663        assert_eq!(from_f64, AgentValue::Number(3.14));
1664
1665        let from_string: AgentValue = "hello".to_string().into();
1666        assert_eq!(
1667            from_string,
1668            AgentValue::String(Arc::new("hello".to_string()))
1669        );
1670
1671        let from_str: AgentValue = "world".into();
1672        assert_eq!(from_str, AgentValue::String(Arc::new("world".to_string())));
1673    }
1674
1675    #[test]
1676    fn test_serialize_deserialize_roundtrip() {
1677        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1678        struct TestStruct {
1679            name: String,
1680            age: i64,
1681            active: bool,
1682        }
1683
1684        let test_data = TestStruct {
1685            name: "Alice".to_string(),
1686            age: 30,
1687            active: true,
1688        };
1689
1690        // Test AgentData roundtrip
1691        let agent_data = AgentValue::from_serialize(&test_data).unwrap();
1692        assert_eq!(agent_data.get_str("name"), Some("Alice"));
1693        assert_eq!(agent_data.get_i64("age"), Some(30));
1694        assert_eq!(agent_data.get_bool("active"), Some(true));
1695
1696        let restored: TestStruct = agent_data.to_deserialize().unwrap();
1697        assert_eq!(restored, test_data);
1698    }
1699
1700    #[test]
1701    fn test_serialize_deserialize_nested() {
1702        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1703        struct Address {
1704            street: String,
1705            city: String,
1706            zip: String,
1707        }
1708
1709        #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
1710        struct Person {
1711            name: String,
1712            age: i64,
1713            address: Address,
1714            tags: Vec<String>,
1715        }
1716
1717        let person = Person {
1718            name: "Bob".to_string(),
1719            age: 25,
1720            address: Address {
1721                street: "123 Main St".to_string(),
1722                city: "Springfield".to_string(),
1723                zip: "12345".to_string(),
1724            },
1725            tags: vec!["developer".to_string(), "rust".to_string()],
1726        };
1727
1728        // Test AgentData roundtrip with nested structures
1729        let agent_data = AgentValue::from_serialize(&person).unwrap();
1730        assert_eq!(agent_data.get_str("name"), Some("Bob"));
1731
1732        let address = agent_data.get_object("address").unwrap();
1733        assert_eq!(
1734            address.get("city").and_then(|v| v.as_str()),
1735            Some("Springfield")
1736        );
1737
1738        let tags = agent_data.get_array("tags").unwrap();
1739        assert_eq!(tags.len(), 2);
1740        assert_eq!(tags[0].as_str(), Some("developer"));
1741
1742        let restored: Person = agent_data.to_deserialize().unwrap();
1743        assert_eq!(restored, person);
1744    }
1745
1746    #[test]
1747    fn test_agent_value_conversions() {
1748        // Boolean
1749        assert_eq!(AgentValue::boolean(true).to_boolean(), Some(true));
1750        assert_eq!(AgentValue::integer(1).to_boolean(), Some(true));
1751        assert_eq!(AgentValue::integer(0).to_boolean(), Some(false));
1752        assert_eq!(AgentValue::number(1.0).to_boolean(), Some(true));
1753        assert_eq!(AgentValue::number(0.0).to_boolean(), Some(false));
1754        assert_eq!(AgentValue::string("true").to_boolean(), Some(true));
1755        assert_eq!(AgentValue::string("false").to_boolean(), Some(false));
1756        assert_eq!(AgentValue::unit().to_boolean(), None);
1757
1758        let bool_arr = AgentValue::array(vector![AgentValue::integer(1), AgentValue::integer(0)]);
1759        let converted = bool_arr.to_boolean_value().unwrap();
1760        assert!(converted.is_array());
1761        let arr = converted.as_array().unwrap();
1762        assert_eq!(arr[0], AgentValue::boolean(true));
1763        assert_eq!(arr[1], AgentValue::boolean(false));
1764
1765        // Integer
1766        assert_eq!(AgentValue::integer(42).to_integer(), Some(42));
1767        assert_eq!(AgentValue::boolean(true).to_integer(), Some(1));
1768        assert_eq!(AgentValue::boolean(false).to_integer(), Some(0));
1769        assert_eq!(AgentValue::number(42.9).to_integer(), Some(42));
1770        assert_eq!(AgentValue::string("42").to_integer(), Some(42));
1771        assert_eq!(AgentValue::unit().to_integer(), None);
1772
1773        let int_arr =
1774            AgentValue::array(vector![AgentValue::string("10"), AgentValue::boolean(true)]);
1775        let converted = int_arr.to_integer_value().unwrap();
1776        assert!(converted.is_array());
1777        let arr = converted.as_array().unwrap();
1778        assert_eq!(arr[0], AgentValue::integer(10));
1779        assert_eq!(arr[1], AgentValue::integer(1));
1780
1781        // Number
1782        assert_eq!(AgentValue::number(3.14).to_number(), Some(3.14));
1783        assert_eq!(AgentValue::integer(42).to_number(), Some(42.0));
1784        assert_eq!(AgentValue::boolean(true).to_number(), Some(1.0));
1785        assert_eq!(AgentValue::string("3.14").to_number(), Some(3.14));
1786        assert_eq!(AgentValue::unit().to_number(), None);
1787
1788        let num_arr =
1789            AgentValue::array(vector![AgentValue::integer(10), AgentValue::string("0.5")]);
1790        let converted = num_arr.to_number_value().unwrap();
1791        assert!(converted.is_array());
1792        let arr = converted.as_array().unwrap();
1793        assert_eq!(arr[0], AgentValue::number(10.0));
1794        assert_eq!(arr[1], AgentValue::number(0.5));
1795
1796        // String
1797        assert_eq!(
1798            AgentValue::string("hello").to_string(),
1799            Some("hello".to_string())
1800        );
1801        assert_eq!(AgentValue::integer(42).to_string(), Some("42".to_string()));
1802        assert_eq!(
1803            AgentValue::boolean(true).to_string(),
1804            Some("true".to_string())
1805        );
1806        assert_eq!(
1807            AgentValue::number(3.14).to_string(),
1808            Some("3.14".to_string())
1809        );
1810        assert_eq!(
1811            AgentValue::message(Message::user("content".to_string())).to_string(),
1812            Some("content".to_string())
1813        );
1814        assert_eq!(AgentValue::unit().to_string(), None);
1815
1816        let str_arr =
1817            AgentValue::array(vector![AgentValue::integer(42), AgentValue::boolean(false)]);
1818        let converted = str_arr.to_string_value().unwrap();
1819        assert!(converted.is_array());
1820        let arr = converted.as_array().unwrap();
1821        assert_eq!(arr[0], AgentValue::string("42"));
1822        assert_eq!(arr[1], AgentValue::string("false"));
1823    }
1824}