@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,276 @@
1
+ # ObservMe Query and Grafana Integration
2
+
3
+ ## 1. Purpose
4
+
5
+ ObservMe is primarily an emitter, but it should also help users query the observability stack from inside Pi. Query commands must be lightweight and optional.
6
+
7
+ ## 2. Query Architecture
8
+
9
+ ```text
10
+ Pi /obs command
11
+ -> ObservMe query client
12
+ -> Grafana API
13
+ -> Tempo API
14
+ -> Loki API
15
+ -> Prometheus/Mimir API
16
+ -> Agent lineage queries (Tempo/Loki)
17
+ -> Render concise result in Pi TUI
18
+ ```
19
+
20
+ Preferred integration is Grafana API because Grafana already knows all datasources and provides stable links.
21
+
22
+ ## 3. Configuration
23
+
24
+ ```yaml
25
+ query:
26
+ enabled: true
27
+ grafana:
28
+ url: https://grafana.example.com
29
+ token: ${OBSERVME_GRAFANA_TOKEN}
30
+ username: ""
31
+ password: ""
32
+ datasourceUids:
33
+ tempo: tempo
34
+ loki: loki
35
+ prometheus: mimir
36
+ tls:
37
+ insecureSkipVerify: false
38
+ transport:
39
+ preferIPv4: false
40
+ links:
41
+ traceUrlTemplate: "https://grafana.example.com/explore?left=..."
42
+ ```
43
+
44
+ Authentication and local transport behavior:
45
+
46
+ - Prefer `query.grafana.token` for Grafana service-account or bearer tokens.
47
+ - If the token is blank or an unresolved environment placeholder, ObservMe may use `query.grafana.username` plus `query.grafana.password` as a local-development Basic auth fallback.
48
+ - Query-backed commands fail fast before backend calls when Grafana auth is unresolved/missing/incomplete, `query.grafana.url` is invalid, or a required datasource UID is blank.
49
+ - `401` and `403` responses are surfaced as Grafana authentication failures without printing token or password values.
50
+ - Browser login cookies are irrelevant because `/obs` commands call the Grafana API directly from the Pi process.
51
+
52
+ Bundled local-stack profile:
53
+
54
+ ```yaml
55
+ query:
56
+ enabled: true
57
+ links:
58
+ traceUrlTemplate: https://observability.local/explore?left=...
59
+ grafana:
60
+ url: https://observability.local
61
+ token: ${OBSERVME_GRAFANA_TOKEN}
62
+ username: admin
63
+ password: ${OBSERVME_GRAFANA_PASSWORD}
64
+ datasourceUids:
65
+ tempo: tempo
66
+ loki: loki
67
+ prometheus: prometheus
68
+ tls:
69
+ insecureSkipVerify: true
70
+ transport:
71
+ preferIPv4: true
72
+ ```
73
+
74
+ For the bundled `observability-stack/`, the supported command path is nginx HTTPS at `https://observability.local`; the default stack does not publish Grafana on `localhost:3000`. Create a Grafana service-account token with Viewer access for read-only datasource queries and export it as `OBSERVME_GRAFANA_TOKEN`, or export/set `OBSERVME_GRAFANA_PASSWORD` from `observability-stack/secrets/grafana_admin_password` for local Basic auth. Extension environment values can come from system environment variables before Pi starts, or from a trusted project `.env` copied from `.env.example`; system variables override `.env`. The local self-signed certificate requires `query.grafana.tls.insecureSkipVerify=true`, and `query.grafana.transport.preferIPv4=true` avoids DNS stalls when `observability.local` resolves to IPv6 first. Provisioned datasource UIDs are `tempo`, `loki`, and `prometheus`; Loki selectors use normalized labels such as `service_name`, `pi_session_id`, `event_name`, and `event_category`.
75
+
76
+ ## 4. Commands
77
+
78
+ ### `/obs status`
79
+
80
+ Shows local ObservMe state.
81
+
82
+ Output:
83
+
84
+ ```text
85
+ ObservMe: enabled
86
+ OTLP endpoint: https://otel.example.com:4318
87
+ Traces: enabled
88
+ Metrics: enabled
89
+ Logs: enabled
90
+ Prompt capture: disabled
91
+ Queue drops: 0
92
+ Last export error: none
93
+ ```
94
+
95
+ ### `/obs health`
96
+
97
+ Checks Collector and Grafana reachability, and reports Grafana query auth/config readiness before datasource calls.
98
+
99
+ ```text
100
+ Collector: reachable
101
+ Grafana: reachable
102
+ Tempo datasource: ok
103
+ Loki datasource: ok
104
+ Metrics datasource: ok
105
+ ```
106
+
107
+ ### `/obs session`
108
+
109
+ Shows current session telemetry summary.
110
+
111
+ ```text
112
+ Session: 8ddf...
113
+ Trace: 4bf92f...
114
+ Turns: 12
115
+ LLM calls: 18
116
+ Tool calls: 35
117
+ Cost: $1.42
118
+ Open trace: https://grafana.example.com/...
119
+ ```
120
+
121
+ ### `/obs trace`
122
+
123
+ Returns a Grafana Tempo trace link. For the current active session, the link is available from runtime state before shutdown. Tempo may show ended child spans before the long-lived root `pi.session` span appears; the root is exported after `session_shutdown`.
124
+
125
+ Options:
126
+
127
+ ```text
128
+ /obs trace
129
+ /obs trace --last-turn
130
+ /obs trace --session <session-id>
131
+ ```
132
+
133
+ ### `/obs cost`
134
+
135
+ Queries Prometheus/Mimir.
136
+
137
+ PromQL example for aggregate cost:
138
+
139
+ ```promql
140
+ sum(increase(observme_llm_cost_usd_total[24h])) by (model, provider)
141
+ ```
142
+
143
+ Session-scoped metric query, only for deployments that explicitly promote session IDs to metric labels:
144
+
145
+ ```promql
146
+ sum(increase(observme_llm_cost_usd_total{pi_session_id="$session"}[24h])) by (model, provider)
147
+ ```
148
+
149
+ Because `session_id` is high cardinality, session-scoped metric queries should be disabled by default. The safer default is querying trace/log attributes for the current session.
150
+
151
+ ### `/obs agents`
152
+
153
+ Shows the current workflow/agent identity and, when query integration is enabled, recent parent/child relationships, depth, fan-out, orphan, and critical-path hints.
154
+
155
+ Output:
156
+
157
+ ```text
158
+ Workflow: 91ce... root=2f4c...
159
+ Agent: 2f4c... (orchestrator depth=0)
160
+ Session: 8ddf...
161
+ Subagents spawned in current trace: 3
162
+ Current tree: depth=2 width=4 active=1 orphaned=0
163
+ Latest child: 7a91... status=ok cost=$0.18 join=1.2s
164
+ Open lineage trace: https://grafana.example.com/...
165
+ ```
166
+
167
+ PromQL aggregate examples must use only low-cardinality labels:
168
+
169
+ ```promql
170
+ sum(rate(observme_subagents_spawned_total[1h])) by (agent_role, subagent_depth, spawn_type, spawn_reason)
171
+ ```
172
+
173
+ ```promql
174
+ histogram_quantile(0.95, sum(rate(observme_agent_fanout_count_bucket[1h])) by (subagent_depth, le))
175
+ ```
176
+
177
+ ```promql
178
+ sum(rate(observme_orphan_agents_total[1h])) by (agent_role, subagent_depth)
179
+ ```
180
+
181
+ Per-agent and per-workflow drill-down should use Tempo/Loki attributes such as `pi_workflow_id`, `pi_agent_id`, `pi_agent_parent_id`, and trace/span IDs, not Prometheus labels.
182
+
183
+ ### `/obs tools`
184
+
185
+ PromQL:
186
+
187
+ ```promql
188
+ topk(10, sum(rate(observme_tool_calls_total[1h])) by (tool_name))
189
+ ```
190
+
191
+ Failures:
192
+
193
+ ```promql
194
+ sum(rate(observme_tool_failures_total[1h])) by (tool_name, error_class)
195
+ ```
196
+
197
+ ### `/obs errors`
198
+
199
+ Loki LogQL:
200
+
201
+ ```logql
202
+ {service_name="observme-pi-extension", event_name=~".*[.]failed|.*[.]dropped|agent[.]orphaned"}
203
+ ```
204
+
205
+ With Loki OTLP ingestion, OTel attribute dots are normalized to underscores (`event.name` -> `event_name`, `pi.session.id` -> `pi_session_id`). `event.category` remains a semantic category such as `lifecycle`, `agent-tree`, or `compaction`; use `event_name` for failure/error selectors. Use `| json` only when the log body itself is JSON; default ObservMe event fields should be OTEL log attributes/structured metadata.
206
+
207
+ ### `/obs logs`
208
+
209
+ Loki LogQL for current session:
210
+
211
+ ```logql
212
+ {service_name="observme-pi-extension", pi_session_id="$session"}
213
+ ```
214
+
215
+ Only available if Loki receives `pi.session.id` as structured metadata or label.
216
+
217
+ ## 5. Trace Links
218
+
219
+ If trace id is available:
220
+
221
+ ```text
222
+ https://grafana.example.com/explore?schemaVersion=1&panes=...
223
+ ```
224
+
225
+ ObservMe should support configurable URL templates because Grafana URL encoding changes across versions and organizations.
226
+
227
+ ## 6. Grafana Query Abstraction
228
+
229
+ Interface:
230
+
231
+ ```typescript
232
+ interface ObservabilityQueryClient {
233
+ health(): Promise<HealthResult>;
234
+ getTraceLink(traceId: string): string;
235
+ queryPrometheus(query: string, time?: Date): Promise<QueryResult>;
236
+ queryLoki(query: string, range: TimeRange): Promise<LogResult[]>;
237
+ searchTempo(attrs: Record<string, string>, range: TimeRange): Promise<TraceSummary[]>;
238
+ }
239
+ ```
240
+
241
+ ## 7. Safe Query Rules
242
+
243
+ - Never send raw prompts as query strings.
244
+ - Prefer session id, trace id, generated workflow id, generated agent id, and hashed fields.
245
+ - Do not query raw prompts, raw commands, raw paths, or inherited subagent environment values.
246
+ - Apply max result limits.
247
+ - Apply query timeouts.
248
+ - Render summaries, not huge raw logs.
249
+
250
+ Defaults:
251
+
252
+ ```yaml
253
+ query:
254
+ timeoutMs: 5000
255
+ maxLogs: 50
256
+ maxTraces: 20
257
+ maxMetricSeries: 20
258
+ maxAgents: 20
259
+ ```
260
+
261
+ ## 8. Dependency Direction
262
+
263
+ ObservMe telemetry emission must not depend on Grafana query availability.
264
+
265
+ Bad:
266
+
267
+ ```text
268
+ Pi event -> Grafana query -> emit telemetry
269
+ ```
270
+
271
+ Good:
272
+
273
+ ```text
274
+ Pi event -> emit telemetry
275
+ /obs command -> optional query
276
+ ```