swiftide_core/chat_completion/
traits.rs1use async_trait::async_trait;
2use dyn_clone::DynClone;
3use std::borrow::Cow;
4
5use crate::{AgentContext, CommandOutput};
6
7use super::{
8 chat_completion_request::ChatCompletionRequest,
9 chat_completion_response::ChatCompletionResponse,
10 errors::{ChatCompletionError, ToolError},
11 ToolOutput, ToolSpec,
12};
13
14#[async_trait]
15pub trait ChatCompletion: Send + Sync + DynClone {
16 async fn complete(
17 &self,
18 request: &ChatCompletionRequest,
19 ) -> Result<ChatCompletionResponse, ChatCompletionError>;
20}
21
22#[async_trait]
23impl ChatCompletion for Box<dyn ChatCompletion> {
24 async fn complete(
25 &self,
26 request: &ChatCompletionRequest,
27 ) -> Result<ChatCompletionResponse, ChatCompletionError> {
28 (**self).complete(request).await
29 }
30}
31
32#[async_trait]
33impl ChatCompletion for &dyn ChatCompletion {
34 async fn complete(
35 &self,
36 request: &ChatCompletionRequest,
37 ) -> Result<ChatCompletionResponse, ChatCompletionError> {
38 (**self).complete(request).await
39 }
40}
41
42#[async_trait]
43impl<T> ChatCompletion for &T
44where
45 T: ChatCompletion + Clone + 'static,
46{
47 async fn complete(
48 &self,
49 request: &ChatCompletionRequest,
50 ) -> Result<ChatCompletionResponse, ChatCompletionError> {
51 (**self).complete(request).await
52 }
53}
54
55impl<LLM> From<&LLM> for Box<dyn ChatCompletion>
56where
57 LLM: ChatCompletion + Clone + 'static,
58{
59 fn from(llm: &LLM) -> Self {
60 Box::new(llm.clone()) as Box<dyn ChatCompletion>
61 }
62}
63
64dyn_clone::clone_trait_object!(ChatCompletion);
65
66impl From<CommandOutput> for ToolOutput {
67 fn from(value: CommandOutput) -> Self {
68 ToolOutput::Text(value.output)
69 }
70}
71
72#[async_trait]
81pub trait Tool: Send + Sync + DynClone {
82 async fn invoke(
84 &self,
85 agent_context: &dyn AgentContext,
86 raw_args: Option<&str>,
87 ) -> Result<ToolOutput, ToolError>;
88
89 fn name(&self) -> Cow<'_, str>;
90
91 fn tool_spec(&self) -> ToolSpec;
92
93 fn boxed<'a>(self) -> Box<dyn Tool + 'a>
94 where
95 Self: Sized + 'a,
96 {
97 Box::new(self) as Box<dyn Tool>
98 }
99}
100
101#[async_trait]
102impl Tool for Box<dyn Tool> {
103 async fn invoke(
104 &self,
105 agent_context: &dyn AgentContext,
106 raw_args: Option<&str>,
107 ) -> Result<ToolOutput, ToolError> {
108 (**self).invoke(agent_context, raw_args).await
109 }
110 fn name(&self) -> Cow<'_, str> {
111 (**self).name()
112 }
113 fn tool_spec(&self) -> ToolSpec {
114 (**self).tool_spec()
115 }
116}
117
118dyn_clone::clone_trait_object!(Tool);
119
120impl PartialEq for Box<dyn Tool> {
123 fn eq(&self, other: &Self) -> bool {
124 self.name() == other.name()
125 }
126}
127impl Eq for Box<dyn Tool> {}
128impl std::hash::Hash for Box<dyn Tool> {
129 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
130 self.name().hash(state);
131 }
132}