Setting the file. One moment.
Deep Dive · Vercel Optimize · vercel-labs/agent-skills · Skills Docs
ContentsBack to the top of the page · scripts
Bundled file Dedup Recs
lib/ deep-dive.mjs
JavaScript · 350 lines · 10 KB
;
14 const ERROR_DEPLOYMENT_LIMIT = 30 ;
15 const ERROR_CODE_LIMIT = 50 ;
16 const WAF_RULE_LIMIT = 20 ;
17 const MIDDLEWARE_PATH_LIMIT = 50 ;
18 const CALLER_LIMIT = 20 ;
19
20 // OData escapes a literal `'` inside a string by doubling it (`it's` → `it''s`).
21 export function escapeODataString ( s ) {
22 if ( typeof s !== 'string' ) return '' ;
23 return s. replace ( /'/ g , "''" );
24 }
25
26 export function odataEq ( dim , value ) {
27 return `${ dim } eq '${ escapeODataString ( value ) }'` ;
28 }
29
30 export function odataAnd ( ... conds ) {
31 return conds. filter (Boolean). join ( ' and ' );
32 }
33
34 export const SPEC_GENERATORS = {
35 slow_route ( c ) {
36 const route = c.route;
37 if ( ! route) return [];
38 const f = odataEq ( 'route' , route);
39 // cacheBreakdown/bandwidthByCache let sub-agent see miss-path cost on static routes (dynamic='error' can still show p95=900ms over millions of requests).
40 return [
41 ... latencyPercentiles ( 'latency' , 'vercel.function_invocation.function_duration_ms' , f),
42 ... latencyPercentiles ( 'ttfb' , 'vercel.function_invocation.ttfb_ms' , f),
43 ... latencyPercentiles ( 'cpu' , 'vercel.function_invocation.function_cpu_time_ms' , f, [ 'p95' ]),
44 {
45 id: 'startTypeSplit' ,
46 metricId: 'vercel.function_invocation.count' ,
47 aggregation: 'sum' ,
48 groupBy: [ 'function_start_type' ],
49 filter: f,
50 broadPassEquivalent: { key: 'fnStartTypeByRoute' , routeFilter: route, projectDims: [ 'function_start_type' ] },
51 },
52 // function-invocation status (5xx from function) — distinct from request-level status, can't reuse broad-pass.
53 {
54 id: 'statusDistribution' ,
55 metricId: 'vercel.function_invocation.count' ,
56 aggregation: 'sum' ,
57 groupBy: [ 'http_status' ],
58 filter: f,
59 },
60 {
61 id: 'perDeployment' ,
62 metricId: 'vercel.function_invocation.function_duration_ms' ,
63 aggregation: 'p95' ,
64 groupBy: [ 'deployment_id' ],
65 filter: f,
66 limit: DEPLOYMENT_LIMIT ,
67 },
68 {
69 id: 'cacheBreakdown' ,
70 metricId: 'vercel.request.count' ,
71 aggregation: 'sum' ,
72 groupBy: [ 'cache_result' ],
73 filter: f,
74 broadPassEquivalent: { key: 'requestsByRouteCache' , routeFilter: route, projectDims: [ 'cache_result' ] },
75 },
76 // broad-pass bandwidthByCacheResult is account-wide, so per-route still required.
77 {
78 id: 'bandwidthByCache' ,
79 metricId: 'vercel.request.fdt_total_bytes' ,
80 aggregation: 'sum' ,
81 groupBy: [ 'cache_result' ],
82 filter: f,
83 },
84 ];
85 },
86
87 uncached_route ( c ) {
88 const route = c.route;
89 if ( ! route) return [];
90 const f = odataEq ( 'route' , route);
91 return [
92 {
93 id: 'cacheBreakdown' ,
94 metricId: 'vercel.request.count' ,
95 aggregation: 'sum' ,
96 groupBy: [ 'cache_result' ],
97 filter: f,
98 broadPassEquivalent: { key: 'requestsByRouteCache' , routeFilter: route, projectDims: [ 'cache_result' ] },
99 },
100 {
101 id: 'methodDistribution' ,
102 metricId: 'vercel.request.count' ,
103 aggregation: 'sum' ,
104 groupBy: [ 'request_method' ],
105 filter: f,
106 broadPassEquivalent: { key: 'requestsByRouteMethod' , routeFilter: route, projectDims: [ 'request_method' ] },
107 },
108 {
109 id: 'botShare' ,
110 metricId: 'vercel.request.fdt_total_bytes' ,
111 aggregation: 'sum' ,
112 groupBy: [ 'bot_category' ],
113 filter: f,
114 },
115 {
116 id: 'bandwidthByCache' ,
117 metricId: 'vercel.request.fdt_total_bytes' ,
118 aggregation: 'sum' ,
119 groupBy: [ 'cache_result' ],
120 filter: f,
121 },
122 ];
123 },
124
125 cold_start ( c ) {
126 const route = c.route;
127 if ( ! route) return [];
128 const f = odataEq ( 'route' , route);
129 return [
130 {
131 id: 'startTypeSplit' ,
132 metricId: 'vercel.function_invocation.count' ,
133 aggregation: 'sum' ,
134 groupBy: [ 'function_start_type' ],
135 filter: f,
136 },
137 {
138 id: 'coldVsWarmLatencyP95' ,
139 metricId: 'vercel.function_invocation.function_duration_ms' ,
140 aggregation: 'p95' ,
141 groupBy: [ 'function_start_type' ],
142 filter: f,
143 },
144 {
145 id: 'coldByDeployment' ,
146 metricId: 'vercel.function_invocation.count' ,
147 aggregation: 'sum' ,
148 groupBy: [ 'deployment_id' ],
149 filter: odataAnd (f, odataEq ( 'function_start_type' , 'cold' )),
150 limit: DEPLOYMENT_LIMIT ,
151 },
152 ];
153 },
154
155 route_errors ( c ) {
156 const route = c.route;
157 if ( ! route) return [];
158 const f = odataEq ( 'route' , route);
159 return [
160 {
161 id: 'errorStatusPattern' ,
162 metricId: 'vercel.request.count' ,
163 aggregation: 'sum' ,
164 groupBy: [ 'http_status' ],
165 filter: odataAnd (f, "http_status ge '500'" ),
166 },
167 {
168 id: 'errorCodes' ,
169 metricId: 'vercel.function_invocation.count' ,
170 aggregation: 'sum' ,
171 groupBy: [ 'error_code' ],
172 filter: f,
173 limit: ERROR_CODE_LIMIT ,
174 },
175 {
176 id: 'errorsByDeployment' ,
177 metricId: 'vercel.function_invocation.count' ,
178 aggregation: 'sum' ,
179 groupBy: [ 'deployment_id' , 'http_status' ],
180 filter: f,
181 limit: ERROR_DEPLOYMENT_LIMIT ,
182 },
183 ];
184 },
185
186 external_api_slow ( c ) {
187 const host = c.hostname;
188 if ( ! host) return [];
189 const f = odataEq ( 'origin_hostname' , host);
190 return [
191 ... latencyPercentiles ( 'latency' , 'vercel.external_api_request.request_duration_ms' , f),
192 {
193 // "calling route" dim is origin_route (verified via metrics schema).
194 id: 'callersByRoute' ,
195 metricId: 'vercel.external_api_request.count' ,
196 aggregation: 'sum' ,
197 groupBy: [ 'origin_route' ],
198 filter: f,
199 limit: CALLER_LIMIT ,
200 },
201 {
202 id: 'transferBytes' ,
203 metricId: 'vercel.external_api_request.transfer_bytes' ,
204 aggregation: 'sum' ,
205 groupBy: [],
206 filter: f,
207 },
208 ];
209 },
210
211 isr_overrevalidation ( c ) {
212 const route = c.route;
213 if ( ! route) return [];
214 const f = odataEq ( 'route' , route);
215 return [
216 {
217 id: 'writePattern' ,
218 metricId: 'vercel.isr_operation.write_units' ,
219 aggregation: 'sum' ,
220 groupBy: [ 'cache_result' ],
221 filter: f,
222 },
223 {
224 id: 'readPattern' ,
225 metricId: 'vercel.isr_operation.read_units' ,
226 aggregation: 'sum' ,
227 groupBy: [ 'cache_result' ],
228 filter: f,
229 },
230 ];
231 },
232
233 cwv_poor ( c ) {
234 const route = c.route;
235 if ( ! route) return [];
236 const f = odataEq ( 'route' , route);
237 return [
238 ... latencyPercentiles ( 'lcp' , 'vercel.speed_insights_metric.lcp' , f, [ 'p50' , 'p75' , 'p95' ]),
239 ... latencyPercentiles ( 'inp' , 'vercel.speed_insights_metric.inp' , f, [ 'p50' , 'p75' , 'p95' ]),
240 ... latencyPercentiles ( 'cls' , 'vercel.speed_insights_metric.cls' , f, [ 'p50' , 'p75' , 'p95' ]),
241 ];
242 },
243
244 middleware_heavy ( _c ) {
245 // Account-scope. Surface top middleware-paths so recommender has named targets.
246 return [
247 {
248 id: 'topMiddlewarePaths' ,
249 metricId: 'vercel.middleware_invocation.count' ,
250 aggregation: 'sum' ,
251 groupBy: [ 'request_path' ],
252 limit: MIDDLEWARE_PATH_LIMIT ,
253 },
254 ];
255 },
256
257 platform_fluid_compute ( _c ) {
258 // Broad-pass fnStartTypeByRoute already covers this account-scope rec; runner notes reuse.
259 return [];
260 },
261
262 platform_bot_protection ( _c ) {
263 return [
264 {
265 id: 'wafRuleFirings' ,
266 metricId: 'vercel.firewall_action.count' ,
267 aggregation: 'sum' ,
268 groupBy: [ 'waf_rule_id' ],
269 limit: WAF_RULE_LIMIT ,
270 },
271 ];
272 },
273
274 observability_events_attribution ( _c ) {
275 // Account-scope billing signal; broad-pass usage and existing route/cache/middleware metrics carry the evidence.
276 return [];
277 },
278
279 usage_spike_triage ( _c ) {
280 // Daily billing breakdown is already in the gate evidence; no per-candidate metrics query exists.
281 return [];
282 },
283
284 build_minutes_fanout ( _c ) {
285 // Account-scope billing signal + scanner findings carry the evidence; no per-candidate query.
286 return [];
287 },
288
289 region_misconfig ( _c ) {
290 // Branch 2 (scanner-only) — per-region TTFB metric unavailable today, so no deep-dive query.
291 return [];
292 },
293 };
294
295 // Scanner-driven kinds skip deep-dive — evidence already in scanner findings (file + line).
296 export const SCANNER_KINDS = new Set ([
297 'image_optimization' ,
298 'cache_header_gap' ,
299 'rendering_candidate' ,
300 'use_cache_date_stamp' ,
301 'cache_components_suspense_dedupe' ,
302 ]);
303
304 export function specsForCandidate ( candidate ) {
305 const kind = candidate?.kind;
306 if ( ! kind) return [];
307 if ( SCANNER_KINDS . has (kind)) return [];
308 const gen = SPEC_GENERATORS [kind];
309 if ( ! gen) return [];
310 return gen (candidate). map (( s ) => ({ since: TIME_WINDOW , ... s }));
311 }
312
313 // One spec per percentile — CLI does not support `-a p50 -a p95` multi-aggregation.
314 function latencyPercentiles ( idPrefix , metricId , filter , percentiles = [ 'p50' , 'p75' , 'p95' , 'p99' ]) {
315 return percentiles. map (( p ) => ({
316 id: `${ idPrefix }.${ p }` ,
317 metricId,
318 aggregation: p,
319 groupBy: [],
320 filter,
321 }));
322 }
323
324 // Dot-notation spec ids (`latency.p95`) nest under their group prefix.
325 export function mergeIntoEvidence ( results ) {
326 const out = {};
327 for ( const r of results) {
328 const id = r?.spec?.id;
329 if ( ! id) continue ;
330 const dot = id. indexOf ( '.' );
331 if (dot > - 1 ) {
332 const head = id. slice ( 0 , dot);
333 const leaf = id. slice (dot + 1 );
334 if ( ! out[head]) out[head] = {};
335 out[head][leaf] = simplify (r);
336 } else {
337 out[id] = simplify (r);
338 }
339 }
340 return out;
341 }
342
343 // Avoid leaking raw CLI payload / candidate+spec wrapper into evidence — keep summary-only.
344 function simplify ( r ) {
345 if ( ! r || r.ok === false ) return { error: r?.error ?? 'unknown' };
346 // Check rows before value so tabular results with both stay tabular.
347 if (Array. isArray (r.rows)) return r.rows;
348 if ( 'value' in r) return r.value;
349 return null ;
350 }