objectiveai_sdk/cli/command/tools/run/
mod.rs1use crate::cli::command::CommandRequest;
4
5#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
6#[schemars(rename = "cli.command.tools.run.Request")]
7pub struct Request {
8 pub path_type: Path,
9 pub owner: String,
10 pub name: String,
11 pub version: String,
12 pub args: Vec<String>,
13 #[serde(flatten)]
14 pub base: crate::cli::command::RequestBase,
15}
16
17#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
18#[schemars(rename = "cli.command.tools.run.Path")]
19pub enum Path {
20 #[serde(rename = "tools/run")]
21 ToolsRun,
22}
23
24impl CommandRequest for Request {
25 fn into_command(&self) -> Vec<String> {
26 let mut argv = vec!["tools".to_string(), "run".to_string()];
27 argv.push("--owner".to_string());
28 argv.push(self.owner.clone());
29 argv.push("--name".to_string());
30 argv.push(self.name.clone());
31 argv.push("--version".to_string());
32 argv.push(self.version.clone());
33 self.base.push_flags(&mut argv);
34 if !self.args.is_empty() {
35 argv.push("--args".to_string());
36 argv.push(serde_json::to_string(&self.args).expect("Vec<String> serializes"));
37 }
38 argv
39 }
40
41 fn request_base(&self) -> &crate::cli::command::RequestBase {
42 &self.base
43 }
44
45 fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
46 Some(&mut self.base)
47 }
48}
49
50#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
51#[serde(untagged)]
52#[schemars(rename = "cli.command.tools.run.ResponseItem")]
53pub enum ResponseItem {
54 #[schemars(title = "Stdout")]
55 Stdout(String),
56 #[schemars(title = "Stderr")]
57 Stderr(crate::cli::Error),
58}
59
60#[derive(clap::Args)]
61pub struct Args {
62 #[arg(long)]
64 pub owner: String,
65 #[arg(long)]
67 pub name: String,
68 #[arg(long)]
70 pub version: String,
71 #[arg(long)]
74 pub args: Option<String>,
75 #[command(flatten)]
76 pub base: crate::cli::command::RequestBaseArgs,
77}
78
79#[derive(clap::Args)]
80#[command(args_conflicts_with_subcommands = true)]
81pub struct Command {
82 #[command(flatten)]
83 pub args: Args,
84 #[command(subcommand)]
85 pub schema: Option<Schema>,
86}
87
88#[derive(clap::Subcommand)]
89pub enum Schema {
90 RequestSchema(request_schema::Args),
92 ResponseSchema(response_schema::Args),
94}
95
96impl TryFrom<Args> for Request {
97 type Error = crate::cli::command::FromArgsError;
98 fn try_from(args: Args) -> Result<Self, Self::Error> {
99 let parsed_args: Vec<String> = match args.args {
100 Some(s) => {
101 let mut de = serde_json::Deserializer::from_str(&s);
102 serde_path_to_error::deserialize(&mut de).map_err(|source| {
103 crate::cli::command::FromArgsError {
104 field: "args",
105 source: source.into(),
106 }
107 })?
108 }
109 None => Vec::new(),
110 };
111 Ok(Self {
112 path_type: Path::ToolsRun,
113 owner: args.owner,
114 name: args.name,
115 version: args.version,
116 args: parsed_args,
117 base: args.base.into(),
118 })
119 }
120}
121
122#[cfg(feature = "cli-executor")]
123pub async fn execute<E: crate::cli::command::CommandExecutor>(
124 executor: &E,
125 mut request: Request,
126
127 agent_arguments: Option<&crate::cli::command::AgentArguments>,
128 ) -> Result<E::Stream<ResponseItem>, E::Error> {
129 request.base.clear_transform();
130 executor.execute(request, agent_arguments).await
131}
132
133#[cfg(feature = "cli-executor")]
134pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
135 executor: &E,
136 mut request: Request,
137 transform: crate::cli::command::Transform,
138
139 agent_arguments: Option<&crate::cli::command::AgentArguments>,
140 ) -> Result<E::Stream<serde_json::Value>, E::Error> {
141 request.base.set_transform(transform);
142 executor.execute(request, agent_arguments).await
143}
144
145#[cfg(feature = "mcp")]
146impl crate::cli::command::CommandResponse for ResponseItem {
147 fn into_mcp(self) -> crate::cli::command::McpResponseItem {
148 use crate::agent::completions::message::RichContentPart;
149 use crate::cli::command::McpResponseItem;
150 match self {
151 ResponseItem::Stdout(s) => {
152 if let Some((mime, payload)) = crate::data_url::parse_data_url(&s) {
156 let part = RichContentPart::from_blob(
157 mime,
158 payload.to_string(),
159 None,
160 );
161 return McpResponseItem::Media(part.into());
162 }
163 McpResponseItem::JSONL(serde_json::Value::String(s))
164 }
165 ResponseItem::Stderr(e) => e.into_mcp(),
166 }
167 }
168}
169
170pub mod request_schema;
171
172
173pub mod response_schema;