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( """ """ ) gr.ChatInterface( chat, type="messages", editable=True, concurrency_limit=200, save_history=True, ) demo.queue().launch(auth=AUTHS, ssr_mode=False)