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