gitdataai/libs/room/src/service/history.rs
ZhenYi adbc0705db feat(room): inject repository details into AI system prompt on mention
When a user mentions a repository in room chat, extract the repo name
from @[repo:name:label] brackets, look up the full repo model from the
database, and inject its details (name, description, default branch,
visibility) into the AI message context. Works independently of
embed_service availability.
2026-04-26 23:58:52 +08:00

93 lines
2.5 KiB
Rust

use db::database::AppDatabase;
use models::repos::repo;
use models::rooms::room_ai;
use models::rooms::room_message::{Column as RmCol, Entity as RoomMessage};
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder, QuerySelect};
use uuid::Uuid;
use super::patterns::mention_bracket_re;
use crate::error::RoomError;
pub async fn get_room_history(
db: &AppDatabase,
room_id: Uuid,
limit: usize,
) -> Result<Vec<models::rooms::room_message::Model>, RoomError> {
let messages = RoomMessage::find()
.filter(RmCol::Room.eq(room_id))
.order_by_desc(RmCol::Seq)
.limit(limit as u64)
.all(db)
.await?;
Ok(messages)
}
pub async fn get_user_names(
db: &AppDatabase,
user_ids: &[Uuid],
) -> std::collections::HashMap<Uuid, String> {
use models::users::User;
let mut names = std::collections::HashMap::new();
if user_ids.is_empty() {
return names;
}
let users = User::find()
.filter(models::users::user::Column::Uid.is_in(user_ids.to_vec()))
.all(db)
.await
.unwrap_or_default();
for user in users {
names.insert(user.uid, user.username);
}
names
}
pub async fn get_room_ai_config(
db: &AppDatabase,
room_id: Uuid,
) -> Result<Option<room_ai::Model>, RoomError> {
let ai_config = room_ai::Entity::find()
.filter(room_ai::Column::Room.eq(room_id))
.one(db)
.await?;
Ok(ai_config)
}
pub async fn extract_mention_context(
db: &AppDatabase,
project_id: Uuid,
content: &str,
) -> Vec<agent::chat::Mention> {
let mut mentions: Vec<agent::chat::Mention> = Vec::new();
let mut seen_repos: Vec<String> = Vec::new();
for cap in mention_bracket_re().captures_iter(content) {
if let (Some(type_m), Some(id_m)) = (cap.get(1), cap.get(2)) {
if type_m.as_str() == "repo" {
let repo_name = id_m.as_str().trim().to_string();
if repo_name.is_empty() || seen_repos.contains(&repo_name) {
continue;
}
seen_repos.push(repo_name.clone());
if let Ok(Some(repo_model)) = repo::Entity::find()
.filter(repo::Column::Project.eq(project_id))
.filter(repo::Column::RepoName.eq(&repo_name))
.one(db)
.await
{
mentions.push(agent::chat::Mention::Repo(repo_model));
}
}
}
}
mentions
}