@@ -28,8 +28,6 @@ export class Environment {
2828 readonly fullStackFramework : FrameworkInfo ;
2929 /** Information about the client-side framework used within the environment. */
3030 readonly clientSideFramework : FrameworkInfo ;
31- /** Prompts that should be executed as a part of the evaluation. */
32- readonly executablePrompts : RootPromptDefinition [ ] ;
3331 /** Path from which to read the code rating prompt. */
3432 readonly codeRatingPromptPath : string | null ;
3533 /** Whether the prompts should be removed from the final report. */
@@ -58,10 +56,6 @@ export class Environment {
5856 this . getFrameworkDisplayName ( config . fullStackFramework ) || config . clientSideFramework ,
5957 }
6058 : { ...this . clientSideFramework } ;
61- this . executablePrompts = this . resolveExecutablePrompts (
62- config . executablePrompts ,
63- config . ratings ,
64- ) ;
6559 this . codeRatingPromptPath = config . codeRatingPrompt
6660 ? join ( rootPath , config . codeRatingPrompt )
6761 : null ;
@@ -70,22 +64,27 @@ export class Environment {
7064 this . executor = config . executor ;
7165 }
7266
73- systemPromptGeneration = lazy ( ( ) => {
74- return this . renderRelativePrompt ( this . config . generationSystemPrompt ) . result ;
67+ /** Prompts that should be executed as a part of the evaluation. */
68+ executablePrompts = lazy ( async ( ) => {
69+ return this . resolveExecutablePrompts ( this . config . executablePrompts , this . config . ratings ) ;
70+ } ) ;
71+
72+ systemPromptGeneration = lazy ( async ( ) => {
73+ return ( await this . renderSystemPrompt ( this . config . generationSystemPrompt ) ) . result ;
7574 } ) ;
7675
77- systemPromptRepair = lazy ( ( ) => {
76+ systemPromptRepair = lazy ( async ( ) => {
7877 if ( ! this . config . repairSystemPrompt ) {
7978 return 'Please fix the given errors and return the corrected code.' ;
8079 }
81- return this . renderRelativePrompt ( this . config . repairSystemPrompt ) . result ;
80+ return ( await this . renderSystemPrompt ( this . config . repairSystemPrompt ) ) . result ;
8281 } ) ;
8382
84- systemPromptEditing = lazy ( ( ) => {
83+ systemPromptEditing = lazy ( async ( ) => {
8584 if ( ! this . config . editingSystemPrompt ) {
8685 return this . systemPromptGeneration ( ) ;
8786 }
88- return this . renderRelativePrompt ( this . config . editingSystemPrompt ) . result ;
87+ return ( await this . renderSystemPrompt ( this . config . editingSystemPrompt ) ) . result ;
8988 } ) ;
9089
9190 /**
@@ -100,8 +99,8 @@ export class Environment {
10099 ) : Promise < string > {
101100 const systemPrompt =
102101 type === 'generation'
103- ? this . systemPromptGeneration ( )
104- : ( this . systemPromptEditing ( ) ?? this . systemPromptGeneration ( ) ) ;
102+ ? await this . systemPromptGeneration ( )
103+ : await this . systemPromptEditing ( ) ;
105104
106105 if ( ! ragEndpoint ) {
107106 return [ systemPrompt , userPrompt ] . join ( '\n\n' ) ;
@@ -168,11 +167,11 @@ export class Environment {
168167 * @param prompts Prompts to be resolved.
169168 * @param envRatings Environment-level ratings.
170169 */
171- private resolveExecutablePrompts (
170+ private async resolveExecutablePrompts (
172171 prompts : EnvironmentConfig [ 'executablePrompts' ] ,
173172 envRatings : Rating [ ] ,
174- ) {
175- const result : RootPromptDefinition [ ] = [ ] ;
173+ ) : Promise < RootPromptDefinition [ ] > {
174+ const result : Promise < RootPromptDefinition > [ ] = [ ] ;
176175
177176 for ( const def of prompts ) {
178177 if ( def instanceof MultiStepPrompt ) {
@@ -191,20 +190,21 @@ export class Environment {
191190 name = def . name ;
192191 }
193192
194- globSync ( path , { cwd : this . rootPath } ) . forEach ( relativePath => {
195- result . push (
196- this . getStepPromptDefinition (
197- name ?? basename ( relativePath , extname ( relativePath ) ) ,
198- relativePath ,
199- ratings ,
200- /* isEditing */ false ,
201- ) ,
202- ) ;
203- } ) ;
193+ result . push (
194+ ...globSync ( path , { cwd : this . rootPath } ) . map (
195+ async relativePath =>
196+ await this . getStepPromptDefinition (
197+ name ?? basename ( relativePath , extname ( relativePath ) ) ,
198+ relativePath ,
199+ ratings ,
200+ /* isEditing */ false ,
201+ ) ,
202+ ) ,
203+ ) ;
204204 }
205205 }
206206
207- return result ;
207+ return Promise . all ( result ) ;
208208 }
209209
210210 /**
@@ -216,13 +216,13 @@ export class Environment {
216216 * @param ratings Ratings to run against the definition.
217217 * @param isEditing Whether this is an editing or generation step.
218218 */
219- private getStepPromptDefinition (
219+ private async getStepPromptDefinition (
220220 name : string ,
221221 relativePath : string ,
222222 ratings : Rating [ ] ,
223223 isEditing : boolean ,
224- ) : PromptDefinition {
225- const { result, contextFiles} = this . renderRelativePrompt ( relativePath ) ;
224+ ) : Promise < PromptDefinition > {
225+ const { result, contextFiles} = await this . renderEnvironmentPrompt ( relativePath ) ;
226226
227227 return {
228228 name : name ,
@@ -240,10 +240,10 @@ export class Environment {
240240 * @param def Definition of the prompt.
241241 * @param envRatings Environment-level ratings.
242242 */
243- private getMultiStepPrompt (
243+ private async getMultiStepPrompt (
244244 def : MultiStepPrompt ,
245245 envRatings : Rating [ ] ,
246- ) : MultiStepPromptDefinition {
246+ ) : Promise < MultiStepPromptDefinition > {
247247 const promptRoot = resolve ( this . rootPath , def . directoryPath ) ;
248248 const name = basename ( promptRoot ) ;
249249 const steps : PromptDefinition [ ] = [ ] ;
@@ -288,7 +288,7 @@ export class Environment {
288288 if ( stepNum === 0 ) {
289289 throw new UserFacingError ( 'Multi-step prompts start with `step-1`.' ) ;
290290 }
291- const step = this . getStepPromptDefinition (
291+ const step = await this . getStepPromptDefinition (
292292 `${ name } -step-${ stepNum } ` ,
293293 join ( def . directoryPath , current . name ) ,
294294 ratings ,
@@ -317,8 +317,20 @@ export class Environment {
317317 }
318318
319319 /** Renders a prompt from a path relative to the environment config. */
320- private renderRelativePrompt ( relativePath : string ) {
320+ private async renderEnvironmentPrompt ( relativePath : string ) {
321321 const path = resolve ( this . rootPath , relativePath ) ;
322322 return this . renderPrompt ( readFileSync ( path , 'utf8' ) , path ) ;
323323 }
324+
325+ private async renderSystemPrompt ( relativePath : string ) {
326+ const result = await this . renderEnvironmentPrompt ( relativePath ) ;
327+
328+ // Optional hooks for post processing environment system prompts. Useful for e.g.
329+ // supporting `@` references from Gemini CLI or inside g3.
330+ if ( this . executor . postProcessSystemPrompt !== undefined ) {
331+ result . result = await this . executor . postProcessSystemPrompt ( result . result , this . rootPath ) ;
332+ }
333+
334+ return result ;
335+ }
324336}
0 commit comments