1use anyhow::Result;
2use assistant_tool::{Tool, ToolResultOutput};
3use futures::{channel::oneshot, future::BoxFuture, stream::BoxStream};
4use gpui::SharedString;
5use std::sync::Arc;
6
7#[derive(Debug, Clone)]
8pub struct AgentThreadId(SharedString);
9
10#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
11pub struct AgentThreadMessageId(usize);
12
13#[derive(Debug, Clone)]
14pub struct AgentThreadToolCallId(SharedString);
15
16pub enum AgentThreadResponseEvent {
17 Text(String),
18 Thinking(String),
19 ToolCallChunk {
20 id: AgentThreadToolCallId,
21 tool: Arc<dyn Tool>,
22 input: serde_json::Value,
23 },
24 ToolCall {
25 id: AgentThreadToolCallId,
26 tool: Arc<dyn Tool>,
27 input: serde_json::Value,
28 response_tx: oneshot::Sender<Result<ToolResultOutput>>,
29 },
30}
31
32pub enum AgentThreadMessage {
33 User {
34 id: AgentThreadMessageId,
35 chunks: Vec<AgentThreadUserMessageChunk>,
36 },
37 Assistant {
38 id: AgentThreadMessageId,
39 chunks: Vec<AgentThreadAssistantMessageChunk>,
40 },
41}
42
43pub enum AgentThreadUserMessageChunk {
44 Text(String),
45 // here's where we would put mentions, etc.
46}
47
48pub enum AgentThreadAssistantMessageChunk {
49 Text(String),
50 Thinking(String),
51 ToolResult {
52 id: AgentThreadToolCallId,
53 tool: Arc<dyn Tool>,
54 input: serde_json::Value,
55 output: Result<ToolResultOutput>,
56 },
57}
58
59struct AgentThreadResponse {
60 user_message_id: AgentThreadMessageId,
61 events: BoxStream<'static, Result<AgentThreadResponseEvent>>,
62}
63
64pub trait AgentThread {
65 fn id(&self) -> AgentThreadId;
66 fn title(&self) -> BoxFuture<'static, Result<String>>;
67 fn summary(&self) -> BoxFuture<'static, Result<String>>;
68 fn messages(&self) -> BoxFuture<'static, Result<Vec<AgentThreadMessage>>>;
69 fn truncate(&self, message_id: AgentThreadMessageId) -> BoxFuture<'static, Result<()>>;
70 fn edit(
71 &self,
72 message_id: AgentThreadMessageId,
73 content: Vec<AgentThreadUserMessageChunk>,
74 max_iterations: usize,
75 ) -> BoxFuture<'static, Result<AgentThreadResponse>>;
76 fn send(
77 &self,
78 content: Vec<AgentThreadUserMessageChunk>,
79 max_iterations: usize,
80 ) -> BoxFuture<'static, Result<AgentThreadResponse>>;
81}