toad-eye 2.4.5 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/README.md +34 -1
  2. package/dist/agent.js +6 -2
  3. package/dist/cli.js +8 -1
  4. package/dist/context/error.d.ts +15 -0
  5. package/dist/context/error.js +17 -0
  6. package/dist/context/guard.d.ts +8 -0
  7. package/dist/context/guard.js +41 -0
  8. package/dist/context/index.d.ts +1 -0
  9. package/dist/context/index.js +4 -0
  10. package/dist/core/metrics.d.ts +4 -1
  11. package/dist/core/metrics.js +74 -2
  12. package/dist/core/pricing.d.ts +2 -0
  13. package/dist/core/pricing.js +61 -16
  14. package/dist/core/spans.d.ts +2 -0
  15. package/dist/core/spans.js +48 -9
  16. package/dist/core/tracer.js +7 -1
  17. package/dist/instrumentations/anthropic.js +8 -2
  18. package/dist/instrumentations/create.js +67 -8
  19. package/dist/instrumentations/gemini.js +7 -0
  20. package/dist/instrumentations/openai.js +5 -0
  21. package/dist/instrumentations/types.d.ts +8 -0
  22. package/dist/mcp/context.d.ts +12 -0
  23. package/dist/mcp/context.js +22 -0
  24. package/dist/mcp/index.d.ts +3 -0
  25. package/dist/mcp/index.js +1 -0
  26. package/dist/mcp/metrics.d.ts +11 -0
  27. package/dist/mcp/metrics.js +58 -0
  28. package/dist/mcp/middleware.d.ts +48 -0
  29. package/dist/mcp/middleware.js +253 -0
  30. package/dist/mcp/spans.d.ts +28 -0
  31. package/dist/mcp/spans.js +67 -0
  32. package/dist/mcp/types.d.ts +34 -0
  33. package/dist/mcp/types.js +1 -0
  34. package/dist/types/attributes.d.ts +1 -0
  35. package/dist/types/attributes.js +1 -0
  36. package/dist/types/config.d.ts +9 -0
  37. package/dist/types/metrics.d.ts +8 -0
  38. package/dist/types/metrics.js +10 -0
  39. package/dist/types/spans.d.ts +4 -0
  40. package/package.json +11 -2
  41. package/templates/docker-compose.yml +4 -4
  42. package/templates/grafana/dashboards/agent-workflow.json +154 -31
  43. package/templates/grafana/dashboards/cost-breakdown.json +168 -40
  44. package/templates/grafana/dashboards/error-drilldown.json +155 -37
  45. package/templates/grafana/dashboards/finops-attribution.json +192 -43
  46. package/templates/grafana/dashboards/latency-analysis.json +103 -24
  47. package/templates/grafana/dashboards/llm-overview.json +268 -66
  48. package/templates/grafana/dashboards/mcp-server.json +519 -0
  49. package/templates/grafana/dashboards/model-comparison.json +119 -26
  50. package/templates/grafana/dashboards/provider-health.json +137 -31
@@ -1,5 +1,7 @@
1
1
  {
2
- "annotations": { "list": [] },
2
+ "annotations": {
3
+ "list": []
4
+ },
3
5
  "editable": true,
4
6
  "fiscalYearStartMonth": 0,
5
7
  "graphTooltip": 1,
@@ -9,8 +11,16 @@
9
11
  {
10
12
  "title": "Total Spend",
11
13
  "type": "stat",
12
- "gridPos": { "h": 4, "w": 6, "x": 0, "y": 0 },
13
- "datasource": { "type": "prometheus", "uid": "prometheus" },
14
+ "gridPos": {
15
+ "h": 4,
16
+ "w": 6,
17
+ "x": 0,
18
+ "y": 0
19
+ },
20
+ "datasource": {
21
+ "type": "prometheus",
22
+ "uid": "prometheus"
23
+ },
14
24
  "targets": [
15
25
  {
16
26
  "expr": "sum(gen_ai_client_request_cost_USD_sum)",
@@ -22,9 +32,18 @@
22
32
  "unit": "currencyUSD",
23
33
  "thresholds": {
24
34
  "steps": [
25
- { "color": "green", "value": null },
26
- { "color": "yellow", "value": 50 },
27
- { "color": "red", "value": 500 }
35
+ {
36
+ "color": "green",
37
+ "value": null
38
+ },
39
+ {
40
+ "color": "yellow",
41
+ "value": 50
42
+ },
43
+ {
44
+ "color": "red",
45
+ "value": 500
46
+ }
28
47
  ]
29
48
  }
30
49
  },
@@ -35,8 +54,16 @@
35
54
  "title": "Projected Monthly Spend",
36
55
  "description": "Linear projection based on last 7 days",
37
56
  "type": "stat",
38
- "gridPos": { "h": 4, "w": 6, "x": 6, "y": 0 },
39
- "datasource": { "type": "prometheus", "uid": "prometheus" },
57
+ "gridPos": {
58
+ "h": 4,
59
+ "w": 6,
60
+ "x": 6,
61
+ "y": 0
62
+ },
63
+ "datasource": {
64
+ "type": "prometheus",
65
+ "uid": "prometheus"
66
+ },
40
67
  "targets": [
41
68
  {
42
69
  "expr": "sum(increase(gen_ai_client_request_cost_USD_sum[7d])) / 7 * 30",
@@ -48,9 +75,18 @@
48
75
  "unit": "currencyUSD",
49
76
  "thresholds": {
50
77
  "steps": [
51
- { "color": "green", "value": null },
52
- { "color": "yellow", "value": 200 },
53
- { "color": "red", "value": 1000 }
78
+ {
79
+ "color": "green",
80
+ "value": null
81
+ },
82
+ {
83
+ "color": "yellow",
84
+ "value": 200
85
+ },
86
+ {
87
+ "color": "red",
88
+ "value": 1000
89
+ }
54
90
  ]
55
91
  }
56
92
  },
@@ -60,8 +96,16 @@
60
96
  {
61
97
  "title": "Requests Today",
62
98
  "type": "stat",
63
- "gridPos": { "h": 4, "w": 6, "x": 12, "y": 0 },
64
- "datasource": { "type": "prometheus", "uid": "prometheus" },
99
+ "gridPos": {
100
+ "h": 4,
101
+ "w": 6,
102
+ "x": 12,
103
+ "y": 0
104
+ },
105
+ "datasource": {
106
+ "type": "prometheus",
107
+ "uid": "prometheus"
108
+ },
65
109
  "targets": [
66
110
  {
67
111
  "expr": "sum(increase(gen_ai_client_requests_total[24h]))",
@@ -69,15 +113,25 @@
69
113
  }
70
114
  ],
71
115
  "fieldConfig": {
72
- "defaults": { "unit": "short" },
116
+ "defaults": {
117
+ "unit": "short"
118
+ },
73
119
  "overrides": []
74
120
  }
75
121
  },
76
122
  {
77
123
  "title": "Avg Cost per Request",
78
124
  "type": "stat",
79
- "gridPos": { "h": 4, "w": 6, "x": 18, "y": 0 },
80
- "datasource": { "type": "prometheus", "uid": "prometheus" },
125
+ "gridPos": {
126
+ "h": 4,
127
+ "w": 6,
128
+ "x": 18,
129
+ "y": 0
130
+ },
131
+ "datasource": {
132
+ "type": "prometheus",
133
+ "uid": "prometheus"
134
+ },
81
135
  "targets": [
82
136
  {
83
137
  "expr": "sum(gen_ai_client_request_cost_USD_sum) / sum(gen_ai_client_request_cost_USD_count) or vector(0)",
@@ -85,18 +139,29 @@
85
139
  }
86
140
  ],
87
141
  "fieldConfig": {
88
- "defaults": { "unit": "currencyUSD", "decimals": 4 },
142
+ "defaults": {
143
+ "unit": "currencyUSD",
144
+ "decimals": 4
145
+ },
89
146
  "overrides": []
90
147
  }
91
148
  },
92
149
  {
93
150
  "title": "Cost by Team",
94
151
  "type": "piechart",
95
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 },
96
- "datasource": { "type": "prometheus", "uid": "prometheus" },
152
+ "gridPos": {
153
+ "h": 8,
154
+ "w": 12,
155
+ "x": 0,
156
+ "y": 4
157
+ },
158
+ "datasource": {
159
+ "type": "prometheus",
160
+ "uid": "prometheus"
161
+ },
97
162
  "targets": [
98
163
  {
99
- "expr": "sum by (toad_eye_team) (gen_ai_client_request_cost_USD_sum{toad_eye_team=~\"$team\"})",
164
+ "expr": "sum by (toad_eye_team) (gen_ai_client_request_cost_USD_sum{job=~\"$service\", toad_eye_team=~\"$team\"})",
100
165
  "legendFormat": "{{toad_eye_team}}",
101
166
  "refId": "A"
102
167
  }
@@ -113,11 +178,19 @@
113
178
  {
114
179
  "title": "Cost by Model (stacked by Team)",
115
180
  "type": "barchart",
116
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 },
117
- "datasource": { "type": "prometheus", "uid": "prometheus" },
181
+ "gridPos": {
182
+ "h": 8,
183
+ "w": 12,
184
+ "x": 12,
185
+ "y": 4
186
+ },
187
+ "datasource": {
188
+ "type": "prometheus",
189
+ "uid": "prometheus"
190
+ },
118
191
  "targets": [
119
192
  {
120
- "expr": "sum by (gen_ai_request_model, toad_eye_team) (gen_ai_client_request_cost_USD_sum{toad_eye_team=~\"$team\", gen_ai_request_model=~\"$model\"})",
193
+ "expr": "sum by (gen_ai_request_model, toad_eye_team) (gen_ai_client_request_cost_USD_sum{job=~\"$service\", toad_eye_team=~\"$team\", gen_ai_request_model=~\"$model\"})",
121
194
  "legendFormat": "{{gen_ai_request_model}} / {{toad_eye_team}}",
122
195
  "refId": "A"
123
196
  }
@@ -129,11 +202,19 @@
129
202
  {
130
203
  "title": "Cost by Feature / Endpoint",
131
204
  "type": "table",
132
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 12 },
133
- "datasource": { "type": "prometheus", "uid": "prometheus" },
205
+ "gridPos": {
206
+ "h": 8,
207
+ "w": 12,
208
+ "x": 0,
209
+ "y": 12
210
+ },
211
+ "datasource": {
212
+ "type": "prometheus",
213
+ "uid": "prometheus"
214
+ },
134
215
  "targets": [
135
216
  {
136
- "expr": "sort_desc(sum by (toad_eye_feature) (gen_ai_client_request_cost_USD_sum{toad_eye_feature=~\"$feature\"}))",
217
+ "expr": "sort_desc(sum by (toad_eye_feature) (gen_ai_client_request_cost_USD_sum{job=~\"$service\", toad_eye_feature=~\"$feature\"}))",
137
218
  "format": "table",
138
219
  "instant": true,
139
220
  "refId": "A"
@@ -154,11 +235,19 @@
154
235
  {
155
236
  "title": "Top 10 Users by Cost",
156
237
  "type": "table",
157
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 12 },
158
- "datasource": { "type": "prometheus", "uid": "prometheus" },
238
+ "gridPos": {
239
+ "h": 8,
240
+ "w": 12,
241
+ "x": 12,
242
+ "y": 12
243
+ },
244
+ "datasource": {
245
+ "type": "prometheus",
246
+ "uid": "prometheus"
247
+ },
159
248
  "targets": [
160
249
  {
161
- "expr": "topk(10, sum by (toad_eye_user_id) (gen_ai_client_request_cost_USD_sum{toad_eye_user_id!=\"\"}))",
250
+ "expr": "topk(10, sum by (toad_eye_user_id) (gen_ai_client_request_cost_USD_sum{job=~\"$service\", toad_eye_user_id!=\"\"}))",
162
251
  "format": "table",
163
252
  "instant": true,
164
253
  "refId": "A"
@@ -179,22 +268,37 @@
179
268
  {
180
269
  "title": "Daily Cost Trend (by Team)",
181
270
  "type": "timeseries",
182
- "gridPos": { "h": 8, "w": 24, "x": 0, "y": 20 },
183
- "datasource": { "type": "prometheus", "uid": "prometheus" },
271
+ "gridPos": {
272
+ "h": 8,
273
+ "w": 24,
274
+ "x": 0,
275
+ "y": 20
276
+ },
277
+ "datasource": {
278
+ "type": "prometheus",
279
+ "uid": "prometheus"
280
+ },
184
281
  "targets": [
185
282
  {
186
- "expr": "sum by (toad_eye_team) (increase(gen_ai_client_request_cost_USD_sum{toad_eye_team=~\"$team\"}[1d]))",
283
+ "expr": "sum by (toad_eye_team) (increase(gen_ai_client_request_cost_USD_sum{job=~\"$service\", toad_eye_team=~\"$team\"}[1d]))",
187
284
  "legendFormat": "{{toad_eye_team}}",
188
285
  "refId": "A"
189
286
  }
190
287
  ],
191
288
  "options": {
192
- "tooltip": { "mode": "multi" }
289
+ "tooltip": {
290
+ "mode": "multi"
291
+ }
193
292
  },
194
293
  "fieldConfig": {
195
294
  "defaults": {
196
295
  "unit": "currencyUSD",
197
- "custom": { "fillOpacity": 20, "stacking": { "mode": "normal" } }
296
+ "custom": {
297
+ "fillOpacity": 20,
298
+ "stacking": {
299
+ "mode": "normal"
300
+ }
301
+ }
198
302
  },
199
303
  "overrides": []
200
304
  }
@@ -203,8 +307,16 @@
203
307
  "title": "What-If: Model Substitution Savings",
204
308
  "description": "Current cost per model vs estimated cost if all traffic moved to cheapest model",
205
309
  "type": "table",
206
- "gridPos": { "h": 8, "w": 24, "x": 0, "y": 28 },
207
- "datasource": { "type": "prometheus", "uid": "prometheus" },
310
+ "gridPos": {
311
+ "h": 8,
312
+ "w": 24,
313
+ "x": 0,
314
+ "y": 28
315
+ },
316
+ "datasource": {
317
+ "type": "prometheus",
318
+ "uid": "prometheus"
319
+ },
208
320
  "targets": [
209
321
  {
210
322
  "expr": "sum by (gen_ai_request_model) (gen_ai_client_request_cost_USD_sum)",
@@ -237,39 +349,76 @@
237
349
  "tags": ["toad-eye", "finops", "cost"],
238
350
  "templating": {
239
351
  "list": [
352
+ {
353
+ "name": "service",
354
+ "type": "query",
355
+ "datasource": {
356
+ "type": "prometheus",
357
+ "uid": "prometheus"
358
+ },
359
+ "query": "label_values(gen_ai_client_requests_total, job)",
360
+ "includeAll": true,
361
+ "allValue": ".*",
362
+ "current": {
363
+ "text": "All",
364
+ "value": "$__all"
365
+ },
366
+ "multi": true
367
+ },
240
368
  {
241
369
  "name": "team",
242
370
  "type": "query",
243
- "datasource": { "type": "prometheus", "uid": "prometheus" },
371
+ "datasource": {
372
+ "type": "prometheus",
373
+ "uid": "prometheus"
374
+ },
244
375
  "query": "label_values(gen_ai_client_request_cost_USD_sum, toad_eye_team)",
245
376
  "includeAll": true,
246
377
  "multi": true,
247
- "current": { "text": "All", "value": "$__all" },
378
+ "current": {
379
+ "text": "All",
380
+ "value": "$__all"
381
+ },
248
382
  "regex": ""
249
383
  },
250
384
  {
251
385
  "name": "feature",
252
386
  "type": "query",
253
- "datasource": { "type": "prometheus", "uid": "prometheus" },
387
+ "datasource": {
388
+ "type": "prometheus",
389
+ "uid": "prometheus"
390
+ },
254
391
  "query": "label_values(gen_ai_client_request_cost_USD_sum, toad_eye_feature)",
255
392
  "includeAll": true,
256
393
  "multi": true,
257
- "current": { "text": "All", "value": "$__all" },
394
+ "current": {
395
+ "text": "All",
396
+ "value": "$__all"
397
+ },
258
398
  "regex": ""
259
399
  },
260
400
  {
261
401
  "name": "model",
262
402
  "type": "query",
263
- "datasource": { "type": "prometheus", "uid": "prometheus" },
403
+ "datasource": {
404
+ "type": "prometheus",
405
+ "uid": "prometheus"
406
+ },
264
407
  "query": "label_values(gen_ai_client_request_cost_USD_sum, gen_ai_request_model)",
265
408
  "includeAll": true,
266
409
  "multi": true,
267
- "current": { "text": "All", "value": "$__all" },
410
+ "current": {
411
+ "text": "All",
412
+ "value": "$__all"
413
+ },
268
414
  "regex": ""
269
415
  }
270
416
  ]
271
417
  },
272
- "time": { "from": "now-7d", "to": "now" },
418
+ "time": {
419
+ "from": "now-7d",
420
+ "to": "now"
421
+ },
273
422
  "timepicker": {},
274
423
  "timezone": "utc",
275
424
  "title": "toad-eye / FinOps Attribution",
@@ -1,5 +1,7 @@
1
1
  {
2
- "annotations": { "list": [] },
2
+ "annotations": {
3
+ "list": []
4
+ },
3
5
  "editable": true,
4
6
  "fiscalYearStartMonth": 0,
5
7
  "graphTooltip": 1,
@@ -9,21 +11,29 @@
9
11
  {
10
12
  "title": "Latency p50 / p95 / p99 by Model",
11
13
  "type": "timeseries",
12
- "gridPos": { "h": 8, "w": 24, "x": 0, "y": 0 },
13
- "datasource": { "type": "prometheus", "uid": "prometheus" },
14
+ "gridPos": {
15
+ "h": 8,
16
+ "w": 24,
17
+ "x": 0,
18
+ "y": 0
19
+ },
20
+ "datasource": {
21
+ "type": "prometheus",
22
+ "uid": "prometheus"
23
+ },
14
24
  "targets": [
15
25
  {
16
- "expr": "histogram_quantile(0.50, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_request_model))",
26
+ "expr": "histogram_quantile(0.50, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_request_model))",
17
27
  "legendFormat": "p50 {{ gen_ai_request_model }}",
18
28
  "refId": "A"
19
29
  },
20
30
  {
21
- "expr": "histogram_quantile(0.95, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_request_model))",
31
+ "expr": "histogram_quantile(0.95, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_request_model))",
22
32
  "legendFormat": "p95 {{ gen_ai_request_model }}",
23
33
  "refId": "B"
24
34
  },
25
35
  {
26
- "expr": "histogram_quantile(0.99, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_request_model))",
36
+ "expr": "histogram_quantile(0.99, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_request_model))",
27
37
  "legendFormat": "p99 {{ gen_ai_request_model }}",
28
38
  "refId": "C"
29
39
  }
@@ -31,7 +41,11 @@
31
41
  "fieldConfig": {
32
42
  "defaults": {
33
43
  "unit": "ms",
34
- "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
44
+ "custom": {
45
+ "drawStyle": "line",
46
+ "fillOpacity": 15,
47
+ "lineWidth": 2
48
+ }
35
49
  },
36
50
  "overrides": []
37
51
  }
@@ -39,11 +53,19 @@
39
53
  {
40
54
  "title": "Latency Distribution",
41
55
  "type": "histogram",
42
- "gridPos": { "h": 8, "w": 12, "x": 0, "y": 8 },
43
- "datasource": { "type": "prometheus", "uid": "prometheus" },
56
+ "gridPos": {
57
+ "h": 8,
58
+ "w": 12,
59
+ "x": 0,
60
+ "y": 8
61
+ },
62
+ "datasource": {
63
+ "type": "prometheus",
64
+ "uid": "prometheus"
65
+ },
44
66
  "targets": [
45
67
  {
46
- "expr": "sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le)",
68
+ "expr": "sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le)",
47
69
  "legendFormat": "{{ le }}",
48
70
  "refId": "A",
49
71
  "format": "heatmap"
@@ -52,7 +74,9 @@
52
74
  "fieldConfig": {
53
75
  "defaults": {
54
76
  "unit": "ms",
55
- "custom": { "fillOpacity": 50 }
77
+ "custom": {
78
+ "fillOpacity": 50
79
+ }
56
80
  },
57
81
  "overrides": []
58
82
  }
@@ -60,11 +84,19 @@
60
84
  {
61
85
  "title": "Avg Latency by Model",
62
86
  "type": "timeseries",
63
- "gridPos": { "h": 8, "w": 12, "x": 12, "y": 8 },
64
- "datasource": { "type": "prometheus", "uid": "prometheus" },
87
+ "gridPos": {
88
+ "h": 8,
89
+ "w": 12,
90
+ "x": 12,
91
+ "y": 8
92
+ },
93
+ "datasource": {
94
+ "type": "prometheus",
95
+ "uid": "prometheus"
96
+ },
65
97
  "targets": [
66
98
  {
67
- "expr": "sum(rate(gen_ai_client_operation_duration_milliseconds_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (gen_ai_request_model) / sum(rate(gen_ai_client_operation_duration_milliseconds_count{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (gen_ai_request_model)",
99
+ "expr": "sum(rate(gen_ai_client_operation_duration_milliseconds_sum{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (gen_ai_request_model) / sum(rate(gen_ai_client_operation_duration_milliseconds_count{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (gen_ai_request_model)",
68
100
  "legendFormat": "{{ gen_ai_request_model }}",
69
101
  "refId": "A"
70
102
  }
@@ -72,7 +104,11 @@
72
104
  "fieldConfig": {
73
105
  "defaults": {
74
106
  "unit": "ms",
75
- "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
107
+ "custom": {
108
+ "drawStyle": "line",
109
+ "fillOpacity": 15,
110
+ "lineWidth": 2
111
+ }
76
112
  },
77
113
  "overrides": []
78
114
  }
@@ -80,11 +116,19 @@
80
116
  {
81
117
  "title": "Slow Requests p99 by Provider",
82
118
  "type": "timeseries",
83
- "gridPos": { "h": 8, "w": 24, "x": 0, "y": 16 },
84
- "datasource": { "type": "prometheus", "uid": "prometheus" },
119
+ "gridPos": {
120
+ "h": 8,
121
+ "w": 24,
122
+ "x": 0,
123
+ "y": 16
124
+ },
125
+ "datasource": {
126
+ "type": "prometheus",
127
+ "uid": "prometheus"
128
+ },
85
129
  "targets": [
86
130
  {
87
- "expr": "histogram_quantile(0.99, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_provider_name))",
131
+ "expr": "histogram_quantile(0.99, sum(rate(gen_ai_client_operation_duration_milliseconds_bucket{job=~\"$service\", gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) by (le, gen_ai_provider_name))",
88
132
  "legendFormat": "p99 {{ gen_ai_provider_name }}",
89
133
  "refId": "A"
90
134
  }
@@ -92,7 +136,11 @@
92
136
  "fieldConfig": {
93
137
  "defaults": {
94
138
  "unit": "ms",
95
- "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
139
+ "custom": {
140
+ "drawStyle": "line",
141
+ "fillOpacity": 15,
142
+ "lineWidth": 2
143
+ }
96
144
  },
97
145
  "overrides": []
98
146
  }
@@ -103,29 +151,60 @@
103
151
  "tags": ["llm", "observability", "toad-eye"],
104
152
  "templating": {
105
153
  "list": [
154
+ {
155
+ "name": "service",
156
+ "type": "query",
157
+ "datasource": {
158
+ "type": "prometheus",
159
+ "uid": "prometheus"
160
+ },
161
+ "query": "label_values(gen_ai_client_requests_total, job)",
162
+ "includeAll": true,
163
+ "allValue": ".*",
164
+ "current": {
165
+ "text": "All",
166
+ "value": "$__all"
167
+ },
168
+ "multi": true
169
+ },
106
170
  {
107
171
  "name": "provider",
108
172
  "type": "query",
109
- "datasource": { "type": "prometheus", "uid": "prometheus" },
173
+ "datasource": {
174
+ "type": "prometheus",
175
+ "uid": "prometheus"
176
+ },
110
177
  "query": "label_values(gen_ai_client_requests_total, gen_ai_provider_name)",
111
178
  "includeAll": true,
112
179
  "allValue": ".*",
113
- "current": { "text": "All", "value": "$__all" },
180
+ "current": {
181
+ "text": "All",
182
+ "value": "$__all"
183
+ },
114
184
  "multi": true
115
185
  },
116
186
  {
117
187
  "name": "model",
118
188
  "type": "query",
119
- "datasource": { "type": "prometheus", "uid": "prometheus" },
189
+ "datasource": {
190
+ "type": "prometheus",
191
+ "uid": "prometheus"
192
+ },
120
193
  "query": "label_values(gen_ai_client_requests_total{gen_ai_provider_name=~\"$provider\"}, gen_ai_request_model)",
121
194
  "includeAll": true,
122
195
  "allValue": ".*",
123
- "current": { "text": "All", "value": "$__all" },
196
+ "current": {
197
+ "text": "All",
198
+ "value": "$__all"
199
+ },
124
200
  "multi": true
125
201
  }
126
202
  ]
127
203
  },
128
- "time": { "from": "now-15m", "to": "now" },
204
+ "time": {
205
+ "from": "now-15m",
206
+ "to": "now"
207
+ },
129
208
  "timepicker": {},
130
209
  "timezone": "browser",
131
210
  "title": "toad-eye: Latency Analysis",