Skip to main content

objectiveai_sdk/functions/expression/
special.rs

1//! Special predefined expression variants.
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6/// Predefined expression behaviors that require no user-authored code.
7#[derive(
8    Debug,
9    Clone,
10    PartialEq,
11    Serialize,
12    Deserialize,
13    JsonSchema,
14    arbitrary::Arbitrary,
15)]
16#[serde(rename_all = "snake_case")]
17#[schemars(rename = "functions.expression.Special")]
18pub enum Special {
19    /// Returns the params input as-is.
20    #[schemars(title = "Input")]
21    Input,
22    /// Returns the params output as-is.
23    #[schemars(title = "Output")]
24    Output,
25    /// L1-normalizes the output. Scalar/Err pass through.
26    /// Vector: L1 normalize. Vectors: L1 normalize each.
27    #[schemars(title = "TaskOutputL1Normalized")]
28    TaskOutputL1Normalized,
29    /// Weighted sum of the output. Vector → Scalar. Vectors → Vector.
30    #[schemars(title = "TaskOutputWeightedSum")]
31    TaskOutputWeightedSum,
32    /// Returns the length of input['items'] as u64
33    #[schemars(title = "InputItemsOutputLength")]
34    InputItemsOutputLength,
35    /// Splits an input containing items and optionally context into multiple inputs
36    #[schemars(title = "InputItemsOptionalContextSplit")]
37    InputItemsOptionalContextSplit,
38    /// Merges multiple inputs containing items and optionally context into a single input
39    #[schemars(title = "InputItemsOptionalContextMerge")]
40    InputItemsOptionalContextMerge,
41}
42
43/// Trait for types that can be produced from a [`Special`] expression variant.
44pub trait FromSpecial: Sized {
45    fn from_special(
46        special: &Special,
47        params: &super::Params,
48    ) -> Result<Self, super::ExpressionError>;
49}
50
51/// Macro for types that never support any Special variant.
52macro_rules! impl_from_special_unsupported {
53    ($($ty:ty),+ $(,)?) => {
54        $(
55            impl $crate::functions::expression::FromSpecial for $ty {
56                fn from_special(
57                    _special: &$crate::functions::expression::Special,
58                    _params: &$crate::functions::expression::Params,
59                ) -> Result<Self, $crate::functions::expression::ExpressionError> {
60                    Err($crate::functions::expression::ExpressionError::UnsupportedSpecial)
61                }
62            }
63        )+
64    };
65}
66pub(crate) use impl_from_special_unsupported;
67
68impl_from_special_unsupported!(bool, i64, String);
69
70impl<K, V, S> FromSpecial for indexmap::IndexMap<K, V, S>
71where
72    K: Sized,
73    V: Sized,
74    S: Sized,
75{
76    fn from_special(
77        _special: &Special,
78        _params: &super::Params,
79    ) -> Result<Self, super::ExpressionError> {
80        Err(super::ExpressionError::UnsupportedSpecial)
81    }
82}
83
84impl FromSpecial for u64 {
85    fn from_special(
86        special: &Special,
87        params: &super::Params,
88    ) -> Result<Self, super::ExpressionError> {
89        match special {
90            Special::InputItemsOutputLength => {
91                let input = match params {
92                    super::Params::Owned(o) => &o.input,
93                    super::Params::Ref(r) => r.input,
94                };
95                match input {
96                    super::InputValue::Object(map) => match map.get("items") {
97                        Some(super::InputValue::Array(arr)) => {
98                            Ok(arr.len() as u64)
99                        }
100                        _ => Err(super::ExpressionError::UnsupportedSpecial),
101                    },
102                    _ => Err(super::ExpressionError::UnsupportedSpecial),
103                }
104            }
105            _ => Err(super::ExpressionError::UnsupportedSpecial),
106        }
107    }
108}
109
110impl<T: FromSpecial> FromSpecial for super::OneOrMany<T> {
111    fn from_special(
112        special: &Special,
113        params: &super::Params,
114    ) -> Result<Self, super::ExpressionError> {
115        Ok(super::OneOrMany::One(T::from_special(special, params)?))
116    }
117}
118
119impl<T: FromSpecial> FromSpecial for Option<T> {
120    fn from_special(
121        special: &Special,
122        params: &super::Params,
123    ) -> Result<Self, super::ExpressionError> {
124        Ok(Some(T::from_special(special, params)?))
125    }
126}