haystack icon indicating copy to clipboard operation
haystack copied to clipboard

Support fully qualified type path in component trace output

Open vblagoje opened this issue 5 months ago • 6 comments

Is your feature request related to a problem? Please describe. In Haystack’s tracing system, each component emits metadata such as haystack.component.name, type, and input/output specs. However, haystack.component.type currently only includes the bare class name (e.g. "OpenAIChatGenerator"), without the fully qualified module path.

This creates friction for tools or devs that want to dynamically resolve or load a component by type — they’re forced to scan the codebase or maintain a manual mapping of known modules. This is especially problematic in modular or plugin-heavy environments.

Describe the solution you'd like Add a new trace field:

"haystack.component.type_fqn": "haystack.components.generators.chat.openai.OpenAIChatGenerator"

This gives the full dotted path to the class, enabling dynamic loading and better tooling. It also aligns with how all other trace metadata already uses fully qualified paths (e.g. in input_spec types).

Describe alternatives you've considered

  • Manually resolving the class by searching across all known modules
  • Overloading type field to include module path (not backward compatible)

Additional context Example for consistency:

"haystack.component.type": "OpenAIChatGenerator",
"haystack.component.type_fqn": "haystack.components.generators.chat.openai.OpenAIChatGenerator"

All other type fields already expose fully qualified paths (e.g. typing.List[haystack.dataclasses.chat_message.ChatMessage]), so this would bring the type field in line and remove ambiguity.

vblagoje avatar Jul 02 '25 08:07 vblagoje

Here is the current tracing output structure with this field added:

{
    "haystack.component.name": "chat_generator",
    "haystack.component.type": "OpenAIChatGenerator",
    "haystack.component.type_fqn": "haystack.components.generators.chat.openai.OpenAIChatGenerator",
    "haystack.component.input_types": {
        "messages": "list",
        "tools": "list"
    },
    "haystack.component.input_spec": {
        "messages": {
            "type": "typing.List[haystack.dataclasses.chat_message.ChatMessage]",
            "senders": []
        },
        "streaming_callback": {
            "type": "typing.Union[typing.Callable[[haystack.dataclasses.streaming_chunk.StreamingChunk], NoneType], typing.Callable[[haystack.dataclasses.streaming_chunk.StreamingChunk], typing.Awaitable[NoneType]], NoneType]",
            "senders": []
        },
        "generation_kwargs": {
            "type": "typing.Optional[typing.Dict[str, typing.Any]]",
            "senders": []
        },
        "tools": {
            "type": "typing.Union[typing.List[haystack.tools.tool.Tool], haystack.tools.toolset.Toolset, NoneType]",
            "senders": []
        },
        "tools_strict": {
            "type": "typing.Optional[bool]",
            "senders": []
        }
    },
    "haystack.component.output_spec": {
        "replies": {
            "type": "typing.List[haystack.dataclasses.chat_message.ChatMessage]",
            "receivers": []
        }
    },
    "haystack.component.visits": 1
}

vblagoje avatar Jul 02 '25 08:07 vblagoje

It is hard to properly fix https://github.com/deepset-ai/haystack-core-integrations/issues/2050 without resolving this issue. And we might likely need this fix anyway. It's a straightforward improvement/fix without any risk, only benefits.

vblagoje avatar Jul 02 '25 09:07 vblagoje

Perhaps we could rename the field to haystack.component.type_qualified_name or haystack.component.fully_qualified_type?

Otherwise I agree we should be providing the fully qualified type for the component so they are easy/straightforward to inspect and not just the class name.

sjrl avatar Jul 02 '25 10:07 sjrl

Alternatively @vblagoje to be more consistent with how we normally provide fully qualified types in our other type fields we could change the "haystack.component.type" to have the fully qualified type via our normal breaking change process. So add a Deprecation Warning in 2.16.0 and make the change in 2.17.0

Simultaneously, we could add a new field called "haystack.component.class_name" which would just have the name of the class in case users find it helpful to have just the last item of the fully qualified type. What do you think?

sjrl avatar Jul 02 '25 10:07 sjrl

Alternatively @vblagoje to be more consistent with how we normally provide fully qualified types in our other type fields we could change the "haystack.component.type" to have the fully qualified type via our normal breaking change process. So add a Deprecation Warning in 2.16.0 and make the change in 2.17.0

You’re more brave than I am - to me this looks that’s like unplugging a random cable in a data center, smiling, thinking everything is fine... and then 🤯

Yeah both are good but fully_qualified_type is more precise and explicit while class_name could again mean just the class name without module path

vblagoje avatar Jul 02 '25 11:07 vblagoje

Yeah both are good but fully_qualified_type is more precise and explicit

Okay let's go for that then!

sjrl avatar Jul 02 '25 11:07 sjrl