@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.
- package/.env.example +57 -0
- package/CHANGELOG.md +52 -0
- package/LICENSE +21 -0
- package/ObservMe-Production-Docs/00-README.md +79 -0
- package/ObservMe-Production-Docs/01-requirements-and-scope.md +207 -0
- package/ObservMe-Production-Docs/02-reference-architecture.md +306 -0
- package/ObservMe-Production-Docs/03-pi-event-and-session-model.md +266 -0
- package/ObservMe-Production-Docs/04-telemetry-semantic-conventions.md +722 -0
- package/ObservMe-Production-Docs/05-otel-pipeline-and-collector.md +355 -0
- package/ObservMe-Production-Docs/06-security-privacy-redaction.md +294 -0
- package/ObservMe-Production-Docs/07-extension-implementation-blueprint.md +447 -0
- package/ObservMe-Production-Docs/08-query-grafana-integration.md +276 -0
- package/ObservMe-Production-Docs/09-dashboards-alerts-slos.md +640 -0
- package/ObservMe-Production-Docs/10-testing-release-operations.md +319 -0
- package/ObservMe-Production-Docs/11-deployment-runbooks.md +203 -0
- package/ObservMe-Production-Docs/12-configuration-reference.md +337 -0
- package/ObservMe-Production-Docs/13-source-notes.md +33 -0
- package/ObservMe-Production-Docs/pi-session-format.md +427 -0
- package/README.md +356 -0
- package/SECURITY.md +45 -0
- package/dashboards/observme-agent-node-graphs.json +250 -0
- package/dashboards/observme-agents.json +1880 -0
- package/dashboards/observme-alerts.yaml +113 -0
- package/dashboards/observme-branches-compactions.json +1042 -0
- package/dashboards/observme-cost.json +1254 -0
- package/dashboards/observme-errors.json +1659 -0
- package/dashboards/observme-export-health.json +1802 -0
- package/dashboards/observme-latency.json +1494 -0
- package/dashboards/observme-llm-conversations.json +730 -0
- package/dashboards/observme-logs-llm.json +644 -0
- package/dashboards/observme-models.json +933 -0
- package/dashboards/observme-overview.json +2129 -0
- package/dashboards/observme-slo-health.json +737 -0
- package/dashboards/observme-slos.yaml +56 -0
- package/dashboards/observme-tools.json +902 -0
- package/dashboards/observme-trace-journey.json +1793 -0
- package/docs/STRUCTURE.md +49 -0
- package/docs/agent-subagent-observability-requirements.md +997 -0
- package/docs/compatibility-matrix.md +39 -0
- package/docs/configuration-tui-design-standard.md +767 -0
- package/docs/configuration.md +38 -0
- package/docs/review-validation.md +115 -0
- package/docs/validation-flow.md +117 -0
- package/examples/collector.yaml +123 -0
- package/examples/observme.yaml +131 -0
- package/img/demo.gif +0 -0
- package/img/icon.svg +47 -0
- package/package.json +103 -0
- package/src/commands/obs-agents-runtime.ts +150 -0
- package/src/commands/obs-agents.ts +491 -0
- package/src/commands/obs-args.ts +63 -0
- package/src/commands/obs-backfill.ts +1334 -0
- package/src/commands/obs-command-support.ts +43 -0
- package/src/commands/obs-cost.ts +228 -0
- package/src/commands/obs-diagnostics.ts +22 -0
- package/src/commands/obs-errors.ts +156 -0
- package/src/commands/obs-health.ts +301 -0
- package/src/commands/obs-link.ts +90 -0
- package/src/commands/obs-logs.ts +194 -0
- package/src/commands/obs-loki-summary.ts +184 -0
- package/src/commands/obs-session.ts +259 -0
- package/src/commands/obs-status.ts +359 -0
- package/src/commands/obs-tools.ts +274 -0
- package/src/commands/obs-trace.ts +411 -0
- package/src/commands/obs.ts +211 -0
- package/src/config/bootstrap-project-config.ts +300 -0
- package/src/config/defaults.ts +143 -0
- package/src/config/load-config.ts +631 -0
- package/src/config/project-paths.ts +61 -0
- package/src/config/schema.ts +405 -0
- package/src/config/validate.ts +456 -0
- package/src/constants.ts +4 -0
- package/src/diagnostics/sanitize.ts +6 -0
- package/src/extension.ts +38 -0
- package/src/otel/logs.ts +160 -0
- package/src/otel/metrics.ts +165 -0
- package/src/otel/otlp-endpoint.ts +10 -0
- package/src/otel/sdk.ts +114 -0
- package/src/otel/shutdown.ts +102 -0
- package/src/otel/traces.ts +166 -0
- package/src/pi/agent-lineage.ts +378 -0
- package/src/pi/agent-tree-tracker.ts +258 -0
- package/src/pi/event-handlers/agent-turn.ts +155 -0
- package/src/pi/event-handlers/lifecycle.ts +642 -0
- package/src/pi/event-handlers/llm.ts +115 -0
- package/src/pi/event-handlers/session-events.ts +159 -0
- package/src/pi/event-handlers/tool-bash.ts +275 -0
- package/src/pi/handler-internals.ts +2154 -0
- package/src/pi/handler-runtime.ts +633 -0
- package/src/pi/handler-types.ts +261 -0
- package/src/pi/handlers.ts +75 -0
- package/src/pi/subagent-spawn.ts +975 -0
- package/src/pi/subagent-types.ts +29 -0
- package/src/privacy/content-capture.ts +104 -0
- package/src/privacy/hash.ts +93 -0
- package/src/privacy/redact.ts +619 -0
- package/src/privacy/secret-patterns.ts +185 -0
- package/src/privacy/truncate.ts +69 -0
- package/src/query/grafana-readiness.ts +164 -0
- package/src/query/grafana-transport.ts +481 -0
- package/src/query/grafana.ts +371 -0
- package/src/query/loki.ts +332 -0
- package/src/query/prometheus.ts +388 -0
- package/src/query/tempo.ts +332 -0
- package/src/safety/sensitive-input.ts +208 -0
- package/src/semconv/attributes.ts +279 -0
- package/src/semconv/metrics.ts +146 -0
- package/src/semconv/spans.ts +19 -0
- package/src/semconv/values.ts +13 -0
- package/src/util/bounded-map.ts +97 -0
- package/tsconfig.json +15 -0
|
@@ -0,0 +1,933 @@
|
|
|
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": "timeseries",
|
|
29
|
+
"name": "Time series",
|
|
30
|
+
"type": "panel",
|
|
31
|
+
"version": ""
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "stat",
|
|
35
|
+
"name": "Stat",
|
|
36
|
+
"type": "panel",
|
|
37
|
+
"version": ""
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "bargauge",
|
|
41
|
+
"name": "Bar gauge",
|
|
42
|
+
"type": "panel",
|
|
43
|
+
"version": ""
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"annotations": {
|
|
47
|
+
"list": [
|
|
48
|
+
{
|
|
49
|
+
"datasource": {
|
|
50
|
+
"type": "prometheus",
|
|
51
|
+
"uid": "prometheus"
|
|
52
|
+
},
|
|
53
|
+
"enable": true,
|
|
54
|
+
"hide": false,
|
|
55
|
+
"iconColor": "rgba(31, 120, 193, 1)",
|
|
56
|
+
"name": "Model changes",
|
|
57
|
+
"expr": "sum(increase(observme_model_changes_total[$__interval])) by (provider, model) > 0",
|
|
58
|
+
"titleFormat": "Model change",
|
|
59
|
+
"textFormat": "{{provider}} / {{model}}"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"datasource": {
|
|
63
|
+
"type": "prometheus",
|
|
64
|
+
"uid": "prometheus"
|
|
65
|
+
},
|
|
66
|
+
"enable": true,
|
|
67
|
+
"hide": false,
|
|
68
|
+
"iconColor": "rgba(245, 183, 0, 1)",
|
|
69
|
+
"name": "Thinking level changes",
|
|
70
|
+
"expr": "sum(increase(observme_thinking_level_changes_total[$__interval])) by (environment) > 0",
|
|
71
|
+
"titleFormat": "Thinking level change",
|
|
72
|
+
"textFormat": "{{environment}}"
|
|
73
|
+
}
|
|
74
|
+
]
|
|
75
|
+
},
|
|
76
|
+
"editable": true,
|
|
77
|
+
"fiscalYearStartMonth": 0,
|
|
78
|
+
"graphTooltip": 1,
|
|
79
|
+
"id": null,
|
|
80
|
+
"links": [
|
|
81
|
+
{
|
|
82
|
+
"icon": "external link",
|
|
83
|
+
"includeVars": true,
|
|
84
|
+
"keepTime": true,
|
|
85
|
+
"targetBlank": false,
|
|
86
|
+
"title": "Cost",
|
|
87
|
+
"tooltip": "Open spend, token, cache, and budget context.",
|
|
88
|
+
"type": "link",
|
|
89
|
+
"url": "/d/observme-cost/observme-cost?${__url_time_range}"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"icon": "external link",
|
|
93
|
+
"includeVars": true,
|
|
94
|
+
"keepTime": true,
|
|
95
|
+
"targetBlank": false,
|
|
96
|
+
"title": "Latency",
|
|
97
|
+
"tooltip": "Open cross-stage latency percentiles and volume context.",
|
|
98
|
+
"type": "link",
|
|
99
|
+
"url": "/d/observme-latency/observme-latency?${__url_time_range}"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"icon": "external link",
|
|
103
|
+
"includeVars": true,
|
|
104
|
+
"keepTime": true,
|
|
105
|
+
"targetBlank": false,
|
|
106
|
+
"title": "Errors",
|
|
107
|
+
"tooltip": "Open aggregate failure pressure and failure-log drill-downs.",
|
|
108
|
+
"type": "link",
|
|
109
|
+
"url": "/d/observme-errors/observme-errors?${__url_time_range}"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"icon": "external link",
|
|
113
|
+
"includeVars": true,
|
|
114
|
+
"keepTime": true,
|
|
115
|
+
"targetBlank": false,
|
|
116
|
+
"title": "LLM lifecycle logs",
|
|
117
|
+
"tooltip": "Open privacy-safe LLM lifecycle logs and token/size trends.",
|
|
118
|
+
"type": "link",
|
|
119
|
+
"url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
"icon": "external link",
|
|
123
|
+
"includeVars": true,
|
|
124
|
+
"keepTime": true,
|
|
125
|
+
"targetBlank": false,
|
|
126
|
+
"title": "LLM Conversations",
|
|
127
|
+
"tooltip": "Open optional redacted prompt, response, and thinking capture.",
|
|
128
|
+
"type": "link",
|
|
129
|
+
"url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"icon": "external link",
|
|
133
|
+
"includeVars": true,
|
|
134
|
+
"keepTime": true,
|
|
135
|
+
"targetBlank": false,
|
|
136
|
+
"title": "Trace Journey",
|
|
137
|
+
"tooltip": "Open execution logs and Tempo traces for representative requests.",
|
|
138
|
+
"type": "link",
|
|
139
|
+
"url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"liveNow": false,
|
|
143
|
+
"panels": [
|
|
144
|
+
{
|
|
145
|
+
"collapsed": false,
|
|
146
|
+
"gridPos": {
|
|
147
|
+
"h": 1,
|
|
148
|
+
"w": 24,
|
|
149
|
+
"x": 0,
|
|
150
|
+
"y": 0
|
|
151
|
+
},
|
|
152
|
+
"id": 100,
|
|
153
|
+
"panels": [],
|
|
154
|
+
"title": "Traffic and reliability",
|
|
155
|
+
"type": "row"
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
"datasource": {
|
|
159
|
+
"type": "prometheus",
|
|
160
|
+
"uid": "prometheus"
|
|
161
|
+
},
|
|
162
|
+
"description": "Top 10 LLM request-rate series grouped by the bounded provider and model labels. No data can mean an idle range or missing request instrumentation; use Export Health before treating an empty panel as healthy.",
|
|
163
|
+
"fieldConfig": {
|
|
164
|
+
"defaults": {
|
|
165
|
+
"color": {
|
|
166
|
+
"mode": "palette-classic"
|
|
167
|
+
},
|
|
168
|
+
"mappings": [],
|
|
169
|
+
"min": 0,
|
|
170
|
+
"thresholds": {
|
|
171
|
+
"mode": "absolute",
|
|
172
|
+
"steps": [
|
|
173
|
+
{
|
|
174
|
+
"color": "blue",
|
|
175
|
+
"value": null
|
|
176
|
+
}
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
"unit": "ops"
|
|
180
|
+
},
|
|
181
|
+
"overrides": []
|
|
182
|
+
},
|
|
183
|
+
"gridPos": {
|
|
184
|
+
"h": 8,
|
|
185
|
+
"w": 12,
|
|
186
|
+
"x": 0,
|
|
187
|
+
"y": 1
|
|
188
|
+
},
|
|
189
|
+
"id": 1,
|
|
190
|
+
"links": [
|
|
191
|
+
{
|
|
192
|
+
"targetBlank": false,
|
|
193
|
+
"title": "Open LLM lifecycle logs",
|
|
194
|
+
"url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"targetBlank": false,
|
|
198
|
+
"title": "Open LLM Conversations",
|
|
199
|
+
"url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}"
|
|
200
|
+
}
|
|
201
|
+
],
|
|
202
|
+
"options": {
|
|
203
|
+
"legend": {
|
|
204
|
+
"calcs": [
|
|
205
|
+
"lastNotNull",
|
|
206
|
+
"max"
|
|
207
|
+
],
|
|
208
|
+
"displayMode": "table",
|
|
209
|
+
"placement": "bottom",
|
|
210
|
+
"showLegend": true
|
|
211
|
+
},
|
|
212
|
+
"tooltip": {
|
|
213
|
+
"mode": "multi",
|
|
214
|
+
"sort": "desc"
|
|
215
|
+
}
|
|
216
|
+
},
|
|
217
|
+
"pluginVersion": "11.1.0",
|
|
218
|
+
"targets": [
|
|
219
|
+
{
|
|
220
|
+
"datasource": {
|
|
221
|
+
"type": "prometheus",
|
|
222
|
+
"uid": "prometheus"
|
|
223
|
+
},
|
|
224
|
+
"editorMode": "code",
|
|
225
|
+
"expr": "topk(10, sum by (provider, model) (rate(observme_llm_requests_total[$__rate_interval])))",
|
|
226
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
227
|
+
"range": true,
|
|
228
|
+
"refId": "A"
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"title": "Requests by provider/model",
|
|
232
|
+
"type": "timeseries"
|
|
233
|
+
},
|
|
234
|
+
{
|
|
235
|
+
"datasource": {
|
|
236
|
+
"type": "prometheus",
|
|
237
|
+
"uid": "prometheus"
|
|
238
|
+
},
|
|
239
|
+
"description": "Top 10 LLM failure ratios by provider/model. Active request series with no matching failure series render as zero without losing labels. Yellow is a 2% review level; red matches the default 5% over 10m ObservMeHighLlmErrorRate alert. No request series remains no data rather than false green health.",
|
|
240
|
+
"fieldConfig": {
|
|
241
|
+
"defaults": {
|
|
242
|
+
"color": {
|
|
243
|
+
"mode": "palette-classic"
|
|
244
|
+
},
|
|
245
|
+
"mappings": [],
|
|
246
|
+
"max": 1,
|
|
247
|
+
"min": 0,
|
|
248
|
+
"thresholds": {
|
|
249
|
+
"mode": "absolute",
|
|
250
|
+
"steps": [
|
|
251
|
+
{
|
|
252
|
+
"color": "green",
|
|
253
|
+
"value": null
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"color": "yellow",
|
|
257
|
+
"value": 0.02
|
|
258
|
+
},
|
|
259
|
+
{
|
|
260
|
+
"color": "red",
|
|
261
|
+
"value": 0.05
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
},
|
|
265
|
+
"unit": "percentunit"
|
|
266
|
+
},
|
|
267
|
+
"overrides": []
|
|
268
|
+
},
|
|
269
|
+
"gridPos": {
|
|
270
|
+
"h": 8,
|
|
271
|
+
"w": 12,
|
|
272
|
+
"x": 12,
|
|
273
|
+
"y": 1
|
|
274
|
+
},
|
|
275
|
+
"id": 2,
|
|
276
|
+
"links": [
|
|
277
|
+
{
|
|
278
|
+
"targetBlank": false,
|
|
279
|
+
"title": "Open Errors",
|
|
280
|
+
"url": "/d/observme-errors/observme-errors?${__url_time_range}"
|
|
281
|
+
},
|
|
282
|
+
{
|
|
283
|
+
"targetBlank": false,
|
|
284
|
+
"title": "Open LLM lifecycle logs",
|
|
285
|
+
"url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
|
|
286
|
+
}
|
|
287
|
+
],
|
|
288
|
+
"options": {
|
|
289
|
+
"legend": {
|
|
290
|
+
"calcs": [
|
|
291
|
+
"lastNotNull",
|
|
292
|
+
"max"
|
|
293
|
+
],
|
|
294
|
+
"displayMode": "table",
|
|
295
|
+
"placement": "bottom",
|
|
296
|
+
"showLegend": true
|
|
297
|
+
},
|
|
298
|
+
"tooltip": {
|
|
299
|
+
"mode": "multi",
|
|
300
|
+
"sort": "desc"
|
|
301
|
+
}
|
|
302
|
+
},
|
|
303
|
+
"pluginVersion": "11.1.0",
|
|
304
|
+
"targets": [
|
|
305
|
+
{
|
|
306
|
+
"datasource": {
|
|
307
|
+
"type": "prometheus",
|
|
308
|
+
"uid": "prometheus"
|
|
309
|
+
},
|
|
310
|
+
"editorMode": "code",
|
|
311
|
+
"expr": "topk(10, clamp_max(((sum by (provider, model) (rate(observme_llm_errors_total[$__rate_interval])) or on (provider, model) (0 * sum by (provider, model) (rate(observme_llm_requests_total[$__rate_interval])))) / on (provider, model) clamp_min(sum by (provider, model) (rate(observme_llm_requests_total[$__rate_interval])), 1e-9)), 1))",
|
|
312
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
313
|
+
"range": true,
|
|
314
|
+
"refId": "A"
|
|
315
|
+
}
|
|
316
|
+
],
|
|
317
|
+
"title": "Error rate by provider/model",
|
|
318
|
+
"type": "timeseries"
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
"datasource": {
|
|
322
|
+
"type": "prometheus",
|
|
323
|
+
"uid": "prometheus"
|
|
324
|
+
},
|
|
325
|
+
"description": "Top 10 provider/model shares of selected-range LLM requests. The denominator is the aggregate LLM request count for the same range. An empty panel means no request series exists; it is not proof of a healthy telemetry path.",
|
|
326
|
+
"fieldConfig": {
|
|
327
|
+
"defaults": {
|
|
328
|
+
"color": {
|
|
329
|
+
"mode": "palette-classic"
|
|
330
|
+
},
|
|
331
|
+
"mappings": [],
|
|
332
|
+
"max": 1,
|
|
333
|
+
"min": 0,
|
|
334
|
+
"thresholds": {
|
|
335
|
+
"mode": "absolute",
|
|
336
|
+
"steps": [
|
|
337
|
+
{
|
|
338
|
+
"color": "blue",
|
|
339
|
+
"value": null
|
|
340
|
+
}
|
|
341
|
+
]
|
|
342
|
+
},
|
|
343
|
+
"unit": "percentunit"
|
|
344
|
+
},
|
|
345
|
+
"overrides": []
|
|
346
|
+
},
|
|
347
|
+
"gridPos": {
|
|
348
|
+
"h": 7,
|
|
349
|
+
"w": 12,
|
|
350
|
+
"x": 0,
|
|
351
|
+
"y": 9
|
|
352
|
+
},
|
|
353
|
+
"id": 7,
|
|
354
|
+
"links": [
|
|
355
|
+
{
|
|
356
|
+
"targetBlank": false,
|
|
357
|
+
"title": "Open Cost",
|
|
358
|
+
"url": "/d/observme-cost/observme-cost?${__url_time_range}"
|
|
359
|
+
}
|
|
360
|
+
],
|
|
361
|
+
"options": {
|
|
362
|
+
"displayMode": "gradient",
|
|
363
|
+
"maxVizHeight": 300,
|
|
364
|
+
"minVizHeight": 16,
|
|
365
|
+
"minVizWidth": 8,
|
|
366
|
+
"namePlacement": "auto",
|
|
367
|
+
"orientation": "horizontal",
|
|
368
|
+
"reduceOptions": {
|
|
369
|
+
"calcs": [
|
|
370
|
+
"lastNotNull"
|
|
371
|
+
],
|
|
372
|
+
"fields": "",
|
|
373
|
+
"values": false
|
|
374
|
+
},
|
|
375
|
+
"showUnfilled": true,
|
|
376
|
+
"sizing": "auto",
|
|
377
|
+
"valueMode": "color"
|
|
378
|
+
},
|
|
379
|
+
"pluginVersion": "11.1.0",
|
|
380
|
+
"targets": [
|
|
381
|
+
{
|
|
382
|
+
"datasource": {
|
|
383
|
+
"type": "prometheus",
|
|
384
|
+
"uid": "prometheus"
|
|
385
|
+
},
|
|
386
|
+
"editorMode": "code",
|
|
387
|
+
"expr": "topk(10, sum by (provider, model) (increase(observme_llm_requests_total[$__range])) / scalar(clamp_min((sum(increase(observme_llm_requests_total[$__range])) or vector(0)), 1)))",
|
|
388
|
+
"instant": true,
|
|
389
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
390
|
+
"range": false,
|
|
391
|
+
"refId": "A"
|
|
392
|
+
}
|
|
393
|
+
],
|
|
394
|
+
"title": "Request share by provider/model",
|
|
395
|
+
"type": "bargauge"
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"datasource": {
|
|
399
|
+
"type": "prometheus",
|
|
400
|
+
"uid": "prometheus"
|
|
401
|
+
},
|
|
402
|
+
"description": "Top 10 selected-range LLM failure totals by provider/model, shown beside failure ratios and request traffic. Active request series with no matching failure series render as labeled zeros. No request telemetry remains no data.",
|
|
403
|
+
"fieldConfig": {
|
|
404
|
+
"defaults": {
|
|
405
|
+
"color": {
|
|
406
|
+
"mode": "thresholds"
|
|
407
|
+
},
|
|
408
|
+
"mappings": [],
|
|
409
|
+
"min": 0,
|
|
410
|
+
"thresholds": {
|
|
411
|
+
"mode": "absolute",
|
|
412
|
+
"steps": [
|
|
413
|
+
{
|
|
414
|
+
"color": "green",
|
|
415
|
+
"value": null
|
|
416
|
+
},
|
|
417
|
+
{
|
|
418
|
+
"color": "red",
|
|
419
|
+
"value": 1e-9
|
|
420
|
+
}
|
|
421
|
+
]
|
|
422
|
+
},
|
|
423
|
+
"unit": "short"
|
|
424
|
+
},
|
|
425
|
+
"overrides": []
|
|
426
|
+
},
|
|
427
|
+
"gridPos": {
|
|
428
|
+
"h": 7,
|
|
429
|
+
"w": 12,
|
|
430
|
+
"x": 12,
|
|
431
|
+
"y": 9
|
|
432
|
+
},
|
|
433
|
+
"id": 8,
|
|
434
|
+
"links": [
|
|
435
|
+
{
|
|
436
|
+
"targetBlank": false,
|
|
437
|
+
"title": "Open Errors",
|
|
438
|
+
"url": "/d/observme-errors/observme-errors?${__url_time_range}"
|
|
439
|
+
},
|
|
440
|
+
{
|
|
441
|
+
"targetBlank": false,
|
|
442
|
+
"title": "Open Trace Journey",
|
|
443
|
+
"url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
|
|
444
|
+
}
|
|
445
|
+
],
|
|
446
|
+
"options": {
|
|
447
|
+
"displayMode": "gradient",
|
|
448
|
+
"maxVizHeight": 300,
|
|
449
|
+
"minVizHeight": 16,
|
|
450
|
+
"minVizWidth": 8,
|
|
451
|
+
"namePlacement": "auto",
|
|
452
|
+
"orientation": "horizontal",
|
|
453
|
+
"reduceOptions": {
|
|
454
|
+
"calcs": [
|
|
455
|
+
"lastNotNull"
|
|
456
|
+
],
|
|
457
|
+
"fields": "",
|
|
458
|
+
"values": false
|
|
459
|
+
},
|
|
460
|
+
"showUnfilled": true,
|
|
461
|
+
"sizing": "auto",
|
|
462
|
+
"valueMode": "color"
|
|
463
|
+
},
|
|
464
|
+
"pluginVersion": "11.1.0",
|
|
465
|
+
"targets": [
|
|
466
|
+
{
|
|
467
|
+
"datasource": {
|
|
468
|
+
"type": "prometheus",
|
|
469
|
+
"uid": "prometheus"
|
|
470
|
+
},
|
|
471
|
+
"editorMode": "code",
|
|
472
|
+
"expr": "topk(10, (sum by (provider, model) (increase(observme_llm_errors_total[$__range])) or on (provider, model) (0 * sum by (provider, model) (increase(observme_llm_requests_total[$__range])))))",
|
|
473
|
+
"instant": true,
|
|
474
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
475
|
+
"range": false,
|
|
476
|
+
"refId": "A"
|
|
477
|
+
}
|
|
478
|
+
],
|
|
479
|
+
"title": "Selected-range errors by provider/model",
|
|
480
|
+
"type": "bargauge"
|
|
481
|
+
},
|
|
482
|
+
{
|
|
483
|
+
"collapsed": false,
|
|
484
|
+
"gridPos": {
|
|
485
|
+
"h": 1,
|
|
486
|
+
"w": 24,
|
|
487
|
+
"x": 0,
|
|
488
|
+
"y": 16
|
|
489
|
+
},
|
|
490
|
+
"id": 101,
|
|
491
|
+
"panels": [],
|
|
492
|
+
"title": "Latency",
|
|
493
|
+
"type": "row"
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
"datasource": {
|
|
497
|
+
"type": "prometheus",
|
|
498
|
+
"uid": "prometheus"
|
|
499
|
+
},
|
|
500
|
+
"description": "Top 10 p95 LLM request-duration trends grouped by provider/model. The histogram keeps le, provider, and model during aggregation. Sparse request volume can make p95 jump or disappear; compare the adjacent selected-range request volume before treating a model as a slow offender.",
|
|
501
|
+
"fieldConfig": {
|
|
502
|
+
"defaults": {
|
|
503
|
+
"color": {
|
|
504
|
+
"mode": "palette-classic"
|
|
505
|
+
},
|
|
506
|
+
"mappings": [],
|
|
507
|
+
"min": 0,
|
|
508
|
+
"thresholds": {
|
|
509
|
+
"mode": "absolute",
|
|
510
|
+
"steps": [
|
|
511
|
+
{
|
|
512
|
+
"color": "blue",
|
|
513
|
+
"value": null
|
|
514
|
+
}
|
|
515
|
+
]
|
|
516
|
+
},
|
|
517
|
+
"unit": "ms"
|
|
518
|
+
},
|
|
519
|
+
"overrides": []
|
|
520
|
+
},
|
|
521
|
+
"gridPos": {
|
|
522
|
+
"h": 8,
|
|
523
|
+
"w": 16,
|
|
524
|
+
"x": 0,
|
|
525
|
+
"y": 17
|
|
526
|
+
},
|
|
527
|
+
"id": 3,
|
|
528
|
+
"links": [
|
|
529
|
+
{
|
|
530
|
+
"targetBlank": false,
|
|
531
|
+
"title": "Open Latency",
|
|
532
|
+
"url": "/d/observme-latency/observme-latency?${__url_time_range}"
|
|
533
|
+
},
|
|
534
|
+
{
|
|
535
|
+
"targetBlank": false,
|
|
536
|
+
"title": "Open Trace Journey",
|
|
537
|
+
"url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
|
|
538
|
+
}
|
|
539
|
+
],
|
|
540
|
+
"options": {
|
|
541
|
+
"legend": {
|
|
542
|
+
"calcs": [
|
|
543
|
+
"lastNotNull",
|
|
544
|
+
"max"
|
|
545
|
+
],
|
|
546
|
+
"displayMode": "table",
|
|
547
|
+
"placement": "bottom",
|
|
548
|
+
"showLegend": true
|
|
549
|
+
},
|
|
550
|
+
"tooltip": {
|
|
551
|
+
"mode": "multi",
|
|
552
|
+
"sort": "desc"
|
|
553
|
+
}
|
|
554
|
+
},
|
|
555
|
+
"pluginVersion": "11.1.0",
|
|
556
|
+
"targets": [
|
|
557
|
+
{
|
|
558
|
+
"datasource": {
|
|
559
|
+
"type": "prometheus",
|
|
560
|
+
"uid": "prometheus"
|
|
561
|
+
},
|
|
562
|
+
"editorMode": "code",
|
|
563
|
+
"expr": "topk(10, histogram_quantile(0.95, sum by (provider, model, le) (rate(observme_llm_request_duration_ms_bucket[$__rate_interval]))))",
|
|
564
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
565
|
+
"range": true,
|
|
566
|
+
"refId": "A"
|
|
567
|
+
}
|
|
568
|
+
],
|
|
569
|
+
"title": "p95 latency by provider/model",
|
|
570
|
+
"type": "timeseries"
|
|
571
|
+
},
|
|
572
|
+
{
|
|
573
|
+
"datasource": {
|
|
574
|
+
"type": "prometheus",
|
|
575
|
+
"uid": "prometheus"
|
|
576
|
+
},
|
|
577
|
+
"description": "Top 10 selected-range LLM request totals for interpreting the adjacent p95 panel. Low volume makes percentile comparisons statistically sparse. No data means no request counter series exists in the selected range.",
|
|
578
|
+
"fieldConfig": {
|
|
579
|
+
"defaults": {
|
|
580
|
+
"color": {
|
|
581
|
+
"mode": "palette-classic"
|
|
582
|
+
},
|
|
583
|
+
"mappings": [],
|
|
584
|
+
"min": 0,
|
|
585
|
+
"thresholds": {
|
|
586
|
+
"mode": "absolute",
|
|
587
|
+
"steps": [
|
|
588
|
+
{
|
|
589
|
+
"color": "blue",
|
|
590
|
+
"value": null
|
|
591
|
+
}
|
|
592
|
+
]
|
|
593
|
+
},
|
|
594
|
+
"unit": "short"
|
|
595
|
+
},
|
|
596
|
+
"overrides": []
|
|
597
|
+
},
|
|
598
|
+
"gridPos": {
|
|
599
|
+
"h": 8,
|
|
600
|
+
"w": 8,
|
|
601
|
+
"x": 16,
|
|
602
|
+
"y": 17
|
|
603
|
+
},
|
|
604
|
+
"id": 9,
|
|
605
|
+
"links": [
|
|
606
|
+
{
|
|
607
|
+
"targetBlank": false,
|
|
608
|
+
"title": "Open Latency",
|
|
609
|
+
"url": "/d/observme-latency/observme-latency?${__url_time_range}"
|
|
610
|
+
}
|
|
611
|
+
],
|
|
612
|
+
"options": {
|
|
613
|
+
"displayMode": "gradient",
|
|
614
|
+
"maxVizHeight": 300,
|
|
615
|
+
"minVizHeight": 16,
|
|
616
|
+
"minVizWidth": 8,
|
|
617
|
+
"namePlacement": "auto",
|
|
618
|
+
"orientation": "horizontal",
|
|
619
|
+
"reduceOptions": {
|
|
620
|
+
"calcs": [
|
|
621
|
+
"lastNotNull"
|
|
622
|
+
],
|
|
623
|
+
"fields": "",
|
|
624
|
+
"values": false
|
|
625
|
+
},
|
|
626
|
+
"showUnfilled": true,
|
|
627
|
+
"sizing": "auto",
|
|
628
|
+
"valueMode": "color"
|
|
629
|
+
},
|
|
630
|
+
"pluginVersion": "11.1.0",
|
|
631
|
+
"targets": [
|
|
632
|
+
{
|
|
633
|
+
"datasource": {
|
|
634
|
+
"type": "prometheus",
|
|
635
|
+
"uid": "prometheus"
|
|
636
|
+
},
|
|
637
|
+
"editorMode": "code",
|
|
638
|
+
"expr": "topk(10, sum by (provider, model) (increase(observme_llm_requests_total[$__range])))",
|
|
639
|
+
"instant": true,
|
|
640
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
641
|
+
"range": false,
|
|
642
|
+
"refId": "A"
|
|
643
|
+
}
|
|
644
|
+
],
|
|
645
|
+
"title": "Latency request volume",
|
|
646
|
+
"type": "bargauge"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"collapsed": false,
|
|
650
|
+
"gridPos": {
|
|
651
|
+
"h": 1,
|
|
652
|
+
"w": 24,
|
|
653
|
+
"x": 0,
|
|
654
|
+
"y": 25
|
|
655
|
+
},
|
|
656
|
+
"id": 102,
|
|
657
|
+
"panels": [],
|
|
658
|
+
"title": "Stop reasons",
|
|
659
|
+
"type": "row"
|
|
660
|
+
},
|
|
661
|
+
{
|
|
662
|
+
"datasource": {
|
|
663
|
+
"type": "loki",
|
|
664
|
+
"uid": "loki"
|
|
665
|
+
},
|
|
666
|
+
"description": "Selected-range totals from completed LLM request logs, grouped by the provisioned pi_llm_stop_reason label. This is an instant query over $__range. Empty means no matching completed requests with a non-empty stop reason were observed; inspect LLM lifecycle logs and Export Health if requests were expected.",
|
|
667
|
+
"fieldConfig": {
|
|
668
|
+
"defaults": {
|
|
669
|
+
"color": {
|
|
670
|
+
"mode": "palette-classic"
|
|
671
|
+
},
|
|
672
|
+
"mappings": [],
|
|
673
|
+
"min": 0,
|
|
674
|
+
"thresholds": {
|
|
675
|
+
"mode": "absolute",
|
|
676
|
+
"steps": [
|
|
677
|
+
{
|
|
678
|
+
"color": "blue",
|
|
679
|
+
"value": null
|
|
680
|
+
}
|
|
681
|
+
]
|
|
682
|
+
},
|
|
683
|
+
"unit": "short"
|
|
684
|
+
},
|
|
685
|
+
"overrides": []
|
|
686
|
+
},
|
|
687
|
+
"gridPos": {
|
|
688
|
+
"h": 7,
|
|
689
|
+
"w": 24,
|
|
690
|
+
"x": 0,
|
|
691
|
+
"y": 26
|
|
692
|
+
},
|
|
693
|
+
"id": 4,
|
|
694
|
+
"links": [
|
|
695
|
+
{
|
|
696
|
+
"targetBlank": false,
|
|
697
|
+
"title": "Open LLM lifecycle logs",
|
|
698
|
+
"url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
"targetBlank": false,
|
|
702
|
+
"title": "Open LLM Conversations",
|
|
703
|
+
"url": "/d/observme-llm-conversations/observme-llm-conversations?${__url_time_range}"
|
|
704
|
+
},
|
|
705
|
+
{
|
|
706
|
+
"targetBlank": false,
|
|
707
|
+
"title": "Open Trace Journey",
|
|
708
|
+
"url": "/d/observme-trace-journey/observme-trace-journey?${__url_time_range}"
|
|
709
|
+
}
|
|
710
|
+
],
|
|
711
|
+
"options": {
|
|
712
|
+
"displayMode": "gradient",
|
|
713
|
+
"maxVizHeight": 300,
|
|
714
|
+
"minVizHeight": 16,
|
|
715
|
+
"minVizWidth": 8,
|
|
716
|
+
"namePlacement": "auto",
|
|
717
|
+
"orientation": "horizontal",
|
|
718
|
+
"reduceOptions": {
|
|
719
|
+
"calcs": [
|
|
720
|
+
"lastNotNull"
|
|
721
|
+
],
|
|
722
|
+
"fields": "",
|
|
723
|
+
"values": false
|
|
724
|
+
},
|
|
725
|
+
"showUnfilled": true,
|
|
726
|
+
"sizing": "auto",
|
|
727
|
+
"valueMode": "color"
|
|
728
|
+
},
|
|
729
|
+
"pluginVersion": "11.1.0",
|
|
730
|
+
"targets": [
|
|
731
|
+
{
|
|
732
|
+
"datasource": {
|
|
733
|
+
"type": "loki",
|
|
734
|
+
"uid": "loki"
|
|
735
|
+
},
|
|
736
|
+
"editorMode": "code",
|
|
737
|
+
"expr": "sum by (pi_llm_stop_reason) (count_over_time({service_name=\"observme-pi-extension\", event_name=\"llm.request.completed\", pi_llm_stop_reason!=\"\"}[$__range]))",
|
|
738
|
+
"instant": true,
|
|
739
|
+
"legendFormat": "{{pi_llm_stop_reason}}",
|
|
740
|
+
"queryType": "instant",
|
|
741
|
+
"range": false,
|
|
742
|
+
"refId": "A"
|
|
743
|
+
}
|
|
744
|
+
],
|
|
745
|
+
"title": "Stop reason distribution",
|
|
746
|
+
"type": "bargauge"
|
|
747
|
+
},
|
|
748
|
+
{
|
|
749
|
+
"collapsed": false,
|
|
750
|
+
"gridPos": {
|
|
751
|
+
"h": 1,
|
|
752
|
+
"w": 24,
|
|
753
|
+
"x": 0,
|
|
754
|
+
"y": 33
|
|
755
|
+
},
|
|
756
|
+
"id": 103,
|
|
757
|
+
"panels": [],
|
|
758
|
+
"title": "Efficiency",
|
|
759
|
+
"type": "row"
|
|
760
|
+
},
|
|
761
|
+
{
|
|
762
|
+
"datasource": {
|
|
763
|
+
"type": "prometheus",
|
|
764
|
+
"uid": "prometheus"
|
|
765
|
+
},
|
|
766
|
+
"description": "Top 10 rolling provider/model LLM costs per 1,000 LLM requests. Cost and request vectors match explicitly on provider and model; this panel never divides model cost by the global turn counter. Active request series with no cost series render as zero, which can also mean provider cost accounting is unsupported or incomplete rather than free usage.",
|
|
767
|
+
"fieldConfig": {
|
|
768
|
+
"defaults": {
|
|
769
|
+
"color": {
|
|
770
|
+
"mode": "palette-classic"
|
|
771
|
+
},
|
|
772
|
+
"mappings": [],
|
|
773
|
+
"min": 0,
|
|
774
|
+
"thresholds": {
|
|
775
|
+
"mode": "absolute",
|
|
776
|
+
"steps": [
|
|
777
|
+
{
|
|
778
|
+
"color": "blue",
|
|
779
|
+
"value": null
|
|
780
|
+
}
|
|
781
|
+
]
|
|
782
|
+
},
|
|
783
|
+
"unit": "currencyUSD"
|
|
784
|
+
},
|
|
785
|
+
"overrides": []
|
|
786
|
+
},
|
|
787
|
+
"gridPos": {
|
|
788
|
+
"h": 8,
|
|
789
|
+
"w": 16,
|
|
790
|
+
"x": 0,
|
|
791
|
+
"y": 34
|
|
792
|
+
},
|
|
793
|
+
"id": 5,
|
|
794
|
+
"links": [
|
|
795
|
+
{
|
|
796
|
+
"targetBlank": false,
|
|
797
|
+
"title": "Open Cost",
|
|
798
|
+
"url": "/d/observme-cost/observme-cost?${__url_time_range}"
|
|
799
|
+
},
|
|
800
|
+
{
|
|
801
|
+
"targetBlank": false,
|
|
802
|
+
"title": "Open LLM lifecycle logs",
|
|
803
|
+
"url": "/d/observme-logs-llm/observme-logs-llm?${__url_time_range}"
|
|
804
|
+
}
|
|
805
|
+
],
|
|
806
|
+
"options": {
|
|
807
|
+
"legend": {
|
|
808
|
+
"calcs": [
|
|
809
|
+
"lastNotNull",
|
|
810
|
+
"max"
|
|
811
|
+
],
|
|
812
|
+
"displayMode": "table",
|
|
813
|
+
"placement": "bottom",
|
|
814
|
+
"showLegend": true
|
|
815
|
+
},
|
|
816
|
+
"tooltip": {
|
|
817
|
+
"mode": "multi",
|
|
818
|
+
"sort": "desc"
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
"pluginVersion": "11.1.0",
|
|
822
|
+
"targets": [
|
|
823
|
+
{
|
|
824
|
+
"datasource": {
|
|
825
|
+
"type": "prometheus",
|
|
826
|
+
"uid": "prometheus"
|
|
827
|
+
},
|
|
828
|
+
"editorMode": "code",
|
|
829
|
+
"expr": "topk(10, 1000 * ((sum by (provider, model) (rate(observme_llm_cost_usd_total[$__rate_interval])) or on (provider, model) (0 * sum by (provider, model) (rate(observme_llm_requests_total[$__rate_interval])))) / on (provider, model) clamp_min(sum by (provider, model) (rate(observme_llm_requests_total[$__rate_interval])), 1e-9)))",
|
|
830
|
+
"legendFormat": "{{provider}} / {{model}}",
|
|
831
|
+
"range": true,
|
|
832
|
+
"refId": "A"
|
|
833
|
+
}
|
|
834
|
+
],
|
|
835
|
+
"title": "Cost per 1k LLM requests",
|
|
836
|
+
"type": "timeseries"
|
|
837
|
+
},
|
|
838
|
+
{
|
|
839
|
+
"datasource": {
|
|
840
|
+
"type": "prometheus",
|
|
841
|
+
"uid": "prometheus"
|
|
842
|
+
},
|
|
843
|
+
"description": "Selected-range aggregate LLM cost divided by completed turns. This is intentionally overall because turn counters do not carry provider/model labels. Zero can mean idle workload or absent provider cost accounting; use Cost for the tunable $50/hour budget reference rather than treating this neutral efficiency value as an alert.",
|
|
844
|
+
"fieldConfig": {
|
|
845
|
+
"defaults": {
|
|
846
|
+
"color": {
|
|
847
|
+
"mode": "thresholds"
|
|
848
|
+
},
|
|
849
|
+
"mappings": [],
|
|
850
|
+
"min": 0,
|
|
851
|
+
"thresholds": {
|
|
852
|
+
"mode": "absolute",
|
|
853
|
+
"steps": [
|
|
854
|
+
{
|
|
855
|
+
"color": "blue",
|
|
856
|
+
"value": null
|
|
857
|
+
}
|
|
858
|
+
]
|
|
859
|
+
},
|
|
860
|
+
"unit": "currencyUSD"
|
|
861
|
+
},
|
|
862
|
+
"overrides": []
|
|
863
|
+
},
|
|
864
|
+
"gridPos": {
|
|
865
|
+
"h": 8,
|
|
866
|
+
"w": 8,
|
|
867
|
+
"x": 16,
|
|
868
|
+
"y": 34
|
|
869
|
+
},
|
|
870
|
+
"id": 6,
|
|
871
|
+
"links": [
|
|
872
|
+
{
|
|
873
|
+
"targetBlank": false,
|
|
874
|
+
"title": "Open Cost",
|
|
875
|
+
"url": "/d/observme-cost/observme-cost?${__url_time_range}"
|
|
876
|
+
}
|
|
877
|
+
],
|
|
878
|
+
"options": {
|
|
879
|
+
"colorMode": "value",
|
|
880
|
+
"graphMode": "area",
|
|
881
|
+
"justifyMode": "auto",
|
|
882
|
+
"orientation": "auto",
|
|
883
|
+
"reduceOptions": {
|
|
884
|
+
"calcs": [
|
|
885
|
+
"lastNotNull"
|
|
886
|
+
],
|
|
887
|
+
"fields": "",
|
|
888
|
+
"values": false
|
|
889
|
+
},
|
|
890
|
+
"showPercentChange": false,
|
|
891
|
+
"textMode": "auto",
|
|
892
|
+
"wideLayout": true
|
|
893
|
+
},
|
|
894
|
+
"pluginVersion": "11.1.0",
|
|
895
|
+
"targets": [
|
|
896
|
+
{
|
|
897
|
+
"datasource": {
|
|
898
|
+
"type": "prometheus",
|
|
899
|
+
"uid": "prometheus"
|
|
900
|
+
},
|
|
901
|
+
"editorMode": "code",
|
|
902
|
+
"expr": "(sum(increase(observme_llm_cost_usd_total[$__range])) or vector(0)) / clamp_min((sum(increase(observme_turns_completed_total[$__range])) or vector(0)), 1)",
|
|
903
|
+
"instant": true,
|
|
904
|
+
"range": false,
|
|
905
|
+
"refId": "A"
|
|
906
|
+
}
|
|
907
|
+
],
|
|
908
|
+
"title": "Overall cost per completed turn",
|
|
909
|
+
"type": "stat"
|
|
910
|
+
}
|
|
911
|
+
],
|
|
912
|
+
"refresh": "30s",
|
|
913
|
+
"schemaVersion": 39,
|
|
914
|
+
"style": "dark",
|
|
915
|
+
"tags": [
|
|
916
|
+
"observme",
|
|
917
|
+
"models",
|
|
918
|
+
"llm"
|
|
919
|
+
],
|
|
920
|
+
"templating": {
|
|
921
|
+
"list": []
|
|
922
|
+
},
|
|
923
|
+
"time": {
|
|
924
|
+
"from": "now-6h",
|
|
925
|
+
"to": "now"
|
|
926
|
+
},
|
|
927
|
+
"timepicker": {},
|
|
928
|
+
"timezone": "browser",
|
|
929
|
+
"title": "ObservMe Models",
|
|
930
|
+
"uid": "observme-models",
|
|
931
|
+
"version": 2,
|
|
932
|
+
"weekStart": ""
|
|
933
|
+
}
|