@@ -36,6 +36,9 @@ pub enum Command {
3636 Context {
3737 subcommand : ContextSubcommand ,
3838 } ,
39+ Knowledge {
40+ subcommand : KnowledgeSubcommand ,
41+ } ,
3942 PromptEditor {
4043 initial_text : Option < String > ,
4144 } ,
@@ -182,6 +185,16 @@ pub enum ContextSubcommand {
182185 Help ,
183186}
184187
188+ #[ derive( Debug , Clone , PartialEq , Eq ) ]
189+ pub enum KnowledgeSubcommand {
190+ Show ,
191+ Add { path : String } ,
192+ Remove { path : String } ,
193+ Update { path : String } ,
194+ Clear ,
195+ Help ,
196+ }
197+
185198impl ContextSubcommand {
186199 const ADD_USAGE : & str = "/context add [--global] [--force] <path1> [path2...]" ;
187200 const AVAILABLE_COMMANDS : & str = color_print:: cstr! { "<cyan!>Available commands</cyan!>
@@ -447,6 +460,113 @@ impl Command {
447460 return Ok ( match parts[ 0 ] . to_lowercase ( ) . as_str ( ) {
448461 "clear" => Self :: Clear ,
449462 "help" => Self :: Help ,
463+ "knowledge" => {
464+ if parts. len ( ) < 2 {
465+ return Ok ( Self :: Knowledge {
466+ subcommand : KnowledgeSubcommand :: Help ,
467+ } ) ;
468+ }
469+
470+ match parts[ 1 ] . to_lowercase ( ) . as_str ( ) {
471+ "show" => Self :: Knowledge {
472+ subcommand : KnowledgeSubcommand :: Show ,
473+ } ,
474+ "add" => {
475+ // Parse add command with path
476+ let mut path = None ;
477+
478+ let args = match shlex:: split ( & parts[ 2 ..] . join ( " " ) ) {
479+ Some ( args) => args,
480+ None => return Err ( "Failed to parse quoted arguments" . to_string ( ) ) ,
481+ } ;
482+
483+ for arg in & args {
484+ if path. is_none ( ) {
485+ path = Some ( arg. to_string ( ) ) ;
486+ } else {
487+ return Err ( format ! ( "Only a single path is allowed. Found extra path: {}" , arg) ) ;
488+ }
489+ }
490+
491+ let path = path. ok_or_else ( || {
492+ format ! (
493+ "Invalid /knowledge arguments.\n \n Usage:\n {}" ,
494+ KnowledgeSubcommand :: ADD_USAGE
495+ )
496+ } ) ?;
497+
498+ Self :: Knowledge {
499+ subcommand : KnowledgeSubcommand :: Add { path } ,
500+ }
501+ } ,
502+ "update" => {
503+ // Parse update command with path
504+ let mut path = None ;
505+
506+ let args = match shlex:: split ( & parts[ 2 ..] . join ( " " ) ) {
507+ Some ( args) => args,
508+ None => return Err ( "Failed to parse quoted arguments" . to_string ( ) ) ,
509+ } ;
510+
511+ for arg in & args {
512+ if path. is_none ( ) {
513+ path = Some ( arg. to_string ( ) ) ;
514+ } else {
515+ return Err ( format ! ( "Only a single path is allowed. Found extra path: {}" , arg) ) ;
516+ }
517+ }
518+
519+ let path = path. ok_or_else ( || {
520+ format ! (
521+ "Invalid /knowledge arguments.\n \n Usage:\n {}" ,
522+ KnowledgeSubcommand :: UPDATE_USAGE
523+ )
524+ } ) ?;
525+
526+ Self :: Knowledge {
527+ subcommand : KnowledgeSubcommand :: Update { path } ,
528+ }
529+ } ,
530+ "rm" => {
531+ // Parse rm command with path
532+ let mut path = None ;
533+ let args = match shlex:: split ( & parts[ 2 ..] . join ( " " ) ) {
534+ Some ( args) => args,
535+ None => return Err ( "Failed to parse quoted arguments" . to_string ( ) ) ,
536+ } ;
537+
538+ for arg in & args {
539+ if path. is_none ( ) {
540+ path = Some ( arg. to_string ( ) ) ;
541+ } else {
542+ return Err ( format ! ( "Only a single path is allowed. Found extra path: {}" , arg) ) ;
543+ }
544+ }
545+
546+ let path = path. ok_or_else ( || {
547+ format ! (
548+ "Invalid /knowledge arguments.\n \n Usage:\n {}" ,
549+ KnowledgeSubcommand :: REMOVE_USAGE
550+ )
551+ } ) ?;
552+ Self :: Knowledge {
553+ subcommand : KnowledgeSubcommand :: Remove { path } ,
554+ }
555+ } ,
556+ "clear" => Self :: Knowledge {
557+ subcommand : KnowledgeSubcommand :: Clear ,
558+ } ,
559+ "help" => Self :: Knowledge {
560+ subcommand : KnowledgeSubcommand :: Help ,
561+ } ,
562+ other => {
563+ return Err ( KnowledgeSubcommand :: usage_msg ( format ! (
564+ "Unknown subcommand '{}'." ,
565+ other
566+ ) ) ) ;
567+ } ,
568+ }
569+ } ,
450570 "compact" => {
451571 let mut prompt = None ;
452572 let show_summary = true ;
@@ -1133,3 +1253,46 @@ mod tests {
11331253 }
11341254 }
11351255}
1256+ impl KnowledgeSubcommand {
1257+ const ADD_USAGE : & str = "/knowledge add <path>" ;
1258+ const AVAILABLE_COMMANDS : & str = color_print:: cstr! { "<cyan!>Available commands</cyan!>
1259+ <em>help</em> <black!>Show an explanation for the knowledge command</black!>
1260+ <em>show</em> <black!>Display the knowledge base contents</black!>
1261+ <em>add <<path>></em> <black!>Add a file or directory to knowledge base</black!>
1262+ <em>update <<path>></em> <black!>Update a file or directory in knowledge base</black!>
1263+ <em>rm <<path>></em> <black!>Remove specified knowledge context by path</black!>
1264+ <em>clear</em> <black!>Remove all knowledge contexts</black!>" } ;
1265+ const BASE_COMMAND : & str = color_print:: cstr! { "<cyan!>Usage: /knowledge [SUBCOMMAND]</cyan!>
1266+
1267+ <cyan!>Description</cyan!>
1268+ Manage knowledge base for semantic search and retrieval.
1269+ Knowledge base is used to store and search information across chat sessions." } ;
1270+ const REMOVE_USAGE : & str = "/knowledge rm <path>" ;
1271+ const UPDATE_USAGE : & str = "/knowledge update <path>" ;
1272+
1273+ fn usage_msg ( header : impl AsRef < str > ) -> String {
1274+ format ! (
1275+ "{}\n \n {}\n \n {}" ,
1276+ header. as_ref( ) ,
1277+ Self :: BASE_COMMAND ,
1278+ Self :: AVAILABLE_COMMANDS
1279+ )
1280+ }
1281+
1282+ pub fn help_text ( ) -> String {
1283+ color_print:: cformat!(
1284+ r#"
1285+ <magenta,em>(Beta) Knowledge Base Management</magenta,em>
1286+
1287+ Knowledge base allows you to store and search information across chat sessions.
1288+ Files and directories added to the knowledge base are indexed for semantic search,
1289+ enabling more relevant and contextual responses.
1290+
1291+ {}
1292+
1293+ {}"# ,
1294+ Self :: BASE_COMMAND ,
1295+ Self :: AVAILABLE_COMMANDS
1296+ )
1297+ }
1298+ }
0 commit comments