pub struct RagClient { /* private fields */ }Expand description
Main client for interacting with the RAG system
This client provides a high-level API for indexing codebases and performing semantic searches. It contains all the core functionality and can be used directly as a library or wrapped by the MCP server.
§Example
use project_rag::{RagClient, IndexRequest, QueryRequest};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
// Create client with default configuration
let client = RagClient::new().await?;
// Index a codebase
let index_req = IndexRequest {
path: "/path/to/code".to_string(),
project: Some("my-project".to_string()),
include_patterns: vec!["**/*.rs".to_string()],
exclude_patterns: vec!["**/target/**".to_string()],
max_file_size: 1_048_576,
};
let response = client.index_codebase(index_req).await?;
println!("Indexed {} files", response.files_indexed);
Ok(())
}Implementations§
Source§impl RagClient
impl RagClient
Sourcepub async fn new() -> Result<Self>
pub async fn new() -> Result<Self>
Create a new RAG client with default configuration
This will initialize the embedding model, vector database, and load any existing caches from disk.
§Errors
Returns an error if:
- Configuration cannot be loaded
- Embedding model cannot be initialized
- Vector database cannot be initialized
Sourcepub async fn with_config(config: Config) -> Result<Self>
pub async fn with_config(config: Config) -> Result<Self>
Create a new RAG client with custom configuration
§Example
use project_rag::{RagClient, Config};
#[tokio::main]
async fn main() -> anyhow::Result<()> {
let mut config = Config::default();
config.embedding.model_name = "BAAI/bge-small-en-v1.5".to_string();
let client = RagClient::with_config(config).await?;
Ok(())
}Sourcepub fn normalize_path(path: &str) -> Result<String>
pub fn normalize_path(path: &str) -> Result<String>
Normalize a path to a canonical absolute form for consistent cache lookups
Sourcepub async fn is_index_dirty(&self, path: &str) -> bool
pub async fn is_index_dirty(&self, path: &str) -> bool
Check if a specific path’s index is dirty (incomplete/corrupted)
Returns true if the path is marked as dirty, meaning a previous indexing operation was interrupted and the data may be inconsistent.
Sourcepub async fn get_dirty_paths(&self) -> Vec<String>
pub async fn get_dirty_paths(&self) -> Vec<String>
Check if any indexed paths are dirty
Returns a list of paths that have dirty indexes.
Sourcepub async fn index_codebase(
&self,
request: IndexRequest,
) -> Result<IndexResponse>
pub async fn index_codebase( &self, request: IndexRequest, ) -> Result<IndexResponse>
Index a codebase directory
This automatically performs full indexing for new codebases or incremental updates for previously indexed codebases.
§Example
use project_rag::{RagClient, IndexRequest};
let client = RagClient::new().await?;
let request = IndexRequest {
path: "/path/to/code".to_string(),
project: Some("my-project".to_string()),
include_patterns: vec!["**/*.rs".to_string()],
exclude_patterns: vec!["**/target/**".to_string()],
max_file_size: 1_048_576,
};
let response = client.index_codebase(request).await?;
println!("Indexed {} files in {} ms",
response.files_indexed,
response.duration_ms);Sourcepub async fn query_codebase(
&self,
request: QueryRequest,
) -> Result<QueryResponse>
pub async fn query_codebase( &self, request: QueryRequest, ) -> Result<QueryResponse>
Query the indexed codebase using semantic search
§Example
use project_rag::{RagClient, QueryRequest};
let client = RagClient::new().await?;
let request = QueryRequest {
query: "authentication logic".to_string(),
project: Some("my-project".to_string()),
limit: 10,
min_score: 0.7,
hybrid: true,
};
let response = client.query_codebase(request).await?;
for result in response.results {
println!("Found in {}: {:.2}", result.file_path, result.score);
println!("{}", result.content);
}Sourcepub async fn search_with_filters(
&self,
request: AdvancedSearchRequest,
) -> Result<QueryResponse>
pub async fn search_with_filters( &self, request: AdvancedSearchRequest, ) -> Result<QueryResponse>
Advanced search with filters for file type, language, and path patterns
Sourcepub async fn get_statistics(&self) -> Result<StatisticsResponse>
pub async fn get_statistics(&self) -> Result<StatisticsResponse>
Get statistics about the indexed codebase
Sourcepub async fn clear_index(&self) -> Result<ClearResponse>
pub async fn clear_index(&self) -> Result<ClearResponse>
Clear all indexed data from the vector database
Sourcepub async fn search_git_history(
&self,
request: SearchGitHistoryRequest,
) -> Result<SearchGitHistoryResponse>
pub async fn search_git_history( &self, request: SearchGitHistoryRequest, ) -> Result<SearchGitHistoryResponse>
Search git commit history using semantic search
§Example
use project_rag::{RagClient, SearchGitHistoryRequest};
let client = RagClient::new().await?;
let request = SearchGitHistoryRequest {
query: "bug fix authentication".to_string(),
path: "/path/to/repo".to_string(),
project: None,
branch: None,
max_commits: 100,
limit: 10,
min_score: 0.7,
author: None,
since: None,
until: None,
file_pattern: None,
};
let response = client.search_git_history(request).await?;
for result in response.results {
println!("Commit {}: {}", result.commit_hash, result.commit_message);
}Sourcepub fn embedding_dimension(&self) -> usize
pub fn embedding_dimension(&self) -> usize
Get the embedding dimension used by this client
Sourcepub async fn find_definition(
&self,
request: FindDefinitionRequest,
) -> Result<FindDefinitionResponse>
pub async fn find_definition( &self, request: FindDefinitionRequest, ) -> Result<FindDefinitionResponse>
Find the definition of a symbol at a given file location
This method looks up the symbol at the specified location and returns its definition information if found.
§Arguments
request- The find definition request containing file path, line, and column
§Returns
A response containing the definition if found, along with precision info
Sourcepub async fn find_references(
&self,
request: FindReferencesRequest,
) -> Result<FindReferencesResponse>
pub async fn find_references( &self, request: FindReferencesRequest, ) -> Result<FindReferencesResponse>
Find all references to a symbol at a given file location
This method finds all locations where the symbol at the given position is referenced throughout the indexed codebase.
§Arguments
request- The find references request containing file path, line, column, and limit
§Returns
A response containing the list of references found
Sourcepub async fn get_call_graph(
&self,
request: GetCallGraphRequest,
) -> Result<GetCallGraphResponse>
pub async fn get_call_graph( &self, request: GetCallGraphRequest, ) -> Result<GetCallGraphResponse>
Get the call graph for a function at a given file location
This method returns the callers (incoming calls) and callees (outgoing calls) for the function at the specified location.
§Arguments
request- The call graph request containing file path, line, column, and depth
§Returns
A response containing the root symbol and its call graph
Trait Implementations§
Auto Trait Implementations§
impl Freeze for RagClient
impl !RefUnwindSafe for RagClient
impl Send for RagClient
impl Sync for RagClient
impl Unpin for RagClient
impl !UnwindSafe for RagClient
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.