devalbot / app copy.py
gtani's picture
Refactor chat functionality and add system prompt for DevalBot
96bd8df
raw
history blame
3.56 kB
import gradio as gr
from bedrock_client import claude_llm, get_anthropic_client, claude_stream_response
from utils import load_users
AUTHS = load_users('user.csv')
HISTORY_LIMIT = 30 # max number of turns (user+assistant) to keep
# 1) Your system prompt
SYSTEM_PROMPT = (
"Du bist DevalBot, ein konversationeller Assistent des Deutschen Evaluierungsinstituts für Entwicklungsbewertung (DEval). DEval bietet staatlichen und zivilgesellschaftlichen Organisationen in der Entwicklungszusammenarbeit unabhÀngige und wissenschaftlich fundierte Evaluierungen. Deine Hauptsprache ist Deutsch; antworte daher standardmÀßig auf Deutsch. Du kannst zudem bei statistischen Analysen und Programmierung in Stata und R unterstützen. Antworte sachlich, prÀzise und stelle bei Unklarheiten klÀrende Rückfragen."
)
def chat(user_message, history):
# ── 1) Guard against empty input ─────────────────────
if not user_message or not user_message.strip():
return
# ── 2) Build the LLM’s messages list ─────────────────
# Always start with the SYSTEM_PROMPT, then the UI history,
# then the new user turn:
llm_messages = [{"role":"system","content":SYSTEM_PROMPT}]
llm_messages += history
llm_messages.append({"role":"user","content":user_message})
# ── 3) Kick off the streaming call ───────────────────
client = get_anthropic_client()
streamer = lambda msgs: claude_stream_response(msgs, client)
# ── 4) Immediately show the user’s turn in the UI ─
ui_history = history + [{"role":"user","content":user_message}]
full_resp = ""
try:
for chunk in streamer(llm_messages):
full_resp += chunk
# yield the UI history plus the growing assistant bubble
yield ui_history + [{"role":"assistant","content": full_resp}]
except Exception as e:
# surface any error inline
err = f"⚠️ Oops, something went wrong: {e}"
yield ui_history + [{"role":"assistant","content": err}]
return
# ── 5) Finalize the assistant turn in the UI ─────────
ui_history.append({"role":"assistant","content": full_resp})
# ── 6) Trim to the last N turns ──────────────────────
if len(ui_history) > HISTORY_LIMIT:
ui_history = ui_history[-HISTORY_LIMIT:]
yield ui_history
with gr.Blocks(css_paths=["static/deval.css"],theme = gr.themes.Default(primary_hue="blue", secondary_hue="yellow"),) as demo:
# ── Logo + Header + Logout ────────────────────────────────
gr.Image(
value="static/logo.png",
show_label=False,
interactive=False,
show_download_button=False,
show_fullscreen_button=False,
elem_id="logo-primary", # matches the CSS above
)
#logout_btn = gr.Button("Logout", elem_id="logout-btn")
# inject auto-reload script
gr.HTML(
"""
<script>
// Reload the page after 1 minutes (300 000 ms)
setTimeout(() => {
window.location.reload();
}, 1000);
</script>
"""
)
gr.ChatInterface(
chat,
type="messages",
editable=True,
concurrency_limit=200,
save_history=True,
)
demo.queue().launch(auth=AUTHS, ssr_mode=False)