Skip to main content

objectiveai_sdk/cli/command/plugins/logs/
mod.rs

1//! `plugins logs` — captured plugin-stderr log tier. One leaf:
2//!
3//! - `list --owner <O> --name <N> --version <V> [--after-id] [--limit]`
4//!   — read the stderr lines captured during `plugins run`, paginated
5//!   by the BIGSERIAL `"index"` cursor.
6
7use crate::cli::command::CommandRequest;
8
9pub mod list;
10
11#[derive(clap::Subcommand)]
12pub enum Command {
13    /// List captured stderr lines for a plugin coordinate.
14    List(list::Command),
15}
16
17#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
18#[serde(untagged)]
19#[schemars(rename = "cli.command.plugins.logs.Request")]
20pub enum Request {
21    #[schemars(title = "List")]
22    List(list::Request),
23    #[schemars(title = "ListRequestSchema")]
24    ListRequestSchema(list::request_schema::Request),
25    #[schemars(title = "ListResponseSchema")]
26    ListResponseSchema(list::response_schema::Request),
27}
28
29// Exempt from json-schema coverage: tier aggregate (see the root
30// `ResponseItem` in command.rs - TS7056).
31#[objectiveai_sdk_macros::json_schema_ignore]
32#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize, schemars::JsonSchema)]
33#[schemars(rename = "cli.command.plugins.logs.ResponseItem")]
34#[serde(untagged)]
35pub enum ResponseItem {
36    #[schemars(title = "List")]
37    List(list::ResponseItem),
38    #[schemars(title = "ListRequestSchema")]
39    ListRequestSchema(list::request_schema::Response),
40    #[schemars(title = "ListResponseSchema")]
41    ListResponseSchema(list::response_schema::Response),
42}
43
44#[cfg(feature = "mcp")]
45impl crate::cli::command::CommandResponse for ResponseItem {
46    fn into_mcp(self) -> crate::cli::command::McpResponseItem {
47        match self {
48            ResponseItem::List(v) => v.into_mcp(),
49            ResponseItem::ListRequestSchema(v) => v.into_mcp(),
50            ResponseItem::ListResponseSchema(v) => v.into_mcp(),
51        }
52    }
53}
54
55impl TryFrom<Command> for Request {
56    type Error = crate::cli::command::FromArgsError;
57    fn try_from(command: Command) -> Result<Self, Self::Error> {
58        match command {
59            Command::List(cmd) => match cmd.schema {
60                None => Ok(Request::List(list::Request::try_from(cmd.args)?)),
61                Some(list::Schema::RequestSchema(args)) => Ok(
62                    Request::ListRequestSchema(list::request_schema::Request::try_from(args)?),
63                ),
64                Some(list::Schema::ResponseSchema(args)) => Ok(
65                    Request::ListResponseSchema(list::response_schema::Request::try_from(args)?),
66                ),
67            },
68        }
69    }
70}
71
72impl CommandRequest for Request {
73    fn request_base(&self) -> &crate::cli::command::RequestBase {
74        match self {
75            Request::List(inner) => inner.request_base(),
76            Request::ListRequestSchema(inner) => inner.request_base(),
77            Request::ListResponseSchema(inner) => inner.request_base(),
78        }
79    }
80
81    fn request_base_mut(&mut self) -> Option<&mut crate::cli::command::RequestBase> {
82        match self {
83            Request::List(inner) => inner.request_base_mut(),
84            Request::ListRequestSchema(inner) => inner.request_base_mut(),
85            Request::ListResponseSchema(inner) => inner.request_base_mut(),
86        }
87    }
88}
89
90#[cfg(feature = "cli-executor")]
91pub async fn execute<E: crate::cli::command::CommandExecutor>(
92    executor: &E,
93    request: Request,
94    agent_arguments: Option<&crate::cli::command::AgentArguments>,
95) -> Result<
96    std::pin::Pin<Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>>,
97    E::Error,
98> {
99    use futures::StreamExt;
100    let stream: std::pin::Pin<
101        Box<dyn futures::Stream<Item = Result<ResponseItem, E::Error>> + Send>,
102    > = match request {
103        Request::List(req) => {
104            let inner = list::execute(executor, req, agent_arguments).await?;
105            Box::pin(inner.map(|r| r.map(ResponseItem::List)))
106        }
107        Request::ListRequestSchema(req) => {
108            let value = list::request_schema::execute(executor, req, agent_arguments).await?;
109            Box::pin(crate::cli::command::StreamOnce::new(Ok(
110                ResponseItem::ListRequestSchema(value),
111            )))
112        }
113        Request::ListResponseSchema(req) => {
114            let value = list::response_schema::execute(executor, req, agent_arguments).await?;
115            Box::pin(crate::cli::command::StreamOnce::new(Ok(
116                ResponseItem::ListResponseSchema(value),
117            )))
118        }
119    };
120    Ok(stream)
121}
122
123#[cfg(feature = "cli-executor")]
124pub async fn execute_transform<E: crate::cli::command::CommandExecutor>(
125    executor: &E,
126    request: Request,
127    transform: crate::cli::command::Transform,
128    agent_arguments: Option<&crate::cli::command::AgentArguments>,
129) -> Result<
130    std::pin::Pin<Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>>,
131    E::Error,
132> {
133    let stream: std::pin::Pin<
134        Box<dyn futures::Stream<Item = Result<serde_json::Value, E::Error>> + Send>,
135    > = match request {
136        Request::List(req) => {
137            let inner = list::execute_transform(executor, req, transform, agent_arguments).await?;
138            Box::pin(inner)
139        }
140        Request::ListRequestSchema(req) => {
141            let value =
142                list::request_schema::execute_transform(executor, req, transform, agent_arguments).await?;
143            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
144        }
145        Request::ListResponseSchema(req) => {
146            let value =
147                list::response_schema::execute_transform(executor, req, transform, agent_arguments).await?;
148            Box::pin(crate::cli::command::StreamOnce::new(Ok(value)))
149        }
150    };
151    Ok(stream)
152}