Skip to content

Commit e25b758

Browse files
fix(observability): map Claude Code user_prompt -> input.value so Langfuse Input isn't null (#59)
Claude Code emits the prompt as the span attribute 'user_prompt' (on claude_code.interaction), but Langfuse reads observation Input from the OpenInference 'input.value' convention -> the Input field showed null while the prompt sat only in the raw-attributes panel. Add an OTTL transform mapping user_prompt -> input.value. Assistant OUTPUT text is NOT emitted on the trace signal (Claude Code sends it via the logs signal, which Langfuse trace ingestion does not consume) -> output shows tokens/cost/finish_reason only; documented inline. Token usage + cost already work (the gen_ai.usage.* transform on main); the recent 'all null' was the stack being down after reboot (4 containers were removed and did not auto-recreate) - brought back up, restart: unless-stopped carries them across reboots. Verified: fresh trace -> observation usage {input:10,output:59,cache...} cost $0.109; claude_code.interaction Input = the prompt text. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent f1fb278 commit e25b758

1 file changed

Lines changed: 6 additions & 0 deletions

File tree

‎docker/otel-collector-config.yaml‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@ processors:
2525
- set(attributes["gen_ai.usage.output_tokens"], attributes["output_tokens"]) where attributes["output_tokens"] != nil
2626
- set(attributes["gen_ai.usage.cache_read_input_tokens"], attributes["cache_read_tokens"]) where attributes["cache_read_tokens"] != nil
2727
- set(attributes["gen_ai.usage.cache_creation_input_tokens"], attributes["cache_creation_tokens"]) where attributes["cache_creation_tokens"] != nil
28+
# Content: Claude Code emits the prompt as `user_prompt` (on claude_code.interaction);
29+
# Langfuse reads observation Input from OpenInference `input.value`. Map it so the
30+
# Input field shows the prompt instead of null. (No completion-text attr exists on
31+
# the trace signal — Claude Code emits assistant output only via the logs signal,
32+
# which Langfuse trace ingestion does not consume; output shows tokens/cost only.)
33+
- set(attributes["input.value"], attributes["user_prompt"]) where attributes["user_prompt"] != nil
2834

2935
exporters:
3036
# Langfuse appends /v1/traces to this base path.

0 commit comments

Comments
 (0)