from pathlib import Path import gradio as gr from logic.profile import Me def _load_css() -> str: css_path = Path(__file__).parent / "styles.css" with open(css_path, "r", encoding="utf-8") as f: return f.read() def build_interface(): me = Me() custom_css = _load_css() with gr.Blocks(css=custom_css) as demo: with gr.Row(elem_classes="app-row"): with gr.Column(scale=3, elem_classes="chat-column"): gr.Markdown( "### Chat with **Evison Ndoni**", elem_classes="title-text", ) chatbot = gr.Chatbot( height=520, elem_id="chatbot", ) with gr.Row(elem_classes="input-row"): msg = gr.Textbox( placeholder=( "Ask about my background, past work, AI/agentic AI, " "or anything career-related..." ), label="", show_label=False, elem_id="chat-input", ) with gr.Row(elem_classes="button-row"): send_btn = gr.Button("Send", elem_id="send-btn") clear_btn = gr.Button("Clear chat", elem_id="clear-btn") with gr.Column(scale=2, elem_classes="sidebar-column"): gr.Markdown( """ ### About Evison Ndoni - Software engineer (React, Next.js, TypeScript, Tailwind CSS, Flutter) - Currently learning **Agentic AI** and building AI-powered projects - Enjoys clean, SaaS-style product design and long-term thinking If you're a recruiter, hiring manager, or potential collaborator, feel free to ask anything about my experience, stack, or projects. You can also **share your email in the chat** if you'd like me to follow up. """, elem_classes="about-card", ) def respond(message, history): """ Gradio 6 Chatbot uses a 'messages' format: history is a list of dicts: [{ "role": "user"|"assistant", "content": "..." }, ...] We must return the *updated* history in the same format. """ if history is None: history = [] assistant_reply = me.chat(message, history) new_history = history + [ {"role": "user", "content": message}, {"role": "assistant", "content": assistant_reply}, ] return new_history send_btn.click( respond, inputs=[msg, chatbot], outputs=chatbot, ) send_btn.click(lambda: "", inputs=None, outputs=msg) clear_btn.click(lambda: [], inputs=None, outputs=chatbot) demo.load(lambda: [], None, chatbot) return demo