use std::{pin::Pin, sync::Arc};
use futures_util::Stream;
use tokio::sync::mpsc;
use crate::{
Config, Result,
agent::{self, AgentContext, types::*},
blocking::runtime::BlockingRuntime,
};
pub struct AgentContextSync {
rt: BlockingRuntime<AgentContext>,
}
impl AgentContextSync {
pub fn new(config: Arc<Config>) -> Result<Self> {
let rt = BlockingRuntime::try_new(
move || {
let ctx = AgentContext::new(config);
let (tx, rx) = mpsc::unbounded_channel::<std::convert::Infallible>();
std::mem::forget(tx);
Ok::<_, crate::Error>((ctx, rx))
},
|_: std::convert::Infallible| {},
)?;
Ok(Self { rt })
}
pub fn workspaces(&self) -> Result<WorkspacesResponse> {
self.rt
.call(move |ctx| async move { ctx.workspaces().await })
}
pub fn agents(
&self,
workspace_id: impl Into<String> + Send + 'static,
opts: impl Into<Option<GetAgentsOptions>> + Send + 'static,
) -> Result<AgentsResponse> {
self.rt
.call(move |ctx| async move { ctx.agents(workspace_id, opts).await })
}
pub fn public_agents(
&self,
opts: impl Into<Option<GetAgentsOptions>> + Send + 'static,
) -> Result<AgentsResponse> {
self.rt
.call(move |ctx| async move { ctx.public_agents(opts).await })
}
pub fn conversation(
&self,
agent_id: impl Into<String> + Send + 'static,
query: impl Into<String> + Send + 'static,
chat_uid: Option<String>,
parent_message_id: Option<String>,
) -> Result<ConversationResponse> {
self.rt.call(move |ctx| async move {
ctx.conversation(agent_id, query, chat_uid, parent_message_id)
.await
})
}
pub fn continue_conversation(
&self,
agent_id: impl Into<String> + Send + 'static,
chat_uid: impl Into<String> + Send + 'static,
message_id: impl Into<String> + Send + 'static,
answers: AnswersByToolCall,
) -> Result<ConversationResponse> {
self.rt.call(move |ctx| async move {
ctx.continue_conversation(agent_id, chat_uid, message_id, answers)
.await
})
}
pub fn conversation_streamed(
&self,
agent_id: impl Into<String> + Send + 'static,
query: impl Into<String> + Send + 'static,
chat_uid: Option<String>,
parent_message_id: Option<String>,
) -> Result<agent::ConversationStreamIter> {
let stream = self.rt.call(move |ctx| async move {
Ok(Box::pin(
ctx.conversation_streamed(agent_id, query, chat_uid, parent_message_id)
.await?,
)
as Pin<
Box<dyn Stream<Item = Result<ConversationStreamEvent>> + Send>,
>)
})?;
Ok(agent::conversation_stream_iter(stream))
}
pub fn continue_conversation_streamed(
&self,
agent_id: impl Into<String> + Send + 'static,
chat_uid: impl Into<String> + Send + 'static,
message_id: impl Into<String> + Send + 'static,
answers: AnswersByToolCall,
) -> Result<agent::ConversationStreamIter> {
let stream = self.rt.call(move |ctx| async move {
Ok(Box::pin(
ctx.continue_conversation_streamed(agent_id, chat_uid, message_id, answers)
.await?,
)
as Pin<
Box<dyn Stream<Item = Result<ConversationStreamEvent>> + Send>,
>)
})?;
Ok(agent::conversation_stream_iter(stream))
}
}