@senad-d/observme 0.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 (111) hide show
  1. package/.env.example +57 -0
  2. package/CHANGELOG.md +52 -0
  3. package/LICENSE +21 -0
  4. package/ObservMe-Production-Docs/00-README.md +79 -0
  5. package/ObservMe-Production-Docs/01-requirements-and-scope.md +207 -0
  6. package/ObservMe-Production-Docs/02-reference-architecture.md +306 -0
  7. package/ObservMe-Production-Docs/03-pi-event-and-session-model.md +266 -0
  8. package/ObservMe-Production-Docs/04-telemetry-semantic-conventions.md +722 -0
  9. package/ObservMe-Production-Docs/05-otel-pipeline-and-collector.md +355 -0
  10. package/ObservMe-Production-Docs/06-security-privacy-redaction.md +294 -0
  11. package/ObservMe-Production-Docs/07-extension-implementation-blueprint.md +447 -0
  12. package/ObservMe-Production-Docs/08-query-grafana-integration.md +276 -0
  13. package/ObservMe-Production-Docs/09-dashboards-alerts-slos.md +640 -0
  14. package/ObservMe-Production-Docs/10-testing-release-operations.md +319 -0
  15. package/ObservMe-Production-Docs/11-deployment-runbooks.md +203 -0
  16. package/ObservMe-Production-Docs/12-configuration-reference.md +337 -0
  17. package/ObservMe-Production-Docs/13-source-notes.md +33 -0
  18. package/ObservMe-Production-Docs/pi-session-format.md +427 -0
  19. package/README.md +356 -0
  20. package/SECURITY.md +45 -0
  21. package/dashboards/observme-agent-node-graphs.json +250 -0
  22. package/dashboards/observme-agents.json +1880 -0
  23. package/dashboards/observme-alerts.yaml +113 -0
  24. package/dashboards/observme-branches-compactions.json +1042 -0
  25. package/dashboards/observme-cost.json +1254 -0
  26. package/dashboards/observme-errors.json +1659 -0
  27. package/dashboards/observme-export-health.json +1802 -0
  28. package/dashboards/observme-latency.json +1494 -0
  29. package/dashboards/observme-llm-conversations.json +730 -0
  30. package/dashboards/observme-logs-llm.json +644 -0
  31. package/dashboards/observme-models.json +933 -0
  32. package/dashboards/observme-overview.json +2129 -0
  33. package/dashboards/observme-slo-health.json +737 -0
  34. package/dashboards/observme-slos.yaml +56 -0
  35. package/dashboards/observme-tools.json +902 -0
  36. package/dashboards/observme-trace-journey.json +1793 -0
  37. package/docs/STRUCTURE.md +49 -0
  38. package/docs/agent-subagent-observability-requirements.md +997 -0
  39. package/docs/compatibility-matrix.md +39 -0
  40. package/docs/configuration-tui-design-standard.md +767 -0
  41. package/docs/configuration.md +38 -0
  42. package/docs/review-validation.md +115 -0
  43. package/docs/validation-flow.md +117 -0
  44. package/examples/collector.yaml +123 -0
  45. package/examples/observme.yaml +131 -0
  46. package/img/demo.gif +0 -0
  47. package/img/icon.svg +47 -0
  48. package/package.json +103 -0
  49. package/src/commands/obs-agents-runtime.ts +150 -0
  50. package/src/commands/obs-agents.ts +491 -0
  51. package/src/commands/obs-args.ts +63 -0
  52. package/src/commands/obs-backfill.ts +1334 -0
  53. package/src/commands/obs-command-support.ts +43 -0
  54. package/src/commands/obs-cost.ts +228 -0
  55. package/src/commands/obs-diagnostics.ts +22 -0
  56. package/src/commands/obs-errors.ts +156 -0
  57. package/src/commands/obs-health.ts +301 -0
  58. package/src/commands/obs-link.ts +90 -0
  59. package/src/commands/obs-logs.ts +194 -0
  60. package/src/commands/obs-loki-summary.ts +184 -0
  61. package/src/commands/obs-session.ts +259 -0
  62. package/src/commands/obs-status.ts +359 -0
  63. package/src/commands/obs-tools.ts +274 -0
  64. package/src/commands/obs-trace.ts +411 -0
  65. package/src/commands/obs.ts +211 -0
  66. package/src/config/bootstrap-project-config.ts +300 -0
  67. package/src/config/defaults.ts +143 -0
  68. package/src/config/load-config.ts +631 -0
  69. package/src/config/project-paths.ts +61 -0
  70. package/src/config/schema.ts +405 -0
  71. package/src/config/validate.ts +456 -0
  72. package/src/constants.ts +4 -0
  73. package/src/diagnostics/sanitize.ts +6 -0
  74. package/src/extension.ts +38 -0
  75. package/src/otel/logs.ts +160 -0
  76. package/src/otel/metrics.ts +165 -0
  77. package/src/otel/otlp-endpoint.ts +10 -0
  78. package/src/otel/sdk.ts +114 -0
  79. package/src/otel/shutdown.ts +102 -0
  80. package/src/otel/traces.ts +166 -0
  81. package/src/pi/agent-lineage.ts +378 -0
  82. package/src/pi/agent-tree-tracker.ts +258 -0
  83. package/src/pi/event-handlers/agent-turn.ts +155 -0
  84. package/src/pi/event-handlers/lifecycle.ts +642 -0
  85. package/src/pi/event-handlers/llm.ts +115 -0
  86. package/src/pi/event-handlers/session-events.ts +159 -0
  87. package/src/pi/event-handlers/tool-bash.ts +275 -0
  88. package/src/pi/handler-internals.ts +2154 -0
  89. package/src/pi/handler-runtime.ts +633 -0
  90. package/src/pi/handler-types.ts +261 -0
  91. package/src/pi/handlers.ts +75 -0
  92. package/src/pi/subagent-spawn.ts +975 -0
  93. package/src/pi/subagent-types.ts +29 -0
  94. package/src/privacy/content-capture.ts +104 -0
  95. package/src/privacy/hash.ts +93 -0
  96. package/src/privacy/redact.ts +619 -0
  97. package/src/privacy/secret-patterns.ts +185 -0
  98. package/src/privacy/truncate.ts +69 -0
  99. package/src/query/grafana-readiness.ts +164 -0
  100. package/src/query/grafana-transport.ts +481 -0
  101. package/src/query/grafana.ts +371 -0
  102. package/src/query/loki.ts +332 -0
  103. package/src/query/prometheus.ts +388 -0
  104. package/src/query/tempo.ts +332 -0
  105. package/src/safety/sensitive-input.ts +208 -0
  106. package/src/semconv/attributes.ts +279 -0
  107. package/src/semconv/metrics.ts +146 -0
  108. package/src/semconv/spans.ts +19 -0
  109. package/src/semconv/values.ts +13 -0
  110. package/src/util/bounded-map.ts +97 -0
  111. package/tsconfig.json +15 -0
@@ -0,0 +1,1494 @@
1
+ {
2
+ "__requires": [
3
+ {
4
+ "id": "grafana",
5
+ "name": "Grafana",
6
+ "type": "grafana",
7
+ "version": "10.0.0"
8
+ },
9
+ {
10
+ "id": "prometheus",
11
+ "name": "Prometheus",
12
+ "type": "datasource",
13
+ "version": "1.0.0"
14
+ },
15
+ {
16
+ "id": "timeseries",
17
+ "name": "Time series",
18
+ "type": "panel",
19
+ "version": ""
20
+ },
21
+ {
22
+ "id": "stat",
23
+ "name": "Stat",
24
+ "type": "panel",
25
+ "version": ""
26
+ },
27
+ {
28
+ "id": "bargauge",
29
+ "name": "Bar gauge",
30
+ "type": "panel",
31
+ "version": ""
32
+ },
33
+ {
34
+ "id": "table",
35
+ "name": "Table",
36
+ "type": "panel",
37
+ "version": ""
38
+ }
39
+ ],
40
+ "annotations": {
41
+ "list": [
42
+ {
43
+ "datasource": {
44
+ "type": "prometheus",
45
+ "uid": "prometheus"
46
+ },
47
+ "enable": true,
48
+ "hide": false,
49
+ "iconColor": "rgba(31, 120, 193, 1)",
50
+ "name": "Model changes",
51
+ "expr": "sum(increase(observme_model_changes_total[$__interval])) by (provider, model) > 0",
52
+ "titleFormat": "Model change",
53
+ "textFormat": "{{provider}} / {{model}}"
54
+ },
55
+ {
56
+ "datasource": {
57
+ "type": "prometheus",
58
+ "uid": "prometheus"
59
+ },
60
+ "enable": true,
61
+ "hide": false,
62
+ "iconColor": "rgba(245, 183, 0, 1)",
63
+ "name": "Thinking level changes",
64
+ "expr": "sum(increase(observme_thinking_level_changes_total[$__interval])) by (environment) > 0",
65
+ "titleFormat": "Thinking level change",
66
+ "textFormat": "{{environment}}"
67
+ }
68
+ ]
69
+ },
70
+ "editable": true,
71
+ "fiscalYearStartMonth": 0,
72
+ "graphTooltip": 0,
73
+ "id": null,
74
+ "links": [
75
+ {
76
+ "icon": "external link",
77
+ "includeVars": true,
78
+ "keepTime": true,
79
+ "targetBlank": false,
80
+ "title": "Models",
81
+ "tooltip": "Open provider/model traffic, reliability, and cost context.",
82
+ "type": "link",
83
+ "url": "/d/observme-models/observme-models?${__url_time_range}"
84
+ },
85
+ {
86
+ "icon": "external link",
87
+ "includeVars": true,
88
+ "keepTime": true,
89
+ "targetBlank": false,
90
+ "title": "Tools",
91
+ "tooltip": "Open tool traffic, failures, sizes, and latency details.",
92
+ "type": "link",
93
+ "url": "/d/observme-tools/observme-tools?${__url_time_range}"
94
+ },
95
+ {
96
+ "icon": "external link",
97
+ "includeVars": true,
98
+ "keepTime": true,
99
+ "targetBlank": false,
100
+ "title": "Agents",
101
+ "tooltip": "Open aggregate agent and subagent orchestration details.",
102
+ "type": "link",
103
+ "url": "/d/observme-agents/observme-agents?${__url_time_range}"
104
+ },
105
+ {
106
+ "icon": "external link",
107
+ "includeVars": true,
108
+ "keepTime": true,
109
+ "targetBlank": false,
110
+ "title": "Trace Journey",
111
+ "tooltip": "Open trace/log drill-downs for latency spikes.",
112
+ "type": "link",
113
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
114
+ },
115
+ {
116
+ "icon": "external link",
117
+ "includeVars": true,
118
+ "keepTime": true,
119
+ "targetBlank": false,
120
+ "title": "Errors",
121
+ "tooltip": "Open failure logs and error ratios for correlated latency incidents.",
122
+ "type": "link",
123
+ "url": "/d/observme-errors/observme-errors?${__url_time_range}"
124
+ }
125
+ ],
126
+ "liveNow": false,
127
+ "panels": [
128
+ {
129
+ "collapsed": false,
130
+ "gridPos": {
131
+ "h": 1,
132
+ "w": 24,
133
+ "x": 0,
134
+ "y": 0
135
+ },
136
+ "id": 100,
137
+ "panels": [],
138
+ "title": "Latency summary",
139
+ "type": "row"
140
+ },
141
+ {
142
+ "datasource": {
143
+ "type": "prometheus",
144
+ "uid": "prometheus"
145
+ },
146
+ "description": "Rolling p95 duration for completed Pi turns. Compare Stage operation volume before acting on sparse samples. No series means no turn-duration bucket observations in the query window; latency is intentionally not synthesized as zero, so verify workload and Export Health before treating missing telemetry as healthy.",
147
+ "fieldConfig": {
148
+ "defaults": {
149
+ "color": {
150
+ "mode": "palette-classic"
151
+ },
152
+ "mappings": [],
153
+ "thresholds": {
154
+ "mode": "absolute",
155
+ "steps": [
156
+ {
157
+ "color": "green",
158
+ "value": null
159
+ }
160
+ ]
161
+ },
162
+ "unit": "ms"
163
+ },
164
+ "overrides": []
165
+ },
166
+ "gridPos": {
167
+ "h": 8,
168
+ "w": 8,
169
+ "x": 0,
170
+ "y": 1
171
+ },
172
+ "id": 1,
173
+ "links": [
174
+ {
175
+ "targetBlank": false,
176
+ "title": "Open Trace Journey",
177
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
178
+ }
179
+ ],
180
+ "options": {
181
+ "legend": {
182
+ "calcs": [],
183
+ "displayMode": "list",
184
+ "placement": "bottom",
185
+ "showLegend": true
186
+ },
187
+ "tooltip": {
188
+ "mode": "single",
189
+ "sort": "none"
190
+ }
191
+ },
192
+ "targets": [
193
+ {
194
+ "datasource": {
195
+ "type": "prometheus",
196
+ "uid": "prometheus"
197
+ },
198
+ "editorMode": "code",
199
+ "expr": "histogram_quantile(0.95, sum(rate(observme_turn_duration_ms_bucket[$__rate_interval])) by (le))",
200
+ "legendFormat": "turn p95",
201
+ "range": true,
202
+ "refId": "A"
203
+ }
204
+ ],
205
+ "title": "p95 turn latency",
206
+ "type": "timeseries"
207
+ },
208
+ {
209
+ "datasource": {
210
+ "type": "prometheus",
211
+ "uid": "prometheus"
212
+ },
213
+ "description": "Rolling p95 duration for LLM requests. Compare Stage operation volume and the bounded provider/model table before acting on sparse samples. No series means no LLM-duration bucket observations in the query window; latency is intentionally not synthesized as zero, so verify workload and Export Health before treating missing telemetry as healthy.",
214
+ "fieldConfig": {
215
+ "defaults": {
216
+ "color": {
217
+ "mode": "palette-classic"
218
+ },
219
+ "mappings": [],
220
+ "thresholds": {
221
+ "mode": "absolute",
222
+ "steps": [
223
+ {
224
+ "color": "green",
225
+ "value": null
226
+ }
227
+ ]
228
+ },
229
+ "unit": "ms"
230
+ },
231
+ "overrides": []
232
+ },
233
+ "gridPos": {
234
+ "h": 8,
235
+ "w": 8,
236
+ "x": 8,
237
+ "y": 1
238
+ },
239
+ "id": 2,
240
+ "links": [
241
+ {
242
+ "targetBlank": false,
243
+ "title": "Open Models",
244
+ "url": "/d/observme-models/observme-models?${__url_time_range}"
245
+ },
246
+ {
247
+ "targetBlank": false,
248
+ "title": "Open Trace Journey",
249
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
250
+ }
251
+ ],
252
+ "options": {
253
+ "legend": {
254
+ "calcs": [],
255
+ "displayMode": "list",
256
+ "placement": "bottom",
257
+ "showLegend": true
258
+ },
259
+ "tooltip": {
260
+ "mode": "single",
261
+ "sort": "none"
262
+ }
263
+ },
264
+ "targets": [
265
+ {
266
+ "datasource": {
267
+ "type": "prometheus",
268
+ "uid": "prometheus"
269
+ },
270
+ "editorMode": "code",
271
+ "expr": "histogram_quantile(0.95, sum(rate(observme_llm_request_duration_ms_bucket[$__rate_interval])) by (le))",
272
+ "legendFormat": "llm p95",
273
+ "range": true,
274
+ "refId": "A"
275
+ }
276
+ ],
277
+ "title": "p95 LLM latency",
278
+ "type": "timeseries"
279
+ },
280
+ {
281
+ "datasource": {
282
+ "type": "prometheus",
283
+ "uid": "prometheus"
284
+ },
285
+ "description": "Rolling p95 duration for tool calls. Compare Stage operation volume and the bounded tool table before acting on sparse samples. No series means no tool-duration bucket observations in the query window; latency is intentionally not synthesized as zero, so verify workload and Export Health before treating missing telemetry as healthy.",
286
+ "fieldConfig": {
287
+ "defaults": {
288
+ "color": {
289
+ "mode": "palette-classic"
290
+ },
291
+ "mappings": [],
292
+ "thresholds": {
293
+ "mode": "absolute",
294
+ "steps": [
295
+ {
296
+ "color": "green",
297
+ "value": null
298
+ }
299
+ ]
300
+ },
301
+ "unit": "ms"
302
+ },
303
+ "overrides": []
304
+ },
305
+ "gridPos": {
306
+ "h": 8,
307
+ "w": 8,
308
+ "x": 16,
309
+ "y": 1
310
+ },
311
+ "id": 3,
312
+ "links": [
313
+ {
314
+ "targetBlank": false,
315
+ "title": "Open Tools",
316
+ "url": "/d/observme-tools/observme-tools?${__url_time_range}"
317
+ },
318
+ {
319
+ "targetBlank": false,
320
+ "title": "Open Trace Journey",
321
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
322
+ }
323
+ ],
324
+ "options": {
325
+ "legend": {
326
+ "calcs": [],
327
+ "displayMode": "list",
328
+ "placement": "bottom",
329
+ "showLegend": true
330
+ },
331
+ "tooltip": {
332
+ "mode": "single",
333
+ "sort": "none"
334
+ }
335
+ },
336
+ "targets": [
337
+ {
338
+ "datasource": {
339
+ "type": "prometheus",
340
+ "uid": "prometheus"
341
+ },
342
+ "editorMode": "code",
343
+ "expr": "histogram_quantile(0.95, sum(rate(observme_tool_duration_ms_bucket[$__rate_interval])) by (le))",
344
+ "legendFormat": "tool p95",
345
+ "range": true,
346
+ "refId": "A"
347
+ }
348
+ ],
349
+ "title": "p95 tool latency",
350
+ "type": "timeseries"
351
+ },
352
+ {
353
+ "collapsed": false,
354
+ "gridPos": {
355
+ "h": 1,
356
+ "w": 24,
357
+ "x": 0,
358
+ "y": 9
359
+ },
360
+ "id": 101,
361
+ "panels": [],
362
+ "title": "Stage comparison",
363
+ "type": "row"
364
+ },
365
+ {
366
+ "datasource": {
367
+ "type": "prometheus",
368
+ "uid": "prometheus"
369
+ },
370
+ "description": "Rolling p95 comparison across user turns, LLMs, tools, bash, agent runs, spawns, waits, and joins for critical-path attribution. Sparse stages can jump or disappear; compare selected-range operation volume. Missing duration series are left absent rather than shown as a healthy zero.",
371
+ "fieldConfig": {
372
+ "defaults": {
373
+ "color": {
374
+ "mode": "palette-classic"
375
+ },
376
+ "mappings": [],
377
+ "thresholds": {
378
+ "mode": "absolute",
379
+ "steps": [
380
+ {
381
+ "color": "green",
382
+ "value": null
383
+ }
384
+ ]
385
+ },
386
+ "unit": "ms"
387
+ },
388
+ "overrides": []
389
+ },
390
+ "gridPos": {
391
+ "h": 8,
392
+ "w": 24,
393
+ "x": 0,
394
+ "y": 10
395
+ },
396
+ "id": 4,
397
+ "links": [
398
+ {
399
+ "targetBlank": false,
400
+ "title": "Open Trace Journey",
401
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
402
+ }
403
+ ],
404
+ "options": {
405
+ "legend": {
406
+ "calcs": [],
407
+ "displayMode": "list",
408
+ "placement": "bottom",
409
+ "showLegend": true
410
+ },
411
+ "tooltip": {
412
+ "mode": "single",
413
+ "sort": "none"
414
+ }
415
+ },
416
+ "targets": [
417
+ {
418
+ "datasource": {
419
+ "type": "prometheus",
420
+ "uid": "prometheus"
421
+ },
422
+ "editorMode": "code",
423
+ "expr": "histogram_quantile(0.95, sum(rate(observme_turn_duration_ms_bucket[$__rate_interval])) by (le))",
424
+ "legendFormat": "turn p95",
425
+ "range": true,
426
+ "refId": "A"
427
+ },
428
+ {
429
+ "datasource": {
430
+ "type": "prometheus",
431
+ "uid": "prometheus"
432
+ },
433
+ "editorMode": "code",
434
+ "expr": "histogram_quantile(0.95, sum(rate(observme_llm_request_duration_ms_bucket[$__rate_interval])) by (le))",
435
+ "legendFormat": "llm p95",
436
+ "range": true,
437
+ "refId": "B"
438
+ },
439
+ {
440
+ "datasource": {
441
+ "type": "prometheus",
442
+ "uid": "prometheus"
443
+ },
444
+ "editorMode": "code",
445
+ "expr": "histogram_quantile(0.95, sum(rate(observme_tool_duration_ms_bucket[$__rate_interval])) by (le))",
446
+ "legendFormat": "tool p95",
447
+ "range": true,
448
+ "refId": "C"
449
+ },
450
+ {
451
+ "datasource": {
452
+ "type": "prometheus",
453
+ "uid": "prometheus"
454
+ },
455
+ "editorMode": "code",
456
+ "expr": "histogram_quantile(0.95, sum(rate(observme_bash_duration_ms_bucket[$__rate_interval])) by (le))",
457
+ "legendFormat": "bash p95",
458
+ "range": true,
459
+ "refId": "D"
460
+ },
461
+ {
462
+ "datasource": {
463
+ "type": "prometheus",
464
+ "uid": "prometheus"
465
+ },
466
+ "editorMode": "code",
467
+ "expr": "histogram_quantile(0.95, sum(rate(observme_agent_run_duration_ms_bucket[$__rate_interval])) by (le))",
468
+ "legendFormat": "agent run p95",
469
+ "range": true,
470
+ "refId": "E"
471
+ },
472
+ {
473
+ "datasource": {
474
+ "type": "prometheus",
475
+ "uid": "prometheus"
476
+ },
477
+ "editorMode": "code",
478
+ "expr": "histogram_quantile(0.95, sum(rate(observme_subagent_spawn_duration_ms_bucket[$__rate_interval])) by (le))",
479
+ "legendFormat": "spawn p95",
480
+ "range": true,
481
+ "refId": "F"
482
+ },
483
+ {
484
+ "datasource": {
485
+ "type": "prometheus",
486
+ "uid": "prometheus"
487
+ },
488
+ "editorMode": "code",
489
+ "expr": "histogram_quantile(0.95, sum(rate(observme_agent_wait_duration_ms_bucket[$__rate_interval])) by (le))",
490
+ "legendFormat": "wait p95",
491
+ "range": true,
492
+ "refId": "G"
493
+ },
494
+ {
495
+ "datasource": {
496
+ "type": "prometheus",
497
+ "uid": "prometheus"
498
+ },
499
+ "editorMode": "code",
500
+ "expr": "histogram_quantile(0.95, sum(rate(observme_agent_join_duration_ms_bucket[$__rate_interval])) by (le))",
501
+ "legendFormat": "join p95",
502
+ "range": true,
503
+ "refId": "H"
504
+ }
505
+ ],
506
+ "title": "Latency comparison",
507
+ "type": "timeseries"
508
+ },
509
+ {
510
+ "datasource": {
511
+ "type": "prometheus",
512
+ "uid": "prometheus"
513
+ },
514
+ "description": "Selected-range p50/p95/p99 latency estimates for turns, LLMs, tools, bash, agent runs, subagent spawn, parent wait, and parent join. Each instant query uses histogram bucket increases over $__range and retains le. Compare Stage operation volume: low counts make percentile ranks sparse, while no value means no matching duration observations or missing instrumentation and is not converted to zero.",
515
+ "fieldConfig": {
516
+ "defaults": {
517
+ "color": {
518
+ "mode": "palette-classic"
519
+ },
520
+ "mappings": [],
521
+ "thresholds": {
522
+ "mode": "absolute",
523
+ "steps": [
524
+ {
525
+ "color": "green",
526
+ "value": null
527
+ }
528
+ ]
529
+ },
530
+ "unit": "ms"
531
+ },
532
+ "overrides": []
533
+ },
534
+ "gridPos": {
535
+ "h": 10,
536
+ "w": 24,
537
+ "x": 0,
538
+ "y": 18
539
+ },
540
+ "id": 5,
541
+ "links": [
542
+ {
543
+ "targetBlank": false,
544
+ "title": "Open Trace Journey",
545
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
546
+ }
547
+ ],
548
+ "options": {
549
+ "cellHeight": "sm",
550
+ "footer": {
551
+ "countRows": false,
552
+ "fields": "",
553
+ "reducer": [
554
+ "sum"
555
+ ],
556
+ "show": false
557
+ },
558
+ "showHeader": true
559
+ },
560
+ "targets": [
561
+ {
562
+ "datasource": {
563
+ "type": "prometheus",
564
+ "uid": "prometheus"
565
+ },
566
+ "editorMode": "code",
567
+ "expr": "histogram_quantile(0.50, sum(increase(observme_turn_duration_ms_bucket[$__range])) by (le))",
568
+ "legendFormat": "turn p50",
569
+ "format": "table",
570
+ "instant": true,
571
+ "range": false,
572
+ "refId": "A"
573
+ },
574
+ {
575
+ "datasource": {
576
+ "type": "prometheus",
577
+ "uid": "prometheus"
578
+ },
579
+ "editorMode": "code",
580
+ "expr": "histogram_quantile(0.95, sum(increase(observme_turn_duration_ms_bucket[$__range])) by (le))",
581
+ "legendFormat": "turn p95",
582
+ "format": "table",
583
+ "instant": true,
584
+ "range": false,
585
+ "refId": "B"
586
+ },
587
+ {
588
+ "datasource": {
589
+ "type": "prometheus",
590
+ "uid": "prometheus"
591
+ },
592
+ "editorMode": "code",
593
+ "expr": "histogram_quantile(0.99, sum(increase(observme_turn_duration_ms_bucket[$__range])) by (le))",
594
+ "legendFormat": "turn p99",
595
+ "format": "table",
596
+ "instant": true,
597
+ "range": false,
598
+ "refId": "C"
599
+ },
600
+ {
601
+ "datasource": {
602
+ "type": "prometheus",
603
+ "uid": "prometheus"
604
+ },
605
+ "editorMode": "code",
606
+ "expr": "histogram_quantile(0.50, sum(increase(observme_llm_request_duration_ms_bucket[$__range])) by (le))",
607
+ "legendFormat": "llm p50",
608
+ "format": "table",
609
+ "instant": true,
610
+ "range": false,
611
+ "refId": "D"
612
+ },
613
+ {
614
+ "datasource": {
615
+ "type": "prometheus",
616
+ "uid": "prometheus"
617
+ },
618
+ "editorMode": "code",
619
+ "expr": "histogram_quantile(0.95, sum(increase(observme_llm_request_duration_ms_bucket[$__range])) by (le))",
620
+ "legendFormat": "llm p95",
621
+ "format": "table",
622
+ "instant": true,
623
+ "range": false,
624
+ "refId": "E"
625
+ },
626
+ {
627
+ "datasource": {
628
+ "type": "prometheus",
629
+ "uid": "prometheus"
630
+ },
631
+ "editorMode": "code",
632
+ "expr": "histogram_quantile(0.99, sum(increase(observme_llm_request_duration_ms_bucket[$__range])) by (le))",
633
+ "legendFormat": "llm p99",
634
+ "format": "table",
635
+ "instant": true,
636
+ "range": false,
637
+ "refId": "F"
638
+ },
639
+ {
640
+ "datasource": {
641
+ "type": "prometheus",
642
+ "uid": "prometheus"
643
+ },
644
+ "editorMode": "code",
645
+ "expr": "histogram_quantile(0.50, sum(increase(observme_tool_duration_ms_bucket[$__range])) by (le))",
646
+ "legendFormat": "tool p50",
647
+ "format": "table",
648
+ "instant": true,
649
+ "range": false,
650
+ "refId": "G"
651
+ },
652
+ {
653
+ "datasource": {
654
+ "type": "prometheus",
655
+ "uid": "prometheus"
656
+ },
657
+ "editorMode": "code",
658
+ "expr": "histogram_quantile(0.95, sum(increase(observme_tool_duration_ms_bucket[$__range])) by (le))",
659
+ "legendFormat": "tool p95",
660
+ "format": "table",
661
+ "instant": true,
662
+ "range": false,
663
+ "refId": "H"
664
+ },
665
+ {
666
+ "datasource": {
667
+ "type": "prometheus",
668
+ "uid": "prometheus"
669
+ },
670
+ "editorMode": "code",
671
+ "expr": "histogram_quantile(0.99, sum(increase(observme_tool_duration_ms_bucket[$__range])) by (le))",
672
+ "legendFormat": "tool p99",
673
+ "format": "table",
674
+ "instant": true,
675
+ "range": false,
676
+ "refId": "I"
677
+ },
678
+ {
679
+ "datasource": {
680
+ "type": "prometheus",
681
+ "uid": "prometheus"
682
+ },
683
+ "editorMode": "code",
684
+ "expr": "histogram_quantile(0.50, sum(increase(observme_bash_duration_ms_bucket[$__range])) by (le))",
685
+ "legendFormat": "bash p50",
686
+ "format": "table",
687
+ "instant": true,
688
+ "range": false,
689
+ "refId": "J"
690
+ },
691
+ {
692
+ "datasource": {
693
+ "type": "prometheus",
694
+ "uid": "prometheus"
695
+ },
696
+ "editorMode": "code",
697
+ "expr": "histogram_quantile(0.95, sum(increase(observme_bash_duration_ms_bucket[$__range])) by (le))",
698
+ "legendFormat": "bash p95",
699
+ "format": "table",
700
+ "instant": true,
701
+ "range": false,
702
+ "refId": "K"
703
+ },
704
+ {
705
+ "datasource": {
706
+ "type": "prometheus",
707
+ "uid": "prometheus"
708
+ },
709
+ "editorMode": "code",
710
+ "expr": "histogram_quantile(0.99, sum(increase(observme_bash_duration_ms_bucket[$__range])) by (le))",
711
+ "legendFormat": "bash p99",
712
+ "format": "table",
713
+ "instant": true,
714
+ "range": false,
715
+ "refId": "L"
716
+ },
717
+ {
718
+ "datasource": {
719
+ "type": "prometheus",
720
+ "uid": "prometheus"
721
+ },
722
+ "editorMode": "code",
723
+ "expr": "histogram_quantile(0.50, sum(increase(observme_agent_run_duration_ms_bucket[$__range])) by (le))",
724
+ "legendFormat": "agent run p50",
725
+ "format": "table",
726
+ "instant": true,
727
+ "range": false,
728
+ "refId": "M"
729
+ },
730
+ {
731
+ "datasource": {
732
+ "type": "prometheus",
733
+ "uid": "prometheus"
734
+ },
735
+ "editorMode": "code",
736
+ "expr": "histogram_quantile(0.95, sum(increase(observme_agent_run_duration_ms_bucket[$__range])) by (le))",
737
+ "legendFormat": "agent run p95",
738
+ "format": "table",
739
+ "instant": true,
740
+ "range": false,
741
+ "refId": "N"
742
+ },
743
+ {
744
+ "datasource": {
745
+ "type": "prometheus",
746
+ "uid": "prometheus"
747
+ },
748
+ "editorMode": "code",
749
+ "expr": "histogram_quantile(0.99, sum(increase(observme_agent_run_duration_ms_bucket[$__range])) by (le))",
750
+ "legendFormat": "agent run p99",
751
+ "format": "table",
752
+ "instant": true,
753
+ "range": false,
754
+ "refId": "O"
755
+ },
756
+ {
757
+ "datasource": {
758
+ "type": "prometheus",
759
+ "uid": "prometheus"
760
+ },
761
+ "editorMode": "code",
762
+ "expr": "histogram_quantile(0.50, sum(increase(observme_subagent_spawn_duration_ms_bucket[$__range])) by (le))",
763
+ "legendFormat": "spawn p50",
764
+ "format": "table",
765
+ "instant": true,
766
+ "range": false,
767
+ "refId": "P"
768
+ },
769
+ {
770
+ "datasource": {
771
+ "type": "prometheus",
772
+ "uid": "prometheus"
773
+ },
774
+ "editorMode": "code",
775
+ "expr": "histogram_quantile(0.95, sum(increase(observme_subagent_spawn_duration_ms_bucket[$__range])) by (le))",
776
+ "legendFormat": "spawn p95",
777
+ "format": "table",
778
+ "instant": true,
779
+ "range": false,
780
+ "refId": "Q"
781
+ },
782
+ {
783
+ "datasource": {
784
+ "type": "prometheus",
785
+ "uid": "prometheus"
786
+ },
787
+ "editorMode": "code",
788
+ "expr": "histogram_quantile(0.99, sum(increase(observme_subagent_spawn_duration_ms_bucket[$__range])) by (le))",
789
+ "legendFormat": "spawn p99",
790
+ "format": "table",
791
+ "instant": true,
792
+ "range": false,
793
+ "refId": "R"
794
+ },
795
+ {
796
+ "datasource": {
797
+ "type": "prometheus",
798
+ "uid": "prometheus"
799
+ },
800
+ "editorMode": "code",
801
+ "expr": "histogram_quantile(0.50, sum(increase(observme_agent_wait_duration_ms_bucket[$__range])) by (le))",
802
+ "legendFormat": "wait p50",
803
+ "format": "table",
804
+ "instant": true,
805
+ "range": false,
806
+ "refId": "S"
807
+ },
808
+ {
809
+ "datasource": {
810
+ "type": "prometheus",
811
+ "uid": "prometheus"
812
+ },
813
+ "editorMode": "code",
814
+ "expr": "histogram_quantile(0.95, sum(increase(observme_agent_wait_duration_ms_bucket[$__range])) by (le))",
815
+ "legendFormat": "wait p95",
816
+ "format": "table",
817
+ "instant": true,
818
+ "range": false,
819
+ "refId": "T"
820
+ },
821
+ {
822
+ "datasource": {
823
+ "type": "prometheus",
824
+ "uid": "prometheus"
825
+ },
826
+ "editorMode": "code",
827
+ "expr": "histogram_quantile(0.99, sum(increase(observme_agent_wait_duration_ms_bucket[$__range])) by (le))",
828
+ "legendFormat": "wait p99",
829
+ "format": "table",
830
+ "instant": true,
831
+ "range": false,
832
+ "refId": "U"
833
+ },
834
+ {
835
+ "datasource": {
836
+ "type": "prometheus",
837
+ "uid": "prometheus"
838
+ },
839
+ "editorMode": "code",
840
+ "expr": "histogram_quantile(0.50, sum(increase(observme_agent_join_duration_ms_bucket[$__range])) by (le))",
841
+ "legendFormat": "join p50",
842
+ "format": "table",
843
+ "instant": true,
844
+ "range": false,
845
+ "refId": "V"
846
+ },
847
+ {
848
+ "datasource": {
849
+ "type": "prometheus",
850
+ "uid": "prometheus"
851
+ },
852
+ "editorMode": "code",
853
+ "expr": "histogram_quantile(0.95, sum(increase(observme_agent_join_duration_ms_bucket[$__range])) by (le))",
854
+ "legendFormat": "join p95",
855
+ "format": "table",
856
+ "instant": true,
857
+ "range": false,
858
+ "refId": "W"
859
+ },
860
+ {
861
+ "datasource": {
862
+ "type": "prometheus",
863
+ "uid": "prometheus"
864
+ },
865
+ "editorMode": "code",
866
+ "expr": "histogram_quantile(0.99, sum(increase(observme_agent_join_duration_ms_bucket[$__range])) by (le))",
867
+ "legendFormat": "join p99",
868
+ "format": "table",
869
+ "instant": true,
870
+ "range": false,
871
+ "refId": "X"
872
+ }
873
+ ],
874
+ "title": "Stage latency quantiles",
875
+ "type": "table"
876
+ },
877
+ {
878
+ "datasource": {
879
+ "type": "prometheus",
880
+ "uid": "prometheus"
881
+ },
882
+ "description": "Selected-range instant operation counts for interpreting sparse percentile estimates. Zero means no matching counter increments were observed; it does not prove duration instrumentation is healthy. Wait/join have no dedicated completion counters, so agent-run volume is contextual rather than an exact wait/join sample count.",
883
+ "fieldConfig": {
884
+ "defaults": {
885
+ "color": {
886
+ "mode": "palette-classic"
887
+ },
888
+ "mappings": [],
889
+ "thresholds": {
890
+ "mode": "absolute",
891
+ "steps": [
892
+ {
893
+ "color": "green",
894
+ "value": null
895
+ }
896
+ ]
897
+ },
898
+ "unit": "short"
899
+ },
900
+ "overrides": []
901
+ },
902
+ "gridPos": {
903
+ "h": 8,
904
+ "w": 24,
905
+ "x": 0,
906
+ "y": 28
907
+ },
908
+ "id": 6,
909
+ "options": {
910
+ "cellHeight": "sm",
911
+ "footer": {
912
+ "countRows": false,
913
+ "fields": "",
914
+ "reducer": [
915
+ "sum"
916
+ ],
917
+ "show": false
918
+ },
919
+ "showHeader": true
920
+ },
921
+ "targets": [
922
+ {
923
+ "datasource": {
924
+ "type": "prometheus",
925
+ "uid": "prometheus"
926
+ },
927
+ "editorMode": "code",
928
+ "expr": "sum(increase(observme_turns_completed_total[$__range])) or vector(0)",
929
+ "legendFormat": "turn completions",
930
+ "format": "table",
931
+ "instant": true,
932
+ "range": false,
933
+ "refId": "A"
934
+ },
935
+ {
936
+ "datasource": {
937
+ "type": "prometheus",
938
+ "uid": "prometheus"
939
+ },
940
+ "editorMode": "code",
941
+ "expr": "sum(increase(observme_llm_requests_total[$__range])) or vector(0)",
942
+ "legendFormat": "llm requests",
943
+ "format": "table",
944
+ "instant": true,
945
+ "range": false,
946
+ "refId": "B"
947
+ },
948
+ {
949
+ "datasource": {
950
+ "type": "prometheus",
951
+ "uid": "prometheus"
952
+ },
953
+ "editorMode": "code",
954
+ "expr": "sum(increase(observme_tool_calls_total[$__range])) or vector(0)",
955
+ "legendFormat": "tool calls",
956
+ "format": "table",
957
+ "instant": true,
958
+ "range": false,
959
+ "refId": "C"
960
+ },
961
+ {
962
+ "datasource": {
963
+ "type": "prometheus",
964
+ "uid": "prometheus"
965
+ },
966
+ "editorMode": "code",
967
+ "expr": "sum(increase(observme_bash_executions_total[$__range])) or vector(0)",
968
+ "legendFormat": "bash executions",
969
+ "format": "table",
970
+ "instant": true,
971
+ "range": false,
972
+ "refId": "D"
973
+ },
974
+ {
975
+ "datasource": {
976
+ "type": "prometheus",
977
+ "uid": "prometheus"
978
+ },
979
+ "editorMode": "code",
980
+ "expr": "sum(increase(observme_agent_runs_total[$__range])) or vector(0)",
981
+ "legendFormat": "agent runs",
982
+ "format": "table",
983
+ "instant": true,
984
+ "range": false,
985
+ "refId": "E"
986
+ },
987
+ {
988
+ "datasource": {
989
+ "type": "prometheus",
990
+ "uid": "prometheus"
991
+ },
992
+ "editorMode": "code",
993
+ "expr": "sum(increase(observme_subagents_spawned_total[$__range])) or vector(0)",
994
+ "legendFormat": "subagent spawns",
995
+ "format": "table",
996
+ "instant": true,
997
+ "range": false,
998
+ "refId": "F"
999
+ },
1000
+ {
1001
+ "datasource": {
1002
+ "type": "prometheus",
1003
+ "uid": "prometheus"
1004
+ },
1005
+ "editorMode": "code",
1006
+ "expr": "sum(increase(observme_agent_runs_total[$__range])) by (agent_role)",
1007
+ "legendFormat": "agent runs by role (wait/join context) {{agent_role}}",
1008
+ "format": "table",
1009
+ "instant": true,
1010
+ "range": false,
1011
+ "refId": "G"
1012
+ }
1013
+ ],
1014
+ "title": "Stage operation volume",
1015
+ "type": "table"
1016
+ },
1017
+ {
1018
+ "collapsed": false,
1019
+ "gridPos": {
1020
+ "h": 1,
1021
+ "w": 24,
1022
+ "x": 0,
1023
+ "y": 36
1024
+ },
1025
+ "id": 102,
1026
+ "panels": [],
1027
+ "title": "Top offenders",
1028
+ "type": "row"
1029
+ },
1030
+ {
1031
+ "datasource": {
1032
+ "type": "prometheus",
1033
+ "uid": "prometheus"
1034
+ },
1035
+ "description": "Top 10 provider/model selected-range p95 LLM latency estimates with request counts. Histogram bucket increases retain provider, model, and le. Low request counts make percentile ranks sparse; an absent row means no matching observations and is not a zero-latency result.",
1036
+ "fieldConfig": {
1037
+ "defaults": {
1038
+ "color": {
1039
+ "mode": "palette-classic"
1040
+ },
1041
+ "mappings": [],
1042
+ "thresholds": {
1043
+ "mode": "absolute",
1044
+ "steps": [
1045
+ {
1046
+ "color": "green",
1047
+ "value": null
1048
+ }
1049
+ ]
1050
+ },
1051
+ "unit": "ms"
1052
+ },
1053
+ "overrides": [
1054
+ {
1055
+ "matcher": {
1056
+ "id": "byFrameRefID",
1057
+ "options": "B"
1058
+ },
1059
+ "properties": [
1060
+ {
1061
+ "id": "unit",
1062
+ "value": "short"
1063
+ }
1064
+ ]
1065
+ }
1066
+ ]
1067
+ },
1068
+ "gridPos": {
1069
+ "h": 8,
1070
+ "w": 8,
1071
+ "x": 0,
1072
+ "y": 37
1073
+ },
1074
+ "id": 7,
1075
+ "links": [
1076
+ {
1077
+ "targetBlank": false,
1078
+ "title": "Open Models",
1079
+ "url": "/d/observme-models/observme-models?${__url_time_range}"
1080
+ },
1081
+ {
1082
+ "targetBlank": false,
1083
+ "title": "Open Trace Journey",
1084
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
1085
+ }
1086
+ ],
1087
+ "options": {
1088
+ "cellHeight": "sm",
1089
+ "footer": {
1090
+ "countRows": false,
1091
+ "fields": "",
1092
+ "reducer": [
1093
+ "sum"
1094
+ ],
1095
+ "show": false
1096
+ },
1097
+ "showHeader": true
1098
+ },
1099
+ "targets": [
1100
+ {
1101
+ "datasource": {
1102
+ "type": "prometheus",
1103
+ "uid": "prometheus"
1104
+ },
1105
+ "editorMode": "code",
1106
+ "expr": "topk(10, histogram_quantile(0.95, sum(increase(observme_llm_request_duration_ms_bucket[$__range])) by (provider, model, le)))",
1107
+ "legendFormat": "p95 {{provider}} / {{model}}",
1108
+ "format": "table",
1109
+ "instant": true,
1110
+ "range": false,
1111
+ "refId": "A"
1112
+ },
1113
+ {
1114
+ "datasource": {
1115
+ "type": "prometheus",
1116
+ "uid": "prometheus"
1117
+ },
1118
+ "editorMode": "code",
1119
+ "expr": "topk(10, sum(increase(observme_llm_requests_total[$__range])) by (provider, model))",
1120
+ "legendFormat": "requests {{provider}} / {{model}}",
1121
+ "format": "table",
1122
+ "instant": true,
1123
+ "range": false,
1124
+ "refId": "B"
1125
+ }
1126
+ ],
1127
+ "title": "Top slow provider/model with volume",
1128
+ "type": "table"
1129
+ },
1130
+ {
1131
+ "datasource": {
1132
+ "type": "prometheus",
1133
+ "uid": "prometheus"
1134
+ },
1135
+ "description": "Top 10 tool selected-range p95 latency estimates with call counts. Histogram bucket increases retain tool_name and le. Low call counts make percentile ranks sparse; an absent row means no matching observations and is not a zero-latency result.",
1136
+ "fieldConfig": {
1137
+ "defaults": {
1138
+ "color": {
1139
+ "mode": "palette-classic"
1140
+ },
1141
+ "mappings": [],
1142
+ "thresholds": {
1143
+ "mode": "absolute",
1144
+ "steps": [
1145
+ {
1146
+ "color": "green",
1147
+ "value": null
1148
+ }
1149
+ ]
1150
+ },
1151
+ "unit": "ms"
1152
+ },
1153
+ "overrides": [
1154
+ {
1155
+ "matcher": {
1156
+ "id": "byFrameRefID",
1157
+ "options": "B"
1158
+ },
1159
+ "properties": [
1160
+ {
1161
+ "id": "unit",
1162
+ "value": "short"
1163
+ }
1164
+ ]
1165
+ }
1166
+ ]
1167
+ },
1168
+ "gridPos": {
1169
+ "h": 8,
1170
+ "w": 8,
1171
+ "x": 8,
1172
+ "y": 37
1173
+ },
1174
+ "id": 8,
1175
+ "links": [
1176
+ {
1177
+ "targetBlank": false,
1178
+ "title": "Open Tools",
1179
+ "url": "/d/observme-tools/observme-tools?${__url_time_range}"
1180
+ },
1181
+ {
1182
+ "targetBlank": false,
1183
+ "title": "Open Trace Journey",
1184
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
1185
+ }
1186
+ ],
1187
+ "options": {
1188
+ "cellHeight": "sm",
1189
+ "footer": {
1190
+ "countRows": false,
1191
+ "fields": "",
1192
+ "reducer": [
1193
+ "sum"
1194
+ ],
1195
+ "show": false
1196
+ },
1197
+ "showHeader": true
1198
+ },
1199
+ "targets": [
1200
+ {
1201
+ "datasource": {
1202
+ "type": "prometheus",
1203
+ "uid": "prometheus"
1204
+ },
1205
+ "editorMode": "code",
1206
+ "expr": "topk(10, histogram_quantile(0.95, sum(increase(observme_tool_duration_ms_bucket[$__range])) by (tool_name, le)))",
1207
+ "legendFormat": "p95 {{tool_name}}",
1208
+ "format": "table",
1209
+ "instant": true,
1210
+ "range": false,
1211
+ "refId": "A"
1212
+ },
1213
+ {
1214
+ "datasource": {
1215
+ "type": "prometheus",
1216
+ "uid": "prometheus"
1217
+ },
1218
+ "editorMode": "code",
1219
+ "expr": "topk(10, sum(increase(observme_tool_calls_total[$__range])) by (tool_name))",
1220
+ "legendFormat": "calls {{tool_name}}",
1221
+ "format": "table",
1222
+ "instant": true,
1223
+ "range": false,
1224
+ "refId": "B"
1225
+ }
1226
+ ],
1227
+ "title": "Top slow tools with volume",
1228
+ "type": "table"
1229
+ },
1230
+ {
1231
+ "datasource": {
1232
+ "type": "prometheus",
1233
+ "uid": "prometheus"
1234
+ },
1235
+ "description": "Top 10 agent-role selected-range p95 run-latency estimates with run counts. Histogram bucket increases retain agent_role and le. Low run counts make percentile ranks sparse; an absent row means no matching observations and is not a zero-latency result.",
1236
+ "fieldConfig": {
1237
+ "defaults": {
1238
+ "color": {
1239
+ "mode": "palette-classic"
1240
+ },
1241
+ "mappings": [],
1242
+ "thresholds": {
1243
+ "mode": "absolute",
1244
+ "steps": [
1245
+ {
1246
+ "color": "green",
1247
+ "value": null
1248
+ }
1249
+ ]
1250
+ },
1251
+ "unit": "ms"
1252
+ },
1253
+ "overrides": [
1254
+ {
1255
+ "matcher": {
1256
+ "id": "byFrameRefID",
1257
+ "options": "B"
1258
+ },
1259
+ "properties": [
1260
+ {
1261
+ "id": "unit",
1262
+ "value": "short"
1263
+ }
1264
+ ]
1265
+ }
1266
+ ]
1267
+ },
1268
+ "gridPos": {
1269
+ "h": 8,
1270
+ "w": 8,
1271
+ "x": 16,
1272
+ "y": 37
1273
+ },
1274
+ "id": 9,
1275
+ "links": [
1276
+ {
1277
+ "targetBlank": false,
1278
+ "title": "Open Agents",
1279
+ "url": "/d/observme-agents/observme-agents?${__url_time_range}"
1280
+ },
1281
+ {
1282
+ "targetBlank": false,
1283
+ "title": "Open Trace Journey",
1284
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
1285
+ }
1286
+ ],
1287
+ "options": {
1288
+ "cellHeight": "sm",
1289
+ "footer": {
1290
+ "countRows": false,
1291
+ "fields": "",
1292
+ "reducer": [
1293
+ "sum"
1294
+ ],
1295
+ "show": false
1296
+ },
1297
+ "showHeader": true
1298
+ },
1299
+ "targets": [
1300
+ {
1301
+ "datasource": {
1302
+ "type": "prometheus",
1303
+ "uid": "prometheus"
1304
+ },
1305
+ "editorMode": "code",
1306
+ "expr": "topk(10, histogram_quantile(0.95, sum(increase(observme_agent_run_duration_ms_bucket[$__range])) by (agent_role, le)))",
1307
+ "legendFormat": "p95 {{agent_role}}",
1308
+ "format": "table",
1309
+ "instant": true,
1310
+ "range": false,
1311
+ "refId": "A"
1312
+ },
1313
+ {
1314
+ "datasource": {
1315
+ "type": "prometheus",
1316
+ "uid": "prometheus"
1317
+ },
1318
+ "editorMode": "code",
1319
+ "expr": "topk(10, sum(increase(observme_agent_runs_total[$__range])) by (agent_role))",
1320
+ "legendFormat": "runs {{agent_role}}",
1321
+ "format": "table",
1322
+ "instant": true,
1323
+ "range": false,
1324
+ "refId": "B"
1325
+ }
1326
+ ],
1327
+ "title": "Top slow agent roles with volume",
1328
+ "type": "table"
1329
+ },
1330
+ {
1331
+ "collapsed": false,
1332
+ "gridPos": {
1333
+ "h": 1,
1334
+ "w": 24,
1335
+ "x": 0,
1336
+ "y": 45
1337
+ },
1338
+ "id": 103,
1339
+ "panels": [],
1340
+ "title": "Detailed trends",
1341
+ "type": "row"
1342
+ },
1343
+ {
1344
+ "datasource": {
1345
+ "type": "prometheus",
1346
+ "uid": "prometheus"
1347
+ },
1348
+ "description": "Top 10 rolling LLM request p95 latency trends grouped only by bounded provider and model labels. Compare the selected-range offender table for request volume. Sparse or absent buckets can make a series jump or disappear; missing duration telemetry is not converted to zero.",
1349
+ "fieldConfig": {
1350
+ "defaults": {
1351
+ "color": {
1352
+ "mode": "palette-classic"
1353
+ },
1354
+ "mappings": [],
1355
+ "thresholds": {
1356
+ "mode": "absolute",
1357
+ "steps": [
1358
+ {
1359
+ "color": "green",
1360
+ "value": null
1361
+ }
1362
+ ]
1363
+ },
1364
+ "unit": "ms"
1365
+ },
1366
+ "overrides": []
1367
+ },
1368
+ "gridPos": {
1369
+ "h": 8,
1370
+ "w": 12,
1371
+ "x": 0,
1372
+ "y": 46
1373
+ },
1374
+ "id": 10,
1375
+ "links": [
1376
+ {
1377
+ "targetBlank": false,
1378
+ "title": "Open Models",
1379
+ "url": "/d/observme-models/observme-models?${__url_time_range}"
1380
+ }
1381
+ ],
1382
+ "options": {
1383
+ "legend": {
1384
+ "calcs": [],
1385
+ "displayMode": "list",
1386
+ "placement": "bottom",
1387
+ "showLegend": true
1388
+ },
1389
+ "tooltip": {
1390
+ "mode": "single",
1391
+ "sort": "none"
1392
+ }
1393
+ },
1394
+ "targets": [
1395
+ {
1396
+ "datasource": {
1397
+ "type": "prometheus",
1398
+ "uid": "prometheus"
1399
+ },
1400
+ "editorMode": "code",
1401
+ "expr": "topk(10, histogram_quantile(0.95, sum(rate(observme_llm_request_duration_ms_bucket[$__rate_interval])) by (provider, model, le)))",
1402
+ "legendFormat": "{{provider}} / {{model}}",
1403
+ "range": true,
1404
+ "refId": "A"
1405
+ }
1406
+ ],
1407
+ "title": "LLM p95 latency by provider and model",
1408
+ "type": "timeseries"
1409
+ },
1410
+ {
1411
+ "datasource": {
1412
+ "type": "prometheus",
1413
+ "uid": "prometheus"
1414
+ },
1415
+ "description": "Top 10 rolling tool-call p95 latency trends grouped by the documented bounded tool_name label. Compare the selected-range offender table for call volume. Sparse or absent buckets can make a series jump or disappear; missing duration telemetry is not converted to zero.",
1416
+ "fieldConfig": {
1417
+ "defaults": {
1418
+ "color": {
1419
+ "mode": "palette-classic"
1420
+ },
1421
+ "mappings": [],
1422
+ "thresholds": {
1423
+ "mode": "absolute",
1424
+ "steps": [
1425
+ {
1426
+ "color": "green",
1427
+ "value": null
1428
+ }
1429
+ ]
1430
+ },
1431
+ "unit": "ms"
1432
+ },
1433
+ "overrides": []
1434
+ },
1435
+ "gridPos": {
1436
+ "h": 8,
1437
+ "w": 12,
1438
+ "x": 12,
1439
+ "y": 46
1440
+ },
1441
+ "id": 11,
1442
+ "links": [
1443
+ {
1444
+ "targetBlank": false,
1445
+ "title": "Open Tools",
1446
+ "url": "/d/observme-tools/observme-tools?${__url_time_range}"
1447
+ }
1448
+ ],
1449
+ "options": {
1450
+ "legend": {
1451
+ "calcs": [],
1452
+ "displayMode": "list",
1453
+ "placement": "bottom",
1454
+ "showLegend": true
1455
+ },
1456
+ "tooltip": {
1457
+ "mode": "single",
1458
+ "sort": "none"
1459
+ }
1460
+ },
1461
+ "targets": [
1462
+ {
1463
+ "datasource": {
1464
+ "type": "prometheus",
1465
+ "uid": "prometheus"
1466
+ },
1467
+ "editorMode": "code",
1468
+ "expr": "topk(10, histogram_quantile(0.95, sum(rate(observme_tool_duration_ms_bucket[$__rate_interval])) by (tool_name, le)))",
1469
+ "legendFormat": "{{tool_name}}",
1470
+ "range": true,
1471
+ "refId": "A"
1472
+ }
1473
+ ],
1474
+ "title": "Tool p95 latency by tool",
1475
+ "type": "timeseries"
1476
+ }
1477
+ ],
1478
+ "refresh": "30s",
1479
+ "schemaVersion": 39,
1480
+ "tags": [
1481
+ "observme",
1482
+ "pi",
1483
+ "opentelemetry"
1484
+ ],
1485
+ "time": {
1486
+ "from": "now-6h",
1487
+ "to": "now"
1488
+ },
1489
+ "timezone": "browser",
1490
+ "title": "ObservMe Latency",
1491
+ "uid": "observme-latency",
1492
+ "version": 2,
1493
+ "weekStart": ""
1494
+ }