@@ -8,7 +8,7 @@ import { readFile } from 'node:fs/promises';
88import { join , parse } from 'node:path' ;
99import { existsSync } from 'node:fs' ;
1010import { SfCommand , Flags } from '@salesforce/sf-plugins-core' ;
11- import { Messages , SfProject } from '@salesforce/core' ;
11+ import { Messages , SfError , SfProject } from '@salesforce/core' ;
1212import { AgentTest } from '@salesforce/agents' ;
1313import { select , input , confirm , checkbox } from '@inquirer/prompts' ;
1414import { XMLParser } from 'fast-xml-parser' ;
@@ -158,39 +158,88 @@ async function getPluginsAndFunctions(
158158 genAiFunctions : string [ ] ;
159159} > {
160160 const botVersions = getMetadataFilePaths ( cs , 'Bot' ) ;
161- const genAiPlanners = getMetadataFilePaths ( cs , 'GenAiPlanner' ) ;
161+ let genAiFunctions : string [ ] = [ ] ;
162+ let genAiPlugins : Record < string , string > = { } ;
162163
163164 const parser = new XMLParser ( ) ;
164165 const botVersionXml = await readFile ( botVersions [ subjectName ] , 'utf-8' ) ;
165166 const parsedBotVersion = parser . parse ( botVersionXml ) as {
166167 BotVersion : { conversationDefinitionPlanners : { genAiPlannerName : string } } ;
167168 } ;
168169
169- const plannerXml = await readFile (
170- genAiPlanners [ parsedBotVersion . BotVersion . conversationDefinitionPlanners . genAiPlannerName ?? subjectName ] ,
171- 'utf-8'
172- ) ;
173- const parsedPlanner = parser . parse ( plannerXml ) as {
174- GenAiPlanner : {
175- genAiPlugins : Array < { genAiPluginName : string } > ;
176- genAiFunctions : Array < { genAiFunctionName : string } > ;
170+ try {
171+ // if the users still have genAiPlanner, not the bundle, we can work with that
172+ const genAiPlanners = getMetadataFilePaths ( cs , 'GenAiPlanner' ) ;
173+
174+ const plannerXml = await readFile (
175+ genAiPlanners [ parsedBotVersion . BotVersion . conversationDefinitionPlanners . genAiPlannerName ?? subjectName ] ,
176+ 'utf-8'
177+ ) ;
178+ const parsedPlanner = parser . parse ( plannerXml ) as {
179+ GenAiPlanner : {
180+ genAiPlugins : Array < { genAiPluginName : string } > ;
181+ genAiFunctions : Array < { genAiFunctionName : string } > ;
182+ } ;
177183 } ;
178- } ;
184+ genAiFunctions = castArray ( parsedPlanner . GenAiPlanner . genAiFunctions ) . map (
185+ ( { genAiFunctionName } ) => genAiFunctionName
186+ ) ;
179187
180- const genAiFunctions = castArray ( parsedPlanner . GenAiPlanner . genAiFunctions ) . map (
181- ( { genAiFunctionName } ) => genAiFunctionName
182- ) ;
188+ genAiPlugins = castArray ( parsedPlanner . GenAiPlanner . genAiPlugins ) . reduce (
189+ ( acc , { genAiPluginName } ) => ( {
190+ ...acc ,
191+ [ genAiPluginName ] : cs . getComponentFilenamesByNameAndType ( {
192+ fullName : genAiPluginName ,
193+ type : 'GenAiPlugin' ,
194+ } ) [ 0 ] ,
195+ } ) ,
196+ { }
197+ ) ;
198+ } catch ( e ) {
199+ // do nothing, we were trying to read the old genAiPlanner
200+ }
183201
184- const genAiPlugins = castArray ( parsedPlanner . GenAiPlanner . genAiPlugins ) . reduce (
185- ( acc , { genAiPluginName } ) => ( {
186- ...acc ,
187- [ genAiPluginName ] : cs . getComponentFilenamesByNameAndType ( {
188- fullName : genAiPluginName ,
189- type : 'GenAiPlugin' ,
190- } ) [ 0 ] ,
191- } ) ,
192- { }
193- ) ;
202+ try {
203+ const genAiPlannerBundles = getMetadataFilePaths ( cs , 'GenAiPlannerBundle' ) ;
204+ const plannerBundleXml = await readFile (
205+ genAiPlannerBundles [ parsedBotVersion . BotVersion . conversationDefinitionPlanners . genAiPlannerName ?? subjectName ] ,
206+ 'utf-8'
207+ ) ;
208+ const parsedPlannerBundle = parser . parse ( plannerBundleXml ) as {
209+ GenAiPlannerBundle : {
210+ genAiPlugins : Array <
211+ | {
212+ genAiPluginName : string ;
213+ }
214+ | { genAiPluginName : string ; genAiCustomizedPlugin : { genAiFunctions : Array < { functionName : string } > } }
215+ > ;
216+ // genAiFunctions: Array<{ genAiFunctionName: string }>;
217+ } ;
218+ } ;
219+ genAiFunctions = castArray ( parsedPlannerBundle . GenAiPlannerBundle . genAiPlugins )
220+ . filter ( ( f ) => 'genAiCustomizedPlugin' in f )
221+ . map (
222+ ( { genAiCustomizedPlugin } ) =>
223+ genAiCustomizedPlugin . genAiFunctions . find ( ( plugin ) => plugin . functionName !== '' ) ! . functionName
224+ ) ;
225+
226+ genAiPlugins = castArray ( parsedPlannerBundle . GenAiPlannerBundle . genAiPlugins ) . reduce (
227+ ( acc , { genAiPluginName } ) => ( {
228+ ...acc ,
229+ [ genAiPluginName ] : cs . getComponentFilenamesByNameAndType ( {
230+ fullName : genAiPluginName ,
231+ type : 'GenAiPlugin' ,
232+ } ) [ 0 ] ,
233+ } ) ,
234+ { }
235+ ) ;
236+ } catch ( e ) {
237+ throw new SfError (
238+ `Error parsing GenAiPlannerBundle: ${
239+ parsedBotVersion . BotVersion . conversationDefinitionPlanners . genAiPlannerName ?? subjectName
240+ } `
241+ ) ;
242+ }
194243
195244 return { genAiPlugins, genAiFunctions } ;
196245}
@@ -292,7 +341,7 @@ export default class AgentGenerateTestSpec extends SfCommand<void> {
292341
293342 const cs = await ComponentSetBuilder . build ( {
294343 metadata : {
295- metadataEntries : [ 'GenAiPlanner ' , 'GenAiPlugin' , 'Bot' ] ,
344+ metadataEntries : [ 'GenAiPlannerBundle ' , 'GenAiPlugin' , 'Bot' ] ,
296345 directoryPaths,
297346 } ,
298347 } ) ;
0 commit comments