Skip to content

bug(langfuse): Observations missing toolCalls/toolCallNames fields; ToolInvoker misses tool arguments #3435

Description

@Hansehart

Describe the bug

When using the Langfuse integration with a Haystack Agent (which uses ToolInvoker internally), TOOL-type observations are created with the correct type but the Langfuse-native toolCalls, toolCallNames, and toolDefinitions fields are always null. This has two practical consequences:

  1. Filtering by tool call name in the Langfuse UI does not work. The "Tool Call Name" filter reads from toolCallNames, which is never populated. The tool name only appears in the observation's name string (e.g. tool_invoker - ['read_pages']), which is not indexed for that filter.

  2. The TOOL observation's input contains the entire conversation message history passed to the ToolInvoker, not just the arguments of the specific tool call that was executed. This makes individual tool observations noisy and hard to read.

Example observation from a real trace (fields trimmed for brevity):

{
  "type": "TOOL",
  "name": "tool_invoker - ['read_pages']",
  "toolDefinitions": null,
  "toolCalls": null,
  "toolCallNames": null
}

The same null values appear on GENERATION observations even when the LLM response contained tool call requests, so the toolCalls field is also missing there.

Root cause

In tracer.py, LangfuseSpan.set_content_tag stores the ToolInvoker input via:

self._span.update(input=messages)  # `messages` is the full ChatMessage list

This writes the entire message list as a generic input blob. The Langfuse SDK fields tool_calls, tool_definitions etc. are never passed to span.update(...), so Langfuse never indexes them.

DefaultSpanHandler.handle similarly never calls span.raw_span().update(tool_calls=..., tool_definitions=...) for either ToolInvoker or ChatGenerator components.

Expected behavior

  • For TOOL observations: input should contain only the arguments of the specific tool call(s) that were executed; output should contain only the corresponding tool result(s). toolCallNames should be populated so the Langfuse filter works.
  • For GENERATION observations: when the LLM reply contains tool call requests, toolCalls should be populated with the structured call data.

To Reproduce

  1. Set up a Haystack Agent with at least one tool and wire up LangfuseConnector.
  2. Run the agent on a query that triggers at least one tool call.
  3. Open the resulting trace in the Langfuse UI.
  4. Try to filter observations by "Tool Call Name" (no results)

Describe your environment:

  • OS: Linux (Ubuntu 24.04)
  • Haystack version: haystack-ai==2.30.1
  • Integration version: langfuse-haystack==5.2.0

Metadata

Metadata

Assignees

No one assigned

    Type

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions