@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,306 @@
|
|
|
1
|
+
# ObservMe Reference Architecture
|
|
2
|
+
|
|
3
|
+
## 1. High-Level Architecture
|
|
4
|
+
|
|
5
|
+
```text
|
|
6
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
7
|
+
│ Pi Agent │
|
|
8
|
+
│ │
|
|
9
|
+
│ ┌────────────────────────────────────────────────────────┐ │
|
|
10
|
+
│ │ ObservMe Extension │ │
|
|
11
|
+
│ │ │ │
|
|
12
|
+
│ │ Event Capture -> Semantic Mapper -> OTEL Emitters │ │
|
|
13
|
+
│ │ │ │ │ │ │
|
|
14
|
+
│ │ │ │ ├─ Traces │ │
|
|
15
|
+
│ │ │ │ ├─ Metrics │ │
|
|
16
|
+
│ │ │ │ └─ Logs │ │
|
|
17
|
+
│ │ │ │ │ │
|
|
18
|
+
│ │ └──── Query Commands /obs ───────────────────────┘ │
|
|
19
|
+
│ └────────────────────────────────────────────────────────┘ │
|
|
20
|
+
└──────────────────────────────┬───────────────────────────────┘
|
|
21
|
+
│ OTLP HTTP/protobuf (4318) or gRPC (4317)
|
|
22
|
+
▼
|
|
23
|
+
┌──────────────────────────────────────────────────────────────┐
|
|
24
|
+
│ OpenTelemetry Collector │
|
|
25
|
+
│ │
|
|
26
|
+
│ Receivers -> Processors -> Exporters │
|
|
27
|
+
│ │
|
|
28
|
+
│ processors: memory_limiter, batch, attributes/filter, sampling │
|
|
29
|
+
└──────────────┬────────────────┬────────────────┬─────────────┘
|
|
30
|
+
│ │ │
|
|
31
|
+
▼ ▼ ▼
|
|
32
|
+
Tempo Loki Prometheus/Mimir
|
|
33
|
+
Traces Logs Metrics
|
|
34
|
+
└────────────────┬────────────────┘
|
|
35
|
+
▼
|
|
36
|
+
Grafana
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## 2. Component Responsibilities
|
|
40
|
+
|
|
41
|
+
### 2.1 ObservMe Pi Extension
|
|
42
|
+
|
|
43
|
+
Responsibilities:
|
|
44
|
+
|
|
45
|
+
- Subscribe to Pi lifecycle events.
|
|
46
|
+
- Read Pi event/session metadata from event payloads and session APIs.
|
|
47
|
+
- Maintain in-memory span context and workflow/agent lineage context.
|
|
48
|
+
- Create OTEL traces, metrics, and logs.
|
|
49
|
+
- Redact sensitive values before export.
|
|
50
|
+
- Provide `/obs` commands for health, links, and downstream queries.
|
|
51
|
+
|
|
52
|
+
Not responsible for:
|
|
53
|
+
|
|
54
|
+
- Long-term telemetry storage
|
|
55
|
+
- Heavy aggregation
|
|
56
|
+
- Dashboard rendering engine
|
|
57
|
+
- Backend-specific data retention
|
|
58
|
+
- Collector-side sampling
|
|
59
|
+
- Durable agent registry storage
|
|
60
|
+
|
|
61
|
+
### 2.2 Agent and Subagent Correlation
|
|
62
|
+
|
|
63
|
+
Each ObservMe runtime has an extension instance identity, a workflow identity, and a logical agent identity:
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
observme.instance.id # unique ObservMe telemetry session/process startup
|
|
67
|
+
pi.workflow.id # generated root workflow/execution id, high-cardinality trace/log attribute
|
|
68
|
+
pi.workflow.root_agent_id
|
|
69
|
+
pi.agent.id # logical Pi agent runtime
|
|
70
|
+
pi.agent.parent_id # parent agent when spawned as a subagent
|
|
71
|
+
pi.agent.root_id # root of the agent tree
|
|
72
|
+
pi.agent.depth # bounded integer depth
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
When a Pi tool or extension starts another Pi agent, ObservMe should create a `pi.agent.spawn` span under the current turn/tool span and pass correlation to the child through environment variables and W3C trace context. If the child receives `traceparent`, its `pi.session` span can continue the parent trace. If it cannot continue the trace, it must still record `pi.agent.parent_id`, `pi.agent.root_id`, and a span link or log event so Grafana can reconstruct lineage.
|
|
76
|
+
|
|
77
|
+
`pi.workflow.id`, `pi.workflow.root_agent_id`, `pi.agent.id`, `pi.agent.parent_id`, and `pi.agent.spawn.id` are high-cardinality identifiers. They belong in resource/span/log attributes and trace links, not Prometheus labels.
|
|
78
|
+
|
|
79
|
+
For orchestrator workloads, ObservMe treats the root agent and every descendant as one logical workflow tree. The root agent creates `pi.workflow.id`; descendants inherit it through environment propagation. Aggregate metrics describe the tree using low-cardinality dimensions such as `agent_role`, `agent_capability`, `subagent_depth`, `spawn_type`, `spawn_reason`, and `status`, while per-workflow drill-down uses Tempo/Loki attributes.
|
|
80
|
+
|
|
81
|
+
### 2.3 OpenTelemetry Collector
|
|
82
|
+
|
|
83
|
+
Responsibilities:
|
|
84
|
+
|
|
85
|
+
- Receive OTLP from ObservMe.
|
|
86
|
+
- Batch telemetry and retry when exporter `sending_queue`/`retry_on_failure` settings are enabled.
|
|
87
|
+
- Apply memory limits.
|
|
88
|
+
- Apply central redaction/filtering when needed.
|
|
89
|
+
- Route traces to Tempo.
|
|
90
|
+
- Route logs to Loki.
|
|
91
|
+
- Route metrics to Prometheus/Mimir.
|
|
92
|
+
|
|
93
|
+
Recommended processors:
|
|
94
|
+
|
|
95
|
+
```yaml
|
|
96
|
+
processors:
|
|
97
|
+
memory_limiter:
|
|
98
|
+
check_interval: 1s
|
|
99
|
+
limit_mib: 512
|
|
100
|
+
spike_limit_mib: 128
|
|
101
|
+
batch:
|
|
102
|
+
timeout: 2s
|
|
103
|
+
send_batch_size: 1024
|
|
104
|
+
send_batch_max_size: 2048
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
Optional processors such as `probabilistic_sampler` and `tail_sampling` are useful at scale. Verify they are included in the Collector distribution you deploy; several advanced processors/exporters are in the Collector Contrib distribution rather than the minimal core distribution.
|
|
108
|
+
|
|
109
|
+
### 2.4 Tempo
|
|
110
|
+
|
|
111
|
+
Stores traces. Trace granularity is session -> agent run -> turn -> operation.
|
|
112
|
+
|
|
113
|
+
Tempo is best used for:
|
|
114
|
+
|
|
115
|
+
- Session timeline
|
|
116
|
+
- Root cause analysis
|
|
117
|
+
- Latency breakdown
|
|
118
|
+
- Tool/LLM correlation
|
|
119
|
+
- Trace-to-log and trace-to-metric linking
|
|
120
|
+
|
|
121
|
+
### 2.5 Loki
|
|
122
|
+
|
|
123
|
+
Stores structured logs. Loki is best used for:
|
|
124
|
+
|
|
125
|
+
- Redacted prompt/response capture if enabled
|
|
126
|
+
- Tool arguments/results if enabled
|
|
127
|
+
- Error bodies
|
|
128
|
+
- Session audit event stream
|
|
129
|
+
- Searching historical sessions without local Pi logs
|
|
130
|
+
|
|
131
|
+
### 2.6 Prometheus / Mimir
|
|
132
|
+
|
|
133
|
+
Stores metrics. Used for:
|
|
134
|
+
|
|
135
|
+
- Cost dashboards
|
|
136
|
+
- Token dashboards
|
|
137
|
+
- Latency dashboards
|
|
138
|
+
- Alerting
|
|
139
|
+
- SLO monitoring
|
|
140
|
+
- Aggregation across agent roles/depths, projects, users, models, providers
|
|
141
|
+
|
|
142
|
+
## 3. Data Flow
|
|
143
|
+
|
|
144
|
+
### 3.1 Session Start
|
|
145
|
+
|
|
146
|
+
```text
|
|
147
|
+
Pi emits session_start
|
|
148
|
+
ObservMe creates root span pi.session
|
|
149
|
+
ObservMe emits log event session.started
|
|
150
|
+
ObservMe increments session counter
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### 3.2 Agent Run and Turn Start
|
|
154
|
+
|
|
155
|
+
```text
|
|
156
|
+
Pi emits agent_start
|
|
157
|
+
ObservMe creates child span pi.agent.run for the user prompt lifecycle
|
|
158
|
+
Pi emits turn_start for each LLM/tool iteration
|
|
159
|
+
ObservMe creates child span pi.turn under the active pi.agent.run
|
|
160
|
+
ObservMe records current model, cwd hash, session id, agent id, agent run id, turn id
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### 3.3 LLM Request
|
|
164
|
+
|
|
165
|
+
```text
|
|
166
|
+
Pi emits before_provider_request before the provider payload is sent
|
|
167
|
+
ObservMe creates a GenAI client span (`pi.llm.request` or official `chat <model>` naming)
|
|
168
|
+
Attributes: provider, model, api, estimated input, settings
|
|
169
|
+
Pi emits message_update/message_end for the assistant response
|
|
170
|
+
ObservMe ends the span and updates usage/cost metrics from the finalized assistant message
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 3.4 Tool Call
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
Pi emits tool_execution_start and tool_call before execution
|
|
177
|
+
ObservMe creates pi.tool.call span
|
|
178
|
+
Pi emits tool_result/tool_execution_end and later a toolResult message
|
|
179
|
+
ObservMe closes the span from tool result/execution-end data
|
|
180
|
+
Metrics update success/failure and latency
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 3.5 Subagent Spawn and Agent-Tree Flow
|
|
184
|
+
|
|
185
|
+
```text
|
|
186
|
+
A parent tool/extension decides to start another Pi agent
|
|
187
|
+
ObservMe creates pi.agent.spawn span with spawn id, workflow id, parent agent id, parent session id, tool call id
|
|
188
|
+
ObservMe propagates traceparent/tracestate, OBSERVME_WORKFLOW_ID, and OBSERVME_AGENT_* environment variables to the child
|
|
189
|
+
Child ObservMe runtime starts pi.session with pi.workflow.id, pi.agent.parent_id, and pi.agent.root_id
|
|
190
|
+
If the parent waits for the child, ObservMe records pi.agent.wait and/or pi.agent.join spans/events
|
|
191
|
+
Metrics increment subagent spawn, fan-out, depth, active-agent, wait/join, orphan, and propagation-failure counters/histograms; per-agent drill-down uses traces/logs, not metric labels
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
### 3.6 Compaction
|
|
195
|
+
|
|
196
|
+
```text
|
|
197
|
+
Pi emits session_compact with compactionEntry
|
|
198
|
+
ObservMe emits pi.compaction span/event/log
|
|
199
|
+
Metrics increment compaction counters and tokens_before histogram
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 3.7 Branching
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
Pi emits session_tree after tree navigation; summaryEntry is present when a branch summary was written
|
|
206
|
+
ObservMe emits pi.branch span/event/log
|
|
207
|
+
Metrics increment branch counters
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 3.8 Shutdown
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
Pi emits session_shutdown
|
|
214
|
+
ObservMe closes root span
|
|
215
|
+
Flushes OTEL SDK with timeout
|
|
216
|
+
No infinite blocking allowed
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## 4. Trace Shape
|
|
220
|
+
|
|
221
|
+
```text
|
|
222
|
+
pi.session
|
|
223
|
+
├── pi.agent.run 1
|
|
224
|
+
│ ├── pi.turn 1
|
|
225
|
+
│ │ ├── pi.llm.request
|
|
226
|
+
│ │ ├── pi.tool.call bash
|
|
227
|
+
│ │ ├── pi.tool.call read
|
|
228
|
+
│ │ └── event: llm.request.completed
|
|
229
|
+
│ └── pi.turn 2
|
|
230
|
+
│ ├── pi.llm.request
|
|
231
|
+
│ ├── pi.tool.call subagent
|
|
232
|
+
│ ├── pi.agent.spawn
|
|
233
|
+
│ ├── pi.agent.wait
|
|
234
|
+
│ └── pi.agent.join
|
|
235
|
+
├── pi.compaction
|
|
236
|
+
└── pi.branch
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## 5. Multi-Agent Operational Signals
|
|
240
|
+
|
|
241
|
+
For orchestrator workloads, operators should watch these signals closely:
|
|
242
|
+
|
|
243
|
+
| Signal | Why it matters | Primary telemetry |
|
|
244
|
+
|---|---|---|
|
|
245
|
+
| Fan-out per parent operation | Detects runaway delegation and cost amplification | `observme_agent_fanout_count`, `pi.agent.child.count` |
|
|
246
|
+
| Tree depth and width | Detects unexpectedly deep/large agent trees | `observme_agent_tree_depth`, `observme_agent_tree_width`, `subagent_depth` |
|
|
247
|
+
| Active agents | Detects stuck or leaked child agents | `observme_active_agents`, `pi.agent.children.active` |
|
|
248
|
+
| Orphan agents | Detects broken lineage propagation | `observme_orphan_agents_total`, `agent.orphaned` logs |
|
|
249
|
+
| Trace-context propagation failures | Detects fragmented traces | `observme_trace_context_propagation_failures_total`, span links/log fallback |
|
|
250
|
+
| Wait/join latency | Shows critical path and slow child results | `pi.agent.wait`, `pi.agent.join`, `observme_agent_wait_duration_ms`, `observme_agent_join_duration_ms` |
|
|
251
|
+
| Child-agent failures and recovery | Separates child failure from parent workflow failure | `observme_child_agent_failures_total`, `observme_parent_recovered_from_child_failure_total` |
|
|
252
|
+
| Cost by role/depth | Shows cost amplification without workflow IDs as labels | existing token/cost metrics labeled by `agent_role`, `agent_capability`, `subagent_depth`, provider, and model |
|
|
253
|
+
|
|
254
|
+
Per-workflow and per-agent drill-down should use Tempo/Loki attributes such as `pi.workflow.id`, `pi.agent.id`, `pi.agent.parent_id`, and trace/span IDs. These identifiers must not become Prometheus labels by default.
|
|
255
|
+
|
|
256
|
+
## 6. Deployment Topologies
|
|
257
|
+
|
|
258
|
+
### 5.1 Local Development
|
|
259
|
+
|
|
260
|
+
```text
|
|
261
|
+
Pi -> localhost:4318 -> Collector -> debug exporter
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Used for extension testing.
|
|
265
|
+
|
|
266
|
+
### 5.2 Developer Workstation with Shared Collector
|
|
267
|
+
|
|
268
|
+
```text
|
|
269
|
+
Pi -> regional collector DNS -> Grafana stack
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
Recommended when developers run Pi locally but telemetry must be centralized.
|
|
273
|
+
|
|
274
|
+
### 5.3 Ephemeral CI Agent
|
|
275
|
+
|
|
276
|
+
```text
|
|
277
|
+
CI Pi container -> sidecar collector -> central collector gateway -> Grafana stack
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Sidecar collector provides fast local handoff and retries while the job is alive.
|
|
281
|
+
|
|
282
|
+
### 5.4 Kubernetes
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
Pi pod -> daemonset collector -> gateway collector -> Tempo/Loki/Mimir
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Recommended for scale and centralized policy.
|
|
289
|
+
|
|
290
|
+
## 7. Failure Modes
|
|
291
|
+
|
|
292
|
+
| Failure | Expected Behavior |
|
|
293
|
+
|---|---|
|
|
294
|
+
| Collector unavailable | Drop after bounded retry; Pi continues |
|
|
295
|
+
| Backend unavailable | Collector buffers/retries if configured; Pi unaffected |
|
|
296
|
+
| Redaction failure | Drop sensitive field and emit redaction error metric |
|
|
297
|
+
| Span context lost | Emit orphan span with session id and agent id attributes |
|
|
298
|
+
| Subagent trace context not propagated | Emit child trace with `pi.agent.parent_id`, `pi.agent.root_id`, `pi.workflow.id`, and span/log link metadata; increment propagation failure counter |
|
|
299
|
+
| Orphan child agent | Mark as root or orphan according to config, emit `agent.orphaned` log, increment orphan counter |
|
|
300
|
+
| Runaway agent fan-out/depth | Continue exporting fail-open but emit high fan-out/depth metrics and alerts; never block Pi by default |
|
|
301
|
+
| Queue full | Drop telemetry and increment drop counter |
|
|
302
|
+
| Shutdown timeout | Abort flush after configured timeout |
|
|
303
|
+
|
|
304
|
+
## 8. Extension Boundary
|
|
305
|
+
|
|
306
|
+
ObservMe should not parse the full session file continuously during normal operation if Pi events provide the data. It may read session state on startup or command execution to reconstruct current session context, but runtime observability should be event-driven.
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Pi Event and Session Model for ObservMe
|
|
2
|
+
|
|
3
|
+
## 1. Purpose
|
|
4
|
+
|
|
5
|
+
This document defines how ObservMe interprets Pi events and session files. The Pi session file is not ObservMe storage. It is a canonical Pi execution record that ObservMe may use as an event source, correlation source, and recovery source.
|
|
6
|
+
|
|
7
|
+
## 2. Pi Session Entries Relevant to ObservMe
|
|
8
|
+
|
|
9
|
+
ObservMe must understand these entry types:
|
|
10
|
+
|
|
11
|
+
- `session`
|
|
12
|
+
- `message`
|
|
13
|
+
- `model_change`
|
|
14
|
+
- `thinking_level_change`
|
|
15
|
+
- `compaction`
|
|
16
|
+
- `branch_summary`
|
|
17
|
+
- `custom`
|
|
18
|
+
- `custom_message`
|
|
19
|
+
- `label`
|
|
20
|
+
- `session_info`
|
|
21
|
+
|
|
22
|
+
## 3. Message Roles and Entry Types Relevant to ObservMe
|
|
23
|
+
|
|
24
|
+
For real-time capture, ObservMe should prefer Pi extension events (`session_start`, `agent_start`, `agent_end`, `turn_start`, `before_provider_request`, `after_provider_response`, `message_*`, `tool_execution_*`, `tool_call`, `tool_result`, `user_bash`, `model_select`, `thinking_level_select`, `session_compact`, `session_tree`, and `session_shutdown`). Session entries are still authoritative for startup recovery, explicit backfill, `/obs session`, and cross-checking event payloads.
|
|
25
|
+
|
|
26
|
+
### `user`
|
|
27
|
+
|
|
28
|
+
Used to detect user turns and optionally capture redacted prompt content.
|
|
29
|
+
|
|
30
|
+
Default telemetry:
|
|
31
|
+
|
|
32
|
+
- role
|
|
33
|
+
- timestamp
|
|
34
|
+
- content length
|
|
35
|
+
- content hash
|
|
36
|
+
- image count if multimodal
|
|
37
|
+
|
|
38
|
+
Optional telemetry:
|
|
39
|
+
|
|
40
|
+
- prompt text
|
|
41
|
+
- image metadata
|
|
42
|
+
|
|
43
|
+
### `assistant`
|
|
44
|
+
|
|
45
|
+
Used to capture provider/model/usage/cost and tool calls.
|
|
46
|
+
|
|
47
|
+
Default telemetry:
|
|
48
|
+
|
|
49
|
+
- provider
|
|
50
|
+
- model
|
|
51
|
+
- api
|
|
52
|
+
- stopReason
|
|
53
|
+
- usage.input
|
|
54
|
+
- usage.output
|
|
55
|
+
- usage.cacheRead
|
|
56
|
+
- usage.cacheWrite
|
|
57
|
+
- usage.cacheWrite1h if reported by the provider
|
|
58
|
+
- usage.reasoning if reported by the provider
|
|
59
|
+
- usage.cost.total
|
|
60
|
+
- responseModel and responseId when available
|
|
61
|
+
- diagnostics count when present
|
|
62
|
+
- tool call count
|
|
63
|
+
- error class if present
|
|
64
|
+
|
|
65
|
+
Optional telemetry:
|
|
66
|
+
|
|
67
|
+
- response text
|
|
68
|
+
- thinking content
|
|
69
|
+
- tool call arguments
|
|
70
|
+
|
|
71
|
+
### `toolResult`
|
|
72
|
+
|
|
73
|
+
Used to close tool spans and emit tool metrics.
|
|
74
|
+
|
|
75
|
+
Default telemetry:
|
|
76
|
+
|
|
77
|
+
- toolCallId
|
|
78
|
+
- toolName
|
|
79
|
+
- isError
|
|
80
|
+
- content length
|
|
81
|
+
- content hash
|
|
82
|
+
|
|
83
|
+
Optional telemetry:
|
|
84
|
+
|
|
85
|
+
- tool result body
|
|
86
|
+
|
|
87
|
+
### `bashExecution`
|
|
88
|
+
|
|
89
|
+
Used for command execution observability.
|
|
90
|
+
|
|
91
|
+
Default telemetry:
|
|
92
|
+
|
|
93
|
+
- command fingerprint
|
|
94
|
+
- exitCode
|
|
95
|
+
- cancelled
|
|
96
|
+
- truncated
|
|
97
|
+
- duration if derivable from event timestamps
|
|
98
|
+
- output length
|
|
99
|
+
- fullOutputPath presence
|
|
100
|
+
|
|
101
|
+
Optional telemetry:
|
|
102
|
+
|
|
103
|
+
- command string
|
|
104
|
+
- output body
|
|
105
|
+
|
|
106
|
+
### `custom` entry
|
|
107
|
+
|
|
108
|
+
Extension state entry created through `pi.appendEntry()`. It does not participate in LLM context. ObservMe should append a custom entry only for explicitly enabled minimal correlation state; by default it should not append custom entries.
|
|
109
|
+
|
|
110
|
+
### `custom_message` entry
|
|
111
|
+
|
|
112
|
+
Extension-injected context entry created through `pi.sendMessage()`/`appendCustomMessageEntry()`. It participates in LLM context and can alter agent behavior. ObservMe must not use `custom_message` for telemetry bookkeeping.
|
|
113
|
+
|
|
114
|
+
## 4. Session Tree Implications
|
|
115
|
+
|
|
116
|
+
Pi sessions are tree-shaped via `id` and `parentId`. ObservMe telemetry must preserve this structure.
|
|
117
|
+
|
|
118
|
+
Required attributes:
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
pi.entry.id
|
|
122
|
+
pi.entry.parent_id
|
|
123
|
+
pi.entry.type
|
|
124
|
+
pi.branch.path_hash
|
|
125
|
+
pi.leaf.id
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Branch events must include:
|
|
129
|
+
|
|
130
|
+
```text
|
|
131
|
+
pi.branch.from_id
|
|
132
|
+
pi.branch.to_id
|
|
133
|
+
pi.branch.common_ancestor_id # if available
|
|
134
|
+
pi.branch.summary.hash
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
## 5. Context and Compaction
|
|
138
|
+
|
|
139
|
+
Compaction changes what the LLM sees, but it does not delete the historical session file. ObservMe should emit compaction telemetry from the `session_compact` event, which carries the saved `compactionEntry`, `reason`, `willRetry`, and whether the summary came from an extension.
|
|
140
|
+
|
|
141
|
+
Required fields:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
pi.compaction.first_kept_entry_id
|
|
145
|
+
pi.compaction.tokens_before
|
|
146
|
+
pi.compaction.summary.hash
|
|
147
|
+
pi.compaction.from_hook
|
|
148
|
+
pi.compaction.reason
|
|
149
|
+
pi.compaction.will_retry
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Optional fields:
|
|
153
|
+
|
|
154
|
+
```text
|
|
155
|
+
pi.compaction.read_files_count
|
|
156
|
+
pi.compaction.modified_files_count
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## 6. Event-to-Span Mapping
|
|
160
|
+
|
|
161
|
+
| Pi Source | ObservMe Operation |
|
|
162
|
+
|---|---|
|
|
163
|
+
| `session_start` | start `pi.session` span and initialize resource/session attributes |
|
|
164
|
+
| `agent_start` / `agent_end` | start/end a `pi.agent.run` span for one user-prompt lifecycle; turns are children of this span |
|
|
165
|
+
| `turn_start` / `turn_end` | start/end `pi.turn` span using `turnIndex` and finalized turn data |
|
|
166
|
+
| `before_provider_request` | start GenAI client span and record provider request metadata available from payload/`ctx.model` |
|
|
167
|
+
| `after_provider_response` | record provider HTTP status/headers that are safe to capture |
|
|
168
|
+
| `message_update` | optionally record streaming progress such as first-token/chunk timing |
|
|
169
|
+
| assistant `message_end` | record final model result, stop reason, usage, cost, and end GenAI span |
|
|
170
|
+
| assistant toolCall block from finalized message | prepare correlation for tool spans when needed |
|
|
171
|
+
| `tool_execution_start` | start `pi.tool.call` span before execution |
|
|
172
|
+
| `tool_call` | validate/record mutable tool input metadata and blocking outcome |
|
|
173
|
+
| `tool_result` / `tool_execution_end` | record result metadata and end `pi.tool.call` span |
|
|
174
|
+
| parent tool/extension launches another Pi agent | emit `pi.agent.spawn` span and propagate trace/workflow/agent lineage to the child |
|
|
175
|
+
| parent tool/extension waits for or receives child agent result | emit `pi.agent.wait` / `pi.agent.join` spans or events with child status and critical-path timing |
|
|
176
|
+
| `toolResult` message | cross-check persisted tool result order and content hashes |
|
|
177
|
+
| `user_bash` plus `bashExecution` session message | create or complete `pi.bash.execution` telemetry for `!`/`!!` commands |
|
|
178
|
+
| `model_select` plus `model_change` entry | emit model-change log event and metric |
|
|
179
|
+
| `thinking_level_select` plus `thinking_level_change` entry | emit thinking-level-change log event and metric |
|
|
180
|
+
| `session_compact` | emit compaction span/log/metric from `compactionEntry` |
|
|
181
|
+
| `session_tree` | emit branch/tree-navigation span/log/metric and include `summaryEntry` when present |
|
|
182
|
+
| `session_shutdown` | end open spans and flush exporters within timeout |
|
|
183
|
+
|
|
184
|
+
User-bash correlation is intentionally single-flight because Pi does not expose a durable call ID for `user_bash`. ObservMe starts the pending span at `user_bash`, retains only safe span/timing metadata, and completes it from the corresponding `bashExecution` record. Overlapping pre-events evict the ambiguous pending span and emit a bounded drop signal rather than risking a wrong match. An unmatched completion records duration only when it contains a valid start/completion timestamp pair; otherwise duration is omitted. Shutdown closes any pending user-bash span as incomplete. Raw commands and output remain subject to the shared opt-in content-capture policy.
|
|
185
|
+
|
|
186
|
+
The root `pi.session` span is intentionally long-lived and remains open until `session_shutdown`. During an active session, Tempo searches may show ended child spans before the root span is exported; post-shutdown traces must include the canonical `pi.session` root with the session and workflow attributes.
|
|
187
|
+
|
|
188
|
+
## 7. Correlation IDs
|
|
189
|
+
|
|
190
|
+
ObservMe must maintain the following IDs:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
observme.instance.id # unique per ObservMe telemetry session/process startup
|
|
194
|
+
observme.export.session_id # same as pi.session.id if available
|
|
195
|
+
pi.session.id
|
|
196
|
+
pi.workflow.id # generated workflow/root execution id, high-cardinality trace/log attribute
|
|
197
|
+
pi.workflow.root_agent_id
|
|
198
|
+
pi.agent.id # logical Pi agent runtime
|
|
199
|
+
pi.agent.parent_id # parent agent when this is a subagent
|
|
200
|
+
pi.agent.root_id # root agent in the lineage tree
|
|
201
|
+
pi.agent.run.id # one user-prompt lifecycle from agent_start to agent_end
|
|
202
|
+
pi.agent.spawn.id # individual subagent spawn operation if known
|
|
203
|
+
pi.entry.id
|
|
204
|
+
pi.turn.id
|
|
205
|
+
pi.tool_call.id
|
|
206
|
+
trace_id
|
|
207
|
+
span_id
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
## 8. Multi-Agent and Subagent Lineage
|
|
211
|
+
|
|
212
|
+
Pi's documented extension events identify sessions, agent prompt lifecycles, turns, tools, and session-tree changes. They do not provide a built-in cross-process subagent lineage event. Therefore ObservMe must create and propagate lineage when an extension/tool starts another Pi agent.
|
|
213
|
+
|
|
214
|
+
Required lineage behavior:
|
|
215
|
+
|
|
216
|
+
1. Generate `pi.agent.id` when the ObservMe runtime starts unless a trusted parent supplied one for a resumed child context.
|
|
217
|
+
2. Set `pi.agent.root_id = pi.agent.id` for root agents.
|
|
218
|
+
3. Generate `pi.workflow.id` in the root agent unless a trusted parent supplied one, and preserve it across every descendant.
|
|
219
|
+
4. For subagents, set `pi.agent.parent_id` to the parent `pi.agent.id`, preserve `pi.agent.root_id`, and increment `pi.agent.depth`.
|
|
220
|
+
5. Create a `pi.agent.spawn` span around the parent operation that launches the child process.
|
|
221
|
+
6. When the parent waits for or receives the child result, emit `pi.agent.wait` and/or `pi.agent.join` spans/events so critical-path latency is visible.
|
|
222
|
+
7. Propagate W3C `traceparent`/`tracestate` plus ObservMe lineage environment variables such as `OBSERVME_WORKFLOW_ID`, `OBSERVME_PARENT_AGENT_ID`, `OBSERVME_ROOT_AGENT_ID`, and `OBSERVME_PARENT_SESSION_ID`.
|
|
223
|
+
8. In the child, continue the trace when trace context is available; otherwise start a new trace and attach a span link or log event with parent trace/span metadata.
|
|
224
|
+
9. If a child starts with malformed or missing parent lineage, classify it as root or orphan according to config and emit an orphan log/metric.
|
|
225
|
+
|
|
226
|
+
Only lineage supplied in the child Pi process environment by an ObservMe-aware launcher is eligible for automatic continuation. Project-local `.env` values are configuration inputs and must not establish parent provenance. A propagated child candidate must carry a complete validated workflow/parent/root/depth/spawn envelope and, when trace propagation is enabled, a valid W3C `traceparent`; `tracestate` and duplicate parent trace/span metadata must also validate and agree when present. Partial, malformed, oversized, or stale envelopes fail open to a new root/orphan trace without exporting inherited raw values. Trusted lineage without usable W3C continuation starts a new trace with a validated parent span link when trace/span metadata is available, otherwise it emits the bounded `trace_context.propagation_failed` fallback signal.
|
|
227
|
+
|
|
228
|
+
Workflow IDs and agent IDs must be generated identifiers or salted hashes. Never derive them directly from raw cwd, username, prompt text, or command line. They are high-cardinality and must not be metric labels.
|
|
229
|
+
|
|
230
|
+
## 9. Turn Identification
|
|
231
|
+
|
|
232
|
+
Pi extension events provide `turnIndex`, not a durable session-file turn id. ObservMe should derive a stable-in-process turn id from `pi.session.id`, `pi.agent.run.id`, active branch/leaf context, and `turnIndex`. If a future Pi API provides a durable turn id, ObservMe must prefer it.
|
|
233
|
+
|
|
234
|
+
Derived format:
|
|
235
|
+
|
|
236
|
+
```text
|
|
237
|
+
agent-run-000001-turn-000001
|
|
238
|
+
agent-run-000001-turn-000002
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
The derived id must be scoped by session id and agent run id and must not be used as a metric label.
|
|
242
|
+
|
|
243
|
+
## 10. Recovery Behavior
|
|
244
|
+
|
|
245
|
+
On extension startup in an existing session:
|
|
246
|
+
|
|
247
|
+
1. Read current session header if available.
|
|
248
|
+
2. Set `pi.session.id`, `pi.workflow.id`, `pi.agent.id`, and resource attributes.
|
|
249
|
+
3. Reconstruct optional workflow/agent lineage only from trusted environment variables or an explicitly enabled minimal custom correlation entry.
|
|
250
|
+
4. Do not replay old telemetry by default.
|
|
251
|
+
5. Optionally support `replayOnStart: true` for backfill, but it must be off by default.
|
|
252
|
+
6. If replay is enabled, mark spans/logs with `observme.replayed=true`.
|
|
253
|
+
|
|
254
|
+
## 11. Local Session Reading Rules
|
|
255
|
+
|
|
256
|
+
Allowed:
|
|
257
|
+
|
|
258
|
+
- Read header on startup.
|
|
259
|
+
- Read current branch on `/obs session`.
|
|
260
|
+
- Read entries for explicit `/obs backfill` command.
|
|
261
|
+
|
|
262
|
+
Not allowed by default:
|
|
263
|
+
|
|
264
|
+
- Continuous tailing of session file when lifecycle events are sufficient.
|
|
265
|
+
- Storing parsed session data locally.
|
|
266
|
+
- Appending telemetry summaries into Pi context.
|