@@ -8,7 +8,6 @@ use crossterm::style::{
88} ;
99use eyre:: Result ;
1010use semantic_search_client:: {
11- KnowledgeContext ,
1211 OperationStatus ,
1312 SystemStatus ,
1413} ;
@@ -103,6 +102,11 @@ impl KnowledgeSubcommand {
103102 }
104103 }
105104
105+ /// Get the current agent from the session
106+ fn get_agent ( session : & ChatSession ) -> Option < & crate :: cli:: Agent > {
107+ session. conversation . agents . get_active ( )
108+ }
109+
106110 async fn execute_operation ( & self , os : & Os , session : & mut ChatSession ) -> OperationResult {
107111 match self {
108112 KnowledgeSubcommand :: Show => {
@@ -116,127 +120,105 @@ impl KnowledgeSubcommand {
116120 include,
117121 exclude,
118122 index_type,
119- } => Self :: handle_add ( os, path, include, exclude, index_type) . await ,
120- KnowledgeSubcommand :: Remove { path } => Self :: handle_remove ( os, path) . await ,
121- KnowledgeSubcommand :: Update { path } => Self :: handle_update ( os, path) . await ,
123+ } => Self :: handle_add ( os, session , path, include, exclude, index_type) . await ,
124+ KnowledgeSubcommand :: Remove { path } => Self :: handle_remove ( os, session , path) . await ,
125+ KnowledgeSubcommand :: Update { path } => Self :: handle_update ( os, session , path) . await ,
122126 KnowledgeSubcommand :: Clear => Self :: handle_clear ( os, session) . await ,
123- KnowledgeSubcommand :: Status => Self :: handle_status ( os) . await ,
124- KnowledgeSubcommand :: Cancel { operation_id } => Self :: handle_cancel ( os, operation_id. as_deref ( ) ) . await ,
127+ KnowledgeSubcommand :: Status => Self :: handle_status ( os, session) . await ,
128+ KnowledgeSubcommand :: Cancel { operation_id } => {
129+ Self :: handle_cancel ( os, session, operation_id. as_deref ( ) ) . await
130+ } ,
125131 }
126132 }
127133
128134 async fn handle_show ( os : & Os , session : & mut ChatSession ) -> Result < ( ) , std:: io:: Error > {
129- match KnowledgeStore :: get_async_instance_with_os ( os) . await {
130- Ok ( store) => {
131- let store = store. lock ( ) . await ;
132- let entries = store. get_all ( ) . await . unwrap_or_else ( |e| {
133- let _ = queue ! (
134- session. stderr,
135- style:: SetForegroundColor ( Color :: Red ) ,
136- style:: Print ( & format!( "Error getting knowledge base entries: {}\n " , e) ) ,
137- style:: ResetColor
138- ) ;
139- Vec :: new ( )
140- } ) ;
141- let _ = Self :: format_knowledge_entries ( session, & entries) ;
142- } ,
143- Err ( e) => {
144- queue ! (
145- session. stderr,
146- style:: SetForegroundColor ( Color :: Red ) ,
147- style:: Print ( & format!( "Error accessing knowledge base: {}\n " , e) ) ,
148- style:: SetForegroundColor ( Color :: Reset )
149- ) ?;
150- } ,
151- }
152- Ok ( ( ) )
153- }
135+ let agent_name = Self :: get_agent ( session) . map ( |a| a. name . clone ( ) ) ;
154136
155- fn format_knowledge_entries (
156- session : & mut ChatSession ,
157- knowledge_entries : & [ KnowledgeContext ] ,
158- ) -> Result < ( ) , std:: io:: Error > {
159- if knowledge_entries. is_empty ( ) {
160- queue ! (
161- session. stderr,
162- style:: Print ( "\n No knowledge base entries found.\n " ) ,
163- style:: Print ( "💡 Tip: If indexing is in progress, entries may not appear until indexing completes.\n " ) ,
164- style:: Print ( " Use 'knowledge status' to check active operations.\n \n " )
165- ) ?;
166- } else {
137+ // Show agent-specific knowledge
138+ if let Some ( agent) = agent_name {
167139 queue ! (
168140 session. stderr,
169- style:: Print ( "\n 📚 Knowledge Base Entries:\n " ) ,
170- style:: Print ( format!( "{}\n " , "━" . repeat( 80 ) ) )
141+ style:: SetAttribute ( crossterm:: style:: Attribute :: Bold ) ,
142+ style:: SetForegroundColor ( Color :: Magenta ) ,
143+ style:: Print ( format!( "👤 Agent ({}):\n " , agent) ) ,
144+ style:: SetAttribute ( crossterm:: style:: Attribute :: Reset ) ,
171145 ) ?;
172146
173- for entry in knowledge_entries {
174- Self :: format_single_entry ( session, & entry) ?;
175- queue ! ( session. stderr, style:: Print ( format!( "{}\n " , "━" . repeat( 80 ) ) ) ) ?;
147+ match KnowledgeStore :: get_async_instance ( os, Self :: get_agent ( session) ) . await {
148+ Ok ( store) => {
149+ let store = store. lock ( ) . await ;
150+ let contexts = store. get_all ( ) . await . unwrap_or_default ( ) ;
151+
152+ if contexts. is_empty ( ) {
153+ queue ! (
154+ session. stderr,
155+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
156+ style:: Print ( " <none>\n \n " ) ,
157+ style:: SetForegroundColor ( Color :: Reset )
158+ ) ?;
159+ } else {
160+ Self :: format_knowledge_entries_with_indent ( session, & contexts, " " ) ?;
161+ }
162+ } ,
163+ Err ( _) => {
164+ queue ! (
165+ session. stderr,
166+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
167+ style:: Print ( " <none>\n \n " ) ,
168+ style:: SetForegroundColor ( Color :: Reset )
169+ ) ?;
170+ } ,
176171 }
177- // Add final newline to match original formatting exactly
178- queue ! ( session. stderr, style:: Print ( "\n " ) ) ?;
179172 }
173+
180174 Ok ( ( ) )
181175 }
182176
183- fn format_single_entry ( session : & mut ChatSession , entry : & & KnowledgeContext ) -> Result < ( ) , std:: io:: Error > {
184- queue ! (
185- session. stderr,
186- style:: SetAttribute ( style:: Attribute :: Bold ) ,
187- style:: SetForegroundColor ( Color :: Cyan ) ,
188- style:: Print ( format!( "📂 {}: " , entry. id) ) ,
189- style:: SetForegroundColor ( Color :: Green ) ,
190- style:: Print ( & entry. name) ,
191- style:: SetAttribute ( style:: Attribute :: Reset ) ,
192- style:: Print ( "\n " )
193- ) ?;
194-
195- queue ! (
196- session. stderr,
197- style:: Print ( format!( " Description: {}\n " , entry. description) ) ,
198- style:: Print ( format!(
199- " Created: {}\n " ,
200- entry. created_at. format( "%Y-%m-%d %H:%M:%S" )
201- ) ) ,
202- style:: Print ( format!(
203- " Updated: {}\n " ,
204- entry. updated_at. format( "%Y-%m-%d %H:%M:%S" )
205- ) )
206- ) ?;
207-
208- if let Some ( path) = & entry. source_path {
209- queue ! ( session. stderr, style:: Print ( format!( " Source: {}\n " , path) ) ) ?;
210- }
211-
212- queue ! (
213- session. stderr,
214- style:: Print ( " Items: " ) ,
215- style:: SetForegroundColor ( Color :: Yellow ) ,
216- style:: Print ( entry. item_count. to_string( ) ) ,
217- style:: SetForegroundColor ( Color :: Reset ) ,
218- style:: Print ( " | Index Type: " ) ,
219- style:: SetForegroundColor ( Color :: Magenta ) ,
220- style:: Print ( entry. embedding_type. description( ) . to_string( ) ) ,
221- style:: SetForegroundColor ( Color :: Reset ) ,
222- style:: Print ( " | Persistent: " )
223- ) ?;
224-
225- if entry. persistent {
177+ fn format_knowledge_entries_with_indent (
178+ session : & mut ChatSession ,
179+ contexts : & [ semantic_search_client:: KnowledgeContext ] ,
180+ indent : & str ,
181+ ) -> Result < ( ) , std:: io:: Error > {
182+ for ctx in contexts {
183+ // Main entry line with name and ID
226184 queue ! (
227185 session. stderr,
186+ style:: Print ( format!( "{}📂 " , indent) ) ,
187+ style:: SetAttribute ( style:: Attribute :: Bold ) ,
188+ style:: SetForegroundColor ( Color :: Grey ) ,
189+ style:: Print ( & ctx. name) ,
228190 style:: SetForegroundColor ( Color :: Green ) ,
229- style:: Print ( "Yes" ) ,
191+ style:: Print ( format!( " ({})" , & ctx. id[ ..8 ] ) ) ,
192+ style:: SetAttribute ( style:: Attribute :: Reset ) ,
230193 style:: SetForegroundColor ( Color :: Reset ) ,
231194 style:: Print ( "\n " )
232195 ) ?;
233- } else {
196+
197+ // Description line with original description
234198 queue ! (
235199 session. stderr,
236- style:: SetForegroundColor ( Color :: Yellow ) ,
237- style:: Print ( "No" ) ,
200+ style:: Print ( format!( "{} " , indent) ) ,
201+ style:: SetForegroundColor ( Color :: Grey ) ,
202+ style:: Print ( format!( "{}\n " , ctx. description) ) ,
203+ style:: SetForegroundColor ( Color :: Reset )
204+ ) ?;
205+
206+ // Stats line with improved colors
207+ queue ! (
208+ session. stderr,
209+ style:: Print ( format!( "{} " , indent) ) ,
210+ style:: SetForegroundColor ( Color :: Green ) ,
211+ style:: Print ( format!( "{} items" , ctx. item_count) ) ,
212+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
213+ style:: Print ( " • " ) ,
214+ style:: SetForegroundColor ( Color :: Blue ) ,
215+ style:: Print ( ctx. embedding_type. description( ) ) ,
216+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
217+ style:: Print ( " • " ) ,
218+ style:: SetForegroundColor ( Color :: DarkGrey ) ,
219+ style:: Print ( format!( "{}" , ctx. updated_at. format( "%m/%d %H:%M" ) ) ) ,
238220 style:: SetForegroundColor ( Color :: Reset ) ,
239- style:: Print ( "\n " )
221+ style:: Print ( "\n \n " )
240222 ) ?;
241223 }
242224 Ok ( ( ) )
@@ -254,14 +236,17 @@ impl KnowledgeSubcommand {
254236
255237 async fn handle_add (
256238 os : & Os ,
239+ session : & mut ChatSession ,
257240 path : & str ,
258241 include_patterns : & [ String ] ,
259242 exclude_patterns : & [ String ] ,
260243 index_type : & Option < String > ,
261244 ) -> OperationResult {
262245 match Self :: validate_and_sanitize_path ( os, path) {
263246 Ok ( sanitized_path) => {
264- let async_knowledge_store = match KnowledgeStore :: get_async_instance_with_os ( os) . await {
247+ let agent = Self :: get_agent ( session) ;
248+
249+ let async_knowledge_store = match KnowledgeStore :: get_async_instance ( os, agent) . await {
265250 Ok ( store) => store,
266251 Err ( e) => return OperationResult :: Error ( format ! ( "Error accessing knowledge base: {}" , e) ) ,
267252 } ;
@@ -307,30 +292,40 @@ impl KnowledgeSubcommand {
307292 }
308293
309294 /// Handle remove operation
310- async fn handle_remove ( os : & Os , path : & str ) -> OperationResult {
295+ async fn handle_remove ( os : & Os , session : & ChatSession , path : & str ) -> OperationResult {
311296 let sanitized_path = sanitize_path_tool_arg ( os, path) ;
297+ let agent = Self :: get_agent ( session) ;
312298
313- let async_knowledge_store = match KnowledgeStore :: get_async_instance_with_os ( os) . await {
299+ let async_knowledge_store = match KnowledgeStore :: get_async_instance ( os, agent ) . await {
314300 Ok ( store) => store,
315301 Err ( e) => return OperationResult :: Error ( format ! ( "Error accessing knowledge base: {}" , e) ) ,
316302 } ;
317303 let mut store = async_knowledge_store. lock ( ) . await ;
318304
305+ let scope_desc = "agent" ;
306+
319307 // Try path first, then name
320308 if store. remove_by_path ( & sanitized_path. to_string_lossy ( ) ) . await . is_ok ( ) {
321- OperationResult :: Success ( format ! ( "Removed knowledge base entry with path '{}'" , path) )
309+ OperationResult :: Success ( format ! (
310+ "Removed {} knowledge base entry with path '{}'" ,
311+ scope_desc, path
312+ ) )
322313 } else if store. remove_by_name ( path) . await . is_ok ( ) {
323- OperationResult :: Success ( format ! ( "Removed knowledge base entry with name '{}'" , path) )
314+ OperationResult :: Success ( format ! (
315+ "Removed {} knowledge base entry with name '{}'" ,
316+ scope_desc, path
317+ ) )
324318 } else {
325- OperationResult :: Warning ( format ! ( "Entry not found in knowledge base: {}" , path) )
319+ OperationResult :: Warning ( format ! ( "Entry not found in {} knowledge base: {}" , scope_desc , path) )
326320 }
327321 }
328322
329323 /// Handle update operation
330- async fn handle_update ( os : & Os , path : & str ) -> OperationResult {
324+ async fn handle_update ( os : & Os , session : & ChatSession , path : & str ) -> OperationResult {
331325 match Self :: validate_and_sanitize_path ( os, path) {
332326 Ok ( sanitized_path) => {
333- let async_knowledge_store = match KnowledgeStore :: get_async_instance_with_os ( os) . await {
327+ let agent = Self :: get_agent ( session) ;
328+ let async_knowledge_store = match KnowledgeStore :: get_async_instance ( os, agent) . await {
334329 Ok ( store) => store,
335330 Err ( e) => {
336331 return OperationResult :: Error ( format ! ( "Error accessing knowledge base directory: {}" , e) ) ;
@@ -368,7 +363,8 @@ impl KnowledgeSubcommand {
368363 return OperationResult :: Info ( "Clear operation cancelled" . to_string ( ) ) ;
369364 }
370365
371- let async_knowledge_store = match KnowledgeStore :: get_async_instance_with_os ( os) . await {
366+ let agent = Self :: get_agent ( session) ;
367+ let async_knowledge_store = match KnowledgeStore :: get_async_instance ( os, agent) . await {
372368 Ok ( store) => store,
373369 Err ( e) => return OperationResult :: Error ( format ! ( "Error accessing knowledge base directory: {}" , e) ) ,
374370 } ;
@@ -401,8 +397,9 @@ impl KnowledgeSubcommand {
401397 }
402398
403399 /// Handle status operation
404- async fn handle_status ( os : & Os ) -> OperationResult {
405- let async_knowledge_store = match KnowledgeStore :: get_async_instance_with_os ( os) . await {
400+ async fn handle_status ( os : & Os , session : & ChatSession ) -> OperationResult {
401+ let agent = Self :: get_agent ( session) ;
402+ let async_knowledge_store = match KnowledgeStore :: get_async_instance ( os, agent) . await {
406403 Ok ( store) => store,
407404 Err ( e) => return OperationResult :: Error ( format ! ( "Error accessing knowledge base directory: {}" , e) ) ,
408405 } ;
@@ -512,8 +509,9 @@ impl KnowledgeSubcommand {
512509 }
513510
514511 /// Handle cancel operation
515- async fn handle_cancel ( os : & Os , operation_id : Option < & str > ) -> OperationResult {
516- let async_knowledge_store = match KnowledgeStore :: get_async_instance_with_os ( os) . await {
512+ async fn handle_cancel ( os : & Os , session : & ChatSession , operation_id : Option < & str > ) -> OperationResult {
513+ let agent = Self :: get_agent ( session) ;
514+ let async_knowledge_store = match KnowledgeStore :: get_async_instance ( os, agent) . await {
517515 Ok ( store) => store,
518516 Err ( e) => return OperationResult :: Error ( format ! ( "Error accessing knowledge base directory: {}" , e) ) ,
519517 } ;
0 commit comments