split main.rs into types, timeline, claude, handlers, session modules
This commit is contained in:
parent
8d2f43b6c5
commit
09259ee5fa
6 changed files with 1337 additions and 1322 deletions
112
src/types.rs
Normal file
112
src/types.rs
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use matrix_sdk::{
|
||||
authentication::matrix::MatrixSession,
|
||||
ruma::{OwnedEventId, OwnedRoomId, OwnedUserId},
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const DEFAULT_MODEL: &str = "claude-sonnet-4-6";
|
||||
pub const DEFAULT_MAX_HISTORY: usize = 20;
|
||||
pub const DEFAULT_RATE_LIMIT_PER_MIN: u32 = 1;
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct Config {
|
||||
pub homeserver: String,
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
pub rate_limit_per_min: Option<u32>,
|
||||
pub model: Option<String>,
|
||||
pub max_history: Option<usize>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct PersistedSession {
|
||||
pub homeserver: String,
|
||||
pub db_path: std::path::PathBuf,
|
||||
pub user_session: MatrixSession,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub sync_token: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum TimelineItem {
|
||||
Message {
|
||||
event_id: OwnedEventId,
|
||||
sender: OwnedUserId,
|
||||
body: String,
|
||||
is_self: bool,
|
||||
/// Unix seconds. 0 if unknown.
|
||||
ts: i64,
|
||||
in_reply_to: Option<OwnedEventId>,
|
||||
},
|
||||
Reaction {
|
||||
sender: OwnedUserId,
|
||||
target_event_id: OwnedEventId,
|
||||
key: String,
|
||||
is_self: bool,
|
||||
ts: i64,
|
||||
},
|
||||
}
|
||||
|
||||
impl TimelineItem {
|
||||
pub fn ts(&self) -> i64 {
|
||||
match self {
|
||||
Self::Message { ts, .. } | Self::Reaction { ts, .. } => *ts,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn event_id(&self) -> Option<&OwnedEventId> {
|
||||
match self {
|
||||
Self::Message { event_id, .. } => Some(event_id),
|
||||
Self::Reaction { .. } => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sender(&self) -> &OwnedUserId {
|
||||
match self {
|
||||
Self::Message { sender, .. } | Self::Reaction { sender, .. } => sender,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_self(&self) -> bool {
|
||||
match self {
|
||||
Self::Message { is_self, .. } | Self::Reaction { is_self, .. } => *is_self,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DaemonState {
|
||||
pub own_user_id: OwnedUserId,
|
||||
/// Per-room: the latest event_id that's been "shown" to Claude. Events
|
||||
/// after this are "new" on the next invocation. Cleared on daemon restart.
|
||||
pub last_shown: HashMap<OwnedRoomId, OwnedEventId>,
|
||||
pub pending_rooms: Vec<OwnedRoomId>,
|
||||
pub rate_budget: u32,
|
||||
pub rate_limit_per_min: u32,
|
||||
pub last_rate_reset: std::time::Instant,
|
||||
pub model: String,
|
||||
pub max_history: usize,
|
||||
}
|
||||
|
||||
pub enum ResponseTarget {
|
||||
Room(OwnedRoomId),
|
||||
Dm(OwnedUserId),
|
||||
}
|
||||
|
||||
/// One document within Claude's multi-doc output. Each doc has its own
|
||||
/// frontmatter; the daemon routes based on which fields are present.
|
||||
pub enum ClaudeDoc {
|
||||
/// A chat message to send.
|
||||
Message {
|
||||
target: ResponseTarget,
|
||||
body: String,
|
||||
},
|
||||
/// A reaction to a message. `target_id_arg` is the event id (possibly
|
||||
/// shortened) the agent saw in the prompt; daemon expands by prefix match.
|
||||
Reaction { target_id_arg: String, key: String },
|
||||
/// Agent's internal monologue. Not sent to chat. Logged to tracing.
|
||||
Thought(String),
|
||||
/// Explicit "do nothing for this slot". Useful as a placeholder.
|
||||
Skip,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue