@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,1042 @@
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": "loki",
17
+ "name": "Loki",
18
+ "type": "datasource",
19
+ "version": "1.0.0"
20
+ },
21
+ {
22
+ "id": "row",
23
+ "name": "Row",
24
+ "type": "panel",
25
+ "version": ""
26
+ },
27
+ {
28
+ "id": "stat",
29
+ "name": "Stat",
30
+ "type": "panel",
31
+ "version": ""
32
+ },
33
+ {
34
+ "id": "timeseries",
35
+ "name": "Time series",
36
+ "type": "panel",
37
+ "version": ""
38
+ },
39
+ {
40
+ "id": "table",
41
+ "name": "Table",
42
+ "type": "panel",
43
+ "version": ""
44
+ }
45
+ ],
46
+ "annotations": {
47
+ "list": []
48
+ },
49
+ "editable": true,
50
+ "fiscalYearStartMonth": 0,
51
+ "graphTooltip": 1,
52
+ "id": null,
53
+ "links": [
54
+ {
55
+ "icon": "external link",
56
+ "includeVars": true,
57
+ "keepTime": true,
58
+ "targetBlank": false,
59
+ "title": "Overview",
60
+ "tooltip": "Open the overview with the current time range.",
61
+ "type": "link",
62
+ "url": "/d/observme-overview/observme-overview?${__url_time_range}"
63
+ },
64
+ {
65
+ "icon": "external link",
66
+ "includeVars": true,
67
+ "keepTime": true,
68
+ "targetBlank": false,
69
+ "title": "Cost",
70
+ "tooltip": "Compare branch, compaction, model, and thinking changes with cost trends.",
71
+ "type": "link",
72
+ "url": "/d/observme-cost/observme-cost?${__url_time_range}"
73
+ },
74
+ {
75
+ "icon": "external link",
76
+ "includeVars": true,
77
+ "keepTime": true,
78
+ "targetBlank": false,
79
+ "title": "Models",
80
+ "tooltip": "Compare model changes with provider and model behavior.",
81
+ "type": "link",
82
+ "url": "/d/observme-models/observme-models?${__url_time_range}"
83
+ },
84
+ {
85
+ "icon": "external link",
86
+ "includeVars": true,
87
+ "keepTime": true,
88
+ "targetBlank": false,
89
+ "title": "Latency",
90
+ "tooltip": "Compare branch and compaction pressure with latency trends.",
91
+ "type": "link",
92
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
93
+ },
94
+ {
95
+ "icon": "external link",
96
+ "includeVars": true,
97
+ "keepTime": true,
98
+ "targetBlank": false,
99
+ "title": "Logs and LLM I/O",
100
+ "tooltip": "Open privacy-safe LLM lifecycle logs and size trends.",
101
+ "type": "link",
102
+ "url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
103
+ },
104
+ {
105
+ "icon": "external link",
106
+ "includeVars": true,
107
+ "keepTime": true,
108
+ "targetBlank": false,
109
+ "title": "Trace Journey",
110
+ "tooltip": "Open per-execution logs and Tempo traces with the current time range.",
111
+ "type": "link",
112
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
113
+ }
114
+ ],
115
+ "liveNow": false,
116
+ "panels": [
117
+ {
118
+ "collapsed": false,
119
+ "gridPos": {
120
+ "h": 1,
121
+ "w": 24,
122
+ "x": 0,
123
+ "y": 0
124
+ },
125
+ "id": 100,
126
+ "panels": [],
127
+ "title": "Selected-range summary",
128
+ "type": "row"
129
+ },
130
+ {
131
+ "datasource": {
132
+ "type": "prometheus",
133
+ "uid": "prometheus"
134
+ },
135
+ "description": "Branch events observed in the selected range. Missing series render as zero, which means no branch events were observed; it does not prove telemetry liveness.",
136
+ "fieldConfig": {
137
+ "defaults": {
138
+ "color": {
139
+ "mode": "thresholds"
140
+ },
141
+ "mappings": [],
142
+ "min": 0,
143
+ "thresholds": {
144
+ "mode": "absolute",
145
+ "steps": [
146
+ {
147
+ "color": "green",
148
+ "value": null
149
+ }
150
+ ]
151
+ },
152
+ "unit": "short"
153
+ },
154
+ "overrides": []
155
+ },
156
+ "gridPos": {
157
+ "h": 5,
158
+ "w": 6,
159
+ "x": 0,
160
+ "y": 1
161
+ },
162
+ "id": 1,
163
+ "links": [
164
+ {
165
+ "targetBlank": false,
166
+ "title": "Open Trace Journey",
167
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
168
+ }
169
+ ],
170
+ "options": {
171
+ "colorMode": "value",
172
+ "graphMode": "area",
173
+ "justifyMode": "auto",
174
+ "orientation": "auto",
175
+ "reduceOptions": {
176
+ "calcs": [
177
+ "lastNotNull"
178
+ ],
179
+ "fields": "",
180
+ "values": false
181
+ },
182
+ "showPercentChange": false,
183
+ "textMode": "auto",
184
+ "wideLayout": true
185
+ },
186
+ "pluginVersion": "11.1.0",
187
+ "targets": [
188
+ {
189
+ "datasource": {
190
+ "type": "prometheus",
191
+ "uid": "prometheus"
192
+ },
193
+ "editorMode": "code",
194
+ "expr": "sum(increase(observme_branches_total[$__range])) or vector(0)",
195
+ "instant": true,
196
+ "legendFormat": "branches",
197
+ "range": false,
198
+ "refId": "A"
199
+ }
200
+ ],
201
+ "title": "Branch events",
202
+ "type": "stat"
203
+ },
204
+ {
205
+ "datasource": {
206
+ "type": "prometheus",
207
+ "uid": "prometheus"
208
+ },
209
+ "description": "Compaction events observed in the selected range. Missing series render as zero, which means no compactions were observed; it does not prove telemetry liveness.",
210
+ "fieldConfig": {
211
+ "defaults": {
212
+ "color": {
213
+ "mode": "thresholds"
214
+ },
215
+ "mappings": [],
216
+ "min": 0,
217
+ "thresholds": {
218
+ "mode": "absolute",
219
+ "steps": [
220
+ {
221
+ "color": "green",
222
+ "value": null
223
+ }
224
+ ]
225
+ },
226
+ "unit": "short"
227
+ },
228
+ "overrides": []
229
+ },
230
+ "gridPos": {
231
+ "h": 5,
232
+ "w": 6,
233
+ "x": 6,
234
+ "y": 1
235
+ },
236
+ "id": 2,
237
+ "links": [
238
+ {
239
+ "targetBlank": false,
240
+ "title": "Open Latency",
241
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
242
+ }
243
+ ],
244
+ "options": {
245
+ "colorMode": "value",
246
+ "graphMode": "area",
247
+ "justifyMode": "auto",
248
+ "orientation": "auto",
249
+ "reduceOptions": {
250
+ "calcs": [
251
+ "lastNotNull"
252
+ ],
253
+ "fields": "",
254
+ "values": false
255
+ },
256
+ "showPercentChange": false,
257
+ "textMode": "auto",
258
+ "wideLayout": true
259
+ },
260
+ "pluginVersion": "11.1.0",
261
+ "targets": [
262
+ {
263
+ "datasource": {
264
+ "type": "prometheus",
265
+ "uid": "prometheus"
266
+ },
267
+ "editorMode": "code",
268
+ "expr": "sum(increase(observme_compactions_total[$__range])) or vector(0)",
269
+ "instant": true,
270
+ "legendFormat": "compactions",
271
+ "range": false,
272
+ "refId": "A"
273
+ }
274
+ ],
275
+ "title": "Compaction events",
276
+ "type": "stat"
277
+ },
278
+ {
279
+ "datasource": {
280
+ "type": "prometheus",
281
+ "uid": "prometheus"
282
+ },
283
+ "description": "Aggregate branch events divided by session starts in the selected range. This is a suite-level estimate because per-session IDs are intentionally excluded from Prometheus labels; sparse ranges and sessions crossing the range boundary can skew it. Zero can mean no branches, no session starts, or absent telemetry.",
284
+ "fieldConfig": {
285
+ "defaults": {
286
+ "color": {
287
+ "mode": "thresholds"
288
+ },
289
+ "decimals": 2,
290
+ "mappings": [],
291
+ "min": 0,
292
+ "thresholds": {
293
+ "mode": "absolute",
294
+ "steps": [
295
+ {
296
+ "color": "green",
297
+ "value": null
298
+ }
299
+ ]
300
+ },
301
+ "unit": "short"
302
+ },
303
+ "overrides": []
304
+ },
305
+ "gridPos": {
306
+ "h": 5,
307
+ "w": 6,
308
+ "x": 12,
309
+ "y": 1
310
+ },
311
+ "id": 3,
312
+ "links": [
313
+ {
314
+ "targetBlank": false,
315
+ "title": "Open Trace Journey",
316
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
317
+ }
318
+ ],
319
+ "options": {
320
+ "colorMode": "value",
321
+ "graphMode": "area",
322
+ "justifyMode": "auto",
323
+ "orientation": "auto",
324
+ "reduceOptions": {
325
+ "calcs": [
326
+ "lastNotNull"
327
+ ],
328
+ "fields": "",
329
+ "values": false
330
+ },
331
+ "showPercentChange": false,
332
+ "textMode": "auto",
333
+ "wideLayout": true
334
+ },
335
+ "pluginVersion": "11.1.0",
336
+ "targets": [
337
+ {
338
+ "datasource": {
339
+ "type": "prometheus",
340
+ "uid": "prometheus"
341
+ },
342
+ "editorMode": "code",
343
+ "expr": "(sum(increase(observme_branches_total[$__range])) or vector(0)) / clamp_min((sum(increase(observme_sessions_started_total[$__range])) or vector(0)), 1)",
344
+ "instant": true,
345
+ "legendFormat": "branches/session estimate",
346
+ "range": false,
347
+ "refId": "A"
348
+ }
349
+ ],
350
+ "title": "Branches per session estimate",
351
+ "type": "stat"
352
+ },
353
+ {
354
+ "datasource": {
355
+ "type": "prometheus",
356
+ "uid": "prometheus"
357
+ },
358
+ "description": "Selected-range p95 of tokens present immediately before compaction. The histogram records token counts, not bytes or characters. No data means no compaction histogram samples were observed and is not converted to a false zero.",
359
+ "fieldConfig": {
360
+ "defaults": {
361
+ "color": {
362
+ "mode": "thresholds"
363
+ },
364
+ "mappings": [],
365
+ "min": 0,
366
+ "thresholds": {
367
+ "mode": "absolute",
368
+ "steps": [
369
+ {
370
+ "color": "green",
371
+ "value": null
372
+ }
373
+ ]
374
+ },
375
+ "unit": "short"
376
+ },
377
+ "overrides": []
378
+ },
379
+ "gridPos": {
380
+ "h": 5,
381
+ "w": 6,
382
+ "x": 18,
383
+ "y": 1
384
+ },
385
+ "id": 4,
386
+ "links": [
387
+ {
388
+ "targetBlank": false,
389
+ "title": "Open Cost",
390
+ "url": "/d/observme-cost/observme-cost?${__url_time_range}"
391
+ },
392
+ {
393
+ "targetBlank": false,
394
+ "title": "Open Latency",
395
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
396
+ }
397
+ ],
398
+ "options": {
399
+ "colorMode": "value",
400
+ "graphMode": "area",
401
+ "justifyMode": "auto",
402
+ "orientation": "auto",
403
+ "reduceOptions": {
404
+ "calcs": [
405
+ "lastNotNull"
406
+ ],
407
+ "fields": "",
408
+ "values": false
409
+ },
410
+ "showPercentChange": false,
411
+ "textMode": "auto",
412
+ "wideLayout": true
413
+ },
414
+ "pluginVersion": "11.1.0",
415
+ "targets": [
416
+ {
417
+ "datasource": {
418
+ "type": "prometheus",
419
+ "uid": "prometheus"
420
+ },
421
+ "editorMode": "code",
422
+ "expr": "histogram_quantile(0.95, sum(increase(observme_compaction_tokens_before_bucket[$__range])) by (le))",
423
+ "instant": true,
424
+ "legendFormat": "p95 tokens",
425
+ "range": false,
426
+ "refId": "A"
427
+ }
428
+ ],
429
+ "title": "p95 tokens before compaction",
430
+ "type": "stat"
431
+ },
432
+ {
433
+ "collapsed": false,
434
+ "gridPos": {
435
+ "h": 1,
436
+ "w": 24,
437
+ "x": 0,
438
+ "y": 6
439
+ },
440
+ "id": 101,
441
+ "panels": [],
442
+ "title": "Branch and compaction trends",
443
+ "type": "row"
444
+ },
445
+ {
446
+ "datasource": {
447
+ "type": "prometheus",
448
+ "uid": "prometheus"
449
+ },
450
+ "description": "Branch and compaction events per second by bounded environment label. Missing series render as an aggregate zero so a quiet range remains visible; use Export Health to distinguish idle activity from absent telemetry.",
451
+ "fieldConfig": {
452
+ "defaults": {
453
+ "color": {
454
+ "mode": "palette-classic"
455
+ },
456
+ "mappings": [],
457
+ "min": 0,
458
+ "thresholds": {
459
+ "mode": "absolute",
460
+ "steps": [
461
+ {
462
+ "color": "green",
463
+ "value": null
464
+ }
465
+ ]
466
+ },
467
+ "unit": "ops"
468
+ },
469
+ "overrides": []
470
+ },
471
+ "gridPos": {
472
+ "h": 8,
473
+ "w": 12,
474
+ "x": 0,
475
+ "y": 7
476
+ },
477
+ "id": 5,
478
+ "options": {
479
+ "legend": {
480
+ "calcs": [
481
+ "lastNotNull",
482
+ "max"
483
+ ],
484
+ "displayMode": "table",
485
+ "placement": "bottom",
486
+ "showLegend": true
487
+ },
488
+ "tooltip": {
489
+ "mode": "multi",
490
+ "sort": "desc"
491
+ }
492
+ },
493
+ "pluginVersion": "11.1.0",
494
+ "targets": [
495
+ {
496
+ "datasource": {
497
+ "type": "prometheus",
498
+ "uid": "prometheus"
499
+ },
500
+ "editorMode": "code",
501
+ "expr": "sum by (environment) (rate(observme_branches_total[$__rate_interval])) or on() vector(0)",
502
+ "legendFormat": "branches {{environment}}",
503
+ "range": true,
504
+ "refId": "A"
505
+ },
506
+ {
507
+ "datasource": {
508
+ "type": "prometheus",
509
+ "uid": "prometheus"
510
+ },
511
+ "editorMode": "code",
512
+ "expr": "sum by (environment) (rate(observme_compactions_total[$__rate_interval])) or on() vector(0)",
513
+ "legendFormat": "compactions {{environment}}",
514
+ "range": true,
515
+ "refId": "B"
516
+ }
517
+ ],
518
+ "title": "Branch and compaction event rates",
519
+ "type": "timeseries"
520
+ },
521
+ {
522
+ "datasource": {
523
+ "type": "prometheus",
524
+ "uid": "prometheus"
525
+ },
526
+ "description": "p50, p95, and p99 token-count quantiles before compaction. The query preserves the required le bucket label. Interpret sparse quantiles with the selected-range Compaction events volume; no data means no histogram observations rather than zero tokens.",
527
+ "fieldConfig": {
528
+ "defaults": {
529
+ "color": {
530
+ "mode": "palette-classic"
531
+ },
532
+ "mappings": [],
533
+ "min": 0,
534
+ "thresholds": {
535
+ "mode": "absolute",
536
+ "steps": [
537
+ {
538
+ "color": "green",
539
+ "value": null
540
+ }
541
+ ]
542
+ },
543
+ "unit": "short"
544
+ },
545
+ "overrides": []
546
+ },
547
+ "gridPos": {
548
+ "h": 8,
549
+ "w": 12,
550
+ "x": 12,
551
+ "y": 7
552
+ },
553
+ "id": 6,
554
+ "links": [
555
+ {
556
+ "targetBlank": false,
557
+ "title": "Open Cost",
558
+ "url": "/d/observme-cost/observme-cost?${__url_time_range}"
559
+ },
560
+ {
561
+ "targetBlank": false,
562
+ "title": "Open Latency",
563
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
564
+ }
565
+ ],
566
+ "options": {
567
+ "legend": {
568
+ "calcs": [
569
+ "lastNotNull",
570
+ "max"
571
+ ],
572
+ "displayMode": "table",
573
+ "placement": "bottom",
574
+ "showLegend": true
575
+ },
576
+ "tooltip": {
577
+ "mode": "multi",
578
+ "sort": "desc"
579
+ }
580
+ },
581
+ "pluginVersion": "11.1.0",
582
+ "targets": [
583
+ {
584
+ "datasource": {
585
+ "type": "prometheus",
586
+ "uid": "prometheus"
587
+ },
588
+ "editorMode": "code",
589
+ "expr": "histogram_quantile(0.50, sum(rate(observme_compaction_tokens_before_bucket[$__rate_interval])) by (le))",
590
+ "legendFormat": "p50 tokens",
591
+ "range": true,
592
+ "refId": "A"
593
+ },
594
+ {
595
+ "datasource": {
596
+ "type": "prometheus",
597
+ "uid": "prometheus"
598
+ },
599
+ "editorMode": "code",
600
+ "expr": "histogram_quantile(0.95, sum(rate(observme_compaction_tokens_before_bucket[$__rate_interval])) by (le))",
601
+ "legendFormat": "p95 tokens",
602
+ "range": true,
603
+ "refId": "B"
604
+ },
605
+ {
606
+ "datasource": {
607
+ "type": "prometheus",
608
+ "uid": "prometheus"
609
+ },
610
+ "editorMode": "code",
611
+ "expr": "histogram_quantile(0.99, sum(rate(observme_compaction_tokens_before_bucket[$__rate_interval])) by (le))",
612
+ "legendFormat": "p99 tokens",
613
+ "range": true,
614
+ "refId": "C"
615
+ }
616
+ ],
617
+ "title": "Tokens before compaction quantiles",
618
+ "type": "timeseries"
619
+ },
620
+ {
621
+ "collapsed": false,
622
+ "gridPos": {
623
+ "h": 1,
624
+ "w": 24,
625
+ "x": 0,
626
+ "y": 15
627
+ },
628
+ "id": 102,
629
+ "panels": [],
630
+ "title": "Model and thinking changes",
631
+ "type": "row"
632
+ },
633
+ {
634
+ "datasource": {
635
+ "type": "prometheus",
636
+ "uid": "prometheus"
637
+ },
638
+ "description": "Model and thinking-level changes per second that can explain later cost, latency, or behavior shifts. Model series use bounded provider/model labels; thinking changes use the bounded environment label. Missing series render as an aggregate zero. Cost, Models, and Latency also show these signals as annotations.",
639
+ "fieldConfig": {
640
+ "defaults": {
641
+ "color": {
642
+ "mode": "palette-classic"
643
+ },
644
+ "mappings": [],
645
+ "min": 0,
646
+ "thresholds": {
647
+ "mode": "absolute",
648
+ "steps": [
649
+ {
650
+ "color": "green",
651
+ "value": null
652
+ }
653
+ ]
654
+ },
655
+ "unit": "ops"
656
+ },
657
+ "overrides": []
658
+ },
659
+ "gridPos": {
660
+ "h": 8,
661
+ "w": 24,
662
+ "x": 0,
663
+ "y": 16
664
+ },
665
+ "id": 7,
666
+ "links": [
667
+ {
668
+ "targetBlank": false,
669
+ "title": "Open Cost annotations",
670
+ "url": "/d/observme-cost/observme-cost?${__url_time_range}"
671
+ },
672
+ {
673
+ "targetBlank": false,
674
+ "title": "Open Model annotations",
675
+ "url": "/d/observme-models/observme-models?${__url_time_range}"
676
+ },
677
+ {
678
+ "targetBlank": false,
679
+ "title": "Open Latency annotations",
680
+ "url": "/d/observme-latency/observme-latency?${__url_time_range}"
681
+ },
682
+ {
683
+ "targetBlank": false,
684
+ "title": "Open Logs and LLM I/O",
685
+ "url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
686
+ }
687
+ ],
688
+ "options": {
689
+ "legend": {
690
+ "calcs": [
691
+ "lastNotNull",
692
+ "max"
693
+ ],
694
+ "displayMode": "table",
695
+ "placement": "bottom",
696
+ "showLegend": true
697
+ },
698
+ "tooltip": {
699
+ "mode": "multi",
700
+ "sort": "desc"
701
+ }
702
+ },
703
+ "pluginVersion": "11.1.0",
704
+ "targets": [
705
+ {
706
+ "datasource": {
707
+ "type": "prometheus",
708
+ "uid": "prometheus"
709
+ },
710
+ "editorMode": "code",
711
+ "expr": "sum by (provider, model) (rate(observme_model_changes_total[$__rate_interval])) or on() vector(0)",
712
+ "legendFormat": "model {{provider}} / {{model}}",
713
+ "range": true,
714
+ "refId": "A"
715
+ },
716
+ {
717
+ "datasource": {
718
+ "type": "prometheus",
719
+ "uid": "prometheus"
720
+ },
721
+ "editorMode": "code",
722
+ "expr": "sum by (environment) (rate(observme_thinking_level_changes_total[$__rate_interval])) or on() vector(0)",
723
+ "legendFormat": "thinking {{environment}}",
724
+ "range": true,
725
+ "refId": "B"
726
+ }
727
+ ],
728
+ "title": "Model changes and thinking level changes",
729
+ "type": "timeseries"
730
+ },
731
+ {
732
+ "collapsed": false,
733
+ "gridPos": {
734
+ "h": 1,
735
+ "w": 24,
736
+ "x": 0,
737
+ "y": 24
738
+ },
739
+ "id": 103,
740
+ "panels": [],
741
+ "title": "Branch and compaction context",
742
+ "type": "row"
743
+ },
744
+ {
745
+ "datasource": {
746
+ "type": "loki",
747
+ "uid": "loki"
748
+ },
749
+ "description": "Latest branch.created events first. A deterministic safe JSON line exposes event, session, workflow, agent, run, trace, and span context while the raw line and metadata fields are hidden. trace_id opens Tempo for branch-specific span attributes; agent_run opens a filtered Trace Journey. Empty means no branch events matched the selected range, which can be healthy when no branching occurred but does not prove log ingestion health.",
750
+ "fieldConfig": {
751
+ "defaults": {},
752
+ "overrides": [
753
+ {
754
+ "matcher": {
755
+ "id": "byName",
756
+ "options": "trace_id"
757
+ },
758
+ "properties": [
759
+ {
760
+ "id": "links",
761
+ "value": [
762
+ {
763
+ "targetBlank": false,
764
+ "title": "Open Tempo trace",
765
+ "url": "/explore?left=%7B%22datasource%22:%22tempo%22,%22queries%22:%5B%7B%22query%22:%22${__value.raw}%22%7D%5D,%22range%22:%7B%22from%22:%22${__from}%22,%22to%22:%22${__to}%22%7D%7D"
766
+ }
767
+ ]
768
+ }
769
+ ]
770
+ },
771
+ {
772
+ "matcher": {
773
+ "id": "byName",
774
+ "options": "agent_run"
775
+ },
776
+ "properties": [
777
+ {
778
+ "id": "links",
779
+ "value": [
780
+ {
781
+ "targetBlank": false,
782
+ "title": "Open filtered Trace Journey",
783
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}&var-session_id=${__data.fields[\"session\"]}&var-workflow_id=${__data.fields[\"workflow\"]}&var-agent_id=${__data.fields[\"agent\"]}&var-agent_run_id=${__value.raw}"
784
+ }
785
+ ]
786
+ }
787
+ ]
788
+ }
789
+ ]
790
+ },
791
+ "gridPos": {
792
+ "h": 11,
793
+ "w": 12,
794
+ "x": 0,
795
+ "y": 25
796
+ },
797
+ "id": 8,
798
+ "links": [
799
+ {
800
+ "targetBlank": false,
801
+ "title": "Open Trace Journey",
802
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
803
+ }
804
+ ],
805
+ "options": {
806
+ "cellHeight": "sm",
807
+ "footer": {
808
+ "countRows": false,
809
+ "fields": "",
810
+ "reducer": [
811
+ "sum"
812
+ ],
813
+ "show": false
814
+ },
815
+ "showHeader": true,
816
+ "sortBy": [
817
+ {
818
+ "desc": true,
819
+ "displayName": "Time"
820
+ }
821
+ ]
822
+ },
823
+ "pluginVersion": "11.1.0",
824
+ "targets": [
825
+ {
826
+ "datasource": {
827
+ "type": "loki",
828
+ "uid": "loki"
829
+ },
830
+ "editorMode": "code",
831
+ "expr": "{service_name=\"observme-pi-extension\", event_name=\"branch.created\"} | line_format `{\"event\":{{ printf \"%q\" .event_name }},\"category\":{{ printf \"%q\" .event_category }},\"session\":{{ printf \"%q\" .pi_session_id }},\"workflow\":{{ printf \"%q\" .pi_workflow_id }},\"agent\":{{ printf \"%q\" .pi_agent_id }},\"agent_run\":{{ printf \"%q\" .pi_agent_run_id }},\"trace_id\":{{ printf \"%q\" .trace_id }},\"span_id\":{{ printf \"%q\" .span_id }}}`",
832
+ "legendFormat": "{{event_name}}",
833
+ "maxLines": 500,
834
+ "queryType": "range",
835
+ "range": true,
836
+ "refId": "A"
837
+ }
838
+ ],
839
+ "title": "Branch summaries created",
840
+ "transformations": [
841
+ {
842
+ "id": "labelsToFields",
843
+ "options": {
844
+ "mode": "columns"
845
+ }
846
+ },
847
+ {
848
+ "id": "extractFields",
849
+ "options": {
850
+ "format": "json",
851
+ "keepTime": true,
852
+ "replace": false,
853
+ "source": "Line"
854
+ }
855
+ },
856
+ {
857
+ "id": "organize",
858
+ "options": {
859
+ "excludeByName": {
860
+ "Line": true,
861
+ "id": true,
862
+ "labels": true,
863
+ "service_name": true,
864
+ "telemetry_source": true,
865
+ "tsNs": true
866
+ },
867
+ "renameByName": {
868
+ "event_category": "category",
869
+ "event_name": "event",
870
+ "pi_agent_id": "agent",
871
+ "pi_agent_run_id": "agent_run",
872
+ "pi_session_id": "session",
873
+ "pi_workflow_id": "workflow",
874
+ "span_id": "span_id",
875
+ "trace_id": "trace_id"
876
+ }
877
+ }
878
+ }
879
+ ],
880
+ "type": "table"
881
+ },
882
+ {
883
+ "datasource": {
884
+ "type": "loki",
885
+ "uid": "loki"
886
+ },
887
+ "description": "Latest compaction.created events first. A deterministic safe JSON line exposes event, session, workflow, agent, run, trace, and span context while the raw line and metadata fields are hidden. trace_id opens Tempo for tokens-before, reason, retry, and summary metadata; agent_run opens a filtered Trace Journey. Empty means no compaction events matched the selected range, which is healthy when no compaction occurred but does not prove log ingestion health.",
888
+ "fieldConfig": {
889
+ "defaults": {},
890
+ "overrides": [
891
+ {
892
+ "matcher": {
893
+ "id": "byName",
894
+ "options": "trace_id"
895
+ },
896
+ "properties": [
897
+ {
898
+ "id": "links",
899
+ "value": [
900
+ {
901
+ "targetBlank": false,
902
+ "title": "Open Tempo trace",
903
+ "url": "/explore?left=%7B%22datasource%22:%22tempo%22,%22queries%22:%5B%7B%22query%22:%22${__value.raw}%22%7D%5D,%22range%22:%7B%22from%22:%22${__from}%22,%22to%22:%22${__to}%22%7D%7D"
904
+ }
905
+ ]
906
+ }
907
+ ]
908
+ },
909
+ {
910
+ "matcher": {
911
+ "id": "byName",
912
+ "options": "agent_run"
913
+ },
914
+ "properties": [
915
+ {
916
+ "id": "links",
917
+ "value": [
918
+ {
919
+ "targetBlank": false,
920
+ "title": "Open filtered Trace Journey",
921
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}&var-session_id=${__data.fields[\"session\"]}&var-workflow_id=${__data.fields[\"workflow\"]}&var-agent_id=${__data.fields[\"agent\"]}&var-agent_run_id=${__value.raw}"
922
+ }
923
+ ]
924
+ }
925
+ ]
926
+ }
927
+ ]
928
+ },
929
+ "gridPos": {
930
+ "h": 11,
931
+ "w": 12,
932
+ "x": 12,
933
+ "y": 25
934
+ },
935
+ "id": 9,
936
+ "links": [
937
+ {
938
+ "targetBlank": false,
939
+ "title": "Open Trace Journey",
940
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
941
+ }
942
+ ],
943
+ "options": {
944
+ "cellHeight": "sm",
945
+ "footer": {
946
+ "countRows": false,
947
+ "fields": "",
948
+ "reducer": [
949
+ "sum"
950
+ ],
951
+ "show": false
952
+ },
953
+ "showHeader": true,
954
+ "sortBy": [
955
+ {
956
+ "desc": true,
957
+ "displayName": "Time"
958
+ }
959
+ ]
960
+ },
961
+ "pluginVersion": "11.1.0",
962
+ "targets": [
963
+ {
964
+ "datasource": {
965
+ "type": "loki",
966
+ "uid": "loki"
967
+ },
968
+ "editorMode": "code",
969
+ "expr": "{service_name=\"observme-pi-extension\", event_name=\"compaction.created\"} | line_format `{\"event\":{{ printf \"%q\" .event_name }},\"category\":{{ printf \"%q\" .event_category }},\"session\":{{ printf \"%q\" .pi_session_id }},\"workflow\":{{ printf \"%q\" .pi_workflow_id }},\"agent\":{{ printf \"%q\" .pi_agent_id }},\"agent_run\":{{ printf \"%q\" .pi_agent_run_id }},\"trace_id\":{{ printf \"%q\" .trace_id }},\"span_id\":{{ printf \"%q\" .span_id }}}`",
970
+ "legendFormat": "{{event_name}}",
971
+ "maxLines": 500,
972
+ "queryType": "range",
973
+ "range": true,
974
+ "refId": "A"
975
+ }
976
+ ],
977
+ "title": "Compaction logs",
978
+ "transformations": [
979
+ {
980
+ "id": "labelsToFields",
981
+ "options": {
982
+ "mode": "columns"
983
+ }
984
+ },
985
+ {
986
+ "id": "extractFields",
987
+ "options": {
988
+ "format": "json",
989
+ "keepTime": true,
990
+ "replace": false,
991
+ "source": "Line"
992
+ }
993
+ },
994
+ {
995
+ "id": "organize",
996
+ "options": {
997
+ "excludeByName": {
998
+ "Line": true,
999
+ "id": true,
1000
+ "labels": true,
1001
+ "service_name": true,
1002
+ "telemetry_source": true,
1003
+ "tsNs": true
1004
+ },
1005
+ "renameByName": {
1006
+ "event_category": "category",
1007
+ "event_name": "event",
1008
+ "pi_agent_id": "agent",
1009
+ "pi_agent_run_id": "agent_run",
1010
+ "pi_session_id": "session",
1011
+ "pi_workflow_id": "workflow",
1012
+ "span_id": "span_id",
1013
+ "trace_id": "trace_id"
1014
+ }
1015
+ }
1016
+ }
1017
+ ],
1018
+ "type": "table"
1019
+ }
1020
+ ],
1021
+ "refresh": "30s",
1022
+ "schemaVersion": 39,
1023
+ "style": "dark",
1024
+ "tags": [
1025
+ "observme",
1026
+ "branches",
1027
+ "compactions"
1028
+ ],
1029
+ "templating": {
1030
+ "list": []
1031
+ },
1032
+ "time": {
1033
+ "from": "now-24h",
1034
+ "to": "now"
1035
+ },
1036
+ "timepicker": {},
1037
+ "timezone": "browser",
1038
+ "title": "ObservMe Branches and Compactions",
1039
+ "uid": "observme-branches-compactions",
1040
+ "version": 2,
1041
+ "weekStart": ""
1042
+ }