pi-langfuse 1.0.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.
@@ -0,0 +1,181 @@
1
+ ---
2
+ name: langfuse-sdk-upgrade
3
+ description: Upgrade Langfuse SDKs from older versions to the latest. Use when migrating Python SDK v2/v3 to v4, or JS/TS SDK v3/v4 to v5.
4
+ ---
5
+
6
+ # Langfuse SDK Upgrade Guide
7
+
8
+ Assist users in upgrading their Langfuse SDK to the latest version. The Python and JS/TS SDKs share the same architectural changes but differ in syntax.
9
+
10
+ ## When to Use
11
+
12
+ - User asks to upgrade/migrate their Langfuse SDK
13
+ - User is on an older SDK version and encounters deprecated APIs
14
+ - User wants to adopt the latest Langfuse features
15
+
16
+ ## Migration Docs
17
+
18
+ Always fetch the latest migration guide before starting — these pages are the source of truth:
19
+
20
+ - **Python (v3 → v4):** https://langfuse.com/docs/observability/sdk/upgrade-path/python-v3-to-v4
21
+ - **JS/TS (v4 → v5):** https://langfuse.com/docs/observability/sdk/upgrade-path/js-v4-to-v5
22
+
23
+ Fetch the relevant page as markdown before implementing any changes:
24
+
25
+ ```bash
26
+ curl -s "https://langfuse.com/docs/observability/sdk/upgrade-path/python-v3-to-v4.md"
27
+ curl -s "https://langfuse.com/docs/observability/sdk/upgrade-path/js-v4-to-v5.md"
28
+ ```
29
+
30
+ ## Upgrade Checklist
31
+
32
+ Work through each item in order. Skip items that don't apply to the user's codebase.
33
+
34
+ ### Both SDKs
35
+
36
+ - [ ] **Update the SDK package** to the latest version
37
+ - [ ] **Audit span filtering**: Non-LLM spans (HTTP, DB, queues) no longer export by default. If the user relied on these, configure a custom `should_export_span` / `shouldExportSpan` filter
38
+ - [ ] **Replace `update_current_trace()` / `updateActiveTrace()`**: Split into three calls:
39
+ - `propagate_attributes()` / `propagateAttributes()` for correlating attributes (`user_id`, `session_id`, `tags`, `metadata`, `trace_name`)
40
+ - `set_current_trace_io()` / `setActiveTraceIO()` for input/output (deprecated — prefer setting I/O on root observation directly)
41
+ - `set_current_trace_as_public()` / `setActiveTraceAsPublic()` for public flag
42
+ - [ ] **Replace `.update_trace()` / `.updateTrace()`** on observation objects (same decomposition as above)
43
+ - [ ] **Update API namespace references**: `observations_v_2` / `observationsV2` → `observations`, `score_v_2` / `scoreV2` → `scores`, `metrics_v_2` / `metricsV2` → `metrics`. Legacy v1 APIs moved to `api.legacy.*`
44
+ - [ ] **Validate metadata format**: Must be `dict[str, str]` / `Record<string, string>` with values ≤200 characters
45
+ - [ ] **Move `release` and `environment`** from code parameters to environment variables (`LANGFUSE_RELEASE`, `LANGFUSE_TRACING_ENVIRONMENT`)
46
+ - [ ] **Enable debug logging** during migration to catch issues (`debug=True` in Python, `LANGFUSE_DEBUG="true"` in JS/TS)
47
+ - [ ] **Test trace hierarchies** to verify no spans are unexpectedly dropped
48
+
49
+ ### Python-specific
50
+
51
+ - [ ] **Replace `start_span()` / `start_generation()`** with `start_observation()` (use `as_type="generation"` for generations)
52
+ - [ ] **Replace `start_as_current_span()` / `start_as_current_generation()`** with `start_as_current_observation()`
53
+ - [ ] **Replace dataset `item.run()`** with `dataset.run_experiment(name=..., task=...)`
54
+ - [ ] **Remove `CallbackHandler(update_trace=...)`** parameter — use `propagate_attributes()` wrapper instead
55
+ - [ ] **Upgrade to Pydantic v2** — the SDK now requires it. Use `pydantic.v1` compatibility shim if migrating gradually
56
+ - [ ] **Update removed types**: `TraceMetadata`, `ObservationParams` removed from `langfuse.types`. Import `MapValue`, `ModelUsage`, `PromptClient` from `langfuse.model`
57
+
58
+ ### JS/TS-specific
59
+
60
+ - [ ] **Update LangChain `CallbackHandler`** — `traceMetadata` now requires string values; internal behavior uses `propagateAttributes()` instead of direct trace updates
61
+ - [ ] **Update OpenAI integration** — `traceMethod` wrapper now uses `propagateAttributes()` internally; wrap entire execution in `propagateAttributes()` if relying on parent attribute inheritance
62
+
63
+ ## Key API Changes Reference
64
+
65
+ ### Correlating attributes (both SDKs)
66
+
67
+ **Before:**
68
+ ```python
69
+ # Python
70
+ langfuse.update_current_trace(name="trace-name", user_id="user-123", session_id="session-abc", tags=["tag1"])
71
+ ```
72
+ ```typescript
73
+ // JS/TS
74
+ updateActiveTrace({ name: "trace-name", userId: "user-123", sessionId: "session-456", tags: ["prod"] });
75
+ ```
76
+
77
+ **After:**
78
+ ```python
79
+ # Python
80
+ from langfuse import propagate_attributes
81
+
82
+ with propagate_attributes(trace_name="trace-name", user_id="user-123", session_id="session-abc", tags=["tag1"]):
83
+ result = call_llm("hello")
84
+ ```
85
+ ```typescript
86
+ // JS/TS
87
+ import { propagateAttributes } from "langfuse";
88
+
89
+ await propagateAttributes(
90
+ { traceName: "trace-name", userId: "user-123", sessionId: "session-456", tags: ["prod"] },
91
+ async () => { /* traced code */ }
92
+ );
93
+ ```
94
+
95
+ ### Span/Generation creation (Python)
96
+
97
+ **Before:**
98
+ ```python
99
+ langfuse.start_span(name="x")
100
+ langfuse.start_generation(name="x", model="gpt-4")
101
+ ```
102
+
103
+ **After:**
104
+ ```python
105
+ langfuse.start_observation(name="x")
106
+ langfuse.start_observation(name="x", as_type="generation", model="gpt-4")
107
+ ```
108
+
109
+ ### Dataset experiments (Python)
110
+
111
+ **Before:**
112
+ ```python
113
+ for item in dataset.items:
114
+ with item.run(run_name="my-run") as span:
115
+ result = my_llm(item.input)
116
+ span.update(output=result)
117
+ ```
118
+
119
+ **After:**
120
+ ```python
121
+ def my_task(*, item, **kwargs):
122
+ return my_llm(item.input)
123
+
124
+ dataset.run_experiment(name="my-run", task=my_task)
125
+ ```
126
+
127
+ ### Span filtering (both SDKs)
128
+
129
+ To restore pre-upgrade "export all" behavior:
130
+
131
+ ```python
132
+ # Python
133
+ langfuse = Langfuse(should_export_span=lambda span: True)
134
+ ```
135
+ ```typescript
136
+ // JS/TS
137
+ const spanProcessor = new LangfuseSpanProcessor({ shouldExportSpan: () => true });
138
+ ```
139
+
140
+ To extend defaults with custom scopes:
141
+
142
+ ```python
143
+ # Python
144
+ from langfuse.span_filter import is_default_export_span
145
+
146
+ langfuse = Langfuse(
147
+ should_export_span=lambda span: (
148
+ is_default_export_span(span)
149
+ or span.instrumentation_scope.name.startswith("my_framework")
150
+ )
151
+ )
152
+ ```
153
+ ```typescript
154
+ // JS/TS
155
+ import { isDefaultExportSpan } from "@langfuse/otel";
156
+
157
+ shouldExportSpan: ({ otelSpan }) =>
158
+ isDefaultExportSpan(otelSpan) || otelSpan.instrumentationScope.name.startsWith("my_framework")
159
+ ```
160
+
161
+ ## Common Pitfalls
162
+
163
+ | Pitfall | Impact | Fix |
164
+ | --- | --- | --- |
165
+ | Dropping intermediate spans via filtering | Breaks trace trees — child spans become orphaned | Use `is_default_export_span` as base and only add/remove specific scopes |
166
+ | Metadata with non-string values | Values silently coerced or dropped | Ensure all metadata values are strings ≤200 characters |
167
+ | Setting attributes outside `propagate_attributes()` callback | Attributes don't attach to observations | Wrap all traced code inside the callback |
168
+ | Using deprecated `set_current_trace_io()` for new code | Will be removed in future versions | Set input/output directly on the root observation |
169
+ | Forgetting Pydantic v2 upgrade (Python) | Import errors or runtime failures | Upgrade Pydantic or use `pydantic.v1` shim |
170
+ | `release`/`environment` still passed as parameters | Silently ignored | Use `LANGFUSE_RELEASE` and `LANGFUSE_TRACING_ENVIRONMENT` env vars |
171
+ | LangChain/OpenAI attribute propagation direction changed | Attributes propagate downward only, not upward to parent traces | Wrap outer call in `propagate_attributes()` |
172
+
173
+ ## Best Practices
174
+
175
+ 1. **Always fetch the migration docs first** — they are the canonical source and may have been updated since this guide was written
176
+ 2. **Enable debug logging during migration** to surface dropped spans and trace hierarchy issues
177
+ 3. **Use `propagate_attributes()` as the primary mechanism** for setting trace-level correlating attributes
178
+ 4. **Set input/output on root observations directly** rather than using deprecated trace-level setters
179
+ 5. **Compose custom span filters** with `is_default_export_span` / `isDefaultExportSpan` to extend defaults rather than replacing them entirely
180
+ 6. **Test thoroughly** — run the application with debug logging, check the Langfuse UI for missing or orphaned spans, verify metadata appears correctly
181
+ 7. **Migrate incrementally** — upgrade the SDK first, fix breaking changes, then adopt new patterns
@@ -0,0 +1,52 @@
1
+ ---
2
+ name: langfuse-skill-feedback
3
+ description: Submit feedback about the Langfuse skill to its maintainers via GitHub Discussions. Use when the user indicates the skill gave incorrect guidance, is missing information, or could be improved.
4
+ ---
5
+
6
+ # Skill Feedback
7
+
8
+ Follow these steps exactly:
9
+
10
+ 1. **Ask permission**: Ask the user if they'd like you to submit feedback to the skill maintainers. Make it clear this is about the skill (the agent instructions), not about Langfuse the product. If they decline, move on.
11
+ 2. **Draft feedback**: Write the feedback using the form structure below. Present the draft to the user and ask if they'd like to change anything before submitting.
12
+ 3. **Submit**: Once approved, submit via `gh` CLI as described below. Share the resulting discussion URL with the user.
13
+
14
+ ## Feedback Form Structure
15
+
16
+ Draft the feedback using these two fields:
17
+
18
+ **Describe your idea or feedback** (required)
19
+ A clear description of what went wrong or what could be improved. Include:
20
+ - What the user was trying to do
21
+ - What the skill did vs what was expected
22
+ - Any specific instructions that were incorrect or missing
23
+
24
+ **What would the ideal outcome look like?** (optional)
25
+ What the correct behavior or guidance should be.
26
+
27
+ Format the body as markdown with the two field labels as headings.
28
+
29
+ ## Submitting
30
+
31
+ Create a GitHub Discussion on the `langfuse/skills` repository using the GraphQL API:
32
+
33
+ ```bash
34
+ gh api graphql -f query='
35
+ mutation($repoId: ID!, $categoryId: ID!, $title: String!, $body: String!) {
36
+ createDiscussion(input: {repositoryId: $repoId, categoryId: $categoryId, title: $title, body: $body}) {
37
+ discussion { url }
38
+ }
39
+ }' \
40
+ -f repoId="$(gh api graphql -f query='{ repository(owner: "langfuse", name: "skills") { id } }' --jq '.data.repository.id')" \
41
+ -f categoryId="$(gh api graphql -f query='{ repository(owner: "langfuse", name: "skills") { discussionCategories(first: 10) { nodes { id name } } } }' --jq '.data.repository.discussionCategories.nodes[] | select(.name == "Ideas & Improvements") | .id')" \
42
+ -f title="<concise title>" \
43
+ -f body="<formatted feedback>"
44
+ ```
45
+
46
+ If the `gh` CLI is not authenticated or the request fails, give the user this link to create the discussion manually:
47
+
48
+ ```
49
+ https://github.com/langfuse/skills/discussions/new?category=ideas-improvements
50
+ ```
51
+
52
+ After submission, share the discussion URL with the user.
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: langfuse-user-feedback
3
+ description: Wires up user feedback (thumbs up/down, ratings, comments) from an application's frontend to Langfuse scores. Use when user wants to capture end-user feedback, add ratings to traces, or connect user complaints to Langfuse.
4
+ ---
5
+
6
+ # User Feedback
7
+
8
+ Tracing must already be set up — feedback is stored as scores on traces.
9
+
10
+ Docs: https://langfuse.com/docs/observability/features/user-feedback
11
+
12
+ ## Workflow
13
+
14
+ ### 1. Determine What Feedback to Capture
15
+
16
+ If the user has asked for something specific, go with that. Otherwise, look at the application and **present a few UX options** for how feedback could work, then ask the user which they prefer before implementing.
17
+
18
+ Common UX patterns to suggest:
19
+
20
+ | UX Pattern | Best for | How it works |
21
+ |------------|----------|--------------|
22
+ | Thumbs up/down | Chat apps, Q&A | Simple binary buttons next to each response |
23
+ | Star rating (1–5) | Content generation, summaries | Star row or dropdown after each output |
24
+ | "Was this helpful?" banner | Search, documentation assistants | Single yes/no prompt at the bottom of a response |
25
+ | Regenerate / copy tracking | Any app with these actions | Implicit — log when users retry (negative signal) or copy output (positive signal) |
26
+ | Free-text comment | Complex outputs, internal tools | Optional text field alongside a rating |
27
+ | Report button | Any user-facing app | Flag icon to report bad/harmful responses |
28
+
29
+ This table is not exhaustive — if the application suggests a different feedback pattern that fits better, propose that instead. Present 2–3 options that match the application's use case and ask the user which approach they'd like. This decision shapes everything downstream (score names, data types, frontend components), so it's important to align early.
30
+
31
+ Feedback can be **explicit** (user rates via thumbs, stars, etc.) or **implicit** (derived from behavior like copying output, retrying, or escalating to support). Both are stored as scores. Explicit feedback requires the trace ID to reach the frontend; implicit feedback is logged server-side where the event already happens.
32
+
33
+ ### 2. Choose Score Names
34
+
35
+ Name reflects the signal source, not what you hope it measures (e.g., `user-thumbs` not `response-quality` — a thumbs down doesn't tell you *what* was wrong). Avoid generic names like `feedback` or `score`.
36
+
37
+ Rules:
38
+ - Lowercase with hyphens
39
+ - One consistent name per feedback type across the entire app
40
+ - If capturing multiple signals, each gets its own distinct name
41
+
42
+ ### 3. Implement Score Creation
43
+
44
+ **For implicit feedback (server-side):** Use `langfuse.create_score()` / `langfuse.score.create()` wherever the event is already handled in application code. Fetch SDK docs for current API: https://langfuse.com/docs/evaluation/evaluation-methods/scores-via-sdk
45
+
46
+ **For explicit feedback (frontend):** Use `LangfuseWeb` in the browser. It uses the public key only — no secret key exposed.
47
+
48
+ ```typescript
49
+ import { LangfuseWeb } from "langfuse";
50
+
51
+ const langfuse = new LangfuseWeb({
52
+ publicKey: process.env.NEXT_PUBLIC_LANGFUSE_PUBLIC_KEY!,
53
+ baseUrl: process.env.NEXT_PUBLIC_LANGFUSE_HOST,
54
+ });
55
+
56
+ langfuse.score({
57
+ traceId,
58
+ name: "user-thumbs",
59
+ value: 1, // 1 = positive, 0 = negative
60
+ dataType: "BOOLEAN",
61
+ comment: optionalUserComment,
62
+ });
63
+ ```
64
+
65
+ The trace ID must be available in the frontend for this to work. For Vercel AI SDK, the non-obvious pattern is using `generateMessageId`:
66
+
67
+ ```typescript
68
+ import { getActiveTraceId } from "@langfuse/tracing";
69
+
70
+ // Inside route handler wrapped with observe()
71
+ return result.toUIMessageStreamResponse({
72
+ generateMessageId: () => getActiveTraceId() || crypto.randomUUID(),
73
+ });
74
+ ```
75
+
76
+ ### 4. Verify
77
+
78
+ Trigger a feedback action and check the trace's Scores tab in Langfuse. Confirm the score name, value, and data type are correct.
79
+
80
+ Point users to what they can do with feedback data: filter traces by low scores, use score analytics for trends, build annotation queues for team review.
81
+
82
+ ## Common Mistakes
83
+
84
+ | Mistake | Problem | Fix |
85
+ |---------|---------|-----|
86
+ | Secret key in frontend code | Security risk | Use `LangfuseWeb` with public key only |
87
+ | Missing `dataType` on boolean scores | Value `1` inferred as `NUMERIC` | Always pass `dataType: "BOOLEAN"` explicitly |
88
+ | Inconsistent score names across the app | Can't aggregate or filter reliably | Pick one name per feedback type, use it everywhere |
package/AGENTS.md ADDED
@@ -0,0 +1,57 @@
1
+ # AGENTS.md
2
+
3
+ ## Project Overview
4
+
5
+ This repository contains a Pi Coding Agent extension that forwards session activity to Langfuse for observability. The runtime is intentionally small:
6
+
7
+ - `index.ts`: extension entrypoint, event listeners, trace/span/generation lifecycle, and scoring
8
+ - `package.json`: package metadata for Pi/NPM
9
+ - `config.json`: local credentials file for manual development only, ignored by git
10
+ - `.agents/skills/langfuse/SKILL.md`: local skill instructions for Langfuse-related workflows
11
+
12
+ ## How The Extension Works
13
+
14
+ The extension listens to Pi lifecycle events and maps them into Langfuse objects:
15
+
16
+ 1. `session_start` captures a stable session id
17
+ 2. `before_agent_start` creates a trace for the user prompt
18
+ 3. `tool_call` / `tool_result` create and close tool spans
19
+ 4. `turn_end` records LLM usage/cost metadata as a generation
20
+ 5. `agent_end` finalizes the trace and publishes aggregate evaluation scores
21
+ 6. `session_shutdown` flushes any remaining state
22
+
23
+ The code is stateful by design. Changes to trace/session bookkeeping should be reviewed carefully because multiple Pi hooks share the same module-level state.
24
+
25
+ ## Local Development
26
+
27
+ Recommended environment:
28
+
29
+ - Node.js `>=22` as declared in `package.json`
30
+ - A local `config.json` with Langfuse credentials
31
+
32
+ Typical workflow:
33
+
34
+ ```bash
35
+ npm install
36
+ pi "test prompt"
37
+ ```
38
+
39
+ There is currently no dedicated test suite or `npm` script. When changing behavior, validate by running Pi with the extension enabled and confirming traces, spans, generations, and scores appear in Langfuse.
40
+
41
+ ## Editing Guidance
42
+
43
+ - Prefer small, behavior-preserving changes in `index.ts`; most bugs here are lifecycle or observability-shape bugs rather than UI issues.
44
+ - Keep credential material out of version control. `config.json` should stay local.
45
+ - When logging tool input/output, be mindful of payload size and serialization failures.
46
+ - If you add new Langfuse fields, verify them against current official docs because the SDK surface evolves.
47
+ - Avoid hard-coding install-layout assumptions when importing SDK files unless Pi requires it.
48
+
49
+ ## Review Focus Areas
50
+
51
+ When reviewing or extending this project, pay extra attention to:
52
+
53
+ - Trace lifecycle consistency across `before_agent_start`, `agent_end`, and `session_shutdown`
54
+ - Correct score attribution at trace level vs observation level
55
+ - Defensive handling of unexpected event payload shapes
56
+ - Truncation/redaction strategy for large tool payloads
57
+ - Compatibility between the installed Langfuse SDK version and any manually declared local TypeScript interfaces
package/AGENTS_CN.md ADDED
@@ -0,0 +1,57 @@
1
+ # AGENTS.md
2
+
3
+ ## 项目概述
4
+
5
+ 此仓库包含一个 Pi Coding Agent 扩展,将会话活动转发到 Langfuse 进行可观测性监控。运行时设计得尽可能精简:
6
+
7
+ - `index.ts`:扩展入口点、事件监听器、跟踪/跨度/生成生命周期和评分
8
+ - `package.json`:Pi/NPM 的包元数据
9
+ - `config.json`:仅用于手动开发的本地凭据文件,被 git 忽略
10
+ - `.agents/skills/langfuse/SKILL.md`:Langfuse 相关工作流的本地技能说明
11
+
12
+ ## 扩展工作原理
13
+
14
+ 该扩展监听 Pi 生命周期事件,并将它们映射到 Langfuse 对象:
15
+
16
+ 1. `session_start` 捕获稳定的会话 ID
17
+ 2. `before_agent_start` 为用户提示创建跟踪
18
+ 3. `tool_call` / `tool_result` 创建和关闭工具跨度
19
+ 4. `turn_end` 将 LLM 使用/成本元数据记录为生成
20
+ 5. `agent_end` 完成跟踪并发布聚合评估分数
21
+ 6. `session_shutdown` 刷新任何剩余状态
22
+
23
+ 代码设计为有状态的。对跟踪/会话簿记的更改应仔细审查,因为多个 Pi 钩子共享相同的模块级状态。
24
+
25
+ ## 本地开发
26
+
27
+ 推荐环境:
28
+
29
+ - Node.js `>=22`(如 `package.json` 中声明)
30
+ - 包含 Langfuse 凭据的本地 `config.json`
31
+
32
+ 典型工作流程:
33
+
34
+ ```bash
35
+ npm install
36
+ pi "test prompt"
37
+ ```
38
+
39
+ 目前没有专门的测试套件或 `npm` 脚本。更改行为时,通过启用扩展运行 Pi 并确认跟踪、跨度、生成和分数出现在 Langfuse 中来验证。
40
+
41
+ ## 编辑指南
42
+
43
+ - 优先在 `index.ts` 中进行小的、保持行为的更改;这里的错误大多是生命周期或可观测性形状错误,而不是 UI 问题。
44
+ - 将凭据材料排除在版本控制之外。`config.json` 应保持本地。
45
+ - 记录工具输入/输出时,注意有效负载大小和序列化失败。
46
+ - 如果添加新的 Langfuse 字段,请根据当前官方文档验证,因为 SDK 表面会演变。
47
+ - 除非 Pi 要求,否则避免在导入 SDK 文件时硬编码安装布局假设。
48
+
49
+ ## 审查重点领域
50
+
51
+ 审查或扩展此项目时,请特别注意:
52
+
53
+ - 跨 `before_agent_start`、`agent_end` 和 `session_shutdown` 的跟踪生命周期一致性
54
+ - 跟踪级别与观察级别的正确分数归属
55
+ - 对意外事件负载形状的防御性处理
56
+ - 大型工具有效负载的截断/编辑策略
57
+ - 已安装的 Langfuse SDK 版本与任何手动声明的本地 TypeScript 接口之间的兼容性
package/README.md ADDED
@@ -0,0 +1,121 @@
1
+ # pi-langfuse
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.
4
+
5
+ ## Why Langfuse?
6
+
7
+ Langfuse provides open-source observability for LLM applications. This extension allows you to **trace**, **monitor**, and **debug** your Pi sessions with production-grade detail, helping you understand exactly how your agent is performing, what it's costing you, and where it might be failing.
8
+
9
+ ## Features
10
+
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.
17
+
18
+ ## Quick Install
19
+
20
+ ### Via npm (recommended)
21
+ ```bash
22
+ pi install npm:pi-langfuse
23
+ ```
24
+
25
+ ## Configuration
26
+
27
+ Get your keys from [Langfuse Cloud](https://cloud.langfuse.com) → Settings → API Keys.
28
+
29
+ On first run, Pi will prompt in the CLI/TUI for:
30
+
31
+ - `LANGFUSE_PUBLIC_KEY`
32
+ - `LANGFUSE_SECRET_KEY`
33
+ - `LANGFUSE_HOST` (optional, defaults to `https://cloud.langfuse.com`)
34
+
35
+ The extension stores this locally in its own `config.json`, which is ignored by git.
36
+
37
+ You can also preconfigure it with environment variables instead of using the interactive prompt.
38
+
39
+ To rerun setup later, use:
40
+
41
+ ```bash
42
+ /langfuse-setup
43
+ ```
44
+
45
+ ## Usage
46
+
47
+ ### Run pi with tracing enabled
48
+
49
+ ```bash
50
+ pi "your prompt"
51
+ ```
52
+
53
+ Pi auto-loads the extension. All sessions will be traced to Langfuse.
54
+
55
+ ## Trace Model
56
+
57
+ ```
58
+ Trace (name: "pi-agent")
59
+ ├── 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
68
+ ```
69
+
70
+ ## What Gets Tracked
71
+
72
+ ### Trace Level
73
+ - `input` - User prompt
74
+ - `output` - Assistant response
75
+ - `sessionId` - Pi session identifier
76
+ - `metadata` - Model, provider, cwd
77
+
78
+ ### 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
88
+
89
+ ## Langfuse Dashboard
90
+
91
+ After running, check your Langfuse project for:
92
+
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
98
+
99
+ ## Troubleshooting
100
+
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
105
+
106
+ **Extension not loading?**
107
+ - Run `pi list` to check installed packages
108
+ - Try restarting pi
109
+
110
+ **Model/cost not showing?**
111
+ - Not all providers expose cost info
112
+ - Check Langfuse traces API for raw observation data
113
+
114
+ ## Dependencies
115
+
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
118
+
119
+ ## License
120
+
121
+ MIT
package/README_CN.md ADDED
@@ -0,0 +1,120 @@
1
+ # pi-langfuse
2
+
3
+ [Pi Coding Agent](https://github.com/earendil-works/pi-coding-agent) 的 Langfuse 可观测性扩展。将跟踪发送到 [Langfuse](https://langfuse.com) 以监控令牌、成本、延迟和工具调用。
4
+
5
+ ## 为什么选择 Langfuse?
6
+
7
+ Langfuse 为 LLM 应用程序提供开源的可观测性。此扩展允许您以生产级细节**跟踪**、**监控**和**调试**您的 Pi 会话,帮助您准确了解代理的性能、成本以及可能失败的地方。
8
+
9
+ ## 功能
10
+
11
+ - **分层跟踪**:将用户提示映射到每轮跨度和嵌套工具执行,实现深度可见性。
12
+ - **LLM 元数据**:自动记录每轮的模型名称、提供商、令牌使用情况和 API 成本。
13
+ - **工具可观测性**:每个工具调用的详细日志,包括参数、结果和错误状态。
14
+ - **会话关联**:将同一 Pi 会话中的所有提示分组到单个 Langfuse 会话中。
15
+ - **成本跟踪**:记录每代输入/输出/总成本(美元)。
16
+ - **令牌使用**:跟踪每轮的输入和输出令牌。
17
+
18
+ ## 快速安装
19
+
20
+ ### 通过 npm(推荐)
21
+ ```bash
22
+ pi install npm:pi-langfuse
23
+ ```
24
+
25
+ ## 配置
26
+
27
+ 从 [Langfuse Cloud](https://cloud.langfuse.com) → 设置 → API 密钥获取您的密钥。
28
+
29
+ 在扩展目录中创建 `config.json`:
30
+
31
+ ```json
32
+ {
33
+ "publicKey": "pk-lf-xxxx",
34
+ "secretKey": "sk-lf-xxxx",
35
+ "host": "https://cloud.langfuse.com"
36
+ }
37
+ ```
38
+
39
+ 对于 npm 安装,扩展位于:
40
+ ```
41
+ ~/.pi/agent/npm/@ravan08/pi-langfuse/index.ts
42
+ ```
43
+
44
+ ## 使用
45
+
46
+ ### 启用跟踪运行 pi
47
+
48
+ ```bash
49
+ pi "your prompt"
50
+ ```
51
+
52
+ Pi 自动加载扩展。所有会话都将被跟踪到 Langfuse。
53
+
54
+ ## 跟踪模型
55
+
56
+ ```
57
+ 跟踪(名称:"pi-agent")
58
+ ├── 会话 ID:<pi-session-id>
59
+ ├── 元数据:模型、提供商、cwd
60
+ └── 跨度(名称:"tool:<name>")
61
+ └── 输入/输出日志
62
+
63
+ 生成(名称:"llm-response")
64
+ ├── 模型:MiniMax-M2.7
65
+ ├── 使用:输入/输出令牌
66
+ └── 成本:输入/输出/总美元
67
+ ```
68
+
69
+ ## 跟踪内容
70
+
71
+ ### 跟踪级别
72
+ - `input` - 用户提示
73
+ - `output` - 助手响应
74
+ - `sessionId` - Pi 会话标识符
75
+ - `metadata` - 模型、提供商、cwd
76
+
77
+ ### 生成观察(LLM 调用)
78
+ - `model` - 模型标识符(例如,"MiniMax-M2.7")
79
+ - `usage` - 令牌计数(输入/输出/总计)
80
+ - `costDetails` - 成本细分(美元)
81
+
82
+ ### 跨度观察(工具调用)
83
+ - `name` - 工具名称(例如,"tool:bash")
84
+ - `input` - 工具参数(JSON)
85
+ - `output` - 工具结果
86
+ - `metadata.isError` - 工具是否失败
87
+
88
+ ## Langfuse 仪表板
89
+
90
+ 运行后,在您的 Langfuse 项目中检查:
91
+
92
+ 1. **跟踪** - 所有 pi 代理运行及其 I/O
93
+ 2. **会话** - 按会话 ID 分组的跟踪
94
+ 3. **观察** - 工具调用和 LLM 生成
95
+ 4. **分数** - 评估指标,如工具错误和成功率
96
+ 5. **模型使用** - 按模型划分的使用情况细分
97
+
98
+ ## 故障排除
99
+
100
+ **没有跟踪出现?**
101
+ - 验证 `config.json` 中的 API 密钥是否正确
102
+ - 检查 Langfuse 项目是否活跃
103
+ - 确保 API 密钥具有写入权限
104
+
105
+ **扩展未加载?**
106
+ - 运行 `pi list` 检查已安装的包
107
+ - 尝试重启 pi
108
+
109
+ **模型/成本未显示?**
110
+ - 并非所有提供商都公开成本信息
111
+ - 检查 Langfuse 跟踪 API 获取原始观察数据
112
+
113
+ ## 依赖项
114
+
115
+ - [langfuse](https://www.npmjs.com/package/langfuse) - Langfuse SDK
116
+ - [@earendil-works/pi-coding-agent](https://www.npmjs.com/package/@earendil-works/pi-coding-agent) - Pi 扩展 API
117
+
118
+ ## 许可证
119
+
120
+ MIT