Allow users to add LLM within the UI (#6)
* Rename AzureChatOpenAI to LCAzureChatOpenAI * Provide vanilla ChatOpenAI and AzureChatOpenAI * Remove the highest accuracy, lowest cost criteria These criteria are unnecessary. The users, not pipeline creators, should choose which LLM to use. Furthermore, it's cumbersome to input this information, really degrades user experience. * Remove the LLM selection in simple reasoning pipeline * Provide a dedicated stream method to generate the output * Return placeholder message to chat if the text is empty
This commit is contained in:
committed by
GitHub
parent
e187e23dd1
commit
a203fc0f7c
@@ -1,6 +1,7 @@
|
||||
import gradio as gr
|
||||
from ktem.app import BasePage
|
||||
from ktem.db.models import User, engine
|
||||
from ktem.llms.ui import LLMManagement
|
||||
from sqlmodel import Session, select
|
||||
|
||||
from .user import UserManagement
|
||||
@@ -16,6 +17,9 @@ class AdminPage(BasePage):
|
||||
with gr.Tab("User Management", visible=False) as self.user_management_tab:
|
||||
self.user_management = UserManagement(self._app)
|
||||
|
||||
with gr.Tab("LLM Management") as self.llm_management_tab:
|
||||
self.llm_management = LLMManagement(self._app)
|
||||
|
||||
def on_subscribe_public_events(self):
|
||||
if self._app.f_user_management:
|
||||
self._app.subscribe_event(
|
||||
|
@@ -9,6 +9,8 @@ from ktem.db.models import Conversation, engine
|
||||
from sqlmodel import Session, select
|
||||
from theflow.settings import settings as flowsettings
|
||||
|
||||
from kotaemon.base import Document
|
||||
|
||||
from .chat_panel import ChatPanel
|
||||
from .chat_suggestion import ChatSuggestion
|
||||
from .common import STATE
|
||||
@@ -189,6 +191,7 @@ class ChatPage(BasePage):
|
||||
self.chat_control.conversation_rn,
|
||||
self.chat_panel.chatbot,
|
||||
self.info_panel,
|
||||
self.chat_state,
|
||||
]
|
||||
+ self._indices_input,
|
||||
show_progress="hidden",
|
||||
@@ -220,6 +223,7 @@ class ChatPage(BasePage):
|
||||
self.chat_control.conversation_rn,
|
||||
self.chat_panel.chatbot,
|
||||
self.info_panel,
|
||||
self.chat_state,
|
||||
]
|
||||
+ self._indices_input,
|
||||
show_progress="hidden",
|
||||
@@ -392,7 +396,7 @@ class ChatPage(BasePage):
|
||||
|
||||
return pipeline, reasoning_state
|
||||
|
||||
async def chat_fn(self, conversation_id, chat_history, settings, state, *selecteds):
|
||||
def chat_fn(self, conversation_id, chat_history, settings, state, *selecteds):
|
||||
"""Chat function"""
|
||||
chat_input = chat_history[-1][0]
|
||||
chat_history = chat_history[:-1]
|
||||
@@ -403,52 +407,43 @@ class ChatPage(BasePage):
|
||||
pipeline, reasoning_state = self.create_pipeline(settings, state, *selecteds)
|
||||
pipeline.set_output_queue(queue)
|
||||
|
||||
asyncio.create_task(pipeline(chat_input, conversation_id, chat_history))
|
||||
text, refs = "", ""
|
||||
|
||||
len_ref = -1 # for logging purpose
|
||||
msg_placeholder = getattr(
|
||||
flowsettings, "KH_CHAT_MSG_PLACEHOLDER", "Thinking ..."
|
||||
)
|
||||
|
||||
print(msg_placeholder)
|
||||
while True:
|
||||
try:
|
||||
response = queue.get_nowait()
|
||||
except Exception:
|
||||
state[pipeline.get_info()["id"]] = reasoning_state["pipeline"]
|
||||
yield chat_history + [
|
||||
(chat_input, text or msg_placeholder)
|
||||
], refs, state
|
||||
yield chat_history + [(chat_input, text or msg_placeholder)], refs, state
|
||||
|
||||
len_ref = -1 # for logging purpose
|
||||
|
||||
for response in pipeline.stream(chat_input, conversation_id, chat_history):
|
||||
|
||||
if not isinstance(response, Document):
|
||||
continue
|
||||
|
||||
if response is None:
|
||||
queue.task_done()
|
||||
print("Chat completed")
|
||||
break
|
||||
if response.channel is None:
|
||||
continue
|
||||
|
||||
if "output" in response:
|
||||
if response["output"] is None:
|
||||
if response.channel == "chat":
|
||||
if response.content is None:
|
||||
text = ""
|
||||
else:
|
||||
text += response["output"]
|
||||
text += response.content
|
||||
|
||||
if "evidence" in response:
|
||||
if response["evidence"] is None:
|
||||
if response.channel == "info":
|
||||
if response.content is None:
|
||||
refs = ""
|
||||
else:
|
||||
refs += response["evidence"]
|
||||
refs += response.content
|
||||
|
||||
if len(refs) > len_ref:
|
||||
print(f"Len refs: {len(refs)}")
|
||||
len_ref = len(refs)
|
||||
|
||||
state[pipeline.get_info()["id"]] = reasoning_state["pipeline"]
|
||||
yield chat_history + [(chat_input, text)], refs, state
|
||||
state[pipeline.get_info()["id"]] = reasoning_state["pipeline"]
|
||||
yield chat_history + [(chat_input, text or msg_placeholder)], refs, state
|
||||
|
||||
async def regen_fn(
|
||||
self, conversation_id, chat_history, settings, state, *selecteds
|
||||
):
|
||||
def regen_fn(self, conversation_id, chat_history, settings, state, *selecteds):
|
||||
"""Regen function"""
|
||||
if not chat_history:
|
||||
gr.Warning("Empty chat")
|
||||
@@ -456,12 +451,11 @@ class ChatPage(BasePage):
|
||||
return
|
||||
|
||||
state["app"]["regen"] = True
|
||||
async for chat, refs, state in self.chat_fn(
|
||||
for chat, refs, state in self.chat_fn(
|
||||
conversation_id, chat_history, settings, state, *selecteds
|
||||
):
|
||||
new_state = deepcopy(state)
|
||||
new_state["app"]["regen"] = False
|
||||
yield chat, refs, new_state
|
||||
else:
|
||||
state["app"]["regen"] = False
|
||||
yield chat_history, "", state
|
||||
|
||||
state["app"]["regen"] = False
|
||||
|
Reference in New Issue
Block a user