Skip to content

Commit e25efa8

Browse files
feat(knowledge): implement pattern filtering and settings integration (TI-3, TI-5) (#2545)
- Add pattern filtering foundation with --include/--exclude CLI flags (TI-3) - Implement knowledge settings integration with database system (TI-5) - Add comprehensive pattern filter module with glob-style support - Enhance file processor with async pattern filtering capabilities - Add extensive test coverage for pattern filtering functionality - Update knowledge CLI with improved error handling and validation - Add settings support for chunk size, overlap, and file limits Co-authored-by: Kenneth S. <[email protected]>
1 parent 754c4d5 commit e25efa8

File tree

19 files changed

+1897
-659
lines changed

19 files changed

+1897
-659
lines changed

Cargo.lock

Lines changed: 312 additions & 238 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/chat-cli/src/cli/chat/cli/knowledge.rs

Lines changed: 244 additions & 61 deletions
Large diffs are not rendered by default.

crates/chat-cli/src/cli/chat/tools/knowledge.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,9 @@ impl Knowledge {
124124
Knowledge::Update(update) => {
125125
// Require at least one identifier (context_id or name)
126126
if update.context_id.is_empty() && update.name.is_empty() && update.path.is_empty() {
127-
eyre::bail!("Please provide either context_id or name or path to identify the context to update");
127+
eyre::bail!(
128+
"Please provide either context_id, name, or path to identify the knowledge base entry to update"
129+
);
128130
}
129131

130132
// Validate the path exists
@@ -310,8 +312,10 @@ impl Knowledge {
310312
}
311313

312314
pub async fn invoke(&self, os: &Os, _updates: &mut impl Write) -> Result<InvokeOutput> {
313-
// Get the async knowledge store singleton
314-
let async_knowledge_store = KnowledgeStore::get_async_instance().await;
315+
// Get the async knowledge store singleton with OS-aware directory
316+
let async_knowledge_store = KnowledgeStore::get_async_instance_with_os(os)
317+
.await
318+
.map_err(|e| eyre::eyre!("Failed to access knowledge base: {}", e))?;
315319
let mut store = async_knowledge_store.lock().await;
316320

317321
let result = match self {
@@ -325,7 +329,14 @@ impl Knowledge {
325329
add.value.clone()
326330
};
327331

328-
match store.add(&add.name, &value_to_use).await {
332+
match store
333+
.add(
334+
&add.name,
335+
&value_to_use,
336+
crate::util::knowledge_store::AddOptions::with_db_defaults(os),
337+
)
338+
.await
339+
{
329340
Ok(context_id) => format!(
330341
"Added '{}' to knowledge base with ID: {}. Track active jobs in '/knowledge status' with provided id.",
331342
add.name, context_id
@@ -412,23 +423,24 @@ impl Knowledge {
412423
.await
413424
.unwrap_or_else(|e| format!("Failed to clear knowledge base: {}", e)),
414425
Knowledge::Search(search) => {
415-
// Only use a spinner for search, not a full progress bar
416426
let results = store.search(&search.query, search.context_id.as_deref()).await;
417427
match results {
418428
Ok(results) => {
419429
if results.is_empty() {
420-
"No matching entries found in knowledge base".to_string()
430+
format!("No matching entries found for query: \"{}\"", search.query)
421431
} else {
422-
let mut output = String::from("Search results:\n");
432+
let mut output = format!("Search results for \"{}\":\n\n", search.query);
423433
for result in results {
424434
if let Some(text) = result.text() {
425-
output.push_str(&format!("- {}\n", text));
435+
output.push_str(&format!("{}\n\n", text));
426436
}
427437
}
428438
output
429439
}
430440
},
431-
Err(e) => format!("Search failed: {}", e),
441+
Err(e) => {
442+
format!("Search failed: {}", e)
443+
},
432444
}
433445
},
434446
Knowledge::Show => {

crates/chat-cli/src/database/settings.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,11 @@ pub enum Setting {
2222
ShareCodeWhispererContent,
2323
EnabledThinking,
2424
EnabledKnowledge,
25+
KnowledgeDefaultIncludePatterns,
26+
KnowledgeDefaultExcludePatterns,
27+
KnowledgeMaxFiles,
28+
KnowledgeChunkSize,
29+
KnowledgeChunkOverlap,
2530
SkimCommandKey,
2631
ChatGreetingEnabled,
2732
ApiTimeout,
@@ -47,6 +52,11 @@ impl AsRef<str> for Setting {
4752
Self::ShareCodeWhispererContent => "codeWhisperer.shareCodeWhispererContentWithAWS",
4853
Self::EnabledThinking => "chat.enableThinking",
4954
Self::EnabledKnowledge => "chat.enableKnowledge",
55+
Self::KnowledgeDefaultIncludePatterns => "knowledge.defaultIncludePatterns",
56+
Self::KnowledgeDefaultExcludePatterns => "knowledge.defaultExcludePatterns",
57+
Self::KnowledgeMaxFiles => "knowledge.maxFiles",
58+
Self::KnowledgeChunkSize => "knowledge.chunkSize",
59+
Self::KnowledgeChunkOverlap => "knowledge.chunkOverlap",
5060
Self::SkimCommandKey => "chat.skimCommandKey",
5161
Self::ChatGreetingEnabled => "chat.greeting.enabled",
5262
Self::ApiTimeout => "api.timeout",
@@ -82,6 +92,11 @@ impl TryFrom<&str> for Setting {
8292
"codeWhisperer.shareCodeWhispererContentWithAWS" => Ok(Self::ShareCodeWhispererContent),
8393
"chat.enableThinking" => Ok(Self::EnabledThinking),
8494
"chat.enableKnowledge" => Ok(Self::EnabledKnowledge),
95+
"knowledge.defaultIncludePatterns" => Ok(Self::KnowledgeDefaultIncludePatterns),
96+
"knowledge.defaultExcludePatterns" => Ok(Self::KnowledgeDefaultExcludePatterns),
97+
"knowledge.maxFiles" => Ok(Self::KnowledgeMaxFiles),
98+
"knowledge.chunkSize" => Ok(Self::KnowledgeChunkSize),
99+
"knowledge.chunkOverlap" => Ok(Self::KnowledgeChunkOverlap),
85100
"chat.skimCommandKey" => Ok(Self::SkimCommandKey),
86101
"chat.greeting.enabled" => Ok(Self::ChatGreetingEnabled),
87102
"api.timeout" => Ok(Self::ApiTimeout),
@@ -166,6 +181,10 @@ impl Settings {
166181
self.get(key).and_then(|value| value.as_i64())
167182
}
168183

184+
pub fn get_int_or(&self, key: Setting, default: usize) -> usize {
185+
self.get_int(key).map_or(default, |v| v as usize)
186+
}
187+
169188
pub async fn save_to_file(&self) -> Result<(), DatabaseError> {
170189
if cfg!(test) {
171190
return Ok(());

crates/chat-cli/src/util/directories.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ pub fn chat_profiles_dir(os: &Os) -> Result<PathBuf> {
185185
Ok(home_dir(os)?.join(".aws").join("amazonq").join("profiles"))
186186
}
187187

188+
/// The directory for knowledge base storage
189+
pub fn knowledge_bases_dir(os: &Os) -> Result<PathBuf> {
190+
Ok(home_dir(os)?.join(".aws").join("amazonq").join("knowledge_bases"))
191+
}
192+
188193
/// The path to the fig settings file
189194
pub fn settings_path() -> Result<PathBuf> {
190195
Ok(fig_data_dir()?.join("settings.json"))

0 commit comments

Comments
 (0)