gradio icon indicating copy to clipboard operation
gradio copied to clipboard

Add support for additional_outputs in `gr.ChatInterface`

Open chengyjonathan opened this issue 10 months ago • 3 comments

  • [yes] I have searched to see if a similar issue already exists.

Is your feature request related to a problem? Please describe.
I'm trying to setup a ChatInterface() Where I can get the output documents that were retrieved along with the response. Ie. if my input query fn outputs both a list of strings for the retrieved docs and a response str, I want to be able to send that list of retrieved docs to a different compoenent.

Describe the solution you'd like
Idk if this is easier than I think it is, but I'd appreciate a way to implement this (if this doesn't exist already). Where I can supply a fn that returns both a response and a list of documents

chengyjonathan avatar Apr 04 '24 18:04 chengyjonathan

Hi @chengyjonathan yes I think we could add support for additional_outputs in gr.ChatInterface similar to how we have additional_inputs. cc @dawoodkhan82

abidlabs avatar Apr 04 '24 20:04 abidlabs

Or alternatively we could support the gr.File component in gr.Chatbot cc @dawoodkhan82

abidlabs avatar Apr 05 '24 05:04 abidlabs

+1 currently I have to embed the additional outputs in the response itself.

justinzyw avatar Apr 11 '24 23:04 justinzyw

This works for me (until a better option in gradio):

RAG_component = gr.Textbox()
# chatbot is a gr.Chatbot() component
chatbot.change(fn=update_RAG_component, inputs=[], outputs=[RAG_component])

The chatbot changes many times, but after the last change, the RAG_component shows the retrieved docs. I have tried other EventListeners, but none of them worked for me.

A nicer solution requires some modifications in the source code, for example:

  1. A new member variable in the ChatInterface class:
self.state_id = Textbox("0", visible=False)
  1. Another submit_event, appended at the end:
...
.then(self._update_state, [self.state_id ], [self.state_id ])
  1. The update function:
def _update_state(self, state:Textbox):
        return Textbox(str(int(state)+1))

Then, an event listener can be set up, which only acts once after the response is generated: chatinterface.state_id.change(fn=update_RAG_component, inputs=[], outputs=[RAG_component])

Balint-Batki avatar Aug 02 '24 09:08 Balint-Batki

+1 for this. It could be useful for a stateful chatbot.

E.g.

def bot_fn(message, history, session_state, <additional_inputs>):
    return bot_message, session_state

taoari avatar Aug 29 '24 18:08 taoari