use rig_compose::{ToolInvocation, ToolInvocationResult};
use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HarnessToolInvocation {
pub name: String,
pub args: Value,
}
impl From<&ToolInvocation> for HarnessToolInvocation {
fn from(value: &ToolInvocation) -> Self {
Self {
name: value.name.clone(),
args: value.args.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HarnessToolResult {
pub invocation: HarnessToolInvocation,
pub output: Value,
}
impl From<&ToolInvocationResult> for HarnessToolResult {
fn from(value: &ToolInvocationResult) -> Self {
Self {
invocation: HarnessToolInvocation::from(&value.invocation),
output: value.output.clone(),
}
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct HarnessRun {
pub schema_version: u32,
pub producer: String,
pub task: String,
pub first_model_output: String,
pub invocations: Vec<HarnessToolInvocation>,
pub dispatch_results: Vec<HarnessToolResult>,
pub final_answer: String,
pub passed_assertions: Vec<String>,
}
impl HarnessRun {
pub const SCHEMA_VERSION: u32 = 1;
#[allow(dead_code)]
pub fn from_native(
producer: impl Into<String>,
task: impl Into<String>,
first_model_output: impl Into<String>,
invocations: &[ToolInvocation],
dispatch_results: &[ToolInvocationResult],
final_answer: impl Into<String>,
passed_assertions: impl IntoIterator<Item = impl Into<String>>,
) -> Self {
Self {
schema_version: Self::SCHEMA_VERSION,
producer: producer.into(),
task: task.into(),
first_model_output: first_model_output.into(),
invocations: invocations
.iter()
.map(HarnessToolInvocation::from)
.collect(),
dispatch_results: dispatch_results
.iter()
.map(HarnessToolResult::from)
.collect(),
final_answer: final_answer.into(),
passed_assertions: passed_assertions.into_iter().map(Into::into).collect(),
}
}
}