use core::fmt; use serde::{Deserialize, Serialize}; use serde_string_enum::{DeserializeLabeledStringEnum, SerializeLabeledStringEnum}; use strum::{Display, EnumString}; use ts_rs::TS; #[derive(Debug)] pub enum LettaError { ConfigurationError(String), ApiKeyError(keyring::Error), RequestError(reqwest::Error), EventSourceError(reqwest_eventsource::Error), } impl fmt::Display for LettaError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { LettaError::ConfigurationError(msg) => write!(f, "Configuration error: {}", msg), LettaError::ApiKeyError(err) => write!(f, "API key error: {}", err), LettaError::RequestError(err) => write!(f, "Letta request error: {}", err), LettaError::EventSourceError(err) => write!(f, "Letta event source error: {}", err), } } } impl From for LettaError { fn from(err: keyring::Error) -> Self { LettaError::ApiKeyError(err) } } impl From for LettaError { fn from(err: reqwest::Error) -> Self { LettaError::RequestError(err) } } impl From for LettaError { fn from(err: reqwest_eventsource::Error) -> Self { LettaError::EventSourceError(err) } } #[derive(Serialize, Deserialize, Clone, Display, EnumString)] #[strum(prefix = "letta")] pub enum LettaConfigKey { BaseUrl, AgentId, } #[derive(Serialize, Deserialize, TS, Debug)] #[ts(export)] pub struct LettaAgentInfo { id: String, name: String, } #[derive(Serialize, Deserialize, TS, Debug, Clone)] #[serde(tag = "type", rename_all = "lowercase")] pub enum LettaMessageContent { Text { text: String }, Image { source: String }, } #[derive(TS, Debug, SerializeLabeledStringEnum, DeserializeLabeledStringEnum, Clone, Copy)] pub enum LettaReasoningSource { #[string = "reasoner_model"] ReasonerModel, #[string = "non_reasoner_model"] NonReasonerModel, } #[derive(SerializeLabeledStringEnum, DeserializeLabeledStringEnum, TS, Debug, Clone, Copy)] pub enum LettaHiddenReasoningState { #[string = "redacted"] Redacted, #[string = "omitted"] Omitted, } #[derive(Serialize, Deserialize, TS, Debug, Clone)] #[serde(untagged)] pub enum LettaToolCall { Call { name: String, arguments: String, tool_call_id: String, }, Delta { name: Option, arguments: Option, tool_call_id: Option, }, } #[derive(SerializeLabeledStringEnum, DeserializeLabeledStringEnum, TS, Debug, Clone, Copy)] pub enum LettaToolReturnStatus { #[string = "success"] Success, #[string = "error"] Error, } #[derive(Serialize, Deserialize, TS, Debug, Clone)] #[serde(tag = "message_type", rename_all = "snake_case")] #[ts(export)] pub enum LettaCompletionMessage { SystemMessage { id: String, date: String, content: String, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, }, UserMessage { id: String, date: String, content: Vec, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, }, ReasoningMessage { id: String, date: String, reasoning: String, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, source: Option, signature: Option, }, HiddenReasoningMessage { id: String, date: String, state: LettaHiddenReasoningState, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, hidden_reasoning: Option, }, ToolCallMessage { id: String, date: String, tool_call: LettaToolCall, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, }, ToolReturnMessage { id: String, date: String, tool_return: String, status: LettaToolReturnStatus, tool_call_id: String, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, stdout: Option>, stderr: Option>, }, AssistantMessage { id: String, date: String, content: Vec, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, }, ApprovalRequestMessage { id: String, date: String, tool_call: LettaToolCall, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, }, ApprovalResponseMessage { id: String, date: String, approve: bool, approval_request_id: String, name: Option, otid: Option, sender_id: Option, step_id: Option, is_err: Option, seq_id: Option, run_id: Option, reason: Option, }, StopReason { // Not documented, only observed value so far is "end_turn" stop_reason: String, }, UsageStatistics { completion_tokens: i64, prompt_tokens: i64, step_count: i64, // Observed but undocumented, inner type unclear // steps_messages: Option>, // Observed but undocumented // run_ids: Option>, }, }