objectiveai_cli/command/functions/
list.rs1use std::pin::Pin;
12
13use futures::Stream;
14use objectiveai_sdk::cli::command::functions::list::{
15 Request, RequestSource, ResponseItem,
16};
17use objectiveai_sdk::functions::list_functions;
18use objectiveai_sdk::functions::request::{ListFunctionsRequest, ListFunctionsSource};
19use objectiveai_sdk::RemotePath;
20
21use crate::context::Context;
22use crate::error::Error;
23
24type ItemStream = Pin<Box<dyn Stream<Item = Result<ResponseItem, Error>> + Send>>;
25
26pub async fn execute(ctx: &Context, request: Request) -> Result<ItemStream, Error> {
27 let stream: ItemStream = match request.source {
28 RequestSource::Filesystem => paths_to_stream(
29 fetch_paths(ctx, ListFunctionsSource::Filesystem).await?,
30 ),
31 RequestSource::Objectiveai => paths_to_stream(
32 fetch_paths(ctx, ListFunctionsSource::Objectiveai).await?,
33 ),
34 RequestSource::Mock => {
35 paths_to_stream(fetch_paths(ctx, ListFunctionsSource::Mock).await?)
36 }
37 RequestSource::All => {
38 let (fs_items, oai_items) = tokio::try_join!(
39 fetch_paths(ctx, ListFunctionsSource::Filesystem),
40 fetch_paths(ctx, ListFunctionsSource::Objectiveai),
41 )?;
42 let items = merge_all(fs_items, oai_items);
43 Box::pin(futures::stream::iter(items.into_iter().map(Ok)))
44 }
45 };
46 Ok(stream)
47}
48
49fn paths_to_stream(paths: Vec<RemotePath>) -> ItemStream {
50 Box::pin(futures::stream::iter(
51 paths.into_iter().map(Ok),
52 ))
53}
54
55async fn fetch_paths(
56 ctx: &Context,
57 source: ListFunctionsSource,
58) -> Result<Vec<RemotePath>, Error> {
59 let resp = list_functions(
60 ctx.api_client().await?,
61 ListFunctionsRequest {
62 source: Some(source),
63 },
64 )
65 .await?;
66 Ok(resp.data)
67}
68
69fn merge_all(
70 fs_items: Vec<RemotePath>,
71 oai_items: Vec<RemotePath>,
72) -> Vec<ResponseItem> {
73 let mut items: Vec<ResponseItem> = fs_items;
75
76 for path in oai_items {
77 let dominated = items.iter().any(|existing| existing == &path);
78 if !dominated {
79 items.push(path);
80 }
81 }
82
83 items
84}
85
86pub mod request_schema {
87 use objectiveai_sdk::cli::command::functions::list as sdk;
88 use objectiveai_sdk::cli::command::functions::list::request_schema::{Request, Response};
89
90 use crate::context::Context;
91 use crate::error::Error;
92
93 pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
94 Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Request)))
95 }
96}
97
98pub mod response_schema {
99 use objectiveai_sdk::cli::command::functions::list as sdk;
100 use objectiveai_sdk::cli::command::functions::list::response_schema::{Request, Response};
101
102 use crate::context::Context;
103 use crate::error::Error;
104
105 pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
106 Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Response)))
107 }
108}