feat(session): add interaction tracking and history management

Added interaction count tracking for sessions with Redis or in-memory fallback. Implemented conversation history replacement functionality to compact and update message history. The changes include:
- New AtomicUsize counter in SessionManager for interaction tracking
- increment_and_get_interaction_count method with Redis support
- replace_conversation_history to update and compact message history
- Maintains existing functionality while adding new features
This commit is contained in:
Rodrigo Rodriguez (Pragmatismo) 2025-11-03 17:22:54 -03:00
parent c39af8b320
commit d2ba036791
4 changed files with 268 additions and 2026 deletions

View file

@ -11,6 +11,7 @@ use serde::{Deserialize, Serialize};
use std::collections::{HashMap, HashSet};
use std::error::Error;
use std::sync::Arc;
use std::sync::atomic::{AtomicUsize, Ordering};
use uuid::Uuid;
#[derive(Clone, Serialize, Deserialize)]
@ -25,6 +26,7 @@ pub struct SessionManager {
sessions: HashMap<Uuid, SessionData>,
waiting_for_input: HashSet<Uuid>,
redis: Option<Arc<Client>>,
interaction_counts: HashMap<Uuid, AtomicUsize>,
}
impl SessionManager {
@ -34,6 +36,7 @@ impl SessionManager {
sessions: HashMap::new(),
waiting_for_input: HashSet::new(),
redis: redis_client,
interaction_counts: HashMap::new(),
}
}
@ -304,6 +307,67 @@ impl SessionManager {
Ok(String::new())
}
pub fn increment_and_get_interaction_count(
&mut self,
session_id: Uuid,
user_id: Uuid,
) -> Result<usize, Box<dyn Error + Send + Sync>> {
use redis::Commands;
let redis_key = format!("interactions:{}:{}", user_id, session_id);
let count = if let Some(redis_client) = &self.redis {
let mut conn = redis_client.get_connection()?;
let count: usize = conn.incr(&redis_key, 1)?;
count
} else {
let counter = self.interaction_counts
.entry(session_id)
.or_insert(AtomicUsize::new(0));
counter.fetch_add(1, Ordering::SeqCst) + 1
};
Ok(count)
}
pub fn replace_conversation_history(
&mut self,
sess_id: Uuid,
user_uuid: Uuid,
new_history: &[(String, String)],
) -> Result<(), Box<dyn Error + Send + Sync>> {
use crate::shared::models::message_history::dsl::*;
// Delete existing history
diesel::delete(message_history)
.filter(session_id.eq(sess_id))
.execute(&mut self.conn)?;
// Insert new compacted history
for (idx, (role_str, content)) in new_history.iter().enumerate() {
let role_num = match role_str.as_str() {
"user" => 1,
"assistant" => 2,
"system" => 3,
_ => 0,
};
diesel::insert_into(message_history)
.values((
id.eq(Uuid::new_v4()),
session_id.eq(sess_id),
user_id.eq(user_uuid),
role.eq(role_num),
content_encrypted.eq(content),
message_type.eq(1),
message_index.eq(idx as i64),
created_at.eq(chrono::Utc::now()),
))
.execute(&mut self.conn)?;
}
info!("Replaced conversation history for session {}", sess_id);
Ok(())
}
pub fn get_conversation_history(
&mut self,
sess_id: Uuid,

View file

@ -1,5 +1,2 @@
name,value
prompt-compact, 10
prompt-cache,true
prompt-fixed-kb,geral
response-suggestions,true

1 name value
2 prompt-compact 10
prompt-cache true
prompt-fixed-kb geral
response-suggestions true

View file

@ -17,8 +17,8 @@ llm-server-host,0.0.0.0
llm-server-port,8081
llm-server-gpu-layers,0
llm-server-n-moe,0
llm-server-ctx-size,512
llm-server-n-predict,256
llm-server-ctx-size,2048
llm-server-n-predict,512
llm-server-parallel,6
llm-server-cont-batching,true
llm-server-mlock,false

Can't render this file because it has a wrong number of fields in line 26.

File diff suppressed because it is too large Load diff