Quansight / ragna

RAG orchestration framework ⛵️
https://ragna.chat
BSD 3-Clause "New" or "Revised" License
179 stars 22 forks source link

web UI is broken for Python 3.11 #359

Closed pmeier closed 8 months ago

pmeier commented 8 months ago

Bug description

Per title. Traceback:

Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x7029d7a85d90>>, <Task finished name='Task-797' coro=<async_execute.<locals>.wrapper() done, defined at /usr/local/lib/python3.11/site-packages/panel/io/server.py:179> exception=RecursionError('maximum recursion depth exceeded')>)
Traceback (most recent call last):
  File "/usr/local/lib/python3.11/site-packages/tornado/ioloop.py", line 750, in _run_callback
    ret = callback()
          ^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/tornado/ioloop.py", line 774, in _discard_future_result
    future.result()
  File "/usr/local/lib/python3.11/site-packages/panel/io/server.py", line 185, in wrapper
    state._handle_exception(e)
  File "/usr/local/lib/python3.11/site-packages/panel/io/state.py", line 442, in _handle_exception
    raise exception
  File "/usr/local/lib/python3.11/site-packages/panel/io/server.py", line 183, in wrapper
    return await func(*args, **kw)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/chat/feed.py", line 547, in _prepare_response
    await self._cleanup_response()
  File "/usr/local/lib/python3.11/site-packages/panel/chat/interface.py", line 598, in _cleanup_response
    await super()._cleanup_response()
  File "/usr/local/lib/python3.11/site-packages/panel/chat/feed.py", line 554, in _cleanup_response
    self._replace_placeholder(None)
  File "/usr/local/lib/python3.11/site-packages/panel/chat/feed.py", line 347, in _replace_placeholder
    index = self.index(self._placeholder)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/layout/base.py", line 489, in index
    return self.objects.index(object)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/pane/base.py", line 217, in __repr__
    params = param_reprs(self, ['object'])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/util/__init__.py", line 166, in param_reprs
    else: v = abbreviated_repr(v)
              ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/util/__init__.py", line 115, in abbreviated_repr
    vrepr = repr(value)
            ^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/pane/base.py", line 217, in __repr__
    params = param_reprs(self, ['object'])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/util/__init__.py", line 166, in param_reprs
    else: v = abbreviated_repr(v)
              ^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/site-packages/panel/util/__init__.py", line 115, in abbreviated_repr
    vrepr = repr(value)
            ^^^^^^^^^^^
[...]

How to reproduce the bug?

Ask a question in the web UI.

Versions and dependencies used

0.2.0rc1

Anything else?

No response

pmeier commented 8 months ago

After some ultimately futile bisecting, I found that the issue is reproducible on 6dd32b7ddea2c4876ebe3812b6a18a2e37f83ba7, i.e. the commit that added docker support. Meaning, it never worked. No idea how this slipped past me in #283.

pmeier commented 8 months ago

This has nothing to do with docker. The issue happens on Python 3.11

https://github.com/Quansight/ragna/blob/4a667f9aced1970f8eab8aa9e01aaf8c67b05db0/Dockerfile#L1

while we are using 3.9 for development

https://github.com/Quansight/ragna/blob/4a667f9aced1970f8eab8aa9e01aaf8c67b05db0/environment-dev.yml#L5

3.10 is also fine.

pmeier commented 8 months ago

Here is a repro:

  1. $ conda create -n ragna-359-py311 -c conda-forge python=3.11
  2. $ conda activate ragna-359-py311
  3. $ pip install --pre ragna==0.2.0rc1
  4. $ ragna init and select the default options. This creates a configuration file picked up automatically by the next command
  5. $ ragna ui
  6. Click "Sign in"
  7. Click "New Chat"
  8. Select a random .md or .txt document
  9. Click "Start Conversation"
  10. Type anything in the text field and press Enter or click the button on the right

image

Changing 1. and 2. to

  1. $ conda create -n ragna-359-py310 -c conda-forge python=3.10
  2. $ conda activate ragna-359-py310

results in

image

pmeier commented 8 months ago

It seems panel is accessing the repr(self._placeholder) at some point and in turn this fails:

from ragna.deploy._ui.central_view import RagnaChatMessage

message = RagnaChatMessage("Bug", role="user", user="")

repr(message)
Traceback (most recent call last):
  File "/home/philip/git/ora/main2.py", line 43, in <module>
    repr(message)
  File "/home/philip/.conda/envs/ragna-359-py311/lib/python3.11/site-packages/panel/pane/base.py", line 217, in __repr__
    params = param_reprs(self, ['object'])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/philip/.conda/envs/ragna-359-py311/lib/python3.11/site-packages/panel/util/__init__.py", line 166, in param_reprs
    else: v = abbreviated_repr(v)
              ^^^^^^^^^^^^^^^^^^^
  File "/home/philip/.conda/envs/ragna-359-py311/lib/python3.11/site-packages/panel/util/__init__.py", line 115, in abbreviated_repr
    vrepr = repr(value)
            ^^^^^^^^^^^
  File "/home/philip/.conda/envs/ragna-359-py311/lib/python3.11/site-packages/panel/pane/base.py", line 217, in __repr__
    params = param_reprs(self, ['object'])
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/philip/.conda/envs/ragna-359-py311/lib/python3.11/site-packages/panel/util/__init__.py", line 166, in param_reprs
    else: v = abbreviated_repr(v)
              ^^^^^^^^^^^^^^^^^^^
  File "/home/philip/.conda/envs/ragna-359-py311/lib/python3.11/site-packages/panel/util/__init__.py", line 115, in abbreviated_repr
    vrepr = repr(value)
            ^^^^^^^^^^^
[...]
pmeier commented 8 months ago

This is a reference cycle. When trying to get the repr for the RagnaChatMessage, the repr for the avatar_lookup parameter is needed. We have implemented this as bound method

https://github.com/Quansight/ragna/blob/4a667f9aced1970f8eab8aa9e01aaf8c67b05db0/ragna/deploy/_ui/central_view.py#L188-L189

Thus, this holds a reference back to the original RagnaChatMessage and thus causing the cycle and ultimately the recursion error.