@sebastianandreasson/pi-autonomous-agents 0.13.1 → 0.14.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/README.md +5 -0
- package/docs/PI_REQUEST_TELEMETRY_EXTENSION.md +182 -0
- package/package.json +4 -3
- package/pi-extensions/request-telemetry/README.md +66 -0
- package/pi-extensions/request-telemetry/index.mjs +516 -0
- package/pi-extensions/request-telemetry/package.json +10 -0
- package/pi.config.json +1 -0
- package/src/index.mjs +22 -0
- package/src/pi-client.mjs +1 -0
- package/src/pi-config.mjs +1 -0
- package/src/pi-request-telemetry.mjs +1069 -0
- package/src/pi-sdk-turn.mjs +15 -6
- package/src/pi-visualizer-server.mjs +21 -2
- package/templates/gitignore.fragment +1 -0
- package/templates/pi.config.example.json +1 -0
- package/visualizer-ui/dist/assets/index-D8qcxkvV.js +12 -0
- package/visualizer-ui/dist/index.html +1 -1
- package/visualizer-ui/dist/assets/index-DCGArR7-.js +0 -12
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 shim to `.pi/extensions/pi-harness-request-telemetry/index.mjs` in the consuming repo, and Pi auto-discovers it 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 shim under `.pi/extensions/pi-harness-request-telemetry/` in the consuming repo before Pi reloads resources. 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.
|
|
4
|
+
"version": "0.14.0",
|
|
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.
|