use crate::functions;
use functions::expression::{
ExpressionError, FromStarlarkValue, WithExpression,
};
use serde::{Deserialize, Serialize};
use starlark::values::dict::DictRef as StarlarkDictRef;
use starlark::values::{UnpackValue, Value as StarlarkValue};
use schemars::JsonSchema;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
#[serde(untagged)]
#[schemars(rename = "agent.completions.message.SimpleContent")]
pub enum SimpleContent {
#[schemars(title = "Text")]
Text(String),
#[schemars(title = "Parts")]
Parts(Vec<SimpleContentPart>),
}
impl SimpleContent {
pub fn push(&mut self, other: &SimpleContent) {
match (&mut *self, other) {
(SimpleContent::Text(self_text), SimpleContent::Text(other_text)) => {
self_text.push_str(&other_text);
}
(SimpleContent::Text(self_text), SimpleContent::Parts(other_parts)) => {
let mut parts = Vec::with_capacity(1 + other_parts.len());
parts.push(SimpleContentPart::Text {
text: std::mem::take(self_text),
});
parts.extend(other_parts.iter().cloned());
*self = SimpleContent::Parts(parts);
}
(SimpleContent::Parts(self_parts), SimpleContent::Text(other_text)) => {
self_parts.push(SimpleContentPart::Text {
text: other_text.clone(),
});
}
(SimpleContent::Parts(self_parts), SimpleContent::Parts(other_parts)) => {
self_parts.extend(other_parts.iter().cloned());
}
}
}
pub fn prepare(&mut self) {
match self {
SimpleContent::Text(_) => {}
SimpleContent::Parts(parts) => {
let text_len = parts
.iter()
.map(|part| match part {
SimpleContentPart::Text { text } => text.len(),
})
.sum();
let mut text = String::with_capacity(text_len);
for part in parts {
match part {
SimpleContentPart::Text { text: part_text } => {
text.push_str(&part_text);
}
}
}
*self = SimpleContent::Text(text)
}
}
}
}
impl FromStarlarkValue for SimpleContent {
fn from_starlark_value(
value: &StarlarkValue,
) -> Result<Self, ExpressionError> {
if let Ok(Some(s)) = <&str as UnpackValue>::unpack_value(*value) {
return Ok(SimpleContent::Text(s.to_owned()));
}
let parts = Vec::<SimpleContentPart>::from_starlark_value(value)?;
Ok(SimpleContent::Parts(parts))
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
#[serde(untagged)]
#[schemars(rename = "agent.completions.message.SimpleContentExpression")]
pub enum SimpleContentExpression {
#[schemars(title = "Text")]
Text(String),
#[schemars(title = "Parts")]
Parts(
Vec<functions::expression::WithExpression<SimpleContentPartExpression>>,
),
}
impl SimpleContentExpression {
pub fn compile(
self,
params: &functions::expression::Params,
) -> Result<SimpleContent, functions::expression::ExpressionError> {
match self {
SimpleContentExpression::Text(text) => {
Ok(SimpleContent::Text(text))
}
SimpleContentExpression::Parts(parts) => {
let mut compiled_parts = Vec::with_capacity(parts.len());
for part in parts {
match part.compile_one_or_many(params)? {
functions::expression::OneOrMany::One(one_part) => {
compiled_parts.push(one_part.compile(params)?);
}
functions::expression::OneOrMany::Many(many_parts) => {
for part in many_parts {
compiled_parts.push(part.compile(params)?);
}
}
}
}
Ok(SimpleContent::Parts(compiled_parts))
}
}
}
}
impl FromStarlarkValue for SimpleContentExpression {
fn from_starlark_value(
value: &StarlarkValue,
) -> Result<Self, ExpressionError> {
if let Ok(Some(s)) = <&str as UnpackValue>::unpack_value(*value) {
return Ok(SimpleContentExpression::Text(s.to_owned()));
}
let parts = Vec::<WithExpression<SimpleContentPartExpression>>::from_starlark_value(value)?;
Ok(SimpleContentExpression::Parts(parts))
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
#[serde(tag = "type", rename_all = "snake_case")]
#[schemars(rename = "agent.completions.message.SimpleContentPart")]
pub enum SimpleContentPart {
Text {
text: String,
},
}
impl FromStarlarkValue for SimpleContentPart {
fn from_starlark_value(
value: &StarlarkValue,
) -> Result<Self, ExpressionError> {
let dict = StarlarkDictRef::from_value(*value).ok_or_else(|| {
ExpressionError::StarlarkConversionError(
"SimpleContentPart: expected dict".into(),
)
})?;
for (k, v) in dict.iter() {
if let Ok(Some("text")) = <&str as UnpackValue>::unpack_value(k) {
return Ok(SimpleContentPart::Text {
text: String::from_starlark_value(&v)?,
});
}
}
Err(ExpressionError::StarlarkConversionError(
"SimpleContentPart: missing text".into(),
))
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, JsonSchema, arbitrary::Arbitrary)]
#[serde(tag = "type", rename_all = "snake_case")]
#[schemars(rename = "agent.completions.message.SimpleContentPartExpression")]
pub enum SimpleContentPartExpression {
Text {
text: functions::expression::WithExpression<String>,
},
}
impl SimpleContentPartExpression {
pub fn compile(
self,
params: &functions::expression::Params,
) -> Result<SimpleContentPart, functions::expression::ExpressionError> {
match self {
SimpleContentPartExpression::Text { text } => {
let text = text.compile_one(params)?;
Ok(SimpleContentPart::Text { text })
}
}
}
}
impl FromStarlarkValue for SimpleContentPartExpression {
fn from_starlark_value(
value: &StarlarkValue,
) -> Result<Self, ExpressionError> {
let part = SimpleContentPart::from_starlark_value(value)?;
match part {
SimpleContentPart::Text { text } => {
Ok(SimpleContentPartExpression::Text {
text: WithExpression::Value(text),
})
}
}
}
}
crate::functions::expression::impl_from_special_unsupported!(
SimpleContentExpression,
SimpleContentPartExpression,
);