Spaces:
Runtime error
Runtime error
File size: 9,278 Bytes
85cec0e 954241d 21ffffb 5058660 21ffffb 85cec0e 954241d 85cec0e 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb 5058660 21ffffb 5058660 85cec0e 21ffffb 5058660 85cec0e 21ffffb 85cec0e 21ffffb 85cec0e 21ffffb 954241d 21ffffb 85cec0e 21ffffb 85cec0e 5058660 85cec0e 21ffffb 954241d 21ffffb 85cec0e 5058660 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 5058660 21ffffb 5058660 21ffffb 5058660 21ffffb 5058660 21ffffb 5058660 21ffffb 5058660 21ffffb 5058660 21ffffb 5058660 85cec0e 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb 954241d 21ffffb |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
import os
import gradio as gr
from bagoodex_client import BagoodexClient
from r_types import ChatMessage
from prompts import (
SYSTEM_PROMPT_FOLLOWUP,
SYSTEM_PROMPT_MAP,
SYSTEM_PROMPT_BASE,
SYSTEM_PROMPT_KNOWLEDGE_BASE
)
from helpers import (
embed_video,
format_links,
embed_google_map,
format_knowledge,
format_followup_questions
)
client = BagoodexClient()
# ----------------------------
# Chat & Follow-up Functions
# ----------------------------
def chat_function(message, history, followup_state, chat_history_state):
"""
Process a new user message.
Appends the message and response to the conversation,
and retrieves follow-up questions.
"""
# complete_chat returns a new followup id and answer
followup_id_new, answer = client.complete_chat(message)
# Update conversation history (if history is None, use an empty list)
if history is None:
history = []
updated_history = history + [ChatMessage({"role": "user", "content": message}),
ChatMessage({"role": "assistant", "content": answer})]
# Retrieve follow-up questions using the updated conversation
followup_questions_raw = client.base_qna(
messages=updated_history, system_prompt=SYSTEM_PROMPT_FOLLOWUP
)
# Format them using the helper
followup_md = format_followup_questions(followup_questions_raw)
return answer, followup_id_new, updated_history, followup_md
def handle_followup_click(question, followup_state, chat_history_state):
"""
When a follow-up question is clicked, send it as a new message.
"""
if not question:
return chat_history_state, followup_state, ""
# Process the follow-up question via complete_chat
followup_id_new, answer = client.complete_chat(question)
updated_history = chat_history_state + [ChatMessage({"role": "user", "content": question}),
ChatMessage({"role": "assistant", "content": answer})]
# Get new follow-up questions
followup_questions_raw = client.base_qna(
messages=updated_history, system_prompt=SYSTEM_PROMPT_FOLLOWUP
)
followup_md = format_followup_questions(followup_questions_raw)
return updated_history, followup_id_new, followup_md
def handle_local_map_click(followup_state, chat_history_state):
"""
On local map click, try to get a local map.
If issues occur, fall back to using the SYSTEM_PROMPT_MAP.
"""
if not followup_state:
return chat_history_state
try:
result = client.get_local_map(followup_state)
if result:
map_url = result.get('link', '')
# Use helper to produce an embedded map iframe
html = embed_google_map(map_url)
# Fall back: use the base_qna call with SYSTEM_PROMPT_MAP
result = client.base_qna(
messages=chat_history_state, system_prompt=SYSTEM_PROMPT_MAP
)
# Assume result contains a 'link' field
html = embed_google_map(result.get('link', ''))
new_message = ChatMessage({"role": "assistant", "content": html})
return chat_history_state + [new_message]
except Exception:
return chat_history_state
def handle_knowledge_click(followup_state, chat_history_state):
"""
On knowledge base click, fetch and format knowledge content.
"""
if not followup_state:
return chat_history_state
try:
print('trying to get knowledge')
result = client.get_knowledge(followup_state)
knowledge_md = format_knowledge(result)
if knowledge_md == 0000:
print('falling back to base_qna')
# Fall back: use the base_qna call with SYSTEM_PROMPT_KNOWLEDGE_BASE
result = client.base_qna(
messages=chat_history_state, system_prompt=SYSTEM_PROMPT_KNOWLEDGE_BASE
)
knowledge_md = format_knowledge(result)
new_message = ChatMessage({"role": "assistant", "content": knowledge_md})
return chat_history_state + [new_message]
except Exception:
return chat_history_state
# ----------------------------
# Advanced Search Functions
# ----------------------------
def perform_image_search(followup_state):
if not followup_state:
return []
result = client.get_images(followup_state)
# For images we simply return a list of original URLs
return [item.get("original", "") for item in result]
def perform_video_search(followup_state):
if not followup_state:
return "<p>No followup ID available.</p>"
result = client.get_videos(followup_state)
# Use the helper to produce the embed iframes (supports multiple videos)
return embed_video(result)
def perform_links_search(followup_state):
if not followup_state:
return gr.Markdown("No followup ID available.")
result = client.get_links(followup_state)
return format_links(result)
# ----------------------------
# UI Build
# ----------------------------
css = """
#chatbot {
height: 100%;
}
"""
# defautl query: how to make slingshot?
# who created light (e.g., electricity) Tesla or Edison in quick short?
with gr.Blocks(css=css, fill_height=True) as demo:
# State variables to hold followup ID and conversation history, plus follow-up questions text
followup_state = gr.State(None)
chat_history_state = gr.State([]) # holds conversation history as a list of messages
followup_md_state = gr.State("") # holds follow-up questions as Markdown text
with gr.Row():
with gr.Column(scale=3):
with gr.Row():
btn_local_map = gr.Button("Local Map Search (coming soon...)", variant="secondary", size="sm", interactive=False)
btn_knowledge = gr.Button("Knowledge Base (coming soon...)", variant="secondary", size="sm", interactive=False)
# The ChatInterface now uses additional outputs for both followup_state and conversation history,
# plus follow-up questions Markdown.
chat = gr.ChatInterface(
fn=chat_function,
type="messages",
additional_inputs=[followup_state, chat_history_state],
additional_outputs=[followup_state, chat_history_state, followup_md_state],
)
# Button callbacks to append local map and knowledge base results to chat
btn_local_map.click(
fn=handle_local_map_click,
inputs=[followup_state, chat_history_state],
outputs=chat.chatbot
)
btn_knowledge.click(
fn=handle_knowledge_click,
inputs=[followup_state, chat_history_state],
outputs=chat.chatbot
)
# Radio-based follow-up questions
followup_radio = gr.Radio(
choices=[],
label="Follow-up Questions (select one and click 'Send Follow-up')"
)
btn_send_followup = gr.Button("Send Follow-up")
# When the user clicks "Send Follow-up", the selected question is passed
# to handle_followup_click
btn_send_followup.click(
fn=handle_followup_click,
inputs=[followup_radio, followup_state, chat_history_state],
outputs=[chat.chatbot, followup_state, followup_md_state]
)
# Update the radio choices when followup_md_state changes
def update_followup_radio(md_text):
"""
Parse Markdown lines to extract questions starting with '- '.
"""
lines = md_text.splitlines()
questions = []
for line in lines:
if line.startswith("- "):
questions.append(line[2:])
return gr.update(choices=questions, value=None)
followup_md_state.change(
fn=update_followup_radio,
inputs=[followup_md_state],
outputs=[followup_radio]
)
with gr.Column(scale=1):
gr.Markdown("### Advanced Search Options")
with gr.Column(variant="panel"):
btn_images = gr.Button("Search Images")
btn_videos = gr.Button("Search Videos")
btn_links = gr.Button("Search Links")
gallery_output = gr.Gallery(label="Image Results", columns=2)
video_output = gr.HTML(label="Video Results") # HTML for embedded video iframes
links_output = gr.Markdown(label="Links Results")
btn_images.click(
fn=perform_image_search,
inputs=[followup_state],
outputs=[gallery_output]
)
btn_videos.click(
fn=perform_video_search,
inputs=[followup_state],
outputs=[video_output]
)
btn_links.click(
fn=perform_links_search,
inputs=[followup_state],
outputs=[links_output]
)
demo.launch()
|