-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: new ChatMessage
#8640
feat!: new ChatMessage
#8640
Conversation
Pull Request Test Coverage Report for Build 12376304805Details
💛 - Coveralls |
formatted_msg["name"] = message.name | ||
|
||
return formatted_msg | ||
return {"role": message.role.value, "content": message.text or ""} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these changes to HF API Chat Generator are only temporary: we will override them soon when porting the support for Tools
openai_msg["name"] = message.name | ||
|
||
return openai_msg | ||
return {"role": message.role.value, "content": message.text} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these changes to the OpenAI Chat Generator are only temporary: we will override them soon when porting the support for Tools
general_msg = ( | ||
"Use the `from_assistant`, `from_user`, `from_system`, and `from_tool` class methods to create a " | ||
"ChatMessage. For more information about the new API and how to migrate, see the documentation:" | ||
" https://docs.haystack.deepset.ai/docs/data-classes#chatmessage" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this link and the following ones will be updated once we have a new documentation page containing examples and the migration guide
raise TypeError(f"Unsupported type in ChatMessage content: `{type(part).__name__}` for `{part}`.") | ||
|
||
serialized["_content"] = content | ||
return serialized |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still do not like the idea that the serialized chatmessage has underscore prefixes. May I ask what is the rationale behind it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This simply stems from the new dataclass definition:
@dataclass
class ChatMessage:
_role: ChatRole
_content: Sequence[ChatMessageContentT]
_meta: Dict[str, Any] = field(default_factory=dict, hash=False)
The idea is that these attributes are internal.
For creation, you should use class methods from_user
, etc.
For attribute access, several properties are available: text
, texts
, tool_call
, tool_calls
, ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anakin87 I get this part, but I still hope the serialized dictionaries can drop the underscore prefixes for easier access. For example, in a deployed chatbot pipeline, I'd prefer something like
{"chat_history": [{"role": "user", "content": [...]}, {"role": "assistant", "content": [...]}, "meta": {...}]}
as a part of the request instead of
{"chat_history": [{"_role": "user", "_content": [...]}, {"_role": "assistant", "_content": [...]}, "_meta": {...}]}
(assuming this takes an input chat_history
of type List[ChatMessage]
).
Also it makes migration a bit easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also as a bonus I have something like this in my draft PR:
if isinstance(data["content"], str):
content.append(TextContent(text=data["content"]))
else:
for part in data["content"]:
... # rest of the logic
This makes the serialization form of a ChatMessage fully backwards compatible, and synergizes well with common shortcuts (in openai and anthropic APIs)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@LastRemote sorry for not responding sooner.
Since this is a substantial change, we decided to make it visible and not backward compatible.
As soon as possible, we will publish a detailed migration guide + GitHub/Discord announcements. (Tracked in #8623 and #8654).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@anakin87 Thanks for the reply, but I'm still not fully convinced. We can still keep the internal attributes with underscore prefixes, but just for serialization/deserialization I would suggest us dropping those for the sake of simplicity. Backward compatibility is not my top concern here.
In my current use cases, I have many deployed haystack pipelines that utilize List[ChatMessage] as a part of input/output (which is very common in chatbots to track chat history and multiple reply candidates), it makes more sense to have something like
{"chat_history": [{"role": "user", "content": [...]}, {"role": "assistant", "content": [...]}, "meta": {...}]}
instead of adding an underscore prefix in all fields. Of course, this could be mitigated by some customized logic on the server end (not sure if hayhook does this), but IMO that adds a layer of unneeded complexity.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good on the first pass. Only one comment regarding ToolCallResult - I'll do another pass soon after we consolidate on that one
:param error: Whether the Tool invocation resulted in an error. | ||
""" | ||
|
||
result: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A note here - I think we should have the result field be a Union of TextContent and other future media types that will include ByteStream and perhaps the upcoming MediaContent. Not sure if it is smart to add that immediately i.e have:
result: TextContent
and then make it Union as we add those new types. Or add it all in one batch sometimes soon when introduce these new types. wdyt is the best approach here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't studied in depth the multimodal support in different API providers, so I would prefer to introduce these changes when we know more, hopefully in a non-breaking way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, neither did I but @mathislucka mentioned encountering this hurdle in his experiments IIRC. If it is a big change to have TextContent here then perhaps lets leave it for next release as this is admittedly already a big change. Wonder what do you think about this @LastRemote - i.e. having tools returning non str content. Have you already encountered that use case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't studied in depth the multimodal support in different API providers, so I would prefer to introduce these changes when we know more, hopefully in a non-breaking way.
@anakin87 I did some research on this previously: Anthropic models can accept image (as an object containing base64 and mime type) tool result as well as text.
Oh, and it can have a list of contents.
https://docs.anthropic.com/en/api/messages#body-messages-content-content
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
having tools returning non str content. Have you already encountered that use case?
@vblagoje I am aware of this but it is not my current use case. To be honest I haven't really thought about this (I didn't change it in my multimodal PR), but this could be another Sequence[ChatMessageContentT]
for maximum flexibility (it is up to the models and corresponding utility functions whether to accept certain types in tool call result)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, something like that. As this future change will likely break few specific tool integrations, and not affect many users, perhaps we can postpone it to after the integration and keep str as ToolCallResult field for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...and not affect many users...
I prefer being a little careful on this one though. If a future change makes result
to be a list (Anthropic already supports this), existing tool implementations may be affected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In all honesty, I would prefer to keep the PR as it is regarding this aspect, especially since these changes have been extensively tested in recent months.
I am afraid that introducing a change on the fly at this time could cause some bugs, as well as complicate our lives.
For the future, unlike this PR, I think we can introduce the changes gradually (and without breaking changes), because they would be much smaller in scope.
(@vblagoje regarding the problems Mathis encountered, my impression was that they were not directly related to the tool message types, but to the Toolnvoker
return types.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In all honesty, I would prefer to keep the PR as it is regarding this aspect...
Sure, I am fine with it. Right now I am not seeing a lot of valid use cases for this, and there is still room for future updates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes @anakin87 agreed
@dfokina please take a look |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pushed one tiny fix, all is good ✅
Related Issues
ChatMessage
to Haystack #8583Proposed Changes:
ChatMessage
dataclass (porting of feat: updateChatMessage
to support tools haystack-experimental#52)How did you test it?
CI
Notes for the reviewer
I have prepared the draft docs for the new
ChatMessage
, including a migration guide. It might be helpful in reviewing this PR.Checklist
fix:
,feat:
,build:
,chore:
,ci:
,docs:
,style:
,refactor:
,perf:
,test:
and added!
in case the PR includes breaking changes.