@@ -77,37 +77,29 @@ const getGreenDevAdditionalWidgetGuidelines = (): string => {
7777
7878 if ( widgetsFromFunctionCalls ) {
7979 return `
80- - CRITICAL: You have access to three functions for adding rich, interactive widgets to your response:
81- \`addInsightWidget\`, \`addNetworkRequestWidget\`, and \`addFlameChartWidget\`.
82- You MUST use these functions whenever you refer to a corresponding entity.
83-
84- - **\`addInsightWidget({insightType: '...'})\`**:
85- - **When to use**: Call this function every time you mention a specific performance insight (e.g., LCP, INP,
86- CLS culprits).
87- - **Purpose**: It embeds an interactive widget that provides a detailed breakdown and visualization of the
88- insight.
89- - **Example**: If you are explaining the causes of a poor LCP score, you MUST also call
90- \`addInsightWidget({insightType: 'LCPBreakdown'})\`. This provides the user with the data to explore
91- alongside your explanation.
92- - **\`addNetworkRequestWidget({eventKey: '...'})\`**:
80+ - CRITICAL: You have access to a function for adding rich, interactive widgets to your response: \`addWidget\`.
81+ You MUST use this function whenever you refer to a corresponding entity.
82+
83+ - **\`addWidget({widget: {type: 'insight', insightType: '...'}})\`**:
84+ - **When to use**: Call this function every time you mention a specific performance insight (e.g., LCP, INP, CLS culprits).
85+ - **Purpose**: It embeds an interactive widget that provides a detailed breakdown and visualization of the insight.
86+ - **Example**: If you are explaining the causes of a poor LCP score, you MUST also call \`addWidget({widget: {type: 'insight', insightType: 'LCPBreakdown'}})\`.
87+
88+ - **\`addWidget({widget: {type: 'network-request', eventKey: '...'}})\`**:
9389 - **When to use**: Call this function whenever you discuss a specific network request.
94- - **Purpose**: It adds a widget displaying the full details of the network request, such as its timing,
95- headers, and priority.
96- - **Critical**: The eventKey should be the trace event key (only the number, no letters prefix or -) of that
97- script's network request.
98- - **Example**: If you identify a render-blocking script, you MUST also call
99- \`addNetworkRequestWidget({eventKey: '...'})\` with the trace event key (only the number, no letters prefix
100- or -) of that script's network request.
101- - **\`addFlameChartWidget({start: ..., end: ...})\`**:
102- - **When to use**: Call this function to highlight a specific time range within the trace, especially when
103- discussing long tasks, specific events, or periods of high activity.
90+ - **Purpose**: It adds a widget displaying the full details of the network request, such as its timing, headers, and priority.
91+ - **Critical**: The eventKey should be the trace event key (only the number, no letters prefix or -) of that script's network request.
92+ - **Example**: If you identify a render-blocking script, you MUST also call \`addWidget({widget: {type: 'network-request', eventKey: '...'}})\`.
93+
94+ - **\`addWidget({widget: {type: 'flamechart', start: ..., end: ...}})\`**:
95+ - **When to use**: Call this function to highlight a specific time range within the trace, especially when discussing long tasks, specific events, or periods of high activity.
10496 - **Purpose**: It embeds a focused flame chart visualization for the given time range (in microseconds).
105- - **Example**: If you find a long task that is blocking the main thread, you MUST also call
106- \`addFlameChartWidget({start: 123456, end: 789012})\`. This provides the user with the data to explore
107- alongside your explanation.
97+ - **Example**: If you find a long task that is blocking the main thread, you MUST also call \`addWidget({widget: {type: 'flamechart', start: 123456, end: 789012}})\`.
98+
10899- **General Rules**:
109- - You MUST call these functions as soon as you identify the entity you are discussing.
100+ - You MUST call this function as soon as you identify the entity you are discussing.
110101 - Do NOT add more than one widget for the same insight, network request, or time range to avoid redundancy.
102+ - If you have already shown a widget for any specific insight, network request, or time range, do not show it again.
111103` ;
112104 }
113105
@@ -1247,104 +1239,105 @@ export class PerformanceAgent extends AiAgent<AgentFocus> {
12471239 }
12481240
12491241 if ( Root . Runtime . hostConfig . devToolsGreenDevUi ?. enabled ) {
1250- this . declareFunction < { insightType : Trace . Insights . Types . InsightKeys } > ( 'addInsightWidget' , {
1242+ this . declareFunction <
1243+ {
1244+ type : 'insight' | 'network-request' | 'flamechart' ,
1245+ insightType ?: Trace . Insights . Types . InsightKeys ,
1246+ eventKey ?: number ,
1247+ start ?: number ,
1248+ end ?: number ,
1249+ } ,
1250+ object | { error : string } > ( 'addWidget' , {
12511251 description :
1252- 'Adds an insight widget to the response. When mentioning an insight, call this function to also display an appropriate widget.' ,
1252+ 'Adds an insight widget to the response. When mentioning an insight, call this function to also display an appropriate widget. Use this as much as possible to provide a better user experience. ' ,
12531253 parameters : {
12541254 type : Host . AidaClient . ParametersTypes . OBJECT ,
12551255 description : '' ,
12561256 nullable : false ,
12571257 properties : {
1258- insightType : {
1258+ type : {
12591259 type : Host . AidaClient . ParametersTypes . STRING ,
1260- description :
1261- 'The name of the insight. Only use the insight names given in the "Available insights" list.' ,
1260+ description : 'The type of the widget to add. Possible values: insight, network-request, flamechart' ,
12621261 nullable : false ,
12631262 } ,
1264- } ,
1265- } ,
1266- handler : async _params => {
1267- ArtifactsManager . instance ( ) . addArtifact ( { type : 'insight' , insightType : _params . insightType } ) ;
1268- return { result : { success : true } } ;
1269- } ,
1270- } ) ;
1271-
1272- this . declareFunction < { eventKey : string } , object | { error : string } > ( 'addNetworkRequestWidget' , {
1273- description :
1274- 'Adds a network request widget to the response. When mentioning a network request, call this function with its trace event key.' ,
1275- parameters : {
1276- type : Host . AidaClient . ParametersTypes . OBJECT ,
1277- description : '' ,
1278- nullable : false ,
1279- properties : {
1263+ insightType : {
1264+ type : Host . AidaClient . ParametersTypes . STRING ,
1265+ description : 'The type of the insight widget. Include for insight widgets.' ,
1266+ nullable : true ,
1267+ } ,
12801268 eventKey : {
12811269 type : Host . AidaClient . ParametersTypes . STRING ,
1282- description : 'The trace event key for the network request.' ,
1283- nullable : false ,
1270+ description : 'The event key for the network request widget. Include for network request widgets .' ,
1271+ nullable : true ,
12841272 } ,
1285- } ,
1286- } ,
1287- handler : async _params => {
1288- const rawTraceEvent =
1289- Trace . Helpers . SyntheticEvents . SyntheticEventsManager . getActiveManager ( ) . getRawTraceEvents ( ) . at (
1290- Number ( _params . eventKey ) ) ;
1291- // Get the trace event object if it is available.
1292- // If the trace is uploaded, we need to use the synthetic event.
1293- if ( rawTraceEvent && Trace . Types . Events . isSyntheticNetworkRequest ( rawTraceEvent ) ) {
1294- const rawTraceEventId = rawTraceEvent ?. args ?. data ?. requestId ;
1295- const rawTraceEventUrl = rawTraceEvent ?. args ?. data ?. url ;
1296- const networkRequest = rawTraceEvent ? Logs . NetworkLog . NetworkLog . instance ( )
1297- . requestsForId ( rawTraceEventId )
1298- . find ( r => r . url ( ) === rawTraceEventUrl ) :
1299- null ;
1300- if ( networkRequest ) {
1301- ArtifactsManager . instance ( ) . addArtifact ( { type : 'network-request' , request : networkRequest } ) ;
1302- return { result : { success : true } } ;
1303- }
1304- }
1305-
1306- const syntheticRequest =
1307- Trace . Helpers . SyntheticEvents . SyntheticEventsManager . getActiveManager ( ) . syntheticEventForRawEventIndex (
1308- Number ( _params . eventKey ) ) ;
1309-
1310- if ( syntheticRequest && Trace . Types . Events . isSyntheticNetworkRequest ( syntheticRequest ) ) {
1311- ArtifactsManager . instance ( ) . addArtifact ( {
1312- type : 'network-request' ,
1313- request : syntheticRequest ,
1314- } ) ;
1315- return { result : { success : true } } ;
1316- }
1317-
1318- return { result : { error : 'Could not find network request' } } ;
1319- } ,
1320- } ) ;
1321-
1322- this . declareFunction < { start : number , end : number } , object | { error : string } > ( 'addFlameChartWidget' , {
1323- description : 'Adds a flame chart widget to the response.' ,
1324- parameters : {
1325- type : Host . AidaClient . ParametersTypes . OBJECT ,
1326- description : '' ,
1327- nullable : false ,
1328- properties : {
13291273 start : {
13301274 type : Host . AidaClient . ParametersTypes . INTEGER ,
1331- description : 'The start time of the flame chart in microseconds .' ,
1332- nullable : false ,
1275+ description : 'The start time for the flame chart widget. Include for flame chart widgets .' ,
1276+ nullable : true ,
13331277 } ,
13341278 end : {
13351279 type : Host . AidaClient . ParametersTypes . INTEGER ,
1336- description : 'The end time of the flame chart in microseconds .' ,
1337- nullable : false ,
1280+ description : 'The end time for the flame chart widget. Include for flame chart widgets .' ,
1281+ nullable : true ,
13381282 } ,
13391283 } ,
13401284 } ,
1341- handler : async _params => {
1342- ArtifactsManager . instance ( ) . addArtifact ( {
1343- type : 'flamechart' ,
1344- start : Trace . Types . Timing . Micro ( _params . start ) ,
1345- end : Trace . Types . Timing . Micro ( _params . end ) ,
1346- } ) ;
1347- return { result : { success : true } } ;
1285+ handler : async params => {
1286+ switch ( params . type ) {
1287+ case 'insight' :
1288+ if ( ! params . insightType ) {
1289+ return { error : 'Missing insightType for insight widget' } ;
1290+ }
1291+ ArtifactsManager . instance ( ) . addArtifact ( { type : 'insight' , insightType : params . insightType } ) ;
1292+ return { result : { success : true } } ;
1293+ case 'network-request' : {
1294+ if ( ! params . eventKey ) {
1295+ return { error : 'Missing eventKey for network-request widget' } ;
1296+ }
1297+ const rawTraceEvent =
1298+ Trace . Helpers . SyntheticEvents . SyntheticEventsManager . getActiveManager ( ) . getRawTraceEvents ( ) . at (
1299+ Number ( params . eventKey ) ) ;
1300+ // Get the trace event object if it is available.
1301+ // If the trace is uploaded, we need to use the synthetic event.
1302+ if ( rawTraceEvent && Trace . Types . Events . isSyntheticNetworkRequest ( rawTraceEvent ) ) {
1303+ const rawTraceEventId = rawTraceEvent ?. args ?. data ?. requestId ;
1304+ const rawTraceEventUrl = rawTraceEvent ?. args ?. data ?. url ;
1305+ const networkRequest = rawTraceEvent ? Logs . NetworkLog . NetworkLog . instance ( )
1306+ . requestsForId ( rawTraceEventId )
1307+ . find ( r => r . url ( ) === rawTraceEventUrl ) :
1308+ null ;
1309+ if ( networkRequest ) {
1310+ ArtifactsManager . instance ( ) . addArtifact ( { type : 'network-request' , request : networkRequest } ) ;
1311+ return { result : { success : true } } ;
1312+ }
1313+ }
1314+
1315+ const syntheticRequest = Trace . Helpers . SyntheticEvents . SyntheticEventsManager . getActiveManager ( )
1316+ . syntheticEventForRawEventIndex ( Number ( params . eventKey ) ) ;
1317+
1318+ if ( syntheticRequest && Trace . Types . Events . isSyntheticNetworkRequest ( syntheticRequest ) ) {
1319+ ArtifactsManager . instance ( ) . addArtifact ( {
1320+ type : 'network-request' ,
1321+ request : syntheticRequest ,
1322+ } ) ;
1323+ return { result : { success : true } } ;
1324+ }
1325+
1326+ return { result : { error : 'Could not find network request' } } ;
1327+ }
1328+ case 'flamechart' :
1329+ if ( params . start === undefined || params . end === undefined ) {
1330+ return { error : 'Missing start or end for flamechart widget' } ;
1331+ }
1332+ ArtifactsManager . instance ( ) . addArtifact ( {
1333+ type : 'flamechart' ,
1334+ start : Trace . Types . Timing . Micro ( params . start ) ,
1335+ end : Trace . Types . Timing . Micro ( params . end ) ,
1336+ } ) ;
1337+ return { result : { success : true } } ;
1338+ default :
1339+ return { error : 'Invalid widget type' } ;
1340+ }
13481341 } ,
13491342 } ) ;
13501343 }
0 commit comments