use crate::{CodeExecutionLanguage, FileSearchResultItem, GoogleSearchResultItem, Step};
pub fn code_execution_call_step(
id: impl Into<String>,
language: CodeExecutionLanguage,
code: impl Into<String>,
) -> Step {
Step::CodeExecutionCall {
id: id.into(),
language,
code: code.into(),
signature: None,
}
}
pub fn code_execution_result_step(
call_id: impl Into<String>,
is_error: bool,
result: impl Into<String>,
) -> Step {
Step::CodeExecutionResult {
call_id: call_id.into(),
is_error,
result: result.into(),
signature: None,
}
}
pub fn code_execution_success(call_id: impl Into<String>, result: impl Into<String>) -> Step {
code_execution_result_step(call_id, false, result)
}
pub fn code_execution_error(call_id: impl Into<String>, error_result: impl Into<String>) -> Step {
code_execution_result_step(call_id, true, error_result)
}
pub fn google_search_call_step(id: impl Into<String>, queries: Vec<impl Into<String>>) -> Step {
Step::GoogleSearchCall {
id: id.into(),
queries: queries.into_iter().map(|q| q.into()).collect(),
search_type: None,
signature: None,
}
}
pub fn google_search_result_step(
call_id: impl Into<String>,
result: Vec<GoogleSearchResultItem>,
) -> Step {
Step::GoogleSearchResult {
call_id: call_id.into(),
result,
is_error: None,
signature: None,
}
}
pub fn file_search_result_step(
call_id: impl Into<String>,
result: Vec<FileSearchResultItem>,
) -> Step {
Step::FileSearchResult {
call_id: call_id.into(),
result,
signature: None,
}
}
pub fn url_context_call_step(
id: impl Into<String>,
urls: impl IntoIterator<Item = impl Into<String>>,
) -> Step {
Step::UrlContextCall {
id: id.into(),
urls: urls.into_iter().map(Into::into).collect(),
signature: None,
}
}
pub fn url_context_result_step(
call_id: impl Into<String>,
result: Vec<crate::UrlContextResultItem>,
) -> Step {
Step::UrlContextResult {
call_id: call_id.into(),
result,
is_error: None,
signature: None,
}
}
pub fn url_context_success(call_id: impl Into<String>, url: impl Into<String>) -> Step {
url_context_result_step(
call_id,
vec![crate::UrlContextResultItem::new(url, "success")],
)
}
pub fn url_context_failure(call_id: impl Into<String>, url: impl Into<String>) -> Step {
url_context_result_step(
call_id,
vec![crate::UrlContextResultItem::new(url, "error")],
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_code_execution_call_step_wire_format() {
let step = code_execution_call_step("call_1", CodeExecutionLanguage::Python, "print(1)");
let json = serde_json::to_value(&step).unwrap();
assert_eq!(json["type"], "code_execution_call");
assert_eq!(json["id"], "call_1");
assert_eq!(json["arguments"]["language"], "python");
assert_eq!(json["arguments"]["code"], "print(1)");
}
#[test]
fn test_code_execution_result_helpers() {
let ok = code_execution_success("c1", "42");
assert!(matches!(
ok,
Step::CodeExecutionResult {
is_error: false,
..
}
));
let err = code_execution_error("c1", "boom");
assert!(matches!(
err,
Step::CodeExecutionResult { is_error: true, .. }
));
}
#[test]
fn test_google_search_call_step_wire_format() {
let step = google_search_call_step("s1", vec!["rust"]);
let json = serde_json::to_value(&step).unwrap();
assert_eq!(json["type"], "google_search_call");
assert_eq!(json["arguments"]["queries"][0], "rust");
}
#[test]
fn test_url_context_helpers() {
let ok = url_context_success("u1", "https://example.com");
match &ok {
Step::UrlContextResult { result, .. } => {
assert!(result[0].is_success());
}
other => panic!("Expected UrlContextResult, got {other:?}"),
}
let err = url_context_failure("u1", "https://example.com");
match &err {
Step::UrlContextResult { result, .. } => {
assert!(result[0].is_error());
}
other => panic!("Expected UrlContextResult, got {other:?}"),
}
}
#[test]
fn test_file_search_result_step() {
let step = file_search_result_step(
"f1",
vec![FileSearchResultItem::new("Doc", "Text", "store")],
);
let json = serde_json::to_value(&step).unwrap();
assert_eq!(json["type"], "file_search_result");
assert_eq!(json["result"][0]["file_search_store"], "store");
}
}