diff --git a/libs/ktem/ktem/assets/css/main.css b/libs/ktem/ktem/assets/css/main.css index 87d173ce..5a272e64 100644 --- a/libs/ktem/ktem/assets/css/main.css +++ b/libs/ktem/ktem/assets/css/main.css @@ -429,6 +429,10 @@ tbody:not(.row_odd) { display: none; } +#paper-suggestion table { + overflow: hidden; +} + svg.markmap { width: 100%; height: 100%; diff --git a/libs/ktem/ktem/pages/chat/__init__.py b/libs/ktem/ktem/pages/chat/__init__.py index 9d1f013d..c65250cc 100644 --- a/libs/ktem/ktem/pages/chat/__init__.py +++ b/libs/ktem/ktem/pages/chat/__init__.py @@ -32,6 +32,7 @@ from .chat_suggestion import ChatSuggestion from .common import STATE from .control import ConversationControl from .demo_hint import HintPage +from .paper_list import PaperListPage from .report import ReportIssue KH_DEMO_MODE = getattr(flowsettings, "KH_DEMO_MODE", False) @@ -59,6 +60,14 @@ function() { } """ +quick_urls_submit_js = """ +function() { + let urlInput = document.querySelector("#quick-url-demo textarea"); + console.log("URL input:", urlInput); + urlInput.dispatchEvent(new KeyboardEvent('keypress', {'key': 'Enter'})); +} +""" + clear_bot_message_selection_js = """ function() { var bot_messages = document.querySelectorAll( @@ -262,6 +271,9 @@ class ChatPage(BasePage): self.hint_page = HintPage(self._app) with gr.Column(scale=6, elem_id="chat-area"): + if KH_DEMO_MODE: + self.paper_list = PaperListPage(self._app) + self.chat_panel = ChatPanel(self._app) with gr.Row(): @@ -765,6 +777,21 @@ class ChatPage(BasePage): js=chat_input_focus_js, ) + if KH_DEMO_MODE: + self.paper_list.examples.select( + self.paper_list.select_example, + outputs=[self.quick_urls], + show_progress="hidden", + ).then( + lambda: gr.update(visible=False), + outputs=[self.paper_list.accordion], + ).then( + fn=None, + inputs=None, + outputs=None, + js=quick_urls_submit_js, + ) + def submit_msg( self, chat_input, diff --git a/libs/ktem/ktem/pages/chat/paper_list.py b/libs/ktem/ktem/pages/chat/paper_list.py new file mode 100644 index 00000000..b7f7cad4 --- /dev/null +++ b/libs/ktem/ktem/pages/chat/paper_list.py @@ -0,0 +1,31 @@ +import gradio as gr +from ktem.app import BasePage +from pandas import DataFrame + +from ...utils.hf_papers import fetch_papers + + +class PaperListPage(BasePage): + def __init__(self, app): + self._app = app + self.on_building_ui() + + def on_building_ui(self): + with gr.Accordion( + label="Browse daily top papers", + open=False, + ) as self.accordion: + self.papers = fetch_papers(top_n=5) + self.examples = gr.DataFrame( + value=DataFrame(self.papers), + headers=["title", "url", "upvotes"], + column_widths=[60, 30, 10], + interactive=False, + elem_id="paper-suggestion", + wrap=True, + ) + return self.examples + + def select_example(self, ev: gr.SelectData): + print("Selected index", ev.index[0]) + return self.papers[ev.index[0]]["url"] diff --git a/libs/ktem/ktem/utils/hf_papers.py b/libs/ktem/ktem/utils/hf_papers.py new file mode 100644 index 00000000..d12450cd --- /dev/null +++ b/libs/ktem/ktem/utils/hf_papers.py @@ -0,0 +1,25 @@ +import requests + +HF_API_URL = "https://huggingface.co/api/daily_papers" +ARXIV_URL = "https://arxiv.org/abs/{paper_id}" + + +def fetch_papers(top_n=5): + try: + response = requests.get(f"{HF_API_URL}?limit=100") + response.raise_for_status() + items = response.json() + items.sort(key=lambda x: x.get("paper", {}).get("upvotes", 0), reverse=True) + items = [ + { + "title": item.get("paper", {}).get("title"), + "url": ARXIV_URL.format(paper_id=item.get("paper", {}).get("id")), + "upvotes": item.get("paper", {}).get("upvotes"), + } + for item in items[:top_n] + ] + except Exception as e: + print(e) + return [] + + return items