holoviz-topics / panel-chat-examples

Examples of Chat Bots using Panels chat features: Traditional, LLMs, AI Agents, LangChain, OpenAI etc
https://holoviz-topics.github.io/panel-chat-examples/
MIT License
105 stars 32 forks source link

authentication issues #7

Closed MarcSkovMadsen closed 11 months ago

MarcSkovMadsen commented 11 months ago

When serving authentication.py

I get

2023-09-30 06:43:57,923 Exception in callback functools.partial(<bound method IOLoop._discard_future_result of <tornado.platform.asyncio.AsyncIOMainLoop object at 0x7f085a341f60>>, <Task finished name='Task-72' coro=<async_execute.<locals>.wrapper() done, defined at /home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/panel/io/server.py:175> exception=TypeError("object function can't be used in 'await' expression")>)
Traceback (most recent call last):
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/tornado/ioloop.py", line 738, in _run_callback
    ret = callback()
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/tornado/ioloop.py", line 762, in _discard_future_result
    future.result()
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/panel/io/server.py", line 181, in wrapper
    state._handle_exception(e)
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/panel/io/state.py", line 436, in _handle_exception
    raise exception
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/panel/io/server.py", line 179, in wrapper
    return await func(*args, **kw)
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/param/parameterized.py", line 2062, in _async_ref
    raise e
  File "/home/jovyan/repos/private/panel-chat-examples/.venv/lib/python3.10/site-packages/param/parameterized.py", line 2060, in _async_ref
    self_.update({pname: await awaitable})
TypeError: object function can't be used in 'await' expression

Futhermore I would suggest

MarcSkovMadsen commented 11 months ago

I see the same issue in the chained_response.py.

ahuang11 commented 11 months ago

Because calling async functions with sync functions is not possible, e.g.

def send(...)
    ...
    await self.respond()

I previously circumvented having pairs of send/async_send(), respond/async_respond functions by triggering a Button's on_click that triggered an async method (_prepare_response).

        # handle async callbacks using this trick
        self._callback_trigger = Button(visible=False)
        self._callback_trigger.on_click(self._prepare_response)
async def _prepare_response(self, _):
    def respond(self):
        """
        Executes the callback with the latest entry in the chat log.
        """
        self._callback_trigger.param.trigger("clicks")

However it no longer seems to work in Param 2.0.

Would like to know what @philippjfr or @maximlt thinks; specifically should I have two separate entry points for async vs sync, or is this considered a regression in Param?

Currently for sync/async callbacks are like:

async def ai_respond(contents: str, user: str, instance: pn.widgets.ChatInterface):
    response = await openai.ChatCompletion.acreate(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": contents}],
        stream=True,
    )
    message = ""
    async for chunk in response:
        message += chunk["choices"][0]["delta"].get("content", "")
        yield message

Regardless of sync/async, both use the callback kwarg:

chat_interface = pn.widgets.ChatInterface(callback=ai_respond)

Should I also introduce an async_callback for async callbacks?

chat_interface = pn.widgets.ChatInterface(async_callback=ai_respond)

And should I introduce a sync/async pair of methods?

philippjfr commented 11 months ago

No likely a change related to Param 2.0. Will resolve that tomorrow.

ahuang11 commented 11 months ago

No likely a change related to Param 2.0.

To clarify, Param is not working as expected, and I should not introduce async/sync pairs?

maximlt commented 11 months ago

Indeed it looks like a regression in Param 2.0. Luckily it's not yet released so we can fix it.

I've faced a similar issue but that had a difference fix, I was setting a Callable parameter value to a method decorated with param.depends. Param 2.0 will by default consider that as a reference, while in my case it was just a method that's called by some other parts of the code. I had to set allow_ref to False for this Callable.

maximlt commented 11 months ago

I actually didn't get any error serving authentication.py with Param from its main branch and Panel from the chat_components branch.

philippjfr commented 11 months ago

I've faced a similar issue but that had a difference fix, I was setting a Callable parameter value to a method decorated with param.depends. Param 2.0 will by default consider that as a reference, while in my case it was just a method that's called by some other parts of the code. I had to set allow_ref to False for this Callable.

To be clear, Param itself does not yet enable allow_refs by default while Panel does.

maximlt commented 11 months ago

Ok thanks for that precision, I missed that!