Skip to main content

objectiveai_sdk/functions/expression/
special.rs

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