@pasko70/pibo 1.9.13 → 1.10.1

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 (163) hide show
  1. package/README.md +183 -183
  2. package/context/codex-base-prompt.md +148 -148
  3. package/context/compute-worker.md +23 -23
  4. package/context/pibo-compaction-prompt.md +100 -100
  5. package/context/pibo-native-tooling.md +18 -18
  6. package/context/pibo-system-prompt.md +77 -77
  7. package/dist/apps/chat/agent-profiles.js +2 -2
  8. package/dist/apps/chat/agent-store.js +263 -250
  9. package/dist/apps/chat/chat-request-normalizers.js +17 -0
  10. package/dist/apps/chat/data/chat-data-mappers.js +2 -0
  11. package/dist/apps/chat/data/project-service.js +168 -168
  12. package/dist/apps/chat/data/read-state-service.js +18 -18
  13. package/dist/apps/chat/data/session-query-service.js +25 -25
  14. package/dist/apps/chat/data/timeline-query-service.js +19 -19
  15. package/dist/apps/chat/loop-api.js +181 -0
  16. package/dist/apps/chat/static-assets.js +854 -854
  17. package/dist/apps/chat/web-app.js +36 -16
  18. package/dist/apps/chat/workflow-manual-trigger-runtime.js +149 -46
  19. package/dist/apps/chat/workflow-persistence.js +255 -255
  20. package/dist/apps/chat-ui/assets/{dist-BZ2eTC4f.js → dist-3Sts0Afa.js} +1 -1
  21. package/dist/apps/chat-ui/assets/{dist-BHa-kcGl.js → dist-4NlLjLs7.js} +1 -1
  22. package/dist/apps/chat-ui/assets/{dist-yCYNNb5d.js → dist-BA6mhAec.js} +1 -1
  23. package/dist/apps/chat-ui/assets/{dist-D811wJeV.js → dist-BPl-fzRB.js} +1 -1
  24. package/dist/apps/chat-ui/assets/{dist-Dq4GxJi3.js → dist-BPnn9e2B.js} +1 -1
  25. package/dist/apps/chat-ui/assets/{dist-CzE6k3F3.js → dist-BpfBSMzK.js} +1 -1
  26. package/dist/apps/chat-ui/assets/{dist-CnVsqwSG.js → dist-Cvx5M97R.js} +1 -1
  27. package/dist/apps/chat-ui/assets/{dist-WyXdYl-w.js → dist-DnXWNQRm.js} +1 -1
  28. package/dist/apps/chat-ui/assets/{dist-BNMu92bb.js → dist-hU-2oAb6.js} +1 -1
  29. package/dist/apps/chat-ui/assets/{dist-BCB6zezO.js → dist-r31x5Fcc.js} +1 -1
  30. package/dist/apps/chat-ui/assets/{dist-HqTN67dc.js → dist-uF6UXzI7.js} +1 -1
  31. package/dist/apps/chat-ui/assets/index-CaTGYBOS.js +173 -0
  32. package/dist/apps/chat-ui/assets/{index-C0x9nEcf.css → index-al8DeEjA.css} +1 -1
  33. package/dist/apps/chat-ui/index.html +18 -18
  34. package/dist/apps/chat-ui/manifest.webmanifest +25 -25
  35. package/dist/apps/chat-ui/sw.js +47 -47
  36. package/dist/apps/chat-vscode-web/assets/index-CK4SMZuu.js +41 -0
  37. package/dist/apps/chat-vscode-web/index.html +13 -13
  38. package/dist/apps/cli-ui/cliSessionsCommand.js +23 -23
  39. package/dist/apps/context-files-ui/index.html +11 -11
  40. package/dist/cli-session/localSessionSource.js +34 -12
  41. package/dist/cli.js +61 -44
  42. package/dist/compute/cli.js +54 -54
  43. package/dist/compute/resource-health.js +35 -2
  44. package/dist/core/events.js +6 -1
  45. package/dist/core/routed-session.js +97 -5
  46. package/dist/core/runtime.js +6 -1
  47. package/dist/core/session-router.js +27 -8
  48. package/dist/cron/cli.js +15 -15
  49. package/dist/cron/store.js +49 -49
  50. package/dist/data/cli.js +23 -23
  51. package/dist/data/event-log.js +23 -23
  52. package/dist/data/ingest-service.js +3 -1
  53. package/dist/data/message-store.js +27 -27
  54. package/dist/data/navigation-store.js +9 -9
  55. package/dist/data/observation-store.js +4 -4
  56. package/dist/data/payload-store.js +17 -17
  57. package/dist/data/schema.js +433 -433
  58. package/dist/data/session-store.js +4 -4
  59. package/dist/data/telemetry-queries.js +54 -54
  60. package/dist/data/telemetry.js +197 -197
  61. package/dist/debug/events.js +12 -12
  62. package/dist/debug/failures.js +6 -6
  63. package/dist/debug/index.js +231 -227
  64. package/dist/debug/messages.js +6 -6
  65. package/dist/debug/pty.js +124 -124
  66. package/dist/debug/session.js +29 -29
  67. package/dist/debug/tools.js +5 -5
  68. package/dist/debug/trace.js +42 -7
  69. package/dist/debug/web-snapshot-browser-scripts.js +294 -294
  70. package/dist/debug/web-streaming-browser-library.js +925 -925
  71. package/dist/debug/web-streaming-browser-scripts.js +232 -232
  72. package/dist/debug/web-streaming-provider-telemetry.js +4 -4
  73. package/dist/debug/web.js +93 -93
  74. package/dist/gateway/cli.js +19 -19
  75. package/dist/gateway/server.js +4 -2
  76. package/dist/gateway/web.js +2 -2
  77. package/dist/index.js +1 -0
  78. package/dist/loops/accounting.js +19 -0
  79. package/dist/loops/channel.js +8 -0
  80. package/dist/loops/cli.js +224 -0
  81. package/dist/loops/plugin.js +16 -0
  82. package/dist/loops/prompts.js +86 -0
  83. package/dist/loops/service.js +446 -0
  84. package/dist/loops/stopping.js +170 -0
  85. package/dist/loops/store.js +642 -0
  86. package/dist/loops/templates.js +232 -0
  87. package/dist/loops/tools.js +184 -0
  88. package/dist/loops/types.js +1 -0
  89. package/dist/mcp/config-command.js +53 -53
  90. package/dist/mcp/index.js +21 -21
  91. package/dist/mcp/registry.js +11 -11
  92. package/dist/pi-packages/cli.js +11 -11
  93. package/dist/plugins/builtin.js +8 -0
  94. package/dist/plugins/context-files-store.js +110 -110
  95. package/dist/plugins/context-files.js +4 -4
  96. package/dist/plugins/registry.js +23 -12
  97. package/dist/ralph/cli.js +18 -18
  98. package/dist/ralph/templates.js +140 -140
  99. package/dist/reliability/store.js +256 -229
  100. package/dist/runs/lifecycle.js +59 -0
  101. package/dist/runs/registry.js +47 -1
  102. package/dist/runs/tools.js +31 -13
  103. package/dist/session-ui/terminalRows.js +66 -2
  104. package/dist/sessions/pibo-data-store.js +16 -16
  105. package/dist/sessions/sqlite-store.js +53 -53
  106. package/dist/setup/cli.js +58 -58
  107. package/dist/shared/trace-async-agent-runs.js +4 -4
  108. package/dist/shared/trace-event-projection.js +59 -19
  109. package/dist/shared/trace-nodes.js +5 -0
  110. package/dist/shared/trace-page-merge.js +15 -0
  111. package/dist/shared/trace-run-notifications.js +3 -1
  112. package/dist/signals/projector.js +6 -2
  113. package/dist/tools/agent-browser-wrapper.js +80 -80
  114. package/dist/tools/browser-pool.js +50 -0
  115. package/dist/tools/browser-use-cdp.js +12 -12
  116. package/dist/tools/browser-use-leases.js +12 -8
  117. package/dist/tools/browser-use-wrapper.js +762 -762
  118. package/dist/tools/guides.js +596 -538
  119. package/dist/tools/index.js +123 -99
  120. package/dist/tools/registry.js +21 -3
  121. package/dist/tools/runtime/node-worker-source.js +205 -205
  122. package/dist/tools/runtime/python-worker-source.js +177 -177
  123. package/dist/vscode/cli.js +9 -9
  124. package/dist/web-annotations/cdp.js +900 -900
  125. package/dist/web-annotations/store.js +96 -96
  126. package/docs/README.md +23 -23
  127. package/docs/ops/install-developer-host.md +112 -112
  128. package/docs/ops/install-user-host.md +96 -96
  129. package/docs/ops/upgrade-user-to-developer-host.md +69 -69
  130. package/docs/ops/vscode-extension-release.md +160 -160
  131. package/package.json +99 -95
  132. package/skills/builtin/graphify/SKILL.md +52 -52
  133. package/skills/builtin/loop/SKILL.md +78 -0
  134. package/skills/builtin/pi-agent-harness/SKILL.md +319 -319
  135. package/skills/builtin/pi-agent-harness/agents/openai.yaml +4 -4
  136. package/skills/builtin/pibo-docker-system/SKILL.md +170 -170
  137. package/skills/builtin/pibo-spec-writing/SKILL.md +330 -330
  138. package/skills/builtin/prd/SKILL.md +143 -143
  139. package/skills/builtin/ralph-loop/SKILL.md +361 -359
  140. package/skills/builtin/ralph-prd-json/SKILL.md +123 -123
  141. package/skills/builtin/skill-creator/LICENSE.txt +201 -201
  142. package/skills/builtin/skill-creator/SKILL.md +513 -513
  143. package/skills/builtin/skill-creator/agents/analyzer.md +274 -274
  144. package/skills/builtin/skill-creator/agents/comparator.md +202 -202
  145. package/skills/builtin/skill-creator/agents/grader.md +223 -223
  146. package/skills/builtin/skill-creator/assets/eval_review.html +146 -146
  147. package/skills/builtin/skill-creator/eval-viewer/generate_review.py +471 -471
  148. package/skills/builtin/skill-creator/eval-viewer/viewer.html +1325 -1325
  149. package/skills/builtin/skill-creator/references/schemas.md +430 -430
  150. package/skills/builtin/skill-creator/scripts/aggregate_benchmark.py +401 -401
  151. package/skills/builtin/skill-creator/scripts/generate_report.py +326 -326
  152. package/skills/builtin/skill-creator/scripts/improve_description.py +247 -247
  153. package/skills/builtin/skill-creator/scripts/package_skill.py +136 -136
  154. package/skills/builtin/skill-creator/scripts/quick_validate.py +102 -102
  155. package/skills/builtin/skill-creator/scripts/run_eval.py +310 -310
  156. package/skills/builtin/skill-creator/scripts/run_loop.py +328 -328
  157. package/skills/builtin/skill-creator/scripts/utils.py +47 -47
  158. package/skills/builtin/web-annotations/SKILL.md +93 -93
  159. package/src/mcp/LICENSE.mcp-cli +21 -21
  160. package/dist/apps/chat-ui/assets/index-DwHJfmiF.js +0 -173
  161. package/dist/apps/chat-vscode-web/assets/index-BAMxIaI_.js +0 -41
  162. package/dist/apps/vscode-artifacts/latest.vsix +0 -0
  163. package/dist/apps/vscode-artifacts/pibo-vscode-ext-1.9.13.vsix +0 -0
@@ -32,11 +32,11 @@ export class TelemetryStore {
32
32
  return getTelemetryTurnTimeline(this.db, turnIdOrEventId, input);
33
33
  }
34
34
  getOpenPhaseForTurn(turnId, name) {
35
- const row = this.db.prepare(`
36
- SELECT * FROM telemetry_phases
37
- WHERE turn_id = ? AND name = ? AND status = 'open'
38
- ORDER BY COALESCE(last_progress_at, started_at) DESC, created_at DESC
39
- LIMIT 1
35
+ const row = this.db.prepare(`
36
+ SELECT * FROM telemetry_phases
37
+ WHERE turn_id = ? AND name = ? AND status = 'open'
38
+ ORDER BY COALESCE(last_progress_at, started_at) DESC, created_at DESC
39
+ LIMIT 1
40
40
  `).get(turnId, name);
41
41
  return row ? phaseFromRow(row) : undefined;
42
42
  }
@@ -45,44 +45,44 @@ export class TelemetryStore {
45
45
  return Number(row.count);
46
46
  }
47
47
  listOpenPhasesForTurn(turnId) {
48
- const rows = this.db.prepare(`
49
- SELECT * FROM telemetry_phases
50
- WHERE turn_id = ? AND status = 'open'
51
- ORDER BY started_at ASC, created_at ASC
48
+ const rows = this.db.prepare(`
49
+ SELECT * FROM telemetry_phases
50
+ WHERE turn_id = ? AND status = 'open'
51
+ ORDER BY started_at ASC, created_at ASC
52
52
  `).all(turnId);
53
53
  return rows.map(phaseFromRow);
54
54
  }
55
55
  getLatestProviderRequestForTurn(turnId) {
56
- const row = this.db.prepare(`
57
- SELECT * FROM telemetry_provider_requests
58
- WHERE turn_id = ?
59
- ORDER BY started_at DESC, created_at DESC
60
- LIMIT 1
56
+ const row = this.db.prepare(`
57
+ SELECT * FROM telemetry_provider_requests
58
+ WHERE turn_id = ?
59
+ ORDER BY started_at DESC, created_at DESC
60
+ LIMIT 1
61
61
  `).get(turnId);
62
62
  return row ? providerRequestFromRow(row) : undefined;
63
63
  }
64
64
  getActiveProviderRequestForTurn(turnId) {
65
- const row = this.db.prepare(`
66
- SELECT * FROM telemetry_provider_requests
67
- WHERE turn_id = ? AND status NOT IN ('completed', 'error', 'aborted', 'timeout')
68
- ORDER BY started_at DESC, created_at DESC
69
- LIMIT 1
65
+ const row = this.db.prepare(`
66
+ SELECT * FROM telemetry_provider_requests
67
+ WHERE turn_id = ? AND status NOT IN ('completed', 'error', 'aborted', 'timeout')
68
+ ORDER BY started_at DESC, created_at DESC
69
+ LIMIT 1
70
70
  `).get(turnId);
71
71
  return row ? providerRequestFromRow(row) : undefined;
72
72
  }
73
73
  listActiveProviderRequestsForTurn(turnId) {
74
- const rows = this.db.prepare(`
75
- SELECT * FROM telemetry_provider_requests
76
- WHERE turn_id = ? AND status NOT IN ('completed', 'error', 'aborted', 'timeout')
77
- ORDER BY started_at ASC, created_at ASC
74
+ const rows = this.db.prepare(`
75
+ SELECT * FROM telemetry_provider_requests
76
+ WHERE turn_id = ? AND status NOT IN ('completed', 'error', 'aborted', 'timeout')
77
+ ORDER BY started_at ASC, created_at ASC
78
78
  `).all(turnId);
79
79
  return rows.map(providerRequestFromRow);
80
80
  }
81
81
  listActiveToolCallsForTurn(turnId) {
82
- const rows = this.db.prepare(`
83
- SELECT * FROM telemetry_tool_calls
84
- WHERE turn_id = ? AND status NOT IN ('ok', 'error', 'aborted', 'timeout')
85
- ORDER BY created_at ASC
82
+ const rows = this.db.prepare(`
83
+ SELECT * FROM telemetry_tool_calls
84
+ WHERE turn_id = ? AND status NOT IN ('ok', 'error', 'aborted', 'timeout')
85
+ ORDER BY created_at ASC
86
86
  `).all(turnId);
87
87
  return rows.map(toolCallFromRow);
88
88
  }
@@ -103,33 +103,33 @@ export class TelemetryStore {
103
103
  const turnId = input.turnId ?? `turn_${randomUUID()}`;
104
104
  const existing = input.turnId ? this.getTurn(input.turnId) : undefined;
105
105
  const queuedAt = input.queuedAt ?? existing?.queuedAt ?? now;
106
- this.db.prepare(`
107
- INSERT INTO telemetry_turns (
108
- turn_id, pibo_session_id, root_session_id, room_id, input_event_id, event_id, event_stream_id,
109
- payload_ref, run_id, source, status, current_phase, queued_at, started_at, completed_at,
110
- last_progress_at, queued_behind, queue_depth, summary, retention_class, created_at, updated_at, metadata_json
111
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
112
- ON CONFLICT(turn_id) DO UPDATE SET
113
- pibo_session_id = excluded.pibo_session_id,
114
- root_session_id = COALESCE(excluded.root_session_id, telemetry_turns.root_session_id),
115
- room_id = COALESCE(excluded.room_id, telemetry_turns.room_id),
116
- input_event_id = COALESCE(excluded.input_event_id, telemetry_turns.input_event_id),
117
- event_id = COALESCE(excluded.event_id, telemetry_turns.event_id),
118
- event_stream_id = COALESCE(excluded.event_stream_id, telemetry_turns.event_stream_id),
119
- payload_ref = COALESCE(excluded.payload_ref, telemetry_turns.payload_ref),
120
- run_id = COALESCE(excluded.run_id, telemetry_turns.run_id),
121
- source = excluded.source,
122
- status = excluded.status,
123
- current_phase = COALESCE(excluded.current_phase, telemetry_turns.current_phase),
124
- started_at = COALESCE(excluded.started_at, telemetry_turns.started_at),
125
- completed_at = COALESCE(excluded.completed_at, telemetry_turns.completed_at),
126
- last_progress_at = COALESCE(excluded.last_progress_at, telemetry_turns.last_progress_at),
127
- queued_behind = COALESCE(excluded.queued_behind, telemetry_turns.queued_behind),
128
- queue_depth = COALESCE(excluded.queue_depth, telemetry_turns.queue_depth),
129
- summary = COALESCE(excluded.summary, telemetry_turns.summary),
130
- retention_class = excluded.retention_class,
131
- updated_at = excluded.updated_at,
132
- metadata_json = COALESCE(excluded.metadata_json, telemetry_turns.metadata_json)
106
+ this.db.prepare(`
107
+ INSERT INTO telemetry_turns (
108
+ turn_id, pibo_session_id, root_session_id, room_id, input_event_id, event_id, event_stream_id,
109
+ payload_ref, run_id, source, status, current_phase, queued_at, started_at, completed_at,
110
+ last_progress_at, queued_behind, queue_depth, summary, retention_class, created_at, updated_at, metadata_json
111
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
112
+ ON CONFLICT(turn_id) DO UPDATE SET
113
+ pibo_session_id = excluded.pibo_session_id,
114
+ root_session_id = COALESCE(excluded.root_session_id, telemetry_turns.root_session_id),
115
+ room_id = COALESCE(excluded.room_id, telemetry_turns.room_id),
116
+ input_event_id = COALESCE(excluded.input_event_id, telemetry_turns.input_event_id),
117
+ event_id = COALESCE(excluded.event_id, telemetry_turns.event_id),
118
+ event_stream_id = COALESCE(excluded.event_stream_id, telemetry_turns.event_stream_id),
119
+ payload_ref = COALESCE(excluded.payload_ref, telemetry_turns.payload_ref),
120
+ run_id = COALESCE(excluded.run_id, telemetry_turns.run_id),
121
+ source = excluded.source,
122
+ status = excluded.status,
123
+ current_phase = COALESCE(excluded.current_phase, telemetry_turns.current_phase),
124
+ started_at = COALESCE(excluded.started_at, telemetry_turns.started_at),
125
+ completed_at = COALESCE(excluded.completed_at, telemetry_turns.completed_at),
126
+ last_progress_at = COALESCE(excluded.last_progress_at, telemetry_turns.last_progress_at),
127
+ queued_behind = COALESCE(excluded.queued_behind, telemetry_turns.queued_behind),
128
+ queue_depth = COALESCE(excluded.queue_depth, telemetry_turns.queue_depth),
129
+ summary = COALESCE(excluded.summary, telemetry_turns.summary),
130
+ retention_class = excluded.retention_class,
131
+ updated_at = excluded.updated_at,
132
+ metadata_json = COALESCE(excluded.metadata_json, telemetry_turns.metadata_json)
133
133
  `).run(turnId, input.piboSessionId, input.rootSessionId ?? null, input.roomId ?? null, input.inputEventId ?? null, input.eventId ?? null, input.eventStreamId ?? null, input.payloadRef ?? null, input.runId ?? null, input.source ?? existing?.source ?? "user", input.status ?? existing?.status ?? "queued", input.currentPhase ?? null, queuedAt, input.startedAt ?? null, input.completedAt ?? null, input.lastProgressAt ?? null, input.queuedBehind ?? null, input.queueDepth ?? null, input.summary ?? null, input.retentionClass ?? existing?.retentionClass ?? "diagnostic", input.createdAt ?? existing?.createdAt ?? now, now, JSON.stringify(input.metadata ?? existing?.metadata ?? {}));
134
134
  return this.getTurn(turnId) ?? fail(`Failed to upsert telemetry turn ${turnId}`);
135
135
  }
@@ -138,32 +138,32 @@ export class TelemetryStore {
138
138
  const phaseId = input.phaseId ?? `phase_${randomUUID()}`;
139
139
  const existing = input.phaseId ? this.getPhase(input.phaseId) : undefined;
140
140
  const startedAt = input.startedAt ?? existing?.startedAt ?? now;
141
- this.db.prepare(`
142
- INSERT INTO telemetry_phases (
143
- phase_id, turn_id, pibo_session_id, root_session_id, room_id, name, status, started_at, ended_at,
144
- last_progress_at, duration_ms, provider_request_id, tool_call_id, event_stream_id, event_id,
145
- payload_ref, run_id, counters_json, summary, retention_class, created_at, updated_at
146
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
147
- ON CONFLICT(phase_id) DO UPDATE SET
148
- turn_id = excluded.turn_id,
149
- pibo_session_id = excluded.pibo_session_id,
150
- root_session_id = COALESCE(excluded.root_session_id, telemetry_phases.root_session_id),
151
- room_id = COALESCE(excluded.room_id, telemetry_phases.room_id),
152
- name = excluded.name,
153
- status = excluded.status,
154
- ended_at = COALESCE(excluded.ended_at, telemetry_phases.ended_at),
155
- last_progress_at = COALESCE(excluded.last_progress_at, telemetry_phases.last_progress_at),
156
- duration_ms = COALESCE(excluded.duration_ms, telemetry_phases.duration_ms),
157
- provider_request_id = COALESCE(excluded.provider_request_id, telemetry_phases.provider_request_id),
158
- tool_call_id = COALESCE(excluded.tool_call_id, telemetry_phases.tool_call_id),
159
- event_stream_id = COALESCE(excluded.event_stream_id, telemetry_phases.event_stream_id),
160
- event_id = COALESCE(excluded.event_id, telemetry_phases.event_id),
161
- payload_ref = COALESCE(excluded.payload_ref, telemetry_phases.payload_ref),
162
- run_id = COALESCE(excluded.run_id, telemetry_phases.run_id),
163
- counters_json = COALESCE(excluded.counters_json, telemetry_phases.counters_json),
164
- summary = COALESCE(excluded.summary, telemetry_phases.summary),
165
- retention_class = excluded.retention_class,
166
- updated_at = excluded.updated_at
141
+ this.db.prepare(`
142
+ INSERT INTO telemetry_phases (
143
+ phase_id, turn_id, pibo_session_id, root_session_id, room_id, name, status, started_at, ended_at,
144
+ last_progress_at, duration_ms, provider_request_id, tool_call_id, event_stream_id, event_id,
145
+ payload_ref, run_id, counters_json, summary, retention_class, created_at, updated_at
146
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
147
+ ON CONFLICT(phase_id) DO UPDATE SET
148
+ turn_id = excluded.turn_id,
149
+ pibo_session_id = excluded.pibo_session_id,
150
+ root_session_id = COALESCE(excluded.root_session_id, telemetry_phases.root_session_id),
151
+ room_id = COALESCE(excluded.room_id, telemetry_phases.room_id),
152
+ name = excluded.name,
153
+ status = excluded.status,
154
+ ended_at = COALESCE(excluded.ended_at, telemetry_phases.ended_at),
155
+ last_progress_at = COALESCE(excluded.last_progress_at, telemetry_phases.last_progress_at),
156
+ duration_ms = COALESCE(excluded.duration_ms, telemetry_phases.duration_ms),
157
+ provider_request_id = COALESCE(excluded.provider_request_id, telemetry_phases.provider_request_id),
158
+ tool_call_id = COALESCE(excluded.tool_call_id, telemetry_phases.tool_call_id),
159
+ event_stream_id = COALESCE(excluded.event_stream_id, telemetry_phases.event_stream_id),
160
+ event_id = COALESCE(excluded.event_id, telemetry_phases.event_id),
161
+ payload_ref = COALESCE(excluded.payload_ref, telemetry_phases.payload_ref),
162
+ run_id = COALESCE(excluded.run_id, telemetry_phases.run_id),
163
+ counters_json = COALESCE(excluded.counters_json, telemetry_phases.counters_json),
164
+ summary = COALESCE(excluded.summary, telemetry_phases.summary),
165
+ retention_class = excluded.retention_class,
166
+ updated_at = excluded.updated_at
167
167
  `).run(phaseId, input.turnId, input.piboSessionId, input.rootSessionId ?? null, input.roomId ?? null, input.name, input.status ?? existing?.status ?? "open", startedAt, input.endedAt ?? null, input.lastProgressAt ?? null, input.durationMs ?? null, input.providerRequestId ?? null, input.toolCallId ?? null, input.eventStreamId ?? null, input.eventId ?? null, input.payloadRef ?? null, input.runId ?? null, JSON.stringify(input.counters ?? existing?.counters ?? {}), input.summary ?? null, input.retentionClass ?? existing?.retentionClass ?? "diagnostic", input.createdAt ?? existing?.createdAt ?? now, now);
168
168
  return this.getPhase(phaseId) ?? fail(`Failed to upsert telemetry phase ${phaseId}`);
169
169
  }
@@ -192,48 +192,48 @@ export class TelemetryStore {
192
192
  const providerRequestId = input.providerRequestId ?? `pr_${randomUUID()}`;
193
193
  const existing = input.providerRequestId ? this.getProviderRequest(input.providerRequestId) : undefined;
194
194
  const startedAt = input.startedAt ?? existing?.startedAt ?? now;
195
- this.db.prepare(`
196
- INSERT INTO telemetry_provider_requests (
197
- provider_request_id, pibo_session_id, root_session_id, room_id, turn_id, phase_id, provider, api, model,
198
- transport, service_tier, status, started_at, response_headers_at, first_byte_at, last_raw_event_at,
199
- last_normalized_event_at, completed_at, http_status, upstream_response_id, raw_event_count,
200
- normalized_event_count, parse_error_count, unknown_event_count, bytes_received, event_type_counts_json,
201
- event_stream_id, event_id, payload_ref, error_category, error_message, capture_mode, retention_class,
202
- created_at, updated_at
203
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
204
- ON CONFLICT(provider_request_id) DO UPDATE SET
205
- pibo_session_id = excluded.pibo_session_id,
206
- root_session_id = COALESCE(excluded.root_session_id, telemetry_provider_requests.root_session_id),
207
- room_id = COALESCE(excluded.room_id, telemetry_provider_requests.room_id),
208
- turn_id = excluded.turn_id,
209
- phase_id = COALESCE(excluded.phase_id, telemetry_provider_requests.phase_id),
210
- provider = excluded.provider,
211
- api = excluded.api,
212
- model = excluded.model,
213
- transport = excluded.transport,
214
- service_tier = COALESCE(excluded.service_tier, telemetry_provider_requests.service_tier),
215
- status = excluded.status,
216
- response_headers_at = COALESCE(excluded.response_headers_at, telemetry_provider_requests.response_headers_at),
217
- first_byte_at = COALESCE(excluded.first_byte_at, telemetry_provider_requests.first_byte_at),
218
- last_raw_event_at = COALESCE(excluded.last_raw_event_at, telemetry_provider_requests.last_raw_event_at),
219
- last_normalized_event_at = COALESCE(excluded.last_normalized_event_at, telemetry_provider_requests.last_normalized_event_at),
220
- completed_at = COALESCE(excluded.completed_at, telemetry_provider_requests.completed_at),
221
- http_status = COALESCE(excluded.http_status, telemetry_provider_requests.http_status),
222
- upstream_response_id = COALESCE(excluded.upstream_response_id, telemetry_provider_requests.upstream_response_id),
223
- raw_event_count = excluded.raw_event_count,
224
- normalized_event_count = excluded.normalized_event_count,
225
- parse_error_count = excluded.parse_error_count,
226
- unknown_event_count = excluded.unknown_event_count,
227
- bytes_received = COALESCE(excluded.bytes_received, telemetry_provider_requests.bytes_received),
228
- event_type_counts_json = excluded.event_type_counts_json,
229
- event_stream_id = COALESCE(excluded.event_stream_id, telemetry_provider_requests.event_stream_id),
230
- event_id = COALESCE(excluded.event_id, telemetry_provider_requests.event_id),
231
- payload_ref = COALESCE(excluded.payload_ref, telemetry_provider_requests.payload_ref),
232
- error_category = COALESCE(excluded.error_category, telemetry_provider_requests.error_category),
233
- error_message = COALESCE(excluded.error_message, telemetry_provider_requests.error_message),
234
- capture_mode = excluded.capture_mode,
235
- retention_class = excluded.retention_class,
236
- updated_at = excluded.updated_at
195
+ this.db.prepare(`
196
+ INSERT INTO telemetry_provider_requests (
197
+ provider_request_id, pibo_session_id, root_session_id, room_id, turn_id, phase_id, provider, api, model,
198
+ transport, service_tier, status, started_at, response_headers_at, first_byte_at, last_raw_event_at,
199
+ last_normalized_event_at, completed_at, http_status, upstream_response_id, raw_event_count,
200
+ normalized_event_count, parse_error_count, unknown_event_count, bytes_received, event_type_counts_json,
201
+ event_stream_id, event_id, payload_ref, error_category, error_message, capture_mode, retention_class,
202
+ created_at, updated_at
203
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
204
+ ON CONFLICT(provider_request_id) DO UPDATE SET
205
+ pibo_session_id = excluded.pibo_session_id,
206
+ root_session_id = COALESCE(excluded.root_session_id, telemetry_provider_requests.root_session_id),
207
+ room_id = COALESCE(excluded.room_id, telemetry_provider_requests.room_id),
208
+ turn_id = excluded.turn_id,
209
+ phase_id = COALESCE(excluded.phase_id, telemetry_provider_requests.phase_id),
210
+ provider = excluded.provider,
211
+ api = excluded.api,
212
+ model = excluded.model,
213
+ transport = excluded.transport,
214
+ service_tier = COALESCE(excluded.service_tier, telemetry_provider_requests.service_tier),
215
+ status = excluded.status,
216
+ response_headers_at = COALESCE(excluded.response_headers_at, telemetry_provider_requests.response_headers_at),
217
+ first_byte_at = COALESCE(excluded.first_byte_at, telemetry_provider_requests.first_byte_at),
218
+ last_raw_event_at = COALESCE(excluded.last_raw_event_at, telemetry_provider_requests.last_raw_event_at),
219
+ last_normalized_event_at = COALESCE(excluded.last_normalized_event_at, telemetry_provider_requests.last_normalized_event_at),
220
+ completed_at = COALESCE(excluded.completed_at, telemetry_provider_requests.completed_at),
221
+ http_status = COALESCE(excluded.http_status, telemetry_provider_requests.http_status),
222
+ upstream_response_id = COALESCE(excluded.upstream_response_id, telemetry_provider_requests.upstream_response_id),
223
+ raw_event_count = excluded.raw_event_count,
224
+ normalized_event_count = excluded.normalized_event_count,
225
+ parse_error_count = excluded.parse_error_count,
226
+ unknown_event_count = excluded.unknown_event_count,
227
+ bytes_received = COALESCE(excluded.bytes_received, telemetry_provider_requests.bytes_received),
228
+ event_type_counts_json = excluded.event_type_counts_json,
229
+ event_stream_id = COALESCE(excluded.event_stream_id, telemetry_provider_requests.event_stream_id),
230
+ event_id = COALESCE(excluded.event_id, telemetry_provider_requests.event_id),
231
+ payload_ref = COALESCE(excluded.payload_ref, telemetry_provider_requests.payload_ref),
232
+ error_category = COALESCE(excluded.error_category, telemetry_provider_requests.error_category),
233
+ error_message = COALESCE(excluded.error_message, telemetry_provider_requests.error_message),
234
+ capture_mode = excluded.capture_mode,
235
+ retention_class = excluded.retention_class,
236
+ updated_at = excluded.updated_at
237
237
  `).run(providerRequestId, input.piboSessionId, input.rootSessionId ?? null, input.roomId ?? null, input.turnId, input.phaseId ?? null, input.provider, input.api, input.model, input.transport ?? existing?.transport ?? "unknown", input.serviceTier ?? null, input.status ?? existing?.status ?? "started", startedAt, input.responseHeadersAt ?? null, input.firstByteAt ?? null, input.lastRawEventAt ?? null, input.lastNormalizedEventAt ?? null, input.completedAt ?? null, input.httpStatus ?? null, input.upstreamResponseId ?? null, input.rawEventCount ?? existing?.rawEventCount ?? 0, input.normalizedEventCount ?? existing?.normalizedEventCount ?? 0, input.parseErrorCount ?? existing?.parseErrorCount ?? 0, input.unknownEventCount ?? existing?.unknownEventCount ?? 0, input.bytesReceived ?? existing?.bytesReceived ?? null, JSON.stringify(input.eventTypeCounts ?? existing?.eventTypeCounts ?? {}), input.eventStreamId ?? null, input.eventId ?? null, input.payloadRef ?? null, input.errorCategory ?? null, input.errorMessage ?? null, input.captureMode ?? existing?.captureMode ?? "metadata_only", input.retentionClass ?? existing?.retentionClass ?? "diagnostic", input.createdAt ?? existing?.createdAt ?? now, now);
238
238
  return this.getProviderRequest(providerRequestId) ?? fail(`Failed to upsert telemetry provider request ${providerRequestId}`);
239
239
  }
@@ -262,20 +262,20 @@ export class TelemetryStore {
262
262
  const unknownEventCount = Math.max(0, input.unknownEventCount ?? 0);
263
263
  const bytesReceived = Math.max(0, input.bytesReceived ?? 0);
264
264
  const updatedAt = input.updatedAt ?? input.lastNormalizedEventAt ?? input.lastRawEventAt ?? new Date().toISOString();
265
- this.db.prepare(`
266
- UPDATE telemetry_provider_requests SET
267
- status = CASE WHEN status IN ('completed', 'error', 'aborted', 'timeout') THEN status ELSE COALESCE(?, status) END,
268
- last_raw_event_at = COALESCE(?, last_raw_event_at),
269
- last_normalized_event_at = COALESCE(?, last_normalized_event_at),
270
- upstream_response_id = COALESCE(?, upstream_response_id),
271
- raw_event_count = raw_event_count + ?,
272
- normalized_event_count = normalized_event_count + ?,
273
- parse_error_count = parse_error_count + ?,
274
- unknown_event_count = unknown_event_count + ?,
275
- bytes_received = CASE WHEN ? = 0 THEN bytes_received ELSE COALESCE(bytes_received, 0) + ? END,
276
- event_type_counts_json = ?,
277
- updated_at = ?
278
- WHERE provider_request_id = ?
265
+ this.db.prepare(`
266
+ UPDATE telemetry_provider_requests SET
267
+ status = CASE WHEN status IN ('completed', 'error', 'aborted', 'timeout') THEN status ELSE COALESCE(?, status) END,
268
+ last_raw_event_at = COALESCE(?, last_raw_event_at),
269
+ last_normalized_event_at = COALESCE(?, last_normalized_event_at),
270
+ upstream_response_id = COALESCE(?, upstream_response_id),
271
+ raw_event_count = raw_event_count + ?,
272
+ normalized_event_count = normalized_event_count + ?,
273
+ parse_error_count = parse_error_count + ?,
274
+ unknown_event_count = unknown_event_count + ?,
275
+ bytes_received = CASE WHEN ? = 0 THEN bytes_received ELSE COALESCE(bytes_received, 0) + ? END,
276
+ event_type_counts_json = ?,
277
+ updated_at = ?
278
+ WHERE provider_request_id = ?
279
279
  `).run(input.status ?? null, input.lastRawEventAt ?? null, input.lastNormalizedEventAt ?? null, input.upstreamResponseId ?? null, rawEventCount, normalizedEventCount, parseErrorCount, unknownEventCount, bytesReceived, bytesReceived, JSON.stringify(eventTypeCounts), updatedAt, input.providerRequestId);
280
280
  return {
281
281
  ...existing,
@@ -300,32 +300,32 @@ export class TelemetryStore {
300
300
  const sequence = input.sequence ?? existingEvent?.sequence ?? this.nextProviderEventSequence(input.providerRequestId);
301
301
  const byteSize = input.byteSize ?? 0;
302
302
  const parseStatus = input.parseStatus ?? "ok";
303
- this.db.prepare(`
304
- INSERT INTO telemetry_provider_events (
305
- raw_event_id, provider_request_id, pibo_session_id, turn_id, phase_id, sequence, received_at,
306
- event_type, byte_size, parse_status, normalized_type, event_stream_id, event_id, item_id,
307
- tool_call_id, payload_ref, payload_preview_ref, safe_fields_json, retention_class, created_at, updated_at
308
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
309
- ON CONFLICT(raw_event_id) DO UPDATE SET
310
- provider_request_id = excluded.provider_request_id,
311
- pibo_session_id = COALESCE(excluded.pibo_session_id, telemetry_provider_events.pibo_session_id),
312
- turn_id = COALESCE(excluded.turn_id, telemetry_provider_events.turn_id),
313
- phase_id = COALESCE(excluded.phase_id, telemetry_provider_events.phase_id),
314
- sequence = excluded.sequence,
315
- received_at = excluded.received_at,
316
- event_type = excluded.event_type,
317
- byte_size = excluded.byte_size,
318
- parse_status = excluded.parse_status,
319
- normalized_type = COALESCE(excluded.normalized_type, telemetry_provider_events.normalized_type),
320
- event_stream_id = COALESCE(excluded.event_stream_id, telemetry_provider_events.event_stream_id),
321
- event_id = COALESCE(excluded.event_id, telemetry_provider_events.event_id),
322
- item_id = COALESCE(excluded.item_id, telemetry_provider_events.item_id),
323
- tool_call_id = COALESCE(excluded.tool_call_id, telemetry_provider_events.tool_call_id),
324
- payload_ref = COALESCE(excluded.payload_ref, telemetry_provider_events.payload_ref),
325
- payload_preview_ref = COALESCE(excluded.payload_preview_ref, telemetry_provider_events.payload_preview_ref),
326
- safe_fields_json = excluded.safe_fields_json,
327
- retention_class = excluded.retention_class,
328
- updated_at = excluded.updated_at
303
+ this.db.prepare(`
304
+ INSERT INTO telemetry_provider_events (
305
+ raw_event_id, provider_request_id, pibo_session_id, turn_id, phase_id, sequence, received_at,
306
+ event_type, byte_size, parse_status, normalized_type, event_stream_id, event_id, item_id,
307
+ tool_call_id, payload_ref, payload_preview_ref, safe_fields_json, retention_class, created_at, updated_at
308
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
309
+ ON CONFLICT(raw_event_id) DO UPDATE SET
310
+ provider_request_id = excluded.provider_request_id,
311
+ pibo_session_id = COALESCE(excluded.pibo_session_id, telemetry_provider_events.pibo_session_id),
312
+ turn_id = COALESCE(excluded.turn_id, telemetry_provider_events.turn_id),
313
+ phase_id = COALESCE(excluded.phase_id, telemetry_provider_events.phase_id),
314
+ sequence = excluded.sequence,
315
+ received_at = excluded.received_at,
316
+ event_type = excluded.event_type,
317
+ byte_size = excluded.byte_size,
318
+ parse_status = excluded.parse_status,
319
+ normalized_type = COALESCE(excluded.normalized_type, telemetry_provider_events.normalized_type),
320
+ event_stream_id = COALESCE(excluded.event_stream_id, telemetry_provider_events.event_stream_id),
321
+ event_id = COALESCE(excluded.event_id, telemetry_provider_events.event_id),
322
+ item_id = COALESCE(excluded.item_id, telemetry_provider_events.item_id),
323
+ tool_call_id = COALESCE(excluded.tool_call_id, telemetry_provider_events.tool_call_id),
324
+ payload_ref = COALESCE(excluded.payload_ref, telemetry_provider_events.payload_ref),
325
+ payload_preview_ref = COALESCE(excluded.payload_preview_ref, telemetry_provider_events.payload_preview_ref),
326
+ safe_fields_json = excluded.safe_fields_json,
327
+ retention_class = excluded.retention_class,
328
+ updated_at = excluded.updated_at
329
329
  `).run(rawEventId, input.providerRequestId, input.piboSessionId ?? null, input.turnId ?? null, input.phaseId ?? null, sequence, receivedAt, input.eventType, byteSize, parseStatus, input.normalizedType ?? null, input.eventStreamId ?? null, input.eventId ?? null, input.itemId ?? null, input.toolCallId ?? null, input.payloadRef ?? null, input.payloadPreviewRef ?? null, JSON.stringify(input.safeFields ?? {}), input.retentionClass ?? "provider_event", input.createdAt ?? now, now);
330
330
  const normalizedDelta = input.normalizedEventDelta ?? (input.normalizedType ? 1 : 0);
331
331
  if (!existingEvent)
@@ -335,41 +335,41 @@ export class TelemetryStore {
335
335
  upsertToolCall(input) {
336
336
  const now = input.updatedAt ?? new Date().toISOString();
337
337
  const existing = this.getToolCall(input.toolCallId);
338
- this.db.prepare(`
339
- INSERT INTO telemetry_tool_calls (
340
- tool_call_id, pibo_session_id, root_session_id, room_id, turn_id, provider_request_id, provider_item_id,
341
- output_index, tool_name, status, args_started_at, first_delta_at, last_delta_at, args_completed_at,
342
- execution_started_at, execution_ended_at, duration_ms, args_bytes, parse_status, safe_arg_keys_json,
343
- event_stream_id, event_id, payload_ref, run_id, error_category, error_message, retention_class, created_at, updated_at
344
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
345
- ON CONFLICT(tool_call_id) DO UPDATE SET
346
- pibo_session_id = excluded.pibo_session_id,
347
- root_session_id = COALESCE(excluded.root_session_id, telemetry_tool_calls.root_session_id),
348
- room_id = COALESCE(excluded.room_id, telemetry_tool_calls.room_id),
349
- turn_id = excluded.turn_id,
350
- provider_request_id = COALESCE(excluded.provider_request_id, telemetry_tool_calls.provider_request_id),
351
- provider_item_id = COALESCE(excluded.provider_item_id, telemetry_tool_calls.provider_item_id),
352
- output_index = COALESCE(excluded.output_index, telemetry_tool_calls.output_index),
353
- tool_name = excluded.tool_name,
354
- status = excluded.status,
355
- args_started_at = COALESCE(excluded.args_started_at, telemetry_tool_calls.args_started_at),
356
- first_delta_at = COALESCE(excluded.first_delta_at, telemetry_tool_calls.first_delta_at),
357
- last_delta_at = COALESCE(excluded.last_delta_at, telemetry_tool_calls.last_delta_at),
358
- args_completed_at = COALESCE(excluded.args_completed_at, telemetry_tool_calls.args_completed_at),
359
- execution_started_at = COALESCE(excluded.execution_started_at, telemetry_tool_calls.execution_started_at),
360
- execution_ended_at = COALESCE(excluded.execution_ended_at, telemetry_tool_calls.execution_ended_at),
361
- duration_ms = COALESCE(excluded.duration_ms, telemetry_tool_calls.duration_ms),
362
- args_bytes = excluded.args_bytes,
363
- parse_status = excluded.parse_status,
364
- safe_arg_keys_json = excluded.safe_arg_keys_json,
365
- event_stream_id = COALESCE(excluded.event_stream_id, telemetry_tool_calls.event_stream_id),
366
- event_id = COALESCE(excluded.event_id, telemetry_tool_calls.event_id),
367
- payload_ref = COALESCE(excluded.payload_ref, telemetry_tool_calls.payload_ref),
368
- run_id = COALESCE(excluded.run_id, telemetry_tool_calls.run_id),
369
- error_category = COALESCE(excluded.error_category, telemetry_tool_calls.error_category),
370
- error_message = COALESCE(excluded.error_message, telemetry_tool_calls.error_message),
371
- retention_class = excluded.retention_class,
372
- updated_at = excluded.updated_at
338
+ this.db.prepare(`
339
+ INSERT INTO telemetry_tool_calls (
340
+ tool_call_id, pibo_session_id, root_session_id, room_id, turn_id, provider_request_id, provider_item_id,
341
+ output_index, tool_name, status, args_started_at, first_delta_at, last_delta_at, args_completed_at,
342
+ execution_started_at, execution_ended_at, duration_ms, args_bytes, parse_status, safe_arg_keys_json,
343
+ event_stream_id, event_id, payload_ref, run_id, error_category, error_message, retention_class, created_at, updated_at
344
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
345
+ ON CONFLICT(tool_call_id) DO UPDATE SET
346
+ pibo_session_id = excluded.pibo_session_id,
347
+ root_session_id = COALESCE(excluded.root_session_id, telemetry_tool_calls.root_session_id),
348
+ room_id = COALESCE(excluded.room_id, telemetry_tool_calls.room_id),
349
+ turn_id = excluded.turn_id,
350
+ provider_request_id = COALESCE(excluded.provider_request_id, telemetry_tool_calls.provider_request_id),
351
+ provider_item_id = COALESCE(excluded.provider_item_id, telemetry_tool_calls.provider_item_id),
352
+ output_index = COALESCE(excluded.output_index, telemetry_tool_calls.output_index),
353
+ tool_name = excluded.tool_name,
354
+ status = excluded.status,
355
+ args_started_at = COALESCE(excluded.args_started_at, telemetry_tool_calls.args_started_at),
356
+ first_delta_at = COALESCE(excluded.first_delta_at, telemetry_tool_calls.first_delta_at),
357
+ last_delta_at = COALESCE(excluded.last_delta_at, telemetry_tool_calls.last_delta_at),
358
+ args_completed_at = COALESCE(excluded.args_completed_at, telemetry_tool_calls.args_completed_at),
359
+ execution_started_at = COALESCE(excluded.execution_started_at, telemetry_tool_calls.execution_started_at),
360
+ execution_ended_at = COALESCE(excluded.execution_ended_at, telemetry_tool_calls.execution_ended_at),
361
+ duration_ms = COALESCE(excluded.duration_ms, telemetry_tool_calls.duration_ms),
362
+ args_bytes = excluded.args_bytes,
363
+ parse_status = excluded.parse_status,
364
+ safe_arg_keys_json = excluded.safe_arg_keys_json,
365
+ event_stream_id = COALESCE(excluded.event_stream_id, telemetry_tool_calls.event_stream_id),
366
+ event_id = COALESCE(excluded.event_id, telemetry_tool_calls.event_id),
367
+ payload_ref = COALESCE(excluded.payload_ref, telemetry_tool_calls.payload_ref),
368
+ run_id = COALESCE(excluded.run_id, telemetry_tool_calls.run_id),
369
+ error_category = COALESCE(excluded.error_category, telemetry_tool_calls.error_category),
370
+ error_message = COALESCE(excluded.error_message, telemetry_tool_calls.error_message),
371
+ retention_class = excluded.retention_class,
372
+ updated_at = excluded.updated_at
373
373
  `).run(input.toolCallId, input.piboSessionId, input.rootSessionId ?? null, input.roomId ?? null, input.turnId, input.providerRequestId ?? null, input.providerItemId ?? null, input.outputIndex ?? null, input.toolName, input.status ?? existing?.status ?? "args_started", input.argsStartedAt ?? null, input.firstDeltaAt ?? null, input.lastDeltaAt ?? null, input.argsCompletedAt ?? null, input.executionStartedAt ?? null, input.executionEndedAt ?? null, input.durationMs ?? null, input.argsBytes ?? existing?.argsBytes ?? 0, input.parseStatus ?? existing?.parseStatus ?? "empty", JSON.stringify(input.safeArgKeys ?? existing?.safeArgKeys ?? []), input.eventStreamId ?? null, input.eventId ?? null, input.payloadRef ?? null, input.runId ?? null, input.errorCategory ?? null, input.errorMessage ?? null, input.retentionClass ?? existing?.retentionClass ?? "diagnostic", input.createdAt ?? existing?.createdAt ?? now, now);
374
374
  return this.getToolCall(input.toolCallId) ?? fail(`Failed to upsert telemetry tool call ${input.toolCallId}`);
375
375
  }
@@ -17,12 +17,12 @@ export function inspectDebugEvents(piboSessionId, store, options = {}) {
17
17
  values.push(options.type);
18
18
  }
19
19
  const rows = db
20
- .prepare(`
21
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
22
- FROM event_log
23
- WHERE ${clauses.join(" AND ")}
24
- ORDER BY stream_id DESC
25
- LIMIT ?
20
+ .prepare(`
21
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
22
+ FROM event_log
23
+ WHERE ${clauses.join(" AND ")}
24
+ ORDER BY stream_id DESC
25
+ LIMIT ?
26
26
  `)
27
27
  .all(...values, limit + 1);
28
28
  const limited = rows.length > limit;
@@ -167,16 +167,16 @@ function formatEventRow(row, fields) {
167
167
  function findEventRow(db, piboSessionId, selector) {
168
168
  const numeric = Number(selector);
169
169
  if (Number.isInteger(numeric)) {
170
- const row = db.prepare(`
171
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
172
- FROM event_log WHERE session_id = ? AND stream_id = ?
170
+ const row = db.prepare(`
171
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
172
+ FROM event_log WHERE session_id = ? AND stream_id = ?
173
173
  `).get(piboSessionId, numeric);
174
174
  if (row)
175
175
  return row;
176
176
  }
177
- return db.prepare(`
178
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
179
- FROM event_log WHERE session_id = ? AND event_id = ? ORDER BY stream_id DESC LIMIT 1
177
+ return db.prepare(`
178
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
179
+ FROM event_log WHERE session_id = ? AND event_id = ? ORDER BY stream_id DESC LIMIT 1
180
180
  `).get(piboSessionId, selector);
181
181
  }
182
182
  function buildListNextCommands(piboSessionId, rows) {
@@ -64,12 +64,12 @@ function readToolFailures(piboSessionId, store, limit) {
64
64
  try {
65
65
  if (!tableExists(db, "event_log"))
66
66
  return [];
67
- const rows = db.prepare(`
68
- SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
69
- FROM event_log
70
- WHERE session_id = ? AND type = 'tool_execution_finished'
71
- ORDER BY stream_id DESC
72
- LIMIT ?
67
+ const rows = db.prepare(`
68
+ SELECT stream_id, session_id, session_sequence, event_id, type, created_at, preview_text, attributes_json
69
+ FROM event_log
70
+ WHERE session_id = ? AND type = 'tool_execution_finished'
71
+ ORDER BY stream_id DESC
72
+ LIMIT ?
73
73
  `).all(piboSessionId, limit + 1);
74
74
  return rows.flatMap((row) => {
75
75
  const payload = eventPayload(row);