Skip to content

feat: trace reasoning content and offered tools on generations - #37

Open
Ali-Aleph-Alpha wants to merge 1 commit into
langfuse:mainfrom
Ali-Aleph-Alpha:feat/reasoning-and-tools
Open

Ali-Aleph-Alpha wants to merge 1 commit into
langfuse:mainfrom
Ali-Aleph-Alpha:feat/reasoning-and-tools

Conversation

@Ali-Aleph-Alpha

Copy link
Copy Markdown

Change

Traces recorded the model's answer text but not its reasoning: thinking blocks were extracted for the history input but dropped from the generation output, so a Langfuse trace showed token counts for reasoning (output_reasoning_tokens) without the reasoning itself.

Generation output now carries the reasoning as Langfuse thinking blocks ({ type: "thinking", content }, the same ChatML shape the history input already uses, which Langfuse renders as collapsible reasoning blocks):

  • Structured thinking blocks from pi's message content are included in the generation output.
  • Reasoning streamed inline as <think> tags — the vLLM default and common on OpenAI-compatible servers that do not send a structured reasoning field — is split out of the answer text. An unclosed tag (aborted stream) is treated as reasoning until the end. Structured blocks win over inline tags so a model emitting both is not traced twice.
  • Thinking content goes through the secret redactor: models regularly quote file contents (including .env) into their reasoning.
  • thinkingSignature stays untraced (provider replay data; already covered by an existing test).

Time to first token now counts thinking tokens, which reasoning models stream before any text — previously TTFT was inflated by the full reasoning phase.

Each generation also records the tool definitions the model was called with (name, description, parameter schema) as available_tools metadata, and the turn root lists the active tool names, so a trace can distinguish "tool not offered" from "tool not chosen".

Notes

Test plan

  • pnpm typecheck, pnpm test (111 tests: unit + integration against the real pi CLI with a mock provider and a fake Langfuse ingest)
  • New coverage: think-tag splitting (closed/unclosed/multiple/redaction), structured-over-inline precedence, redaction of secrets in reasoning, readAvailableTools filtering and older-pi fallback, integration assertions for thinking in generation output and available_tools metadata

@CLAassistant

CLAassistant commented Sep 15, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

Generation output now carries the model's reasoning as Langfuse thinking
blocks next to the answer text:

- structured thinking blocks from pi's message content are included in
  the generation output (previously only in the history input)
- reasoning streamed inline as <think> tags (vLLM default, DeepSeek
  distill, and other OpenAI-compatible servers that do not send a
  structured reasoning field) is split out of the answer text; an
  unclosed tag is treated as reasoning until the end of the stream
- structured blocks win over inline tags so a model emitting both is
  not traced twice
- thinking content goes through the secret redactor, since models
  regularly quote file contents (including .env) into their reasoning
- thinkingSignature stays untraced (provider replay data)

Time to first token now counts thinking tokens, which reasoning models
stream before any text.

Each generation also records the tool definitions the model was called
with (name, description, parameter schema) as available_tools metadata,
and the turn root lists the active tool names, so a trace can
distinguish 'tool not offered' from 'tool not chosen'.

Note: the available_tools part overlaps with langfuse#34 (which attaches tool
definitions to the generation input for playground replay). Happy to
drop it in favor of langfuse#34 and keep only the reasoning changes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants