@@ -2,6 +2,7 @@ import { existsSync, readdirSync } from 'node:fs';
22import * as path from 'node:path' ;
33
44import { loadWorkflowModule , isWorkflowTemplate } from '../../../workflows/index.js' ;
5+ import { getAllWorkflowDirectories } from '../../imports/index.js' ;
56
67export type WorkflowAgentDefinition = {
78 id : string ;
@@ -22,46 +23,85 @@ function discoverWorkflowFiles(root: string): string[] {
2223 . map ( ( file ) => path . resolve ( baseDir , file ) ) ;
2324}
2425
26+ /**
27+ * Discover workflow files from all workflow directories including imports
28+ */
29+ function discoverAllWorkflowFiles ( localRoot : string ) : string [ ] {
30+ const allFiles : string [ ] = [ ] ;
31+ const seenDirs = new Set < string > ( ) ;
32+
33+ // Get all workflow directories (imports + local)
34+ const workflowDirs = getAllWorkflowDirectories ( localRoot ) ;
35+
36+ for ( const dir of workflowDirs ) {
37+ if ( seenDirs . has ( dir ) || ! existsSync ( dir ) ) continue ;
38+ seenDirs . add ( dir ) ;
39+
40+ const files = readdirSync ( dir )
41+ . filter ( ( file ) => file . endsWith ( '.workflow.js' ) )
42+ . map ( ( file ) => path . resolve ( dir , file ) ) ;
43+ allFiles . push ( ...files ) ;
44+ }
45+
46+ return allFiles ;
47+ }
48+
2549export async function collectAgentsFromWorkflows ( roots : string [ ] ) : Promise < WorkflowAgentDefinition [ ] > {
2650 const seenFiles = new Set < string > ( ) ;
2751 const byId = new Map < string , WorkflowAgentDefinition > ( ) ;
2852
53+ // Collect workflow files from all roots
54+ const allWorkflowFiles : string [ ] = [ ] ;
55+
2956 for ( const root of roots ) {
3057 if ( ! root ) continue ;
3158 const resolvedRoot = path . resolve ( root ) ;
59+
60+ // Use both traditional discovery and import-aware discovery
3261 for ( const filePath of discoverWorkflowFiles ( resolvedRoot ) ) {
33- if ( seenFiles . has ( filePath ) ) continue ;
34- seenFiles . add ( filePath ) ;
62+ allWorkflowFiles . push ( filePath ) ;
63+ }
64+ }
65+
66+ // Also discover from all import directories (handles case where imports aren't in roots)
67+ if ( roots . length > 0 ) {
68+ const importFiles = discoverAllWorkflowFiles ( roots [ 0 ] ) ;
69+ allWorkflowFiles . push ( ...importFiles ) ;
70+ }
71+
72+ // Process all discovered workflow files
73+ for ( const filePath of allWorkflowFiles ) {
74+ if ( seenFiles . has ( filePath ) ) continue ;
75+ seenFiles . add ( filePath ) ;
3576
36- try {
37- const template = await loadWorkflowModule ( filePath ) ;
38- if ( ! isWorkflowTemplate ( template ) ) {
77+ try {
78+ const template = await loadWorkflowModule ( filePath ) ;
79+ if ( ! isWorkflowTemplate ( template ) ) {
80+ continue ;
81+ }
82+
83+ for ( const step of template . steps ?? [ ] ) {
84+ if ( ! step || step . type !== 'module' ) {
3985 continue ;
4086 }
4187
42- for ( const step of template . steps ?? [ ] ) {
43- if ( ! step || step . type !== 'module' ) {
44- continue ;
45- }
46-
47- const id = typeof step . agentId === 'string' ? step . agentId . trim ( ) : '' ;
48- if ( ! id ) {
49- continue ;
50- }
51-
52- const existing = byId . get ( id ) ?? { id } ;
53- byId . set ( id , {
54- ...existing ,
55- id,
56- name : step . agentName ?? existing . name ,
57- promptPath : step . promptPath ?? existing . promptPath ,
58- model : step . model ?? existing . model ,
59- modelReasoningEffort : step . modelReasoningEffort ?? existing . modelReasoningEffort ,
60- } ) ;
88+ const id = typeof step . agentId === 'string' ? step . agentId . trim ( ) : '' ;
89+ if ( ! id ) {
90+ continue ;
6191 }
62- } catch {
63- // Ignore templates that fail to load; other files might still provide definitions.
92+
93+ const existing = byId . get ( id ) ?? { id } ;
94+ byId . set ( id , {
95+ ...existing ,
96+ id,
97+ name : step . agentName ?? existing . name ,
98+ promptPath : step . promptPath ?? existing . promptPath ,
99+ model : step . model ?? existing . model ,
100+ modelReasoningEffort : step . modelReasoningEffort ?? existing . modelReasoningEffort ,
101+ } ) ;
64102 }
103+ } catch {
104+ // Ignore templates that fail to load; other files might still provide definitions.
65105 }
66106 }
67107
0 commit comments