diff --git a/libs/agent/chat/service.rs b/libs/agent/chat/service.rs index 8c886d8..7eb7f8d 100644 --- a/libs/agent/chat/service.rs +++ b/libs/agent/chat/service.rs @@ -605,19 +605,37 @@ impl ChatService { } } - if let Some(embed_service) = &self.embed_service { - for mention in &request.mention { - match mention { - Mention::Repo(repo) => { + for mention in &request.mention { + match mention { + Mention::Repo(repo) => { + // Inject repo details into system prompt so AI knows the repo context + let mut parts = vec![ + format!("Name: {}", repo.repo_name), + format!("ID: {}", repo.id), + ]; + if let Some(ref desc) = repo.description { + parts.push(format!("Description: {}", desc)); + } + parts.push(format!("Default branch: {}", repo.default_branch)); + parts.push(format!("Private: {}", if repo.is_private { "yes" } else { "no" })); + parts.push(format!("Created: {}", repo.created_at.format("%Y-%m-%d"))); + messages.push(ChatRequestMessage::system(format!( + "Mentioned repository:\n{}", + parts.join("\n") + ))); + + // Vector search for related issues and repos (enhancement, optional) + if let Some(embed_service) = &self.embed_service { let query = format!( "{} {}", repo.repo_name, repo.description.as_deref().unwrap_or_default() ); - match embed_service.search_issues(&query, 5).await { - Ok(issues) if !issues.is_empty() => { + if let Ok(issues) = embed_service.search_issues(&query, 5).await { + if !issues.is_empty() { let context = format!( - "Related issues:\n{}", + "Related issues for repo {}:\n{}", + repo.repo_name, issues .iter() .map(|i| format!("- {}", i.payload.text)) @@ -626,15 +644,11 @@ impl ChatService { ); messages.push(ChatRequestMessage::system(context)); } - Err(e) => { - let _ = e; - } - _ => {} } - match embed_service.search_repos(&query, 3).await { - Ok(repos) if !repos.is_empty() => { + if let Ok(repos) = embed_service.search_repos(&query, 3).await { + if !repos.is_empty() { let context = format!( - "Related repositories:\n{}", + "Similar repositories:\n{}", repos .iter() .map(|r| format!("- {}", r.payload.text)) @@ -643,28 +657,24 @@ impl ChatService { ); messages.push(ChatRequestMessage::system(context)); } - Err(e) => { - let _ = e; - } - _ => {} } } - Mention::User(user) => { - let mut profile_parts = vec![format!("Username: {}", user.username)]; - if let Some(ref display_name) = user.display_name { - profile_parts.push(format!("Display name: {}", display_name)); - } - if let Some(ref org) = user.organization { - profile_parts.push(format!("Organization: {}", org)); - } - if let Some(ref website) = user.website_url { - profile_parts.push(format!("Website: {}", website)); - } - messages.push(ChatRequestMessage::system(format!( - "Mentioned user profile:\n{}", - profile_parts.join("\n") - ))); + } + Mention::User(user) => { + let mut profile_parts = vec![format!("Username: {}", user.username)]; + if let Some(ref display_name) = user.display_name { + profile_parts.push(format!("Display name: {}", display_name)); } + if let Some(ref org) = user.organization { + profile_parts.push(format!("Organization: {}", org)); + } + if let Some(ref website) = user.website_url { + profile_parts.push(format!("Website: {}", website)); + } + messages.push(ChatRequestMessage::system(format!( + "Mentioned user profile:\n{}", + profile_parts.join("\n") + ))); } } } diff --git a/libs/room/src/service/history.rs b/libs/room/src/service/history.rs index c225f16..c454aba 100644 --- a/libs/room/src/service/history.rs +++ b/libs/room/src/service/history.rs @@ -1,9 +1,11 @@ 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( @@ -57,6 +59,34 @@ pub async fn get_room_ai_config( Ok(ai_config) } -pub async fn extract_mention_context(_content: &str) -> Vec { - Vec::new() +pub async fn extract_mention_context( + db: &AppDatabase, + project_id: Uuid, + content: &str, +) -> Vec { + let mut mentions: Vec = Vec::new(); + let mut seen_repos: Vec = 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 } diff --git a/libs/room/src/service/mod.rs b/libs/room/src/service/mod.rs index 1cfea77..21ff430 100644 --- a/libs/room/src/service/mod.rs +++ b/libs/room/src/service/mod.rs @@ -374,7 +374,7 @@ impl RoomService { .collect(); let user_names = self.get_user_names(&user_ids).await; - let mentions = history::extract_mention_context(&content).await; + let mentions = history::extract_mention_context(&self.db, room.project, &content).await; let request = AiRequest { db: self.db.clone(),