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#[derive(Debug, Clone, Default)]
24pub enum AgentValue {
25 #[default]
27 Unit,
28
29 Boolean(bool),
31
32 Integer(i64),
34
35 Number(f64),
37
38 String(Arc<String>),
40
41 #[cfg(feature = "image")]
43 Image(Arc<PhotonImage>),
44
45 Array(Vector<AgentValue>),
47
48 Object(HashMap<String, AgentValue>),
50
51 Tensor(Arc<Vec<f32>>),
53
54 #[cfg(feature = "llm")]
56 Message(Arc<Message>),
57
58 Error(Arc<AgentError>),
60}
61
62pub type AgentValueMap<S, T> = HashMap<S, T>;
64
65impl AgentValue {
66 pub fn unit() -> Self {
68 AgentValue::Unit
69 }
70
71 pub fn boolean(value: bool) -> Self {
73 AgentValue::Boolean(value)
74 }
75
76 pub fn integer(value: i64) -> Self {
78 AgentValue::Integer(value)
79 }
80
81 pub fn number(value: f64) -> Self {
83 AgentValue::Number(value)
84 }
85
86 pub fn string(value: impl Into<String>) -> Self {
88 AgentValue::String(Arc::new(value.into()))
89 }
90
91 #[cfg(feature = "image")]
93 pub fn image(value: PhotonImage) -> Self {
94 AgentValue::Image(Arc::new(value))
95 }
96
97 #[cfg(feature = "image")]
99 pub fn image_arc(value: Arc<PhotonImage>) -> Self {
100 AgentValue::Image(value)
101 }
102
103 pub fn array(value: Vector<AgentValue>) -> Self {
105 AgentValue::Array(value)
106 }
107
108 pub fn object(value: AgentValueMap<String, AgentValue>) -> Self {
110 AgentValue::Object(value)
111 }
112
113 pub fn tensor(value: Vec<f32>) -> Self {
115 AgentValue::Tensor(Arc::new(value))
116 }
117
118 #[cfg(feature = "llm")]
120 pub fn message(value: Message) -> Self {
121 AgentValue::Message(Arc::new(value))
122 }
123
124 pub fn boolean_default() -> Self {
126 AgentValue::Boolean(false)
127 }
128
129 pub fn integer_default() -> Self {
131 AgentValue::Integer(0)
132 }
133
134 pub fn number_default() -> Self {
136 AgentValue::Number(0.0)
137 }
138
139 pub fn string_default() -> Self {
141 AgentValue::String(Arc::new(String::new()))
142 }
143
144 #[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 pub fn array_default() -> Self {
152 AgentValue::Array(Vector::new())
153 }
154
155 pub fn object_default() -> Self {
157 AgentValue::Object(HashMap::new())
158 }
159
160 pub fn tensor_default() -> Self {
162 AgentValue::Tensor(Arc::new(Vec::new()))
163 }
164
165 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 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, }
254 }
255
256 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 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 pub fn is_unit(&self) -> bool {
274 matches!(self, AgentValue::Unit)
275 }
276
277 pub fn is_boolean(&self) -> bool {
279 matches!(self, AgentValue::Boolean(_))
280 }
281
282 pub fn is_integer(&self) -> bool {
284 matches!(self, AgentValue::Integer(_))
285 }
286
287 pub fn is_number(&self) -> bool {
289 matches!(self, AgentValue::Number(_))
290 }
291
292 pub fn is_string(&self) -> bool {
294 matches!(self, AgentValue::String(_))
295 }
296
297 #[cfg(feature = "image")]
299 pub fn is_image(&self) -> bool {
300 matches!(self, AgentValue::Image(_))
301 }
302
303 pub fn is_array(&self) -> bool {
305 matches!(self, AgentValue::Array(_))
306 }
307
308 pub fn is_object(&self) -> bool {
310 matches!(self, AgentValue::Object(_))
311 }
312
313 pub fn is_tensor(&self) -> bool {
315 matches!(self, AgentValue::Tensor(_))
316 }
317
318 #[cfg(feature = "llm")]
320 pub fn is_message(&self) -> bool {
321 matches!(self, AgentValue::Message(_))
322 }
323
324 pub fn as_bool(&self) -> Option<bool> {
328 match self {
329 AgentValue::Boolean(b) => Some(*b),
330 _ => None,
331 }
332 }
333
334 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 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 pub fn as_str(&self) -> Option<&str> {
354 match self {
355 AgentValue::String(s) => Some(s),
356 _ => None,
357 }
358 }
359
360 #[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 #[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 #[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 #[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 #[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 #[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 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 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 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 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 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 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 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 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 #[cfg(feature = "llm")]
540 pub fn to_message(&self) -> Option<Message> {
541 Message::try_from(self.clone()).ok()
542 }
543
544 #[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 pub fn as_object(&self) -> Option<&AgentValueMap<String, AgentValue>> {
569 match self {
570 AgentValue::Object(o) => Some(o),
571 _ => None,
572 }
573 }
574
575 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 pub fn into_object(self) -> Option<AgentValueMap<String, AgentValue>> {
585 match self {
586 AgentValue::Object(o) => Some(o),
587 _ => None,
588 }
589 }
590
591 pub fn as_array(&self) -> Option<&Vector<AgentValue>> {
593 match self {
594 AgentValue::Array(a) => Some(a),
595 _ => None,
596 }
597 }
598
599 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 pub fn into_array(self) -> Option<Vector<AgentValue>> {
609 match self {
610 AgentValue::Array(a) => Some(a),
611 _ => None,
612 }
613 }
614
615 pub fn as_tensor(&self) -> Option<&Vec<f32>> {
617 match self {
618 AgentValue::Tensor(t) => Some(t),
619 _ => None,
620 }
621 }
622
623 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 pub fn into_tensor(self) -> Option<Arc<Vec<f32>>> {
633 match self {
634 AgentValue::Tensor(t) => Some(t),
635 _ => None,
636 }
637 }
638
639 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 pub fn get(&self, key: &str) -> Option<&AgentValue> {
653 self.as_object().and_then(|o| o.get(key))
654 }
655
656 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 pub fn get_bool(&self, key: &str) -> Option<bool> {
663 self.get(key).and_then(|v| v.as_bool())
664 }
665
666 pub fn get_i64(&self, key: &str) -> Option<i64> {
668 self.get(key).and_then(|v| v.as_i64())
669 }
670
671 pub fn get_f64(&self, key: &str) -> Option<f64> {
673 self.get(key).and_then(|v| v.as_f64())
674 }
675
676 pub fn get_str(&self, key: &str) -> Option<&str> {
678 self.get(key).and_then(|v| v.as_str())
679 }
680
681 #[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 #[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 pub fn get_object(&self, key: &str) -> Option<&AgentValueMap<String, AgentValue>> {
695 self.get(key).and_then(|v| v.as_object())
696 }
697
698 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 pub fn get_array(&self, key: &str) -> Option<&Vector<AgentValue>> {
705 self.get(key).and_then(|v| v.as_array())
706 }
707
708 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 pub fn get_tensor(&self, key: &str) -> Option<&Vec<f32>> {
715 self.get(key).and_then(|v| v.as_tensor())
716 }
717
718 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 #[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 #[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 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 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(), }
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
907impl 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
919impl 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
931impl From<AgentError> for AgentValue {
933 fn from(value: AgentError) -> Self {
934 AgentValue::Error(Arc::new(value))
935 }
936}
937
938impl 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 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 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 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 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 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)); 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 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 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 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 {
1513 let null = AgentValue::Unit;
1514 assert_eq!(serde_json::to_string(&null).unwrap(), "null");
1515 }
1516
1517 {
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 {
1528 let integer = AgentValue::integer(42);
1529 assert_eq!(serde_json::to_string(&integer).unwrap(), "42");
1530 }
1531
1532 {
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 {
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 #[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 #[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 {
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 {
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 {
1603 let deserialized: AgentValue = serde_json::from_str("null").unwrap();
1604 assert_eq!(deserialized, AgentValue::Unit);
1605 }
1606
1607 {
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 {
1618 let deserialized: AgentValue = serde_json::from_str("123").unwrap();
1619 assert_eq!(deserialized, AgentValue::integer(123));
1620 }
1621
1622 {
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 {
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 #[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 {
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 {
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 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 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 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 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 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 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 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}