Spaces:
Running
Running
| import os | |
| import json | |
| import gradio as gr | |
| import requests | |
| # ---- Secrets (Space Settings → Secrets) ---- | |
| HF_TOKEN = os.getenv("HF_TOKEN", "") | |
| DEFAULT_MODEL = os.getenv("HF_MODEL", "Qwen/Qwen2.5-7B-Instruct") | |
| # HF Router (OpenAI-compatible) | |
| ROUTER_URL = "https://router.huggingface.co/v1/chat/completions" | |
| SYSTEM_INSTRUCTIONS = """ | |
| You are a senior enterprise Account Executive specializing in converting open-source platform usage into enterprise-grade commercial engagements. | |
| Rules: | |
| - Do NOT represent any specific vendor. | |
| - Do NOT claim access to private/internal data. | |
| - Anchor everything in public signals and state assumptions clearly. | |
| - Avoid generic SaaS buzzwords. Be executable. | |
| You MUST output exactly these headings: | |
| 1. Account Snapshot | |
| 2. Usage Hypotheses | |
| 3. Persona Mapping | |
| 4. Outbound Campaign Design | |
| 5. Message Examples | |
| 6. How This Scales | |
| Under Message Examples: | |
| - One technical-user message | |
| - One decision-maker message | |
| Tone: senior AE speaking to peers. No emojis. | |
| """.strip() | |
| USER_TEMPLATE = """ | |
| Account (name or org URL): {account} | |
| Optional context: | |
| Industry: {industry} | |
| Region: {region} | |
| Primary persona: {primary_persona} | |
| Secondary personas: {secondary_personas} | |
| Offer focus: {offer_focus} | |
| Goal: {goal} | |
| Notes: {notes} | |
| Task: | |
| Create a structured outbound plan for this account based on public open-source platform usage and OSS → Enterprise conversion patterns. | |
| """.strip() | |
| def call_router(model: str, system: str, user: str) -> str: | |
| if not HF_TOKEN: | |
| return ( | |
| "Missing HF_TOKEN.\n\n" | |
| "Fix:\n" | |
| "Space → Settings → Secrets → add HF_TOKEN with permission:\n" | |
| "✅ Make calls to Inference Providers" | |
| ) | |
| headers = { | |
| "Authorization": f"Bearer {HF_TOKEN}", | |
| "Content-Type": "application/json", | |
| } | |
| payload = { | |
| "model": model, | |
| "messages": [ | |
| {"role": "system", "content": system}, | |
| {"role": "user", "content": user}, | |
| ], | |
| "temperature": 0.4, | |
| "max_tokens": 1400, | |
| } | |
| try: | |
| r = requests.post(ROUTER_URL, headers=headers, data=json.dumps(payload), timeout=60) | |
| if r.status_code != 200: | |
| return ( | |
| "Model call failed.\n\n" | |
| f"HTTP {r.status_code}\n" | |
| f"Response: {r.text}\n\n" | |
| "Quick fixes:\n" | |
| "1) Try a smaller model (e.g., Qwen/Qwen2.5-7B-Instruct or mistralai/Mistral-7B-Instruct-v0.3)\n" | |
| "2) Ensure your HF_TOKEN includes 'Make calls to Inference Providers'\n" | |
| "3) If the model is gated, pick a model you have access to" | |
| ) | |
| data = r.json() | |
| return data["choices"][0]["message"]["content"].strip() | |
| except requests.exceptions.Timeout: | |
| return ( | |
| "Model call timed out.\n\n" | |
| "Fixes:\n" | |
| "1) Use a smaller model\n" | |
| "2) Reduce max_tokens\n" | |
| ) | |
| except Exception as e: | |
| return f"Unexpected error calling router: {repr(e)}" | |
| def generate(account, industry, region, primary_persona, secondary_personas, offer_focus, goal, notes, model): | |
| account = (account or "").strip() | |
| if not account: | |
| return "Please input an account name or org URL." | |
| model = (model or DEFAULT_MODEL).strip() | |
| user_prompt = USER_TEMPLATE.format( | |
| account=account, | |
| industry=industry or "Not provided", | |
| region=region or "Not provided", | |
| primary_persona=primary_persona or "Not provided", | |
| secondary_personas=secondary_personas or "Not provided", | |
| offer_focus=offer_focus or "Not provided", | |
| goal=goal or "Convert free/community usage to enterprise engagement", | |
| notes=notes or "Not provided", | |
| ) | |
| return call_router(model=model, system=SYSTEM_INSTRUCTIONS, user=user_prompt) | |
| with gr.Blocks(title="Enterprise OSS → Outbound Ops") as app: | |
| gr.Markdown( | |
| "# Enterprise OSS → Outbound Ops\n" | |
| "Input an **account name or public org URL** to generate a structured enterprise outbound plan." | |
| ) | |
| account = gr.Textbox( | |
| label="Account name or org URL", | |
| placeholder="e.g., Emirates OR https://huggingface.co/emirates", | |
| lines=1, | |
| ) | |
| with gr.Row(): | |
| industry = gr.Textbox(label="Industry (optional)", placeholder="e.g., Airlines, Energy, Banking") | |
| region = gr.Textbox(label="Region (optional)", placeholder="e.g., MENA, KSA, UAE, Global") | |
| with gr.Row(): | |
| primary_persona = gr.Textbox(label="Primary persona (optional)", placeholder="e.g., Head of Data/AI, VP Eng, CISO") | |
| secondary_personas = gr.Textbox(label="Secondary personas (optional)", placeholder="e.g., ML Eng, DS, Platform, Security") | |
| offer_focus = gr.Textbox(label="Offer focus (optional)", placeholder="e.g., governance, SSO, audit, private collaboration") | |
| goal = gr.Textbox(label="Goal (optional)", placeholder="e.g., Identify champions + secure intro call with platform owner") | |
| notes = gr.Textbox(label="Notes / known public signals (optional)", lines=4) | |
| model = gr.Textbox(label="Model", value=DEFAULT_MODEL) | |
| run = gr.Button("Generate outbound plan") | |
| output = gr.Markdown() | |
| run.click( | |
| fn=generate, | |
| inputs=[account, industry, region, primary_persona, secondary_personas, offer_focus, goal, notes, model], | |
| outputs=output, | |
| ) | |
| app.launch(server_name="0.0.0.0", server_port=7860) | |