toad-eye 1.1.0 → 2.1.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 (90) hide show
  1. package/README.md +132 -87
  2. package/dist/agent.d.ts +41 -0
  3. package/dist/agent.js +91 -0
  4. package/dist/alerts/channels.d.ts +2 -0
  5. package/dist/alerts/channels.js +81 -0
  6. package/dist/alerts/conditions.d.ts +29 -0
  7. package/dist/alerts/conditions.js +147 -0
  8. package/dist/alerts/grafana.d.ts +5 -0
  9. package/dist/alerts/grafana.js +19 -0
  10. package/dist/alerts/index.d.ts +5 -0
  11. package/dist/alerts/index.js +12 -0
  12. package/dist/alerts/manager.d.ts +13 -0
  13. package/dist/alerts/manager.js +87 -0
  14. package/dist/alerts/types.d.ts +46 -0
  15. package/dist/alerts/types.js +1 -0
  16. package/dist/budget/error.d.ts +10 -0
  17. package/dist/budget/error.js +22 -0
  18. package/dist/budget/index.d.ts +3 -0
  19. package/dist/budget/index.js +2 -0
  20. package/dist/budget/tracker.d.ts +35 -0
  21. package/dist/budget/tracker.js +121 -0
  22. package/dist/budget/types.d.ts +34 -0
  23. package/dist/budget/types.js +1 -0
  24. package/dist/cli.js +127 -18
  25. package/dist/core/metrics.d.ts +14 -0
  26. package/dist/core/metrics.js +119 -0
  27. package/dist/core/pricing.d.ts +24 -0
  28. package/dist/core/pricing.js +52 -0
  29. package/dist/{spans.d.ts → core/spans.d.ts} +3 -1
  30. package/dist/core/spans.js +143 -0
  31. package/dist/core/tracer.d.ts +9 -0
  32. package/dist/core/tracer.js +93 -0
  33. package/dist/drift/baseline.d.ts +16 -0
  34. package/dist/drift/baseline.js +16 -0
  35. package/dist/drift/cosine.d.ts +13 -0
  36. package/dist/drift/cosine.js +39 -0
  37. package/dist/drift/embedding-provider.d.ts +21 -0
  38. package/dist/drift/embedding-provider.js +8 -0
  39. package/dist/drift/index.d.ts +9 -0
  40. package/dist/drift/index.js +8 -0
  41. package/dist/drift/monitor.d.ts +29 -0
  42. package/dist/drift/monitor.js +47 -0
  43. package/dist/drift/openai-embeddings.d.ts +6 -0
  44. package/dist/drift/openai-embeddings.js +26 -0
  45. package/dist/export.d.ts +46 -0
  46. package/dist/export.js +108 -0
  47. package/dist/guard.d.ts +26 -0
  48. package/dist/guard.js +45 -0
  49. package/dist/index.d.ts +17 -5
  50. package/dist/index.js +10 -3
  51. package/dist/instrumentations/anthropic.d.ts +1 -0
  52. package/dist/instrumentations/anthropic.js +73 -0
  53. package/dist/instrumentations/create.d.ts +11 -0
  54. package/dist/instrumentations/create.js +165 -0
  55. package/dist/instrumentations/gemini.d.ts +1 -0
  56. package/dist/instrumentations/gemini.js +48 -0
  57. package/dist/instrumentations/openai.d.ts +1 -0
  58. package/dist/instrumentations/openai.js +94 -0
  59. package/dist/instrumentations/registry.d.ts +5 -0
  60. package/dist/instrumentations/registry.js +31 -0
  61. package/dist/instrumentations/types.d.ts +37 -0
  62. package/dist/instrumentations/types.js +1 -0
  63. package/dist/types/attributes.d.ts +48 -0
  64. package/dist/types/attributes.js +53 -0
  65. package/dist/types/config.d.ts +34 -0
  66. package/dist/types/config.js +1 -0
  67. package/dist/types/index.d.ts +17 -0
  68. package/dist/types/index.js +13 -0
  69. package/dist/types/metrics.d.ts +33 -0
  70. package/dist/types/metrics.js +35 -0
  71. package/dist/types/providers.d.ts +5 -0
  72. package/dist/types/providers.js +1 -0
  73. package/dist/types/spans.d.ts +40 -0
  74. package/dist/types/spans.js +1 -0
  75. package/package.json +38 -4
  76. package/templates/alerts.example.yml +54 -0
  77. package/templates/docker-compose.yml +1 -2
  78. package/templates/grafana/dashboards/cost-breakdown.json +208 -0
  79. package/templates/grafana/dashboards/error-drilldown.json +188 -0
  80. package/templates/grafana/dashboards/finops-attribution.json +278 -0
  81. package/templates/grafana/dashboards/latency-analysis.json +134 -0
  82. package/templates/grafana/dashboards/llm-overview.json +161 -30
  83. package/templates/grafana/dashboards/model-comparison.json +143 -0
  84. package/dist/metrics.d.ts +0 -6
  85. package/dist/metrics.js +0 -46
  86. package/dist/spans.js +0 -61
  87. package/dist/tracer.d.ts +0 -4
  88. package/dist/tracer.js +0 -46
  89. package/dist/types.d.ts +0 -69
  90. package/dist/types.js +0 -32
@@ -0,0 +1,208 @@
1
+ {
2
+ "annotations": { "list": [] },
3
+ "editable": true,
4
+ "fiscalYearStartMonth": 0,
5
+ "graphTooltip": 1,
6
+ "id": null,
7
+ "links": [],
8
+ "panels": [
9
+ {
10
+ "title": "Total Cost",
11
+ "type": "stat",
12
+ "gridPos": { "h": 4, "w": 8, "x": 0, "y": 0 },
13
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
14
+ "targets": [
15
+ {
16
+ "expr": "sum(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"})",
17
+ "refId": "A"
18
+ }
19
+ ],
20
+ "fieldConfig": {
21
+ "defaults": {
22
+ "unit": "currencyUSD",
23
+ "thresholds": {
24
+ "steps": [
25
+ { "color": "green", "value": null },
26
+ { "color": "yellow", "value": 50 },
27
+ { "color": "red", "value": 500 }
28
+ ]
29
+ }
30
+ },
31
+ "overrides": []
32
+ }
33
+ },
34
+ {
35
+ "title": "Cost Today",
36
+ "type": "stat",
37
+ "gridPos": { "h": 4, "w": 8, "x": 8, "y": 0 },
38
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
39
+ "targets": [
40
+ {
41
+ "expr": "sum(increase(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1d]))",
42
+ "refId": "A"
43
+ }
44
+ ],
45
+ "fieldConfig": {
46
+ "defaults": {
47
+ "unit": "currencyUSD",
48
+ "thresholds": {
49
+ "steps": [
50
+ { "color": "green", "value": null },
51
+ { "color": "yellow", "value": 10 },
52
+ { "color": "red", "value": 50 }
53
+ ]
54
+ }
55
+ },
56
+ "overrides": []
57
+ }
58
+ },
59
+ {
60
+ "title": "Projected Monthly Cost",
61
+ "type": "stat",
62
+ "gridPos": { "h": 4, "w": 8, "x": 16, "y": 0 },
63
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
64
+ "targets": [
65
+ {
66
+ "expr": "sum(rate(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1d])) * 86400 * 30",
67
+ "refId": "A"
68
+ }
69
+ ],
70
+ "fieldConfig": {
71
+ "defaults": {
72
+ "unit": "currencyUSD",
73
+ "thresholds": {
74
+ "steps": [
75
+ { "color": "green", "value": null },
76
+ { "color": "yellow", "value": 100 },
77
+ { "color": "red", "value": 1000 }
78
+ ]
79
+ }
80
+ },
81
+ "overrides": []
82
+ }
83
+ },
84
+ {
85
+ "title": "Cost by Provider",
86
+ "type": "timeseries",
87
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 },
88
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
89
+ "targets": [
90
+ {
91
+ "expr": "sum(rate(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m])) by (gen_ai_provider_name) * 60",
92
+ "legendFormat": "{{ gen_ai_provider_name }}",
93
+ "refId": "A"
94
+ }
95
+ ],
96
+ "fieldConfig": {
97
+ "defaults": {
98
+ "unit": "currencyUSD",
99
+ "custom": {
100
+ "drawStyle": "bars",
101
+ "fillOpacity": 50,
102
+ "lineWidth": 1,
103
+ "stacking": { "mode": "normal" }
104
+ }
105
+ },
106
+ "overrides": []
107
+ }
108
+ },
109
+ {
110
+ "title": "Cost by Model",
111
+ "type": "timeseries",
112
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 },
113
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
114
+ "targets": [
115
+ {
116
+ "expr": "sum(rate(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m])) by (gen_ai_request_model) * 60",
117
+ "legendFormat": "{{ gen_ai_request_model }}",
118
+ "refId": "A"
119
+ }
120
+ ],
121
+ "fieldConfig": {
122
+ "defaults": {
123
+ "unit": "currencyUSD",
124
+ "custom": {
125
+ "drawStyle": "bars",
126
+ "fillOpacity": 50,
127
+ "lineWidth": 1,
128
+ "stacking": { "mode": "normal" }
129
+ }
130
+ },
131
+ "overrides": []
132
+ }
133
+ },
134
+ {
135
+ "title": "Cost per Request",
136
+ "type": "timeseries",
137
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 12 },
138
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
139
+ "targets": [
140
+ {
141
+ "expr": "sum(rate(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m])) / sum(rate(gen_ai_client_request_cost_USD_count{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[5m]))",
142
+ "legendFormat": "avg cost/request",
143
+ "refId": "A"
144
+ }
145
+ ],
146
+ "fieldConfig": {
147
+ "defaults": {
148
+ "unit": "currencyUSD",
149
+ "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
150
+ },
151
+ "overrides": []
152
+ }
153
+ },
154
+ {
155
+ "title": "Daily Cost Trend",
156
+ "type": "timeseries",
157
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 12 },
158
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
159
+ "targets": [
160
+ {
161
+ "expr": "sum(increase(gen_ai_client_request_cost_USD_sum{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1h]))",
162
+ "legendFormat": "hourly cost",
163
+ "refId": "A"
164
+ }
165
+ ],
166
+ "fieldConfig": {
167
+ "defaults": {
168
+ "unit": "currencyUSD",
169
+ "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
170
+ },
171
+ "overrides": []
172
+ }
173
+ }
174
+ ],
175
+ "refresh": "5s",
176
+ "schemaVersion": 39,
177
+ "tags": ["llm", "observability", "toad-eye"],
178
+ "templating": {
179
+ "list": [
180
+ {
181
+ "name": "provider",
182
+ "type": "query",
183
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
184
+ "query": "label_values(gen_ai_client_requests_total, gen_ai_provider_name)",
185
+ "includeAll": true,
186
+ "allValue": ".*",
187
+ "current": { "text": "All", "value": "$__all" },
188
+ "multi": true
189
+ },
190
+ {
191
+ "name": "model",
192
+ "type": "query",
193
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
194
+ "query": "label_values(gen_ai_client_requests_total{gen_ai_provider_name=~\"$provider\"}, gen_ai_request_model)",
195
+ "includeAll": true,
196
+ "allValue": ".*",
197
+ "current": { "text": "All", "value": "$__all" },
198
+ "multi": true
199
+ }
200
+ ]
201
+ },
202
+ "time": { "from": "now-15m", "to": "now" },
203
+ "timepicker": {},
204
+ "timezone": "browser",
205
+ "title": "toad-eye: Cost Breakdown",
206
+ "uid": "toad-eye-cost",
207
+ "version": 1
208
+ }
@@ -0,0 +1,188 @@
1
+ {
2
+ "annotations": { "list": [] },
3
+ "editable": true,
4
+ "fiscalYearStartMonth": 0,
5
+ "graphTooltip": 1,
6
+ "id": null,
7
+ "links": [],
8
+ "panels": [
9
+ {
10
+ "title": "Total Errors",
11
+ "type": "stat",
12
+ "gridPos": { "h": 4, "w": 8, "x": 0, "y": 0 },
13
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
14
+ "targets": [
15
+ {
16
+ "expr": "sum(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"})",
17
+ "refId": "A"
18
+ }
19
+ ],
20
+ "fieldConfig": {
21
+ "defaults": {
22
+ "unit": "short",
23
+ "thresholds": {
24
+ "steps": [
25
+ { "color": "green", "value": null },
26
+ { "color": "yellow", "value": 10 },
27
+ { "color": "red", "value": 100 }
28
+ ]
29
+ }
30
+ },
31
+ "overrides": []
32
+ }
33
+ },
34
+ {
35
+ "title": "Error Rate %",
36
+ "type": "stat",
37
+ "gridPos": { "h": 4, "w": 8, "x": 8, "y": 0 },
38
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
39
+ "targets": [
40
+ {
41
+ "expr": "sum(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}) / sum(gen_ai_client_requests_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}) * 100",
42
+ "refId": "A"
43
+ }
44
+ ],
45
+ "fieldConfig": {
46
+ "defaults": {
47
+ "unit": "percent",
48
+ "thresholds": {
49
+ "steps": [
50
+ { "color": "green", "value": null },
51
+ { "color": "yellow", "value": 5 },
52
+ { "color": "red", "value": 20 }
53
+ ]
54
+ }
55
+ },
56
+ "overrides": []
57
+ }
58
+ },
59
+ {
60
+ "title": "Errors Last Hour",
61
+ "type": "stat",
62
+ "gridPos": { "h": 4, "w": 8, "x": 16, "y": 0 },
63
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
64
+ "targets": [
65
+ {
66
+ "expr": "sum(increase(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1h]))",
67
+ "refId": "A"
68
+ }
69
+ ],
70
+ "fieldConfig": {
71
+ "defaults": {
72
+ "unit": "short",
73
+ "thresholds": {
74
+ "steps": [
75
+ { "color": "green", "value": null },
76
+ { "color": "yellow", "value": 5 },
77
+ { "color": "red", "value": 50 }
78
+ ]
79
+ }
80
+ },
81
+ "overrides": []
82
+ }
83
+ },
84
+ {
85
+ "title": "Error Rate by Provider",
86
+ "type": "timeseries",
87
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 },
88
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
89
+ "targets": [
90
+ {
91
+ "expr": "sum(rate(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m])) by (gen_ai_provider_name) * 60",
92
+ "legendFormat": "{{ gen_ai_provider_name }}",
93
+ "refId": "A"
94
+ }
95
+ ],
96
+ "fieldConfig": {
97
+ "defaults": {
98
+ "unit": "reqpm",
99
+ "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
100
+ },
101
+ "overrides": []
102
+ }
103
+ },
104
+ {
105
+ "title": "Error Rate by Model",
106
+ "type": "timeseries",
107
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 },
108
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
109
+ "targets": [
110
+ {
111
+ "expr": "sum(rate(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m])) by (gen_ai_request_model) * 60",
112
+ "legendFormat": "{{ gen_ai_request_model }}",
113
+ "refId": "A"
114
+ }
115
+ ],
116
+ "fieldConfig": {
117
+ "defaults": {
118
+ "unit": "reqpm",
119
+ "custom": { "drawStyle": "line", "fillOpacity": 15, "lineWidth": 2 }
120
+ },
121
+ "overrides": []
122
+ }
123
+ },
124
+ {
125
+ "title": "Error vs Success Rate",
126
+ "type": "timeseries",
127
+ "gridPos": { "h": 8, "w": 24, "x": 0, "y": 12 },
128
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
129
+ "targets": [
130
+ {
131
+ "expr": "sum(rate(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m])) * 60",
132
+ "legendFormat": "errors/min",
133
+ "refId": "A"
134
+ },
135
+ {
136
+ "expr": "(sum(rate(gen_ai_client_requests_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m])) - sum(rate(gen_ai_client_errors_total{gen_ai_provider_name=~\"$provider\", gen_ai_request_model=~\"$model\"}[1m]))) * 60",
137
+ "legendFormat": "success/min",
138
+ "refId": "B"
139
+ }
140
+ ],
141
+ "fieldConfig": {
142
+ "defaults": {
143
+ "unit": "reqpm",
144
+ "custom": {
145
+ "drawStyle": "line",
146
+ "fillOpacity": 15,
147
+ "lineWidth": 2,
148
+ "stacking": { "mode": "normal" }
149
+ }
150
+ },
151
+ "overrides": []
152
+ }
153
+ }
154
+ ],
155
+ "refresh": "5s",
156
+ "schemaVersion": 39,
157
+ "tags": ["llm", "observability", "toad-eye"],
158
+ "templating": {
159
+ "list": [
160
+ {
161
+ "name": "provider",
162
+ "type": "query",
163
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
164
+ "query": "label_values(gen_ai_client_requests_total, gen_ai_provider_name)",
165
+ "includeAll": true,
166
+ "allValue": ".*",
167
+ "current": { "text": "All", "value": "$__all" },
168
+ "multi": true
169
+ },
170
+ {
171
+ "name": "model",
172
+ "type": "query",
173
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
174
+ "query": "label_values(gen_ai_client_requests_total{gen_ai_provider_name=~\"$provider\"}, gen_ai_request_model)",
175
+ "includeAll": true,
176
+ "allValue": ".*",
177
+ "current": { "text": "All", "value": "$__all" },
178
+ "multi": true
179
+ }
180
+ ]
181
+ },
182
+ "time": { "from": "now-15m", "to": "now" },
183
+ "timepicker": {},
184
+ "timezone": "browser",
185
+ "title": "toad-eye: Error Drill-down",
186
+ "uid": "toad-eye-errors",
187
+ "version": 1
188
+ }
@@ -0,0 +1,278 @@
1
+ {
2
+ "annotations": { "list": [] },
3
+ "editable": true,
4
+ "fiscalYearStartMonth": 0,
5
+ "graphTooltip": 1,
6
+ "id": null,
7
+ "links": [],
8
+ "panels": [
9
+ {
10
+ "title": "Total Spend",
11
+ "type": "stat",
12
+ "gridPos": { "h": 4, "w": 6, "x": 0, "y": 0 },
13
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
14
+ "targets": [
15
+ {
16
+ "expr": "sum(gen_ai_client_request_cost_USD_sum)",
17
+ "refId": "A"
18
+ }
19
+ ],
20
+ "fieldConfig": {
21
+ "defaults": {
22
+ "unit": "currencyUSD",
23
+ "thresholds": {
24
+ "steps": [
25
+ { "color": "green", "value": null },
26
+ { "color": "yellow", "value": 50 },
27
+ { "color": "red", "value": 500 }
28
+ ]
29
+ }
30
+ },
31
+ "overrides": []
32
+ }
33
+ },
34
+ {
35
+ "title": "Projected Monthly Spend",
36
+ "description": "Linear projection based on last 7 days",
37
+ "type": "stat",
38
+ "gridPos": { "h": 4, "w": 6, "x": 6, "y": 0 },
39
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
40
+ "targets": [
41
+ {
42
+ "expr": "sum(increase(gen_ai_client_request_cost_USD_sum[7d])) / 7 * 30",
43
+ "refId": "A"
44
+ }
45
+ ],
46
+ "fieldConfig": {
47
+ "defaults": {
48
+ "unit": "currencyUSD",
49
+ "thresholds": {
50
+ "steps": [
51
+ { "color": "green", "value": null },
52
+ { "color": "yellow", "value": 200 },
53
+ { "color": "red", "value": 1000 }
54
+ ]
55
+ }
56
+ },
57
+ "overrides": []
58
+ }
59
+ },
60
+ {
61
+ "title": "Requests Today",
62
+ "type": "stat",
63
+ "gridPos": { "h": 4, "w": 6, "x": 12, "y": 0 },
64
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
65
+ "targets": [
66
+ {
67
+ "expr": "sum(increase(gen_ai_client_requests_total[24h]))",
68
+ "refId": "A"
69
+ }
70
+ ],
71
+ "fieldConfig": {
72
+ "defaults": { "unit": "short" },
73
+ "overrides": []
74
+ }
75
+ },
76
+ {
77
+ "title": "Avg Cost per Request",
78
+ "type": "stat",
79
+ "gridPos": { "h": 4, "w": 6, "x": 18, "y": 0 },
80
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
81
+ "targets": [
82
+ {
83
+ "expr": "sum(gen_ai_client_request_cost_USD_sum) / sum(gen_ai_client_request_cost_USD_count) or vector(0)",
84
+ "refId": "A"
85
+ }
86
+ ],
87
+ "fieldConfig": {
88
+ "defaults": { "unit": "currencyUSD", "decimals": 4 },
89
+ "overrides": []
90
+ }
91
+ },
92
+ {
93
+ "title": "Cost by Team",
94
+ "type": "piechart",
95
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 4 },
96
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
97
+ "targets": [
98
+ {
99
+ "expr": "sum by (toad_eye_team) (gen_ai_client_request_cost_USD_sum{toad_eye_team=~\"$team\"})",
100
+ "legendFormat": "{{toad_eye_team}}",
101
+ "refId": "A"
102
+ }
103
+ ],
104
+ "options": {
105
+ "legend": {
106
+ "displayMode": "table",
107
+ "placement": "right",
108
+ "values": ["value", "percent"]
109
+ },
110
+ "pieType": "donut"
111
+ }
112
+ },
113
+ {
114
+ "title": "Cost by Model (stacked by Team)",
115
+ "type": "barchart",
116
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 4 },
117
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
118
+ "targets": [
119
+ {
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\"})",
121
+ "legendFormat": "{{gen_ai_request_model}} / {{toad_eye_team}}",
122
+ "refId": "A"
123
+ }
124
+ ],
125
+ "options": {
126
+ "stacking": "normal"
127
+ }
128
+ },
129
+ {
130
+ "title": "Cost by Feature / Endpoint",
131
+ "type": "table",
132
+ "gridPos": { "h": 8, "w": 12, "x": 0, "y": 12 },
133
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
134
+ "targets": [
135
+ {
136
+ "expr": "sort_desc(sum by (toad_eye_feature) (gen_ai_client_request_cost_USD_sum{toad_eye_feature=~\"$feature\"}))",
137
+ "format": "table",
138
+ "instant": true,
139
+ "refId": "A"
140
+ }
141
+ ],
142
+ "transformations": [
143
+ {
144
+ "id": "organize",
145
+ "options": {
146
+ "renameByName": {
147
+ "toad_eye_feature": "Feature",
148
+ "Value": "Cost (USD)"
149
+ }
150
+ }
151
+ }
152
+ ]
153
+ },
154
+ {
155
+ "title": "Top 10 Users by Cost",
156
+ "type": "table",
157
+ "gridPos": { "h": 8, "w": 12, "x": 12, "y": 12 },
158
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
159
+ "targets": [
160
+ {
161
+ "expr": "topk(10, sum by (toad_eye_user_id) (gen_ai_client_request_cost_USD_sum{toad_eye_user_id!=\"\"}))",
162
+ "format": "table",
163
+ "instant": true,
164
+ "refId": "A"
165
+ }
166
+ ],
167
+ "transformations": [
168
+ {
169
+ "id": "organize",
170
+ "options": {
171
+ "renameByName": {
172
+ "toad_eye_user_id": "User ID",
173
+ "Value": "Cost (USD)"
174
+ }
175
+ }
176
+ }
177
+ ]
178
+ },
179
+ {
180
+ "title": "Daily Cost Trend (by Team)",
181
+ "type": "timeseries",
182
+ "gridPos": { "h": 8, "w": 24, "x": 0, "y": 20 },
183
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
184
+ "targets": [
185
+ {
186
+ "expr": "sum by (toad_eye_team) (increase(gen_ai_client_request_cost_USD_sum{toad_eye_team=~\"$team\"}[1d]))",
187
+ "legendFormat": "{{toad_eye_team}}",
188
+ "refId": "A"
189
+ }
190
+ ],
191
+ "options": {
192
+ "tooltip": { "mode": "multi" }
193
+ },
194
+ "fieldConfig": {
195
+ "defaults": {
196
+ "unit": "currencyUSD",
197
+ "custom": { "fillOpacity": 20, "stacking": { "mode": "normal" } }
198
+ },
199
+ "overrides": []
200
+ }
201
+ },
202
+ {
203
+ "title": "What-If: Model Substitution Savings",
204
+ "description": "Current cost per model vs estimated cost if all traffic moved to cheapest model",
205
+ "type": "table",
206
+ "gridPos": { "h": 8, "w": 24, "x": 0, "y": 28 },
207
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
208
+ "targets": [
209
+ {
210
+ "expr": "sum by (gen_ai_request_model) (gen_ai_client_request_cost_USD_sum)",
211
+ "format": "table",
212
+ "instant": true,
213
+ "refId": "current_cost"
214
+ },
215
+ {
216
+ "expr": "sum by (gen_ai_request_model) (gen_ai_client_token_usage_total)",
217
+ "format": "table",
218
+ "instant": true,
219
+ "refId": "total_tokens"
220
+ }
221
+ ],
222
+ "transformations": [
223
+ {
224
+ "id": "organize",
225
+ "options": {
226
+ "renameByName": {
227
+ "gen_ai_request_model": "Model",
228
+ "Value #current_cost": "Current Cost (USD)",
229
+ "Value #total_tokens": "Total Tokens"
230
+ }
231
+ }
232
+ }
233
+ ]
234
+ }
235
+ ],
236
+ "schemaVersion": 39,
237
+ "tags": ["toad-eye", "finops", "cost"],
238
+ "templating": {
239
+ "list": [
240
+ {
241
+ "name": "team",
242
+ "type": "query",
243
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
244
+ "query": "label_values(gen_ai_client_request_cost_USD_sum, toad_eye_team)",
245
+ "includeAll": true,
246
+ "multi": true,
247
+ "current": { "text": "All", "value": "$__all" },
248
+ "regex": ""
249
+ },
250
+ {
251
+ "name": "feature",
252
+ "type": "query",
253
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
254
+ "query": "label_values(gen_ai_client_request_cost_USD_sum, toad_eye_feature)",
255
+ "includeAll": true,
256
+ "multi": true,
257
+ "current": { "text": "All", "value": "$__all" },
258
+ "regex": ""
259
+ },
260
+ {
261
+ "name": "model",
262
+ "type": "query",
263
+ "datasource": { "type": "prometheus", "uid": "prometheus" },
264
+ "query": "label_values(gen_ai_client_request_cost_USD_sum, gen_ai_request_model)",
265
+ "includeAll": true,
266
+ "multi": true,
267
+ "current": { "text": "All", "value": "$__all" },
268
+ "regex": ""
269
+ }
270
+ ]
271
+ },
272
+ "time": { "from": "now-7d", "to": "now" },
273
+ "timepicker": {},
274
+ "timezone": "utc",
275
+ "title": "toad-eye / FinOps Attribution",
276
+ "uid": "toad-eye-finops",
277
+ "version": 1
278
+ }