File size: 5,464 Bytes
614bb71
c4a975e
614bb71
c4a975e
ca283e9
c4a975e
614bb71
c4a975e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac0e51
c4a975e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
614bb71
9a9150c
 
c4a975e
 
 
9a9150c
614bb71
c4a975e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac0e51
c4a975e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
bac0e51
 
c4a975e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
614bb71
c4a975e
 
 
 
 
614bb71
c4a975e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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)