@@ -519,46 +519,93 @@ export class FrontendPromptCustomizationServiceImpl implements PromptCustomizati
519
519
}
520
520
521
521
async getCustomAgents ( ) : Promise < CustomAgentDescription [ ] > {
522
- const customAgentYamlUri = ( await this . getTemplatesDirectoryURI ( ) ) . resolve ( 'customAgents.yml' ) ;
522
+ const agentsById = new Map < string , CustomAgentDescription > ( ) ;
523
+ // First, process additional (workspace) template directories to give them precedence
524
+ for ( const dirPath of this . additionalTemplateDirs ) {
525
+ const dirURI = URI . fromFilePath ( dirPath ) ;
526
+ await this . loadCustomAgentsFromDirectory ( dirURI , agentsById ) ;
527
+ }
528
+ // Then process global template directory (only adding agents that don't conflict)
529
+ const globalTemplateDir = await this . getTemplatesDirectoryURI ( ) ;
530
+ await this . loadCustomAgentsFromDirectory ( globalTemplateDir , agentsById ) ;
531
+ // Return the merged list of agents
532
+ return Array . from ( agentsById . values ( ) ) ;
533
+ }
534
+
535
+ /**
536
+ * Load custom agents from a specific directory
537
+ * @param directoryURI The URI of the directory to load from
538
+ * @param agentsById Map to store the loaded agents by ID
539
+ */
540
+ protected async loadCustomAgentsFromDirectory (
541
+ directoryURI : URI ,
542
+ agentsById : Map < string , CustomAgentDescription >
543
+ ) : Promise < void > {
544
+ const customAgentYamlUri = directoryURI . resolve ( 'customAgents.yml' ) ;
523
545
const yamlExists = await this . fileService . exists ( customAgentYamlUri ) ;
524
546
if ( ! yamlExists ) {
525
- return [ ] ;
547
+ return ;
526
548
}
527
- const fileContent = await this . fileService . read ( customAgentYamlUri , { encoding : 'utf-8' } ) ;
549
+
528
550
try {
551
+ const fileContent = await this . fileService . read ( customAgentYamlUri , { encoding : 'utf-8' } ) ;
529
552
const doc = load ( fileContent . value ) ;
553
+
530
554
if ( ! Array . isArray ( doc ) || ! doc . every ( entry => CustomAgentDescription . is ( entry ) ) ) {
531
- console . debug ( ' Invalid customAgents.yml file content' ) ;
532
- return [ ] ;
555
+ console . debug ( ` Invalid customAgents.yml file content in ${ directoryURI . toString ( ) } ` ) ;
556
+ return ;
533
557
}
558
+
534
559
const readAgents = doc as CustomAgentDescription [ ] ;
535
- // make sure all agents are unique (id and name)
536
- const uniqueAgentIds = new Set < string > ( ) ;
537
- const uniqueAgents : CustomAgentDescription [ ] = [ ] ;
538
- readAgents . forEach ( agent => {
539
- if ( uniqueAgentIds . has ( agent . id ) ) {
540
- return ;
560
+
561
+ // Add agents to the map if they don't already exist
562
+ for ( const agent of readAgents ) {
563
+ if ( ! agentsById . has ( agent . id ) ) {
564
+ agentsById . set ( agent . id , agent ) ;
541
565
}
542
- uniqueAgentIds . add ( agent . id ) ;
543
- uniqueAgents . push ( agent ) ;
544
- } ) ;
545
- return uniqueAgents ;
566
+ }
546
567
} catch ( e ) {
547
- console . debug ( e . message , e ) ;
548
- return [ ] ;
568
+ console . debug ( `Error loading customAgents.yml from ${ directoryURI . toString ( ) } : ${ e . message } ` , e ) ;
549
569
}
550
570
}
551
571
552
- async openCustomAgentYaml ( ) : Promise < void > {
553
- const customAgentYamlUri = ( await this . getTemplatesDirectoryURI ( ) ) . resolve ( 'customAgents.yml' ) ;
572
+ /**
573
+ * Returns all locations of existing customAgents.yml files and potential locations where
574
+ * new customAgents.yml files could be created.
575
+ *
576
+ * @returns An array of objects containing the URI and whether the file exists
577
+ */
578
+ async getCustomAgentsLocations ( ) : Promise < { uri : URI , exists : boolean } [ ] > {
579
+ const locations : { uri : URI , exists : boolean } [ ] = [ ] ;
580
+ // Check global template directory
581
+ const globalTemplateDir = await this . getTemplatesDirectoryURI ( ) ;
582
+ const globalAgentsUri = globalTemplateDir . resolve ( 'customAgents.yml' ) ;
583
+ const globalExists = await this . fileService . exists ( globalAgentsUri ) ;
584
+ locations . push ( { uri : globalAgentsUri , exists : globalExists } ) ;
585
+ // Check additional (workspace) template directories
586
+ for ( const dirPath of this . additionalTemplateDirs ) {
587
+ const dirURI = URI . fromFilePath ( dirPath ) ;
588
+ const agentsUri = dirURI . resolve ( 'customAgents.yml' ) ;
589
+ const exists = await this . fileService . exists ( agentsUri ) ;
590
+ locations . push ( { uri : agentsUri , exists : exists } ) ;
591
+ }
592
+ return locations ;
593
+ }
594
+
595
+ /**
596
+ * Opens an existing customAgents.yml file at the given URI, or creates a new one if it doesn't exist.
597
+ *
598
+ * @param uri The URI of the customAgents.yml file to open or create
599
+ */
600
+ async openCustomAgentYaml ( uri : URI ) : Promise < void > {
554
601
const content = dump ( [ templateEntry ] ) ;
555
- if ( ! await this . fileService . exists ( customAgentYamlUri ) ) {
556
- await this . fileService . createFile ( customAgentYamlUri , BinaryBuffer . fromString ( content ) ) ;
602
+ if ( ! await this . fileService . exists ( uri ) ) {
603
+ await this . fileService . createFile ( uri , BinaryBuffer . fromString ( content ) ) ;
557
604
} else {
558
- const fileContent = ( await this . fileService . readFile ( customAgentYamlUri ) ) . value ;
559
- await this . fileService . writeFile ( customAgentYamlUri , BinaryBuffer . concat ( [ fileContent , BinaryBuffer . fromString ( content ) ] ) ) ;
605
+ const fileContent = ( await this . fileService . readFile ( uri ) ) . value ;
606
+ await this . fileService . writeFile ( uri , BinaryBuffer . concat ( [ fileContent , BinaryBuffer . fromString ( content ) ] ) ) ;
560
607
}
561
- const openHandler = await this . openerService . getOpener ( customAgentYamlUri ) ;
562
- openHandler . open ( customAgentYamlUri ) ;
608
+ const openHandler = await this . openerService . getOpener ( uri ) ;
609
+ openHandler . open ( uri ) ;
563
610
}
564
611
}
0 commit comments