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