Setting the file. One moment.
Platform Fluid Compute · Vercel Optimize · vercel-labs/agent-skills · Skills Docs
ContentsBack to the top of the page lib/gates/platform-fluid-compute.mjs
lib/gates/ platform-fluid-compute.mjs
JavaScript · 83 lines · 4 KB
,
11 };
12
13 export function gate ( signals ) {
14 // If project config failed to load we can't tell if Fluid is on; recommending it when already-on
15 // erodes trust badly, so stay silent and let Strengths note the gap.
16 if (signals.project?.error) return [];
17
18 const fluidEnabled =
19 signals.project?.resourceConfig?.fluid === true
20 || signals.project?.defaultResourceConfig?.fluid === true ;
21 if (fluidEnabled) return [];
22
23 const cold = extractHighColdRoutes (signals);
24 const slow = extractSlowHotRoutes (signals);
25 if (cold. length === 0 && slow. length === 0 ) return [];
26
27 return [{
28 kind: metadata.id,
29 scope: 'account' ,
30 files: [],
31 priority: 50 ,
32 confidence: cold. length > 0 ? 0.85 : 0.65 ,
33 o11ySignal: cold. length > 0
34 ? `${ cold . length } route(s) with high cold-start rate`
35 : `${ slow . length } hot route(s) with p95>1s; cold-start not directly observable` ,
36 reason: cold. length > 0
37 ? 'cold starts observed and Fluid Compute is disabled'
38 : 'slow hot routes and Fluid Compute is disabled' ,
39 question: 'Would enabling Fluid Compute reduce cold-start and warm-instance reuse overhead for the observed hot routes?' ,
40 evidence: { fluidEnabled, highColdRoutes: cold. slice ( 0 , 5 ), slowHotRoutes: slow. slice ( 0 , 5 ) },
41 }];
42 }
43
44 function extractHighColdRoutes ( signals ) {
45 const live = signals.metrics?.fnStartTypeByRoute?.rows;
46 if (Array. isArray (live) && live. some (( r ) => 'coldCount' in r || 'coldPct' in r)) {
47 return live. filter (( r ) => r.route && (r.coldPct ?? 0 ) > 0.3 && (r.total ?? 0 ) > 100 );
48 }
49 // Legacy pre-derived fixture shape.
50 const direct = signals.metrics?.coldStartByRoute?.rows;
51 if (Array. isArray (direct)) {
52 return direct. filter (( r ) => r.route && (r.coldPct ?? 0 ) > 0.3 && (r.total ?? 0 ) > 100 );
53 }
54 const legacy = signals.metrics?.coldStarts?.series;
55 if (Array. isArray (legacy)) {
56 return legacy
57 . map (( s ) => {
58 const total = s.summary?.count ?? 0 ;
59 const coldCount = s.summary?.coldCount ?? s.summary?.sum ?? 0 ;
60 return { route: s.groupValues?.route, total, coldPct: total > 0 ? coldCount / total : 0 };
61 })
62 . filter (( r ) => r.route && r.coldPct > 0.3 && r.total > 100 );
63 }
64 return [];
65 }
66
67 function extractSlowHotRoutes ( signals ) {
68 const dur = signals.metrics?.fnDurationP95ByRoute?.rows;
69 const cache = signals.metrics?.requestsByRouteCache?.rows;
70 if ( ! Array. isArray (dur)) return [];
71
72 // Sum requests per route across cache_result.
73 const inv = new Map ();
74 for ( const r of (cache ?? [])) {
75 if ( ! r.route) continue ;
76 inv. set (r.route, (inv. get (r.route) ?? 0 ) + (r.value ?? 0 ));
77 }
78 return dur
79 . filter (( r ) => r.route)
80 . map (( r ) => ({ route: r.route, p95Ms: Math. round (r.value ?? 0 ), invocations: inv. get (r.route) ?? 0 }))
81 // inv>500 floor is the 14d-window equivalent of the old 1000/30d.
82 . filter (( r ) => r.p95Ms > 1000 && r.invocations > 500 );
83 }