Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "langfuse-observability",
"description": "The Langfuse x Claude Code Observability Plugin",
"version": "1.2.2",
"version": "1.3.0",
"author": {
"name": "Langfuse"
},
Expand Down Expand Up @@ -67,6 +67,12 @@
"description": "Send the conversation so far as each LLM call's input. On long sessions this grows quadratically and span batches can exceed the exporter's 64 MiB limit, which drops them. Set to false to send each call's own new input only.",
"default": true
},
"CC_LANGFUSE_TC_HEADERS": {
"type": "boolean",
"title": "Lift [tc] prompt headers",
"description": "Copy a leading \"[tc key=value ...]\" prompt line into the agent span's metadata (tc_<key>, plus tc_source own|inherited|none), into every agent below it that has no header of its own, and into tc:migration= / tc:work= trace tags.",
"default": true
},
"CC_LANGFUSE_DETERMINISTIC_IDS": {
"type": "boolean",
"title": "Deterministic observation ids",
Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,40 @@ claude plugin update langfuse-observability@langfuse-observability
Restart Claude Code afterwards. `claude plugin list` shows the installed
version.

A session that was already running keeps the hook version it started with,
including a resumed one: the update reaches it only after a restart. Since
1.2.2 every firing writes `langfuse_agents.<key>.json` beside the state file
(`~/.claude/state` by default), so a state directory with no such file has not
run 1.2.2 or later yet.

## Prompt headers

A launcher can start an agent's prompt with one line that says what the work
is for:

```text
[tc migration=m1 batch=b2 fqn=pkg.a:svc phase=codegen]
```

The hook reads it from the agent's full prompt, not from the span input,
which is truncated to `CC_LANGFUSE_MAX_CHARS`. It counts on the first non-blank
line, or on any line that begins with it in the first 4000 characters. A
workflow agent's computed task is read before the relayed user request above
it.

- Each pair becomes `tc_<key>` in the agent span's metadata. Empty values
(`pr=`) are dropped.
- `tc_source` says where they came from: `own`, `inherited` (from the agent
or main-thread turn that launched it, at any depth, workflow agents
included), or `none`. An own header replaces the inherited one whole.
- A main-thread turn whose prompt has a header carries it on its root span.
The root also gets `tc_session_agents` when it ends: the session's agents
so far by source, with `unattributed` for those with no header to own or
inherit.
- `migration` and `work` also become trace tags (`tc:migration=m1`).

Set `CC_LANGFUSE_TC_HEADERS=false` to turn this off.

## Backfilling a past session

The hook can re-upload a finished session from its transcript, for example
Expand Down
Loading
Loading