Spaces:
Sleeping
Sleeping
| import os | |
| import requests | |
| import gradio as gr | |
| # --- Config (HF Spaces: set Repository Secret GROQ_API_KEY) --- | |
| groq_api_key = os.getenv("GROQ_API_KEY") | |
| if not groq_api_key: | |
| raise RuntimeError( | |
| "Missing GROQ_API_KEY. In your Space, go to Settings → Repository secrets → Add 'GROQ_API_KEY'." | |
| ) | |
| url = "https://api.groq.com/openai/v1/chat/completions" | |
| headers = { | |
| "Authorization": f"Bearer {groq_api_key}", | |
| "Content-Type": "application/json", | |
| } | |
| LOGO_URL = "https://raw.githubusercontent.com/Decoding-Data-Science/Omantel/main/download%20(36).png" | |
| OMANTEL_SYSTEM = """You are Aisha, the Omantel AI assistant for developer enablement. | |
| Style | |
| - Be concise, professional, and action-oriented. | |
| - Structure all answers as: Summary → Steps → Code → Notes. | |
| - Prefer bullet points over long paragraphs. | |
| Domain | |
| - Focus on telecom/customer-care use cases: RAG over KB articles, intent classification, call/chat summarization, ticket triage, PII redaction, and evaluation. | |
| - Show Python examples (requests, FastAPI, Gradio) and Groq (Llama 3.1-8B). | |
| - Use realistic ops/QA metrics when relevant: FRT, AHT, intent accuracy, containment/deflection rate, CSAT, latency (p95), and token usage. | |
| Safety & Privacy | |
| - Do not invent facts; say “I’m not sure” if uncertain. | |
| - Never include real keys, internal URLs, or customer data. Use placeholders. | |
| - Redact PII patterns in examples (MSISDN, IMSI, national IDs, emails). | |
| - Assume all data is confidential; follow least-privilege principles. | |
| Localization | |
| - Default to English. If the user writes in Arabic, reply in Arabic. | |
| - Use Asia/Muscat timezone for dates/times when needed. | |
| Formatting | |
| - Put code in fenced blocks with minimal, runnable examples. | |
| - Include curl when helpful. | |
| - Add clear TODOs for env vars and secrets. | |
| """ | |
| def call_groq(messages, temperature=0.2, max_tokens=600, model="llama-3.1-8b-instant"): | |
| body = { | |
| "model": model, | |
| "messages": messages, | |
| "temperature": temperature, | |
| "max_tokens": max_tokens, | |
| } | |
| try: | |
| resp = requests.post(url, headers=headers, json=body, timeout=60) | |
| except requests.RequestException as e: | |
| return f"Error: network/request failed: {e}" | |
| if resp.status_code == 200: | |
| return resp.json()["choices"][0]["message"]["content"] | |
| else: | |
| try: | |
| return f"Error: {resp.status_code} {resp.json()}" | |
| except Exception: | |
| return f"Error: {resp.status_code} {resp.text}" | |
| def groq_chat(message, history): | |
| messages = [{"role": "system", "content": OMANTEL_SYSTEM}] | |
| for u, a in history: | |
| if u: | |
| messages.append({"role": "user", "content": u}) | |
| if a: | |
| messages.append({"role": "assistant", "content": a}) | |
| messages.append({"role": "user", "content": message}) | |
| return call_groq(messages) | |
| # --- Minimal UI with Submit button (structure preserved) --- | |
| with gr.Blocks(title="Omantel Developer Assistant") as app: | |
| gr.HTML(""" | |
| <style> | |
| .header-row { display:flex; align-items:center; gap:12px; } | |
| .header-logo img { max-height:48px; border-radius:8px; } | |
| .header-title { font-size:20px; font-weight:600; margin:0; } | |
| </style> | |
| """) | |
| with gr.Row(elem_classes=["header-row"]): | |
| gr.Image( | |
| value=LOGO_URL, label=None, show_label=False, | |
| interactive=False, height=100, elem_classes=["header-logo"] | |
| ) | |
| title_box = gr.Textbox(value="Omantel Developer Assistant (Aisha)", label="Title", lines=1) | |
| header_md = gr.Markdown("### Omantel Developer Assistant (Aisha)", elem_classes=["header-title"]) | |
| def _update_header(t): | |
| return f"### {t}" if t.strip() else "### Omantel Developer Assistant (Aisha)" | |
| title_box.change(_update_header, inputs=title_box, outputs=header_md) | |
| gr.Markdown("Ask about telecom/customer-care AI use cases. Answers follow **Summary → Steps → Code → Notes**.") | |
| chatbot = gr.Chatbot(height=420) | |
| user_in = gr.Textbox(placeholder="Type your question…", lines=2, label="Your message") | |
| submit_btn = gr.Button("Submit", variant="primary") | |
| history_state = gr.State([]) # list of (user, assistant) | |
| def on_submit(user_msg, history): | |
| history = history or [] | |
| if not user_msg or not user_msg.strip(): | |
| return history, gr.update(), "" | |
| bot_reply = groq_chat(user_msg.strip(), history) | |
| history.append((user_msg.strip(), bot_reply)) | |
| return history, gr.update(value=history), "" | |
| submit_btn.click( | |
| fn=on_submit, | |
| inputs=[user_in, history_state], | |
| outputs=[history_state, chatbot, user_in], | |
| api_name=False | |
| ) | |
| # HF Spaces: bind to 0.0.0.0 | |
| if __name__ == "__main__": | |
| app.launch(server_name="0.0.0.0", server_port=int(os.getenv("PORT", "7860"))) | |