pi-langfuse 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (5) hide show
  1. package/README.md +270 -59
  2. package/README_CN.md +273 -61
  3. package/image.png +0 -0
  4. package/index.ts +877 -325
  5. package/package.json +18 -3
package/README.md CHANGED
@@ -1,6 +1,11 @@
1
1
  # pi-langfuse
2
2
 
3
- Langfuse observability extension for [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent). Sends traces to [Langfuse](https://langfuse.com) for monitoring tokens, costs, latency, and tool calls.
3
+ [![npm version](https://img.shields.io/npm/v/pi-langfuse)](https://www.npmjs.com/package/pi-langfuse)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ [**English**](./README.md) | [**简体中文**](./README_CN.md)
7
+
8
+ Langfuse observability extension for [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent). Sends complete Pi agent runs to [Langfuse](https://langfuse.com) so you can inspect the user prompt, root agent workflow, every LLM generation, every tool call, final assistant response, usage, cost, and health scores in one trace.
4
9
 
5
10
  ## Why Langfuse?
6
11
 
@@ -8,113 +13,319 @@ Langfuse provides open-source observability for LLM applications. This extension
8
13
 
9
14
  ## Features
10
15
 
11
- - **Hierarchical Tracing**: Maps user prompts to per-turn spans and nested tool executions for deep visibility.
12
- - **LLM Metadata**: Automatically records model name, provider, token usage, and API costs per turn.
13
- - **Tool Observability**: Detailed logs for every tool call, including arguments, results, and error states.
14
- - **Session Correlation**: Groups all prompts from the same Pi session into a single Langfuse session.
15
- - **Cost Tracking**: Records input/output/total costs in USD per generation.
16
- - **Token Usage**: Tracks input and output tokens per turn.
16
+ - **Complete Agent Traces**: Creates one trace per user prompt with a root `agent` observation containing the prompt input and final assistant output.
17
+ - **Per-Request Generations**: Records a separate `generation` observation for every provider request, including the actual provider payload instead of only the original prompt.
18
+ - **Final Message Capture**: Uses finalized assistant messages for generation and root outputs, so Langfuse shows what the user actually saw in Pi.
19
+ - **Tool Observability**: Creates Langfuse `tool` observations for every tool call, including arguments, results, and error states.
20
+ - **Parallel Tool Safety**: Correlates tool observations by `toolCallId`, avoiding result mix-ups when Pi runs tools concurrently.
21
+ - **Session Correlation**: Groups traces from the same Pi session under a shared Langfuse session ID.
22
+ - **Cost and Token Tracking**: Records usage and cost details on each generation when Pi/provider payloads expose them.
23
+ - **Evaluation Scores**: Automatically computes and sends tool success rates, error counts, and session health metrics.
24
+ - **Defensive Payload Shaping**: Parses JSON-like strings when possible, limits object depth, and truncates large payloads before upload.
25
+
26
+ ## Highlights
27
+
28
+ `pi-langfuse` is designed to make a Pi run readable as an agent workflow, not just a bag of logs:
29
+
30
+ - The trace input/output mirrors the root `agent` observation, making the run understandable from the Langfuse trace list and detail view.
31
+ - The first generation in a tool-using run can show the assistant's tool-call message, the tool observation shows execution I/O, and the follow-up generation shows the final natural-language answer.
32
+ - Tool failures are marked on the tool observation and reflected in trace-level scores, while later generations still preserve the tool error result in their input history.
33
+ - Shutdown and interrupted runs flush pending telemetry and mark unfinished observations as cancelled/warning instead of silently losing the trace.
17
34
 
18
- ## Quick Install
35
+ ## Prerequisites
36
+
37
+ - **Node.js** >= 22
38
+ - **Pi Coding Agent** installed and configured
39
+ - A **Langfuse** account ([cloud](https://cloud.langfuse.com) or self-hosted)
40
+
41
+ ## Installation
42
+
43
+ ### Option 1: Install via npm (recommended for users)
19
44
 
20
- ### Via npm (recommended)
21
45
  ```bash
22
46
  pi install npm:pi-langfuse
23
47
  ```
24
48
 
49
+ Pi will download the package and register it as an extension.
50
+
51
+ ### Option 2: Install from local source (recommended for development)
52
+
53
+ ```bash
54
+ git clone <your-repo-url>
55
+ cd pi-langfuse
56
+ npm install
57
+ ```
58
+
59
+ Then tell Pi to use it:
60
+
61
+ ```bash
62
+ pi link /path/to/pi-langfuse
63
+ ```
64
+
65
+ Or run Pi from the project directory — Pi auto-discovers extensions in the current directory's `package.json`.
66
+
25
67
  ## Configuration
26
68
 
27
- Get your keys from [Langfuse Cloud](https://cloud.langfuse.com) → Settings → API Keys.
69
+ You need Langfuse API keys. Get them from **Langfuse Cloud****Settings****API Keys**.
28
70
 
29
- On first run, Pi will prompt in the CLI/TUI for:
71
+ There are three ways to configure the extension:
30
72
 
31
- - `LANGFUSE_PUBLIC_KEY`
32
- - `LANGFUSE_SECRET_KEY`
33
- - `LANGFUSE_HOST` (optional, defaults to `https://cloud.langfuse.com`)
73
+ ### Method 1: Interactive setup (easiest)
34
74
 
35
- The extension stores this locally in its own `config.json`, which is ignored by git.
75
+ Run any `pi` command with the extension loaded. On first run without configuration, Pi will prompt you in the CLI or TUI for:
36
76
 
37
- You can also preconfigure it with environment variables instead of using the interactive prompt.
77
+ 1. **Langfuse public key** starts with `pk-lf-...`
78
+ 2. **Langfuse secret key** — starts with `sk-lf-...`
79
+ 3. **Langfuse host** — defaults to `https://cloud.langfuse.com`
38
80
 
39
- To rerun setup later, use:
81
+ The extension saves these to a local `config.json` (ignored by git).
40
82
 
41
- ```bash
83
+ To re-run setup at any time:
84
+
85
+ ```
42
86
  /langfuse-setup
43
87
  ```
44
88
 
89
+ ### Method 2: Environment variables
90
+
91
+ Set these before starting Pi:
92
+
93
+ ```bash
94
+ export LANGFUSE_PUBLIC_KEY="pk-lf-xxxx"
95
+ export LANGFUSE_SECRET_KEY="sk-lf-xxxx"
96
+ export LANGFUSE_BASE_URL="https://cloud.langfuse.com" # optional; LANGFUSE_HOST is also supported
97
+ ```
98
+
99
+ The extension checks the local `config.json` first, then falls back to environment variables.
100
+
101
+ ### Method 3: Local config.json (development only)
102
+
103
+ For local development, create a `config.json` in the project root:
104
+
105
+ ```json
106
+ {
107
+ "publicKey": "pk-lf-xxxx",
108
+ "secretKey": "sk-lf-xxxx",
109
+ "host": "https://cloud.langfuse.com"
110
+ }
111
+ ```
112
+
113
+ > **⚠️ Security**: `config.json` is not tracked by git. Never commit API keys to version control.
114
+
45
115
  ## Usage
46
116
 
47
- ### Run pi with tracing enabled
117
+ ### Basic usage
118
+
119
+ Run Pi as usual — the extension auto-loads and traces every agent run:
48
120
 
49
121
  ```bash
50
- pi "your prompt"
122
+ pi "Explain the architecture of Redis"
51
123
  ```
52
124
 
53
- Pi auto-loads the extension. All sessions will be traced to Langfuse.
125
+ After the session ends, check your [Langfuse dashboard](https://cloud.langfuse.com) for the trace.
126
+
127
+ ### Verify the extension is loaded
128
+
129
+ ```bash
130
+ pi list
131
+ ```
132
+
133
+ You should see `pi-langfuse` in the list of installed packages.
134
+
135
+ ### Multiple sessions
136
+
137
+ Each Pi session gets its own Langfuse session ID. Each user prompt within that Pi session becomes a separate Langfuse trace grouped under the same session.
138
+
139
+ ## Development Setup
140
+
141
+ If you're contributing to this extension:
142
+
143
+ ```bash
144
+ # Clone and install dependencies
145
+ git clone <your-repo-url>
146
+ cd pi-langfuse
147
+ npm install
148
+
149
+ # Type-check your changes
150
+ npm run typecheck
151
+
152
+ # Test with Pi
153
+ pi "test prompt"
154
+ ```
155
+
156
+ ### Project structure
157
+
158
+ ```
159
+ pi-langfuse/
160
+ ├── index.ts # Extension entrypoint and core logic
161
+ ├── package.json # Package metadata
162
+ ├── tsconfig.json # TypeScript configuration
163
+ ├── config.json # Local credentials (git-ignored)
164
+ ├── types/
165
+ │ ├── pi-coding-agent.d.ts # Pi extension API types
166
+ │ └── node-shims.d.ts # Node.js module shims
167
+ ├── .agents/
168
+ │ └── skills/
169
+ │ └── langfuse/
170
+ │ └── SKILL.md # Langfuse CLI skill for data queries
171
+ ├── AGENTS.md # Developer guide (extended)
172
+ ├── README.md # This file
173
+ ├── README_CN.md # Chinese translation
174
+ └── AGENTS_CN.md # Developer guide (Chinese)
175
+ ```
176
+
177
+ ### Validation
178
+
179
+ There is no dedicated test suite yet. To validate changes:
180
+
181
+ 1. Run `npm run typecheck` for TypeScript errors
182
+ 2. Start Pi with the extension enabled
183
+ 3. Run a few prompts
184
+ 4. Confirm traces, the root agent observation, tool observations, generations, and evaluation scores appear in your Langfuse project
54
185
 
55
186
  ## Trace Model
56
187
 
57
188
  ```
58
189
  Trace (name: "pi-agent")
59
190
  ├── Session ID: <pi-session-id>
60
- ├── Metadata: model, provider, cwd
61
- └── Span (name: "tool:<name>")
62
- └── Input/Output logs
63
-
64
- Generation (name: "llm-response")
65
- ├── Model: MiniMax-M2.7
66
- ├── Usage: input/output tokens
67
- └── Cost: input/output/total USD
191
+ ├── input: user prompt, images/context summary when present
192
+ ├── output: final assistant response
193
+ └── Agent observation (name: "pi-agent", type: agent)
194
+ ├── input: current user prompt
195
+ ├── output: final assistant response
196
+ ├── Generation observation (name: "llm-generation", type: generation)
197
+ ├── input: provider request payload / message history
198
+ │ ├── output: finalized assistant message or tool-call message
199
+ │ ├── model, usageDetails, costDetails
200
+ │ └── metadata: provider/request details
201
+ └── Tool observation (name: "<tool-name>", type: tool)
202
+ ├── input: tool parameters
203
+ ├── output: tool result
204
+ └── metadata: toolCallId, isError
68
205
  ```
69
206
 
70
207
  ## What Gets Tracked
71
208
 
72
209
  ### Trace Level
73
- - `input` - User prompt
74
- - `output` - Assistant response
75
- - `sessionId` - Pi session identifier
76
- - `metadata` - Model, provider, cwd
210
+ | Field | Description |
211
+ |-------|-------------|
212
+ | `input` | User prompt, with images/context summary when available |
213
+ | `output` | Final assistant response shown in Pi |
214
+ | `sessionId` | Pi session identifier |
215
+ | `metadata.model` | Model identifier (e.g., "MiniMax-M2.7") |
216
+ | `metadata.provider` | LLM provider name |
217
+ | `metadata.cwd` | Working directory |
218
+
219
+ ### Agent Observation (Root Workflow)
220
+ | Field | Description |
221
+ |-------|-------------|
222
+ | `type` | `agent` |
223
+ | `name` | `pi-agent` |
224
+ | `input` | Current user prompt payload |
225
+ | `output` | Final assistant response |
226
+ | `metadata.sessionId` | Pi session identifier |
227
+ | `metadata.cwd` | Working directory |
228
+ | `metadata.model` | Selected model when available |
229
+ | `metadata.provider` | Provider when available |
230
+
231
+ ### Evaluation Scores (Trace Level)
232
+
233
+ | Score Name | Type | Description |
234
+ |------------|------|-------------|
235
+ | `tool_call_count` | number | Total tool calls in session |
236
+ | `turn_count` | number | Number of assistant turns |
237
+ | `total_tool_errors` | number | Tools that returned errors |
238
+ | `tool_success_rate` | float (0-1) | Ratio of successful tool calls |
239
+ | `session_had_errors` | 0 or 1 | Whether any tool errored |
77
240
 
78
241
  ### Generation Observations (LLM Calls)
79
- - `model` - Model identifier (e.g., "MiniMax-M2.7")
80
- - `usage` - Token counts (input/output/total)
81
- - `costDetails` - Cost breakdown in USD
82
-
83
- ### Span Observations (Tool Calls)
84
- - `name` - Tool name (e.g., "tool:bash")
85
- - `input` - Tool parameters (JSON)
86
- - `output` - Tool result
87
- - `metadata.isError` - Whether tool failed
242
+ | Field | Description |
243
+ |-------|-------------|
244
+ | `type` | `generation` |
245
+ | `name` | `llm-generation` |
246
+ | `input` | Actual provider request payload / message history |
247
+ | `output` | Finalized assistant message, including tool-call payloads for tool-calling turns |
248
+ | `model` | Model identifier (e.g., "MiniMax-M2.7") |
249
+ | `usageDetails.input` | Input token count |
250
+ | `usageDetails.output` | Output token count |
251
+ | `usageDetails.total` | Total token count |
252
+ | `costDetails.total` | Total cost in USD |
253
+ | `costDetails.input` | Input cost in USD |
254
+ | `costDetails.output` | Output cost in USD |
255
+ | `metadata.provider` | Provider name |
256
+ | `metadata.requestId` | Provider/Pi request identifier when available |
257
+ | `metadata.status` | HTTP/provider status when available |
258
+
259
+ ### Tool Observations
260
+ | Field | Description |
261
+ |-------|-------------|
262
+ | `type` | `tool` |
263
+ | `name` | Tool name (e.g., "bash", "read") |
264
+ | `input` | Tool parameters |
265
+ | `output` | Tool result, shaped and truncated for readability |
266
+ | `metadata.toolCallId` | Stable Pi tool call identifier |
267
+ | `metadata.isError` | Whether the tool failed |
268
+ | `level` | `ERROR` for failed tool calls, otherwise `DEFAULT` |
269
+
270
+ ### Observation-Level Scores
271
+ | Score Name | Description |
272
+ |------------|-------------|
273
+ | `tool_is_error` | Value 1 assigned to individual tool observations that errored |
88
274
 
89
275
  ## Langfuse Dashboard
90
276
 
91
277
  After running, check your Langfuse project for:
92
278
 
93
- 1. **Traces** - All pi agent runs with I/O
94
- 2. **Sessions** - Traces grouped by session ID
95
- 3. **Observations** - Tool calls and LLM generations
96
- 4. **Scores** - Evaluation metrics such as tool errors and success rate
97
- 5. **Model Usage** - Usage breakdown by model
279
+ 1. **Traces** All pi agent runs with I/O
280
+ 2. **Sessions** Traces grouped by session ID
281
+ 3. **Observations** Tool calls and LLM generations
282
+ 4. **Scores** Evaluation metrics (tool errors, success rate, etc.)
283
+ 5. **Model Usage** Usage breakdown by model
284
+
285
+ You can also monitor your Langfuse data directly from the terminal using the built-in Langfuse skill:
286
+
287
+ ```
288
+ /pi-langfuse-langfuse <your-query>
289
+ ```
98
290
 
99
291
  ## Troubleshooting
100
292
 
101
- **No traces appearing?**
102
- - Verify API keys are correct in `config.json`
103
- - Check Langfuse project is active
104
- - Ensure API keys have write permissions
293
+ ### No traces appearing?
294
+ - Verify API keys are correct run `/langfuse-setup` to re-configure
295
+ - Check your Langfuse project is active and has write capacity
296
+ - Ensure API keys have write permissions (not read-only)
297
+ - Look for `📊 Langfuse:` log messages in the Pi output
298
+
299
+ ### Extension not loading?
300
+ ```bash
301
+ pi list # Verify pi-langfuse is installed
302
+ pi install npm:pi-langfuse # Reinstall if missing
303
+ ```
304
+
305
+ ### "Missing config" message on startup?
306
+ - The extension needs credentials. Use the interactive `/langfuse-setup` command
307
+ - Or set `LANGFUSE_PUBLIC_KEY` and `LANGFUSE_SECRET_KEY` environment variables
105
308
 
106
- **Extension not loading?**
107
- - Run `pi list` to check installed packages
108
- - Try restarting pi
309
+ ### Model/cost not showing?
310
+ - Not all providers expose cost information
311
+ - Check the Langfuse traces API for raw observation data
312
+ - The `model` field in generations comes from provider events, finalized assistant messages, `model_select`, or `ctx.model`
109
313
 
110
- **Model/cost not showing?**
111
- - Not all providers expose cost info
112
- - Check Langfuse traces API for raw observation data
314
+ ### API key errors?
315
+ - Langfuse public keys start with `pk-lf-`, secret keys with `sk-lf-`
316
+ - If self-hosting, verify your host URL is correct
113
317
 
114
318
  ## Dependencies
115
319
 
116
- - [langfuse](https://www.npmjs.com/package/langfuse) - Langfuse SDK
117
- - [@earendil-works/pi-coding-agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) - Pi extension API
320
+ - [@langfuse/tracing](https://www.npmjs.com/package/@langfuse/tracing) Langfuse observation API for `agent`, `generation`, and `tool` traces
321
+ - [@langfuse/otel](https://www.npmjs.com/package/@langfuse/otel) OpenTelemetry span processor for exporting traces to Langfuse
322
+ - [@langfuse/client](https://www.npmjs.com/package/@langfuse/client) — Langfuse API client used for scores
323
+ - [@opentelemetry/sdk-node](https://www.npmjs.com/package/@opentelemetry/sdk-node) — Node OpenTelemetry SDK
324
+ - [@earendil-works/pi-coding-agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) — Pi extension API (peer dependency)
325
+
326
+ ## About Langfuse Skill
327
+
328
+ This package includes a Langfuse CLI skill (at `.agents/skills/langfuse/`) that lets you query Langfuse data directly from Pi. Use it to look up traces, prompts, datasets, and scores without leaving the terminal. The skill is auto-registered when the extension is installed globally.
118
329
 
119
330
  ## License
120
331