agent2.rs

  1use anyhow::Result;
  2use assistant_tool::{Tool, ToolResultOutput};
  3use futures::{channel::oneshot, future::BoxFuture, stream::BoxStream};
  4use gpui::SharedString;
  5use schemars::JsonSchema;
  6use serde::{Deserialize, Serialize};
  7use std::{
  8    fmt::{self, Display},
  9    sync::Arc,
 10};
 11
 12#[derive(
 13    Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, JsonSchema,
 14)]
 15pub struct ThreadId(SharedString);
 16
 17impl ThreadId {
 18    pub fn as_str(&self) -> &str {
 19        &self.0
 20    }
 21
 22    pub fn to_string(&self) -> String {
 23        self.0.to_string()
 24    }
 25}
 26
 27impl From<&str> for ThreadId {
 28    fn from(value: &str) -> Self {
 29        ThreadId(SharedString::from(value.to_string()))
 30    }
 31}
 32
 33impl Display for ThreadId {
 34    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 35        write!(f, "{}", self.0)
 36    }
 37}
 38
 39#[derive(Debug, Clone, Copy, Ord, PartialOrd, Eq, PartialEq, Hash, Serialize, Deserialize)]
 40pub struct MessageId(pub usize);
 41
 42#[derive(Debug, Clone)]
 43pub struct AgentThreadToolCallId(SharedString);
 44
 45pub enum AgentThreadResponseEvent {
 46    Text(String),
 47    Thinking(String),
 48    ToolCallChunk {
 49        id: AgentThreadToolCallId,
 50        tool: Arc<dyn Tool>,
 51        input: serde_json::Value,
 52    },
 53    ToolCall {
 54        id: AgentThreadToolCallId,
 55        tool: Arc<dyn Tool>,
 56        input: serde_json::Value,
 57        response_tx: oneshot::Sender<Result<ToolResultOutput>>,
 58    },
 59}
 60
 61pub enum AgentThreadMessage {
 62    User {
 63        id: MessageId,
 64        chunks: Vec<AgentThreadUserMessageChunk>,
 65    },
 66    Assistant {
 67        id: MessageId,
 68        chunks: Vec<AgentThreadAssistantMessageChunk>,
 69    },
 70}
 71
 72pub enum AgentThreadUserMessageChunk {
 73    Text(String),
 74    // here's where we would put mentions, etc.
 75}
 76
 77pub enum AgentThreadAssistantMessageChunk {
 78    Text(String),
 79    Thinking(String),
 80    ToolResult {
 81        id: AgentThreadToolCallId,
 82        tool: Arc<dyn Tool>,
 83        input: serde_json::Value,
 84        output: Result<ToolResultOutput>,
 85    },
 86}
 87
 88pub struct AgentThreadResponse {
 89    pub user_message_id: MessageId,
 90    pub events: BoxStream<'static, Result<AgentThreadResponseEvent>>,
 91}
 92
 93pub trait Agent {
 94    fn create_thread();
 95    fn list_threads();
 96    fn load_thread();
 97}
 98
 99pub trait AgentThread {
100    fn id(&self) -> ThreadId;
101    fn title(&self) -> BoxFuture<'static, Result<String>>;
102    fn summary(&self) -> BoxFuture<'static, Result<String>>;
103    fn messages(&self) -> BoxFuture<'static, Result<Vec<AgentThreadMessage>>>;
104    fn truncate(&self, message_id: MessageId) -> BoxFuture<'static, Result<()>>;
105    fn edit(
106        &self,
107        message_id: MessageId,
108        content: Vec<AgentThreadUserMessageChunk>,
109        max_iterations: usize,
110    ) -> BoxFuture<'static, Result<AgentThreadResponse>>;
111    fn send(
112        &self,
113        content: Vec<AgentThreadUserMessageChunk>,
114        max_iterations: usize,
115    ) -> BoxFuture<'static, Result<AgentThreadResponse>>;
116}