@sebastianandreasson/pi-autonomous-agents 0.13.1 → 0.14.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.
package/README.md CHANGED
@@ -80,6 +80,8 @@ Typical scripts:
80
80
 
81
81
  Start from [templates/pi.config.example.json](./templates/pi.config.example.json), [templates/DEVELOPER.md](./templates/DEVELOPER.md), [templates/TESTER.md](./templates/TESTER.md), and [templates/gitignore.fragment](./templates/gitignore.fragment).
82
82
 
83
+ Request telemetry is enabled by default for SDK runs. `pi-harness` writes a managed Pi extension package under `.pi/extensions/pi-harness-request-telemetry/` in the consuming repo, with a `package.json` manifest and `index.mjs` shim that Pi auto-discovers on the next resource reload. Disable that with `PI_REQUEST_TELEMETRY_ENABLED=0` or `"piRequestTelemetryEnabled": false`.
84
+
83
85
  ## CLI
84
86
 
85
87
  ```bash
@@ -183,6 +185,7 @@ Common fields in `pi.config.json`:
183
185
  - `testerInstructionsFile`
184
186
  - `transport` (`sdk` or `mock`)
185
187
  - `piModel`
188
+ - `piRequestTelemetryEnabled`
186
189
  - `models`
187
190
  - `roleModels`
188
191
  - `commitMode`
@@ -324,6 +327,8 @@ That clears configured harness runtime/history artifacts and verifies they are g
324
327
  More detailed flow, transport, telemetry, and runtime documentation.
325
328
  - [docs/TOKEN_USAGE_ARTIFACTS.md](./docs/TOKEN_USAGE_ARTIFACTS.md)
326
329
  Agent-facing contract and usage guidance for token-usage artifacts and downstream tooling.
330
+ - [docs/PI_REQUEST_TELEMETRY_EXTENSION.md](./docs/PI_REQUEST_TELEMETRY_EXTENSION.md)
331
+ Repo-local Pi extension prototype for request-level telemetry via Pi hooks.
327
332
  - [templates/PROJECT_SETUP.md](./templates/PROJECT_SETUP.md)
328
333
  Minimal consuming-repo layout summary.
329
334
 
@@ -0,0 +1,182 @@
1
+ # Pi Request Telemetry Extension
2
+
3
+ This document describes the repo-local Pi extension prototype under [pi-extensions/request-telemetry](../pi-extensions/request-telemetry/README.md).
4
+
5
+ In normal `pi-harness` SDK runs, this extension is auto-enabled by installing a managed extension package under `.pi/extensions/pi-harness-request-telemetry/` in the consuming repo before Pi reloads resources. That package contains a `package.json` Pi manifest plus the generated `index.mjs` shim. Opt out with `PI_REQUEST_TELEMETRY_ENABLED=0` or `"piRequestTelemetryEnabled": false`.
6
+
7
+ The purpose of this extension is to gather request-level data directly from Pi extension hooks before we decide whether to patch `@mariozechner/pi-coding-agent` or `pi-ai`.
8
+
9
+ ## Produced Artifacts
10
+
11
+ - `pi-output/request-telemetry/hooks.jsonl`
12
+ - `pi-output/request-telemetry/requests.jsonl`
13
+ - `pi-output/request-telemetry/spans.jsonl`
14
+
15
+ These artifacts are intentionally separate from the existing `pi-output/token-usage/*` files.
16
+
17
+ `token-usage` remains the harness-level normalized output.
18
+ `request-telemetry` is the lower-level Pi-extension probe for real request boundaries and prompt composition.
19
+
20
+ ## Hook Coverage
21
+
22
+ The extension listens to:
23
+
24
+ - `session_start`
25
+ - `session_switch`
26
+ - `model_select`
27
+ - `turn_start`
28
+ - `context`
29
+ - `before_provider_request`
30
+ - `after_provider_response`
31
+ - `tool_execution_start`
32
+ - `tool_result`
33
+ - `message_end`
34
+ - `turn_end`
35
+
36
+ The documented hooks come from Pi’s extension API:
37
+
38
+ - [Extension Hooks](https://pt-act-pi-mono.mintlify.app/api/coding-agent/hooks)
39
+ - [Extension System](https://pt-act-pi-mono.mintlify.app/concepts/extensions)
40
+
41
+ The current source also exposes undocumented provider-boundary hooks:
42
+
43
+ - `before_provider_request`
44
+ - `after_provider_response`
45
+
46
+ Source:
47
+
48
+ - [packages/coding-agent/src/core/extensions/types.ts](https://github.com/badlogic/pi-mono/blob/main/packages/coding-agent/src/core/extensions/types.ts)
49
+
50
+ ## Request Artifact Schema
51
+
52
+ Each row in `requests.jsonl` contains one provider request finalized by the following assistant `message_end`:
53
+
54
+ - `schemaVersion`
55
+ - `timestamp`
56
+ - `requestId`
57
+ - `sessionId`
58
+ - `turnIndex`
59
+ - `startedAt`
60
+ - `finishedAt`
61
+ - `durationMs`
62
+ - `statusCode`
63
+ - `provider`
64
+ - `model`
65
+ - `api`
66
+ - `stopReason`
67
+ - `usageSource`
68
+ - `source`
69
+ - `spanSource`
70
+ - `contextMessageCount`
71
+ - `spanCount`
72
+ - `textChars`
73
+ - `textBytes`
74
+ - `toolNames`
75
+ - `files`
76
+ - `providerPayloadSummary`
77
+ - `responseHeaders`
78
+ - `inputTokens`
79
+ - `outputTokens`
80
+ - `totalTokens`
81
+ - `cacheReadTokens`
82
+ - `cacheWriteTokens`
83
+
84
+ `usageSource` is one of:
85
+
86
+ - `message_usage`
87
+ - `unavailable`
88
+
89
+ This is intentionally conservative. The extension does not invent totals when the provider does not expose them.
90
+
91
+ `spanSource` describes where the prompt-span reconstruction came from:
92
+
93
+ - `provider_payload`
94
+ - `context`
95
+ - `session_history`
96
+
97
+ Interpretation:
98
+
99
+ - `provider_payload` is the strongest source because it comes from the final request payload.
100
+ - `context` is also exact for the pre-request message set Pi exposed to the extension.
101
+ - `session_history` is a fallback when Pi omits both `context` and provider payload hooks for a given assistant response.
102
+
103
+ `hooks.jsonl` is a lifecycle trace of:
104
+
105
+ - `turn_start`
106
+ - `context`
107
+ - `before_provider_request`
108
+ - `after_provider_response`
109
+ - `message_end`
110
+ - `turn_end`
111
+
112
+ Use it to debug request association problems or confirm whether Pi emitted provider-boundary hooks for a specific run.
113
+
114
+ ## Span Artifact Schema
115
+
116
+ Each row in `spans.jsonl` contains one extracted prompt span:
117
+
118
+ - `schemaVersion`
119
+ - `timestamp`
120
+ - `requestId`
121
+ - `sessionId`
122
+ - `turnIndex`
123
+ - `source`
124
+ - `role`
125
+ - `messageIndex`
126
+ - `spanIndex`
127
+ - `spanKind`
128
+ - `toolCallId`
129
+ - `toolName`
130
+ - `paths`
131
+ - `primaryPath`
132
+ - `charCount`
133
+ - `byteCount`
134
+ - `text`
135
+ - `preview`
136
+
137
+ Current `spanKind` values include:
138
+
139
+ - `text`
140
+ - `thinking`
141
+ - `tool_call`
142
+ - `tool_result`
143
+ - `image`
144
+ - `unknown`
145
+
146
+ ## Exact vs Inferred
147
+
148
+ This extension is meant to move the data model closer to real accounting.
149
+
150
+ Exact today:
151
+
152
+ - provider request boundaries when `before_provider_request` fires
153
+ - pre-request context messages
154
+ - provider-payload-derived spans when Pi exposes the final payload
155
+ - provider payload summary
156
+ - tool/file context seen by extension hooks
157
+ - final request totals when `message.usage` is present
158
+
159
+ Not exact today:
160
+
161
+ - token counts for each prompt span
162
+ - per-file token billing
163
+ - request totals when the backend omits usage entirely
164
+ - `session_history` span reconstructions when neither `context` nor provider payload is exposed
165
+
166
+ That means these artifacts are suitable for:
167
+
168
+ - validating whether Pi/provider already exposes exact request usage
169
+ - seeing the true prompt composition for each provider request
170
+ - building tokenizer-backed attribution later from exact captured spans
171
+
172
+ They are not yet a replacement for exact per-file cost accounting.
173
+
174
+ ## Recommended Next Step
175
+
176
+ Use this extension first to answer two questions:
177
+
178
+ 1. Does your backend populate `message.usage` consistently?
179
+ 2. Does `before_provider_request` give enough final payload detail to tokenize exact prompt spans?
180
+
181
+ If both answers are yes, the next step is tokenizer-backed per-span accounting.
182
+ If usage is still missing, the right fix is likely upstream in `pi-ai` or `pi-coding-agent`, not more harness-side heuristics.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@sebastianandreasson/pi-autonomous-agents",
3
3
  "private": false,
4
- "version": "0.13.1",
4
+ "version": "0.14.1",
5
5
  "type": "module",
6
6
  "description": "Portable unattended PI harness for developer/tester/visual-review loops.",
7
7
  "license": "MIT",
@@ -19,8 +19,8 @@
19
19
  "@mariozechner/pi-coding-agent": "^0.66.1"
20
20
  },
21
21
  "scripts": {
22
- "check": "node --check src/cli.mjs && node --check src/pi-clear-history.mjs && node --check src/pi-client.mjs && node --check src/pi-config.mjs && node --check src/pi-debug-live.mjs && node --check src/pi-flow.mjs && node --check src/pi-heartbeat.mjs && node --check src/pi-history.mjs && node --check src/pi-preflight.mjs && node --check src/pi-prompts.mjs && node --check src/pi-repo.mjs && node --check src/pi-report.mjs && node --check src/pi-sdk-turn.mjs && node --check src/pi-supervisor.mjs && node --check src/pi-telemetry.mjs && node --check src/pi-token-analysis.mjs && node --check src/pi-visual-once.mjs && node --check src/pi-visual-review.mjs && node --check src/pi-visualizer.mjs && node --check src/pi-visualizer-server.mjs && node --check src/pi-visualizer-shared.mjs && node --check src/index.mjs && node --check test/pi-heartbeat.test.mjs && node --check test/pi-lifecycle.test.mjs && node --check test/pi-role-models.test.mjs && node --check test/pi-flow.test.mjs && node --check test/pi-history.test.mjs && node --check test/pi-prompts.test.mjs && node --check test/pi-preflight.test.mjs && node --check test/pi-repo.test.mjs && node --check test/pi-sdk-supervisor.test.mjs && node --check test/pi-sdk-turn.test.mjs && node --check test/pi-telemetry.test.mjs && node --check test/pi-token-analysis.test.mjs && node --check test/pi-visualizer-shared.test.mjs && node --check test/fixtures/fake-pi.mjs && node --check test/fixtures/fake-pi-sdk.mjs && node --check test/fixtures/fake-live-pi-sdk.mjs",
23
- "test": "node --test test/pi-heartbeat.test.mjs test/pi-lifecycle.test.mjs test/pi-role-models.test.mjs test/pi-flow.test.mjs test/pi-history.test.mjs test/pi-prompts.test.mjs test/pi-preflight.test.mjs test/pi-repo.test.mjs test/pi-sdk-supervisor.test.mjs test/pi-sdk-turn.test.mjs test/pi-telemetry.test.mjs test/pi-token-analysis.test.mjs test/pi-visualizer-shared.test.mjs",
22
+ "check": "node --check src/cli.mjs && node --check src/pi-clear-history.mjs && node --check src/pi-client.mjs && node --check src/pi-config.mjs && node --check src/pi-debug-live.mjs && node --check src/pi-flow.mjs && node --check src/pi-heartbeat.mjs && node --check src/pi-history.mjs && node --check src/pi-preflight.mjs && node --check src/pi-prompts.mjs && node --check src/pi-repo.mjs && node --check src/pi-report.mjs && node --check src/pi-request-telemetry.mjs && node --check src/pi-sdk-turn.mjs && node --check src/pi-supervisor.mjs && node --check src/pi-telemetry.mjs && node --check src/pi-token-analysis.mjs && node --check src/pi-visual-once.mjs && node --check src/pi-visual-review.mjs && node --check src/pi-visualizer.mjs && node --check src/pi-visualizer-server.mjs && node --check src/pi-visualizer-shared.mjs && node --check src/index.mjs && node --check pi-extensions/request-telemetry/index.mjs && node --check test/pi-heartbeat.test.mjs && node --check test/pi-lifecycle.test.mjs && node --check test/pi-request-telemetry.test.mjs && node --check test/pi-role-models.test.mjs && node --check test/pi-flow.test.mjs && node --check test/pi-history.test.mjs && node --check test/pi-prompts.test.mjs && node --check test/pi-preflight.test.mjs && node --check test/pi-repo.test.mjs && node --check test/pi-sdk-supervisor.test.mjs && node --check test/pi-sdk-turn.test.mjs && node --check test/pi-telemetry.test.mjs && node --check test/pi-token-analysis.test.mjs && node --check test/pi-visualizer-shared.test.mjs && node --check test/fixtures/fake-pi.mjs && node --check test/fixtures/fake-pi-sdk.mjs && node --check test/fixtures/fake-live-pi-sdk.mjs",
23
+ "test": "node --test test/pi-heartbeat.test.mjs test/pi-lifecycle.test.mjs test/pi-request-telemetry.test.mjs test/pi-role-models.test.mjs test/pi-flow.test.mjs test/pi-history.test.mjs test/pi-prompts.test.mjs test/pi-preflight.test.mjs test/pi-repo.test.mjs test/pi-sdk-supervisor.test.mjs test/pi-sdk-turn.test.mjs test/pi-telemetry.test.mjs test/pi-token-analysis.test.mjs test/pi-visualizer-shared.test.mjs",
24
24
  "debug:live-ui": "node src/cli.mjs debug-live --reset",
25
25
  "dev:visualizer:ui": "npm --prefix visualizer-ui run dev",
26
26
  "build:visualizer:ui": "npm --prefix visualizer-ui run build",
@@ -28,6 +28,7 @@
28
28
  },
29
29
  "files": [
30
30
  "src",
31
+ "pi-extensions",
31
32
  "templates",
32
33
  "docs",
33
34
  "visualizer-ui/dist",
@@ -0,0 +1,66 @@
1
+ # Request Telemetry Pi Extension
2
+
3
+ This is a repo-local Pi extension prototype for capturing lower-level request telemetry than `pi-harness` can see on its own.
4
+
5
+ It writes:
6
+
7
+ - `pi-output/request-telemetry/hooks.jsonl`
8
+ - `pi-output/request-telemetry/requests.jsonl`
9
+ - `pi-output/request-telemetry/spans.jsonl`
10
+
11
+ The goal is to capture exact request boundaries and exact prompt composition before deciding whether we need to patch `pi-mono` itself.
12
+
13
+ ## What It Captures
14
+
15
+ - one request record per provider request
16
+ - exact `context` messages seen before the provider call
17
+ - exact prompt spans extracted from the provider payload when available
18
+ - context-derived fallback spans when Pi exposes `context` but not the final payload
19
+ - tool names and file paths seen through tool hooks
20
+ - provider payload summary from `before_provider_request`
21
+ - response status and headers from `after_provider_response`
22
+ - final assistant-message usage if Pi exposes it on `message.usage`
23
+ - lifecycle hook traces in `hooks.jsonl` so you can debug request association
24
+ - `spanSource` on each request so consumers can distinguish:
25
+ - `provider_payload`
26
+ - `context`
27
+ - `session_history`
28
+
29
+ ## What It Does Not Claim Yet
30
+
31
+ - exact per-file token spend
32
+ - exact per-span token counts
33
+ - exact request usage when the provider does not return usage
34
+
35
+ Those need either:
36
+
37
+ - normalized request-usage exposure from Pi/provider adapters
38
+ - or tokenizer-backed accounting from the exact serialized payload
39
+
40
+ ## Normal Package Behavior
41
+
42
+ When `pi-harness` runs through the SDK transport, it now installs a managed shim at:
43
+
44
+ - `.pi/extensions/pi-harness-request-telemetry/index.mjs`
45
+
46
+ That makes request telemetry auto-load in consuming repos without needing `--extension`.
47
+
48
+ Disable that path with:
49
+
50
+ - `PI_REQUEST_TELEMETRY_ENABLED=0`
51
+ - `"piRequestTelemetryEnabled": false` in `pi.config.json`
52
+
53
+ ## Running It From This Repo
54
+
55
+ Use the extension file directly:
56
+
57
+ ```bash
58
+ pi --extension ./pi-extensions/request-telemetry/index.mjs
59
+ ```
60
+
61
+ Or copy or symlink it into a Pi extension directory:
62
+
63
+ - project-local: `./.pi/extensions/`
64
+ - global: `~/.pi/agent/extensions/`
65
+
66
+ If you move only `index.mjs`, it will break because it currently imports helpers from this repo at `src/pi-request-telemetry.mjs`. Keep the repo checkout intact for this prototype.