| 1 | use serde::{Deserialize, Serialize}; |
| 2 | use uuid::Uuid; |
| 3 | |
| 4 | use super::BlockId; |
| 5 | |
| 6 | /// An opaque id to track agent prompt requests from viewers. |
| 7 | #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] |
| 8 | pub struct AgentPromptRequestId(String); |
| 9 | |
| 10 | impl AgentPromptRequestId { |
| 11 | pub fn new() -> Self { |
| 12 | Self(Uuid::new_v4().to_string()) |
| 13 | } |
| 14 | } |
| 15 | |
| 16 | impl Default for AgentPromptRequestId { |
| 17 | fn default() -> Self { |
| 18 | Self::new() |
| 19 | } |
| 20 | } |
| 21 | |
| 22 | /// A set of reasons for which an agent prompt request might fail. |
| 23 | #[derive(Clone, Debug, Serialize, Deserialize)] |
| 24 | pub enum AgentPromptFailureReason { |
| 25 | /// The viewer does not have sufficient permissions to send agent prompts. |
| 26 | InsufficientPermissions, |
| 27 | |
| 28 | /// The conversation ID provided is invalid or doesn't exist. |
| 29 | InvalidConversation, |
| 30 | |
| 31 | // There is a long running command that is already in progress. |
| 32 | CommandInProgress, |
| 33 | } |
| 34 | |
| 35 | /// Represents an AI agent attachment that can be sent with a prompt. |
| 36 | /// This is a simplified version for the protocol - the sharer will reconstruct |
| 37 | /// the full attachment from the block ID. |
| 38 | /// |
| 39 | /// TODO: Add support for image attachments. Images are currently handled as |
| 40 | /// AIAgentContext::Image (contextual info) rather than AIAgentAttachment in the client, |
| 41 | /// so we need to decide whether to treat viewer-attached images as context or attachments |
| 42 | /// before adding them to the protocol. |
| 43 | #[derive(Clone, Debug, Serialize, Deserialize)] |
| 44 | pub enum AgentAttachment { |
| 45 | /// A reference to a terminal block by ID. |
| 46 | /// The sharer will resolve this to the actual block content. |
| 47 | BlockReference { block_id: BlockId }, |
| 48 | |
| 49 | /// Plain text attachment (e.g., clipboard content). |
| 50 | PlainText { content: String }, |
| 51 | |
| 52 | /// A reference to a file that has been uploaded to GCS. |
| 53 | /// The host fetches download URLs directly from warp-server using the attachment ID. |
| 54 | FileReference { |
| 55 | attachment_id: String, |
| 56 | file_name: String, |
| 57 | }, |
| 58 | } |
| 59 | |
| 60 | /// An optional server conversation token for continuing an existing agent conversation. |
| 61 | /// The id provided here is 1:1 with the ServerConversationToken used on the client/server (not AIAgentConversationId). |
| 62 | /// If no token is provided, a new conversation will be started. |
| 63 | #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash, Copy)] |
| 64 | pub struct ServerConversationToken(Uuid); |
| 65 | |
| 66 | impl ServerConversationToken { |
| 67 | pub fn new() -> Self { |
| 68 | Self(Uuid::new_v4()) |
| 69 | } |
| 70 | |
| 71 | pub fn from_uuid(uuid: Uuid) -> Self { |
| 72 | Self(uuid) |
| 73 | } |
| 74 | |
| 75 | pub fn as_uuid(&self) -> Uuid { |
| 76 | self.0 |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | impl Default for ServerConversationToken { |
| 81 | fn default() -> Self { |
| 82 | Self::new() |
| 83 | } |
| 84 | } |
| 85 | |
| 86 | impl std::fmt::Display for ServerConversationToken { |
| 87 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { |
| 88 | write!(f, "{}", self.0) |
| 89 | } |
| 90 | } |
| 91 | |
| 92 | impl std::str::FromStr for ServerConversationToken { |
| 93 | type Err = uuid::Error; |
| 94 | |
| 95 | fn from_str(s: &str) -> Result<Self, Self::Err> { |
| 96 | Ok(Self(Uuid::parse_str(s)?)) |
| 97 | } |
| 98 | } |
| 99 | |
| 100 | /// The data for an agent prompt request from a viewer. |
| 101 | #[derive(Clone, Debug, Serialize, Deserialize)] |
| 102 | pub struct AgentPromptRequest { |
| 103 | /// Unique identifier for this request. |
| 104 | pub id: AgentPromptRequestId, |
| 105 | |
| 106 | /// The server conversation token to continue. If None, start a new conversation. |
| 107 | /// This is the server_conversation_token that links viewer and sharer conversations. |
| 108 | pub server_conversation_token: Option<ServerConversationToken>, |
| 109 | |
| 110 | /// The user's prompt/query. |
| 111 | pub prompt: String, |
| 112 | |
| 113 | /// Optional attachments (blocks, files, etc.) referenced in the prompt. |
| 114 | #[serde(default)] |
| 115 | pub attachments: Vec<AgentAttachment>, |
| 116 | } |