use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum InputType {
Message,
Heartbeat,
Cron,
Hook,
Webhook,
AgentMessage,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct InputSource {
pub channel: String,
pub identifier: String,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum HookEvent {
AppStarted,
AppStopping,
SessionStarted {
session_key: String,
},
SessionCompleted {
session_key: String,
},
SessionError {
session_key: String,
error: String,
},
RoutineTriggered {
routine_id: String,
},
RoutineCompleted {
routine_id: String,
},
Custom {
name: String,
data: serde_json::Value,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct KeelInput {
pub id: String,
pub input_type: InputType,
pub source: InputSource,
pub payload: serde_json::Value,
pub session_key: Option<String>,
pub project_id: Option<String>,
pub created_at: DateTime<Utc>,
}
impl KeelInput {
pub fn new(
input_type: InputType,
source: InputSource,
payload: serde_json::Value,
) -> Self {
Self {
id: uuid::Uuid::new_v4().to_string(),
input_type,
source,
payload,
session_key: None,
project_id: None,
created_at: Utc::now(),
}
}
pub fn with_session(mut self, key: String) -> Self {
self.session_key = Some(key);
self
}
pub fn with_project(mut self, id: String) -> Self {
self.project_id = Some(id);
self
}
pub fn message(channel: &str, identifier: &str, text: &str) -> Self {
Self::new(
InputType::Message,
InputSource {
channel: channel.to_string(),
identifier: identifier.to_string(),
},
serde_json::json!({ "text": text }),
)
}
pub fn heartbeat(prompt: &str) -> Self {
Self::new(
InputType::Heartbeat,
InputSource {
channel: "system".to_string(),
identifier: "heartbeat".to_string(),
},
serde_json::json!({ "prompt": prompt }),
)
}
pub fn cron(job_name: &str, prompt: &str) -> Self {
Self::new(
InputType::Cron,
InputSource {
channel: "system".to_string(),
identifier: job_name.to_string(),
},
serde_json::json!({ "prompt": prompt }),
)
}
pub fn hook(event: HookEvent) -> Self {
let payload = serde_json::to_value(&event).unwrap_or_default();
Self::new(
InputType::Hook,
InputSource {
channel: "system".to_string(),
identifier: "hook".to_string(),
},
payload,
)
}
pub fn webhook(endpoint: &str, payload: serde_json::Value) -> Self {
Self::new(
InputType::Webhook,
InputSource {
channel: "webhook".to_string(),
identifier: endpoint.to_string(),
},
payload,
)
}
pub fn agent_message(from_agent: &str, to_agent: &str, text: &str) -> Self {
Self::new(
InputType::AgentMessage,
InputSource {
channel: "agent".to_string(),
identifier: from_agent.to_string(),
},
serde_json::json!({ "to": to_agent, "text": text }),
)
}
}