use crate::{
agent, error,
functions::{self, executions::response},
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
#[schemars(rename = "functions.executions.response.unary.FunctionExecution")]
pub struct FunctionExecution {
pub id: String,
pub tasks: Vec<super::Task>,
pub tasks_errors: bool,
pub reasoning: Option<super::ReasoningSummary>,
pub output: super::super::Output,
pub error: Option<error::ResponseError>,
pub created: u64,
pub function: Option<crate::RemotePath>,
pub profile: Option<crate::RemotePath>,
pub object: super::Object,
pub usage: agent::completions::response::Usage,
}
impl FunctionExecution {
pub fn any_usage(&self) -> bool {
self.usage.any_usage()
}
pub fn normalize_for_tests(&mut self) {
self.id = String::new();
self.created = 0;
self.usage.normalize_for_tests();
for task in &mut self.tasks {
match task {
super::Task::VectorCompletion(vt) => {
vt.index = vt.task_path.last().copied().unwrap_or(0);
vt.inner.normalize_for_tests();
}
super::Task::FunctionExecution(ft) => {
ft.index = ft.task_path.last().copied().unwrap_or(0);
ft.inner.normalize_for_tests();
}
}
}
self.tasks.sort_by_cached_key(|t| t.snapshot_sort_key());
}
}
impl From<response::streaming::FunctionExecutionChunk> for FunctionExecution {
fn from(
response::streaming::FunctionExecutionChunk {
id,
tasks,
tasks_errors,
reasoning,
output,
error,
created,
function,
profile,
object,
usage,
}: response::streaming::FunctionExecutionChunk,
) -> Self {
Self {
id,
tasks: tasks.into_iter().map(super::Task::from).collect(),
tasks_errors: tasks_errors.unwrap_or(false),
reasoning: reasoning.map(super::ReasoningSummary::from),
output: output.unwrap_or(response::Output {
output: functions::expression::TaskOutputOwned::Err {
error: serde_json::Value::Null,
},
}),
error,
created,
function,
profile,
object: object.into(),
usage: usage.unwrap_or_default(),
}
}
}