Skip to content
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

add support for json objects in the Message component #292

Merged
merged 5 commits into from
Aug 30, 2023

Conversation

willydouhard
Copy link
Collaborator

@willydouhard willydouhard commented Aug 18, 2023

proposal to fix #291
Screenshot 2023-08-18 at 17 16 42

@@ -49,6 +49,10 @@ function prepareContent({ id, elements, content, language }: Props) {
? new RegExp(`(${elementNames.join('|')})`, 'g')
: undefined;

if (typeof content === 'object') {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might technically be a number or boolean too. Perhaps typeof content !== 'string' ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just moved the logic to the server. it has to be a string because the message can be persisted and has to respect the DB schema

src/chainlit/message.py Outdated Show resolved Hide resolved
src/chainlit/message.py Outdated Show resolved Hide resolved
src/chainlit/message.py Outdated Show resolved Hide resolved
Copy link
Contributor

@ramnes ramnes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@mpartel
Copy link

mpartel commented Aug 18, 2023

Just occurred to me that LangChain's web scrapers produce Document. (They are Serializable and have methods json/to_json and dict). Not sure if they're dict'ified before they reach you, but worth checking I think.

@mpartel
Copy link

mpartel commented Aug 18, 2023

It gets a little fiddly.
If I add the following to #291 's code:

from langchain.schema.document import Document
...
                'structured': {
                    'doc': Document(page_content='...'),
                    ...

then I get

future: <Task finished name='Task-83' coro=<AsyncServer._emit_internal() done, defined at /home/martin/.cache/pypoetry/virtualenvs/chainlit-bug-6EGjyFTw-py3.10/lib/python3.10/site-packages/socketio/asyncio_server.py:427> exception=TypeError('Object of type Document is not JSON serializable')>
Traceback (most recent call last):
  File "/usr/lib/python3.10/asyncio/tasks.py", line 232, in __step
    result = coro.send(None)
  File "/home/martin/.cache/pypoetry/virtualenvs/chainlit-bug-6EGjyFTw-py3.10/lib/python3.10/site-packages/socketio/asyncio_server.py", line 437, in _emit_internal
    await self._send_packet(sid, self.packet_class(
  File "/home/martin/.cache/pypoetry/virtualenvs/chainlit-bug-6EGjyFTw-py3.10/lib/python3.10/site-packages/socketio/asyncio_server.py", line 442, in _send_packet
    encoded_packet = pkt.encode()
  File "/home/martin/.cache/pypoetry/virtualenvs/chainlit-bug-6EGjyFTw-py3.10/lib/python3.10/site-packages/socketio/packet.py", line 64, in encode
    encoded_packet += self.json.dumps(data, separators=(',', ':'))
  File "/usr/lib/python3.10/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/lib/python3.10/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/lib/python3.10/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "/usr/lib/python3.10/json/encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Document is not JSON serializable

Looks like we'd need to give socketio.AsyncServer a json module (object?) that uses a JSONEncoder that supports LangChain's Serializable.

@ramnes
Copy link
Contributor

ramnes commented Aug 18, 2023

This is another topic IMO. For this I'd say that we should let users pass whatever JSONEncoder they want to Chainlit rather than trying to handle all cases ourselves.

Edit: Actually no, I'll come back to what I just say: LangChain callback chain of thoughts should work out of the box indeed, so yes, we need something like this, at least when the LangChain callback handler is used.

willydouhard and others added 3 commits August 23, 2023 16:22
Co-authored-by: Guillaume Gelin <[email protected]>
Co-authored-by: Guillaume Gelin <[email protected]>
Co-authored-by: Guillaume Gelin <[email protected]>
@willydouhard
Copy link
Collaborator Author

willydouhard commented Aug 23, 2023

I could even argue that a Langchain document should be a text element rather than a message content.

Should we keep the support for dicts in the message class and open another PR for Langchain edge cases or do you think everything should be handled in the Langchain specific solution and the message class should always accept a string?

@willydouhard willydouhard merged commit bfbf0d7 into main Aug 30, 2023
4 checks passed
@willydouhard willydouhard deleted the wd/json-message branch August 30, 2023 14:20
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.

Chain of Thought UI crashes when langchain steps output dicts instead of strings
3 participants