@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,644 @@
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": "timeseries",
23
+ "name": "Time series",
24
+ "type": "panel",
25
+ "version": ""
26
+ },
27
+ {
28
+ "id": "row",
29
+ "name": "Row",
30
+ "type": "panel",
31
+ "version": ""
32
+ },
33
+ {
34
+ "id": "logs",
35
+ "name": "Logs",
36
+ "type": "panel",
37
+ "version": ""
38
+ },
39
+ {
40
+ "id": "text",
41
+ "name": "Text",
42
+ "type": "panel",
43
+ "version": ""
44
+ }
45
+ ],
46
+ "annotations": {
47
+ "list": []
48
+ },
49
+ "editable": true,
50
+ "fiscalYearStartMonth": 0,
51
+ "graphTooltip": 0,
52
+ "id": null,
53
+ "links": [
54
+ {
55
+ "targetBlank": false,
56
+ "title": "Open canonical LLM Conversations",
57
+ "url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}&${provider:queryparam}&${model:queryparam}&${content_kind:queryparam}"
58
+ },
59
+ {
60
+ "targetBlank": false,
61
+ "title": "Open matching Trace Journey",
62
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}"
63
+ }
64
+ ],
65
+ "liveNow": false,
66
+ "panels": [
67
+ {
68
+ "collapsed": false,
69
+ "gridPos": {
70
+ "h": 1,
71
+ "w": 24,
72
+ "x": 0,
73
+ "y": 0
74
+ },
75
+ "id": 100,
76
+ "panels": [],
77
+ "title": "Aggregate LLM telemetry",
78
+ "type": "row"
79
+ },
80
+ {
81
+ "datasource": {
82
+ "type": "prometheus",
83
+ "uid": "prometheus"
84
+ },
85
+ "description": "LLM prompt/response p95 size trends measured in characters and filterable by provider/model. These *_size_chars histograms work even when content capture is disabled and must not be interpreted as bytes. No data means matching histogram samples are absent, not that size is zero.",
86
+ "fieldConfig": {
87
+ "defaults": {
88
+ "mappings": [],
89
+ "thresholds": {
90
+ "mode": "absolute",
91
+ "steps": [
92
+ {
93
+ "color": "green",
94
+ "value": null
95
+ }
96
+ ]
97
+ },
98
+ "unit": "short"
99
+ },
100
+ "overrides": []
101
+ },
102
+ "gridPos": {
103
+ "h": 8,
104
+ "w": 12,
105
+ "x": 0,
106
+ "y": 1
107
+ },
108
+ "id": 1,
109
+ "options": {
110
+ "legend": {
111
+ "calcs": [
112
+ "lastNotNull",
113
+ "max"
114
+ ],
115
+ "displayMode": "table",
116
+ "placement": "bottom",
117
+ "showLegend": true
118
+ },
119
+ "tooltip": {
120
+ "mode": "multi",
121
+ "sort": "desc"
122
+ }
123
+ },
124
+ "pluginVersion": "11.1.0",
125
+ "targets": [
126
+ {
127
+ "datasource": {
128
+ "type": "prometheus",
129
+ "uid": "prometheus"
130
+ },
131
+ "editorMode": "code",
132
+ "expr": "histogram_quantile(0.95, sum by (le) (rate(observme_prompt_size_chars_bucket{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__rate_interval])))",
133
+ "legendFormat": "prompt p95",
134
+ "range": true,
135
+ "refId": "A"
136
+ },
137
+ {
138
+ "datasource": {
139
+ "type": "prometheus",
140
+ "uid": "prometheus"
141
+ },
142
+ "editorMode": "code",
143
+ "expr": "histogram_quantile(0.95, sum by (le) (rate(observme_response_size_chars_bucket{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__rate_interval])))",
144
+ "legendFormat": "response p95",
145
+ "range": true,
146
+ "refId": "B"
147
+ }
148
+ ],
149
+ "title": "LLM input/output size p95 (characters)",
150
+ "type": "timeseries"
151
+ },
152
+ {
153
+ "datasource": {
154
+ "type": "prometheus",
155
+ "uid": "prometheus"
156
+ },
157
+ "description": "Interval token deltas by selected provider/model for input, output, total, reasoning, and cache token families. Each point uses increase(...[$__interval]); optional reasoning/cache families may show no data when a provider does not report them.",
158
+ "fieldConfig": {
159
+ "defaults": {
160
+ "mappings": [],
161
+ "thresholds": {
162
+ "mode": "absolute",
163
+ "steps": [
164
+ {
165
+ "color": "green",
166
+ "value": null
167
+ }
168
+ ]
169
+ },
170
+ "unit": "short"
171
+ },
172
+ "overrides": []
173
+ },
174
+ "gridPos": {
175
+ "h": 8,
176
+ "w": 12,
177
+ "x": 12,
178
+ "y": 1
179
+ },
180
+ "id": 2,
181
+ "options": {
182
+ "legend": {
183
+ "calcs": [
184
+ "lastNotNull",
185
+ "sum"
186
+ ],
187
+ "displayMode": "table",
188
+ "placement": "bottom",
189
+ "showLegend": true
190
+ },
191
+ "tooltip": {
192
+ "mode": "multi",
193
+ "sort": "desc"
194
+ }
195
+ },
196
+ "pluginVersion": "11.1.0",
197
+ "targets": [
198
+ {
199
+ "datasource": {
200
+ "type": "prometheus",
201
+ "uid": "prometheus"
202
+ },
203
+ "editorMode": "code",
204
+ "expr": "sum(increase(observme_llm_input_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
205
+ "legendFormat": "input {{provider}}/{{model}}",
206
+ "range": true,
207
+ "refId": "A"
208
+ },
209
+ {
210
+ "datasource": {
211
+ "type": "prometheus",
212
+ "uid": "prometheus"
213
+ },
214
+ "editorMode": "code",
215
+ "expr": "sum(increase(observme_llm_output_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
216
+ "legendFormat": "output {{provider}}/{{model}}",
217
+ "range": true,
218
+ "refId": "B"
219
+ },
220
+ {
221
+ "datasource": {
222
+ "type": "prometheus",
223
+ "uid": "prometheus"
224
+ },
225
+ "editorMode": "code",
226
+ "expr": "sum(increase(observme_llm_total_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
227
+ "legendFormat": "total {{provider}}/{{model}}",
228
+ "range": true,
229
+ "refId": "C"
230
+ },
231
+ {
232
+ "datasource": {
233
+ "type": "prometheus",
234
+ "uid": "prometheus"
235
+ },
236
+ "editorMode": "code",
237
+ "expr": "sum(increase(observme_llm_reasoning_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
238
+ "legendFormat": "reasoning {{provider}}/{{model}}",
239
+ "range": true,
240
+ "refId": "D"
241
+ },
242
+ {
243
+ "datasource": {
244
+ "type": "prometheus",
245
+ "uid": "prometheus"
246
+ },
247
+ "editorMode": "code",
248
+ "expr": "sum(increase(observme_llm_cache_read_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
249
+ "legendFormat": "cache read {{provider}}/{{model}}",
250
+ "range": true,
251
+ "refId": "E"
252
+ },
253
+ {
254
+ "datasource": {
255
+ "type": "prometheus",
256
+ "uid": "prometheus"
257
+ },
258
+ "editorMode": "code",
259
+ "expr": "sum(increase(observme_llm_cache_write_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
260
+ "legendFormat": "cache write {{provider}}/{{model}}",
261
+ "range": true,
262
+ "refId": "F"
263
+ },
264
+ {
265
+ "datasource": {
266
+ "type": "prometheus",
267
+ "uid": "prometheus"
268
+ },
269
+ "editorMode": "code",
270
+ "expr": "sum(increase(observme_llm_cache_write_1h_tokens_total{provider=~\"${provider:regex}\", model=~\"${model:regex}\"}[$__interval])) by (provider, model)",
271
+ "legendFormat": "cache write 1h {{provider}}/{{model}}",
272
+ "range": true,
273
+ "refId": "G"
274
+ }
275
+ ],
276
+ "title": "LLM token trends by type",
277
+ "type": "timeseries"
278
+ },
279
+ {
280
+ "collapsed": false,
281
+ "gridPos": {
282
+ "h": 1,
283
+ "w": 24,
284
+ "x": 0,
285
+ "y": 9
286
+ },
287
+ "id": 101,
288
+ "panels": [],
289
+ "title": "Privacy-safe content routing",
290
+ "type": "row"
291
+ },
292
+ {
293
+ "datasource": null,
294
+ "description": "Visible privacy and empty-state guidance for optional redacted LLM content. This dashboard keeps aggregate telemetry and content-free lifecycle logs here, while prompt, response, and thinking bodies remain in the canonical conversation view.",
295
+ "fieldConfig": {
296
+ "defaults": {},
297
+ "overrides": []
298
+ },
299
+ "gridPos": {
300
+ "h": 6,
301
+ "w": 24,
302
+ "x": 0,
303
+ "y": 10
304
+ },
305
+ "id": 3,
306
+ "links": [
307
+ {
308
+ "targetBlank": false,
309
+ "title": "Open canonical LLM Conversations",
310
+ "url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}&${provider:queryparam}&${model:queryparam}&${content_kind:queryparam}"
311
+ }
312
+ ],
313
+ "options": {
314
+ "code": {
315
+ "language": "plaintext",
316
+ "showLineNumbers": false,
317
+ "showMiniMap": false
318
+ },
319
+ "content": "## Canonical LLM conversation drill-down\n\nPrompts, responses, and thinking are redacted, opt-in content. Open **ObservMe LLM Conversations** with the current session/workflow/agent/run/provider/model/content-kind filters for the canonical timeline. Empty content can mean capture is disabled or no matching events exist. Explicit unsafe capture can expose sensitive text when redaction is disabled. Do not query by raw prompt, response, or thinking text.",
320
+ "mode": "markdown"
321
+ },
322
+ "pluginVersion": "11.1.0",
323
+ "title": "Canonical LLM conversation drill-down",
324
+ "type": "text"
325
+ },
326
+ {
327
+ "collapsed": false,
328
+ "gridPos": {
329
+ "h": 1,
330
+ "w": 24,
331
+ "x": 0,
332
+ "y": 16
333
+ },
334
+ "id": 102,
335
+ "panels": [],
336
+ "title": "Content-free lifecycle logs",
337
+ "type": "row"
338
+ },
339
+ {
340
+ "datasource": {
341
+ "type": "loki",
342
+ "uid": "loki"
343
+ },
344
+ "description": "Newest-first LLM request lifecycle logs filtered by session, workflow, agent, run, provider, and model labels, capped at 500 lines. Structured labels remain available in log details. Use canonical LLM Conversations for redacted prompt/response/thinking bodies and Trace Journey for waterfalls.",
345
+ "gridPos": {
346
+ "h": 10,
347
+ "w": 12,
348
+ "x": 0,
349
+ "y": 17
350
+ },
351
+ "id": 4,
352
+ "options": {
353
+ "dedupStrategy": "none",
354
+ "enableLogDetails": true,
355
+ "prettifyLogMessage": false,
356
+ "showCommonLabels": false,
357
+ "showLabels": true,
358
+ "showTime": true,
359
+ "sortOrder": "Descending",
360
+ "wrapLogMessage": true
361
+ },
362
+ "targets": [
363
+ {
364
+ "datasource": {
365
+ "type": "loki",
366
+ "uid": "loki"
367
+ },
368
+ "editorMode": "code",
369
+ "expr": "{service_name=\"observme-pi-extension\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\", gen_ai_provider_name=~\"${provider:regex}\", gen_ai_request_model=~\"${model:regex}\", event_name=~\"llm[.]request[.](started|completed|failed)\", event_category!=\"llm_content\"}",
370
+ "maxLines": 500,
371
+ "queryType": "range",
372
+ "range": true,
373
+ "refId": "A"
374
+ }
375
+ ],
376
+ "pluginVersion": "11.1.0",
377
+ "title": "LLM request logs",
378
+ "type": "logs",
379
+ "links": [
380
+ {
381
+ "targetBlank": false,
382
+ "title": "Open canonical LLM Conversations",
383
+ "url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}&${provider:queryparam}&${model:queryparam}&${content_kind:queryparam}"
384
+ },
385
+ {
386
+ "targetBlank": false,
387
+ "title": "Open matching Trace Journey",
388
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}"
389
+ }
390
+ ]
391
+ },
392
+ {
393
+ "datasource": {
394
+ "type": "loki",
395
+ "uid": "loki"
396
+ },
397
+ "description": "Newest-first non-content ObservMe logs for the selected session/workflow/agent/run filters, capped at 500 lines. Structured labels remain available in log details. Provider/model filters intentionally apply only to the LLM request panel because general lifecycle records may not carry those labels. This panel excludes llm_content and tool_content so captured bodies remain in canonical content views; do not query by raw content.",
398
+ "gridPos": {
399
+ "h": 10,
400
+ "w": 12,
401
+ "x": 12,
402
+ "y": 17
403
+ },
404
+ "id": 5,
405
+ "options": {
406
+ "dedupStrategy": "none",
407
+ "enableLogDetails": true,
408
+ "prettifyLogMessage": false,
409
+ "showCommonLabels": false,
410
+ "showLabels": true,
411
+ "showTime": true,
412
+ "sortOrder": "Descending",
413
+ "wrapLogMessage": true
414
+ },
415
+ "targets": [
416
+ {
417
+ "datasource": {
418
+ "type": "loki",
419
+ "uid": "loki"
420
+ },
421
+ "editorMode": "code",
422
+ "expr": "{service_name=\"observme-pi-extension\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\", event_category!~\"llm_content|tool_content\"}",
423
+ "maxLines": 500,
424
+ "queryType": "range",
425
+ "range": true,
426
+ "refId": "A"
427
+ }
428
+ ],
429
+ "pluginVersion": "11.1.0",
430
+ "title": "Session logs",
431
+ "type": "logs",
432
+ "links": [
433
+ {
434
+ "targetBlank": false,
435
+ "title": "Open canonical LLM Conversations",
436
+ "url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}&${provider:queryparam}&${model:queryparam}&${content_kind:queryparam}"
437
+ },
438
+ {
439
+ "targetBlank": false,
440
+ "title": "Open matching Trace Journey",
441
+ "url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}&${session_id:queryparam}&${workflow_id:queryparam}&${agent_id:queryparam}&${agent_run_id:queryparam}"
442
+ }
443
+ ]
444
+ }
445
+ ],
446
+ "refresh": "30s",
447
+ "schemaVersion": 39,
448
+ "style": "dark",
449
+ "tags": [
450
+ "observme",
451
+ "pi",
452
+ "logs",
453
+ "llm"
454
+ ],
455
+ "templating": {
456
+ "list": [
457
+ {
458
+ "allValue": ".*",
459
+ "current": {
460
+ "selected": true,
461
+ "text": "All",
462
+ "value": "$__all"
463
+ },
464
+ "datasource": {
465
+ "type": "loki",
466
+ "uid": "loki"
467
+ },
468
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\"}, pi_session_id)",
469
+ "hide": 0,
470
+ "includeAll": true,
471
+ "label": "Session ID",
472
+ "multi": true,
473
+ "name": "session_id",
474
+ "options": [],
475
+ "query": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\"}, pi_session_id)",
476
+ "refresh": 2,
477
+ "regex": "",
478
+ "skipUrlSync": false,
479
+ "sort": 1,
480
+ "type": "query"
481
+ },
482
+ {
483
+ "allValue": ".*",
484
+ "current": {
485
+ "selected": true,
486
+ "text": "All",
487
+ "value": "$__all"
488
+ },
489
+ "datasource": {
490
+ "type": "loki",
491
+ "uid": "loki"
492
+ },
493
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\"}, pi_workflow_id)",
494
+ "hide": 0,
495
+ "includeAll": true,
496
+ "label": "Workflow ID",
497
+ "multi": true,
498
+ "name": "workflow_id",
499
+ "options": [],
500
+ "query": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\"}, pi_workflow_id)",
501
+ "refresh": 2,
502
+ "regex": "",
503
+ "skipUrlSync": false,
504
+ "sort": 1,
505
+ "type": "query"
506
+ },
507
+ {
508
+ "allValue": ".*",
509
+ "current": {
510
+ "selected": true,
511
+ "text": "All",
512
+ "value": "$__all"
513
+ },
514
+ "datasource": {
515
+ "type": "loki",
516
+ "uid": "loki"
517
+ },
518
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\"}, pi_agent_id)",
519
+ "hide": 0,
520
+ "includeAll": true,
521
+ "label": "Agent ID",
522
+ "multi": true,
523
+ "name": "agent_id",
524
+ "options": [],
525
+ "query": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\"}, pi_agent_id)",
526
+ "refresh": 2,
527
+ "regex": "",
528
+ "skipUrlSync": false,
529
+ "sort": 1,
530
+ "type": "query"
531
+ },
532
+ {
533
+ "allValue": ".*",
534
+ "current": {
535
+ "selected": true,
536
+ "text": "All",
537
+ "value": "$__all"
538
+ },
539
+ "datasource": {
540
+ "type": "loki",
541
+ "uid": "loki"
542
+ },
543
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\"}, pi_agent_run_id)",
544
+ "hide": 0,
545
+ "includeAll": true,
546
+ "label": "Agent run ID",
547
+ "multi": true,
548
+ "name": "agent_run_id",
549
+ "options": [],
550
+ "query": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\"}, pi_agent_run_id)",
551
+ "refresh": 2,
552
+ "regex": "",
553
+ "skipUrlSync": false,
554
+ "sort": 1,
555
+ "type": "query"
556
+ },
557
+ {
558
+ "allValue": ".*",
559
+ "current": {
560
+ "selected": true,
561
+ "text": "All",
562
+ "value": "$__all"
563
+ },
564
+ "datasource": {
565
+ "type": "loki",
566
+ "uid": "loki"
567
+ },
568
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\"}, gen_ai_provider_name)",
569
+ "hide": 0,
570
+ "includeAll": true,
571
+ "label": "Provider",
572
+ "multi": true,
573
+ "name": "provider",
574
+ "options": [],
575
+ "query": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\"}, gen_ai_provider_name)",
576
+ "refresh": 2,
577
+ "regex": "",
578
+ "skipUrlSync": false,
579
+ "sort": 1,
580
+ "type": "query"
581
+ },
582
+ {
583
+ "allValue": ".*",
584
+ "current": {
585
+ "selected": true,
586
+ "text": "All",
587
+ "value": "$__all"
588
+ },
589
+ "datasource": {
590
+ "type": "loki",
591
+ "uid": "loki"
592
+ },
593
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\", gen_ai_provider_name=~\"${provider:regex}\"}, gen_ai_request_model)",
594
+ "hide": 0,
595
+ "includeAll": true,
596
+ "label": "Model",
597
+ "multi": true,
598
+ "name": "model",
599
+ "options": [],
600
+ "query": "label_values({service_name=\"observme-pi-extension\", event_name=~\"llm[.]request[.](started|completed|failed)|llm[.](prompt|response|thinking)[.]captured\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\", gen_ai_provider_name=~\"${provider:regex}\"}, gen_ai_request_model)",
601
+ "refresh": 2,
602
+ "regex": "",
603
+ "skipUrlSync": false,
604
+ "sort": 1,
605
+ "type": "query"
606
+ },
607
+ {
608
+ "allValue": ".*",
609
+ "current": {
610
+ "selected": true,
611
+ "text": "All",
612
+ "value": "$__all"
613
+ },
614
+ "datasource": {
615
+ "type": "loki",
616
+ "uid": "loki"
617
+ },
618
+ "definition": "label_values({service_name=\"observme-pi-extension\", event_category=\"llm_content\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\", gen_ai_provider_name=~\"${provider:regex}\", gen_ai_request_model=~\"${model:regex}\"}, pi_llm_content_kind)",
619
+ "hide": 0,
620
+ "includeAll": true,
621
+ "label": "Content kind",
622
+ "multi": true,
623
+ "name": "content_kind",
624
+ "options": [],
625
+ "query": "label_values({service_name=\"observme-pi-extension\", event_category=\"llm_content\", pi_session_id=~\"${session_id:regex}\", pi_workflow_id=~\"${workflow_id:regex}\", pi_agent_id=~\"${agent_id:regex}\", pi_agent_run_id=~\"${agent_run_id:regex}\", gen_ai_provider_name=~\"${provider:regex}\", gen_ai_request_model=~\"${model:regex}\"}, pi_llm_content_kind)",
626
+ "refresh": 2,
627
+ "regex": "",
628
+ "skipUrlSync": false,
629
+ "sort": 1,
630
+ "type": "query"
631
+ }
632
+ ]
633
+ },
634
+ "time": {
635
+ "from": "now-6h",
636
+ "to": "now"
637
+ },
638
+ "timepicker": {},
639
+ "timezone": "browser",
640
+ "title": "ObservMe Logs and LLM I/O",
641
+ "uid": "observme-logs-llm",
642
+ "version": 3,
643
+ "weekStart": ""
644
+ }