hayhooks icon indicating copy to clipboard operation
hayhooks copied to clipboard

API does not work with the ChatMessage

Open bmstoyon opened this issue 1 year ago • 1 comments

Hayhooks fails with Chat Messages because the pydantic conversion to a dict remove ChatMessage class.

I had to work around like this:

        dict_local = pipeline_run_req.dict()
        dict_local["prompt_builder"]["prompt_source"] = pipeline_run_req.prompt_builder.prompt_source
        result = pipe.run(data=dict_local)

bmstoyon avatar Apr 15 '24 18:04 bmstoyon

Hey!

I have a similar problem where I send a messages dict to a Multiplexer component in a pipeline. But it is not converted to a List[ChatMessage] but rather a dict is passed on.

So my serialized pipeline looks like this:

chat_pipeline = Pipeline()
chat_pipeline.add_component("msg_receiver", Multiplexer(List[ChatMessage]))
chat_pipeline.add_component("generator", chat_generator)
chat_pipeline.connect("msg_receiver.value", "generator.messages")

and in my API call

  "data": {
    "msg_receiver": {
      "value": [
        {
          "content": "Test",
          "role": "user",
          "name": null
        }
      ]
    },
    "generator": {},

this raises an error in the Generator:

File "/home/anaconda3/envs/hsenv/lib/python3.10/site-packages/haystack/core/pipeline/pipeline.py", line 864, in run res = comp.run(**last_inputs[name]) File "/home/anaconda3/envs/hsenv/lib/python3.10/site-packages/haystack/components/generators/chat/hugging_face_api.py", line 194, in run formatted_messages = [m.to_openai_format() for m in messages] File "/home/anaconda3/envs/hsenv/lib/python3.10/site-packages/haystack/components/generators/chat/hugging_face_api.py", line 194, in formatted_messages = [m.to_openai_format() for m in messages] AttributeError: 'dict' object has no attribute 'to_openai_format

Update:

A custom component included before the multiplexer helped me work around the errors - leaving it here in case somebody else runs into the same issue:

from typing import List, Dict, Any
from haystack import component
from haystack.dataclasses import ChatMessage, ChatRole

@component
class ChatMessageRepairer:
    
    @component.output_types(messages=List[ChatMessage])
    def run(self, raw_messages: List[Dict[str, Any]]):
        messages = []
        for msg in raw_messages:
            try:
                role = ChatRole(msg["role"])
                messages.append(ChatMessage(content=msg["content"], role=role, name=None))
            except ValueError:
                raise ValueError(f"{role_str} is not a valid ChatRole")
                   
        return {"messages": messages}

IronD7 avatar May 22 '24 07:05 IronD7

Hey @mpangrazzi is this still an issue with your recent updates to hayhooks?

sjrl avatar Feb 19 '25 10:02 sjrl

@sjrl it shouldn't be anymore an issue after introduction of PipelineWrapper.

Now you can create your custom run_api method so you can declare any JSON-compatible values as API input and do yourself any needed conversion / casting before calling run() method of Haystack pipeline.

Feel free to reopen if needed!

mpangrazzi avatar Feb 24 '25 20:02 mpangrazzi