objectiveai_sdk/agent/completions/message/
simple_content.rs1use crate::functions;
4use functions::expression::{
5 ExpressionError, FromStarlarkValue, WithExpression,
6};
7use serde::{Deserialize, Serialize};
8use starlark::values::dict::DictRef as StarlarkDictRef;
9use starlark::values::{UnpackValue, Value as StarlarkValue};
10use schemars::JsonSchema;
11
12#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
14#[serde(untagged)]
15#[schemars(rename = "agent.completions.message.SimpleContent")]
16pub enum SimpleContent {
17 #[schemars(title = "Text")]
19 Text(String),
20 #[schemars(title = "Parts")]
22 Parts(Vec<SimpleContentPart>),
23}
24
25impl SimpleContent {
26 pub fn push(&mut self, other: &SimpleContent) {
27 match (&mut *self, other) {
28 (SimpleContent::Text(self_text), SimpleContent::Text(other_text)) => {
29 self_text.push_str(&other_text);
30 }
31 (SimpleContent::Text(self_text), SimpleContent::Parts(other_parts)) => {
32 let mut parts = Vec::with_capacity(1 + other_parts.len());
33 parts.push(SimpleContentPart::Text {
34 text: std::mem::take(self_text),
35 });
36 parts.extend(other_parts.iter().cloned());
37 *self = SimpleContent::Parts(parts);
38 }
39 (SimpleContent::Parts(self_parts), SimpleContent::Text(other_text)) => {
40 self_parts.push(SimpleContentPart::Text {
41 text: other_text.clone(),
42 });
43 }
44 (SimpleContent::Parts(self_parts), SimpleContent::Parts(other_parts)) => {
45 self_parts.extend(other_parts.iter().cloned());
46 }
47 }
48 }
49
50 pub fn prepare(&mut self) {
52 match self {
53 SimpleContent::Text(_) => {}
54 SimpleContent::Parts(parts) => {
55 let text_len = parts
56 .iter()
57 .map(|part| match part {
58 SimpleContentPart::Text { text } => text.len(),
59 })
60 .sum();
61 let mut text = String::with_capacity(text_len);
62 for part in parts {
63 match part {
64 SimpleContentPart::Text { text: part_text } => {
65 text.push_str(&part_text);
66 }
67 }
68 }
69 *self = SimpleContent::Text(text)
70 }
71 }
72 }
73}
74
75impl FromStarlarkValue for SimpleContent {
76 fn from_starlark_value(
77 value: &StarlarkValue,
78 ) -> Result<Self, ExpressionError> {
79 if let Ok(Some(s)) = <&str as UnpackValue>::unpack_value(*value) {
80 return Ok(SimpleContent::Text(s.to_owned()));
81 }
82 let parts = Vec::<SimpleContentPart>::from_starlark_value(value)?;
83 Ok(SimpleContent::Parts(parts))
84 }
85}
86
87#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
89#[serde(untagged)]
90#[schemars(rename = "agent.completions.message.SimpleContentExpression")]
91pub enum SimpleContentExpression {
92 #[schemars(title = "Text")]
94 Text(String),
95 #[schemars(title = "Parts")]
97 Parts(
98 Vec<functions::expression::WithExpression<SimpleContentPartExpression>>,
99 ),
100}
101
102impl SimpleContentExpression {
103 pub fn compile(
105 self,
106 params: &functions::expression::Params,
107 ) -> Result<SimpleContent, functions::expression::ExpressionError> {
108 match self {
109 SimpleContentExpression::Text(text) => {
110 Ok(SimpleContent::Text(text))
111 }
112 SimpleContentExpression::Parts(parts) => {
113 let mut compiled_parts = Vec::with_capacity(parts.len());
114 for part in parts {
115 match part.compile_one_or_many(params)? {
116 functions::expression::OneOrMany::One(one_part) => {
117 compiled_parts.push(one_part.compile(params)?);
118 }
119 functions::expression::OneOrMany::Many(many_parts) => {
120 for part in many_parts {
121 compiled_parts.push(part.compile(params)?);
122 }
123 }
124 }
125 }
126 Ok(SimpleContent::Parts(compiled_parts))
127 }
128 }
129 }
130}
131
132impl FromStarlarkValue for SimpleContentExpression {
133 fn from_starlark_value(
134 value: &StarlarkValue,
135 ) -> Result<Self, ExpressionError> {
136 if let Ok(Some(s)) = <&str as UnpackValue>::unpack_value(*value) {
137 return Ok(SimpleContentExpression::Text(s.to_owned()));
138 }
139 let parts = Vec::<WithExpression<SimpleContentPartExpression>>::from_starlark_value(value)?;
140 Ok(SimpleContentExpression::Parts(parts))
141 }
142}
143
144#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
146#[serde(tag = "type", rename_all = "snake_case")]
147#[schemars(rename = "agent.completions.message.SimpleContentPart")]
148pub enum SimpleContentPart {
149 Text {
151 text: String,
153 },
154}
155
156impl FromStarlarkValue for SimpleContentPart {
157 fn from_starlark_value(
158 value: &StarlarkValue,
159 ) -> Result<Self, ExpressionError> {
160 let dict = StarlarkDictRef::from_value(*value).ok_or_else(|| {
161 ExpressionError::StarlarkConversionError(
162 "SimpleContentPart: expected dict".into(),
163 )
164 })?;
165 for (k, v) in dict.iter() {
166 if let Ok(Some("text")) = <&str as UnpackValue>::unpack_value(k) {
167 return Ok(SimpleContentPart::Text {
168 text: String::from_starlark_value(&v)?,
169 });
170 }
171 }
172 Err(ExpressionError::StarlarkConversionError(
173 "SimpleContentPart: missing text".into(),
174 ))
175 }
176}
177
178#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
180#[serde(tag = "type", rename_all = "snake_case")]
181#[schemars(rename = "agent.completions.message.SimpleContentPartExpression")]
182pub enum SimpleContentPartExpression {
183 Text {
185 text: functions::expression::WithExpression<String>,
187 },
188}
189
190impl SimpleContentPartExpression {
191 pub fn compile(
193 self,
194 params: &functions::expression::Params,
195 ) -> Result<SimpleContentPart, functions::expression::ExpressionError> {
196 match self {
197 SimpleContentPartExpression::Text { text } => {
198 let text = text.compile_one(params)?;
199 Ok(SimpleContentPart::Text { text })
200 }
201 }
202 }
203}
204
205impl FromStarlarkValue for SimpleContentPartExpression {
206 fn from_starlark_value(
207 value: &StarlarkValue,
208 ) -> Result<Self, ExpressionError> {
209 let part = SimpleContentPart::from_starlark_value(value)?;
210 match part {
211 SimpleContentPart::Text { text } => {
212 Ok(SimpleContentPartExpression::Text {
213 text: WithExpression::Value(text),
214 })
215 }
216 }
217 }
218}
219
220crate::functions::expression::impl_from_special_unsupported!(
221 SimpleContentExpression,
222 SimpleContentPartExpression,
223);