File size: 10,822 Bytes
a1689b8
 
d29e860
 
 
5b8a690
 
 
 
 
 
 
 
 
 
 
a1689b8
 
5b8a690
a1689b8
 
5b8a690
 
a1689b8
5b8a690
 
a1689b8
5b8a690
 
 
 
 
 
 
 
a1689b8
 
 
 
 
5b8a690
 
 
 
 
 
 
 
a1689b8
5b8a690
a1689b8
 
 
 
 
 
 
 
 
 
 
 
 
5b8a690
 
 
a1689b8
5b8a690
 
a1689b8
 
5b8a690
d29e860
a1689b8
5b8a690
a1689b8
 
 
 
 
 
 
5b8a690
 
 
a1689b8
5b8a690
 
a1689b8
 
5b8a690
a1689b8
d29e860
5b8a690
a1689b8
 
5b8a690
a1689b8
5b8a690
a1689b8
d29e860
a1689b8
d29e860
 
5b8a690
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a1689b8
5b8a690
 
d29e860
5b8a690
 
a1689b8
 
5b8a690
d29e860
5b8a690
d29e860
 
5b8a690
 
a1689b8
 
 
 
5b8a690
d29e860
a1689b8
 
5b8a690
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
a1689b8
5b8a690
 
 
 
 
 
a1689b8
 
 
5b8a690
 
 
 
 
 
a1689b8
5b8a690
 
 
 
 
 
 
 
 
 
 
 
a1689b8
5b8a690
 
 
 
 
a1689b8
5b8a690
 
 
 
a1689b8
5b8a690
 
 
 
 
a1689b8
5b8a690
 
 
 
a1689b8
5b8a690
 
 
 
a1689b8
5b8a690
 
 
 
 
a1689b8
5b8a690
 
 
 
 
a1689b8
5b8a690
 
 
 
 
 
a1689b8
5b8a690
 
 
 
 
a1689b8
5b8a690
 
 
 
 
 
 
 
 
a1689b8
 
 
 
 
 
 
 
 
 
 
 
5b8a690
 
 
a1689b8
5b8a690
 
a1689b8
 
5b8a690
a1689b8
5b8a690
a1689b8
 
3147ce7
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
import json
import time
import gradio as gr


# ---------- Helpers ----------

def _yes_no(v: bool) -> str:
    return "Yes" if v else "No"


def _join(items):
    return ", ".join(items) if items else "Not specified"


def qualify_signal(users_in_scope, required_features, stage, timeline, review_teams):
    score = 0

    # scale
    if users_in_scope in ["200–1,000", "1,000+"]:
        score += 2
    elif users_in_scope == "50–200":
        score += 1

    # governance/security must-haves
    required_features = set(required_features or [])
    must_haves = {"Mandatory SSO", "Audit logs", "Team-based access (Resource Groups)"}
    score += 1 if len(must_haves.intersection(required_features)) >= 2 else 0
    score += 1 if "SCIM provisioning/deprovisioning" in required_features else 0
    score += 1 if "Exportable logs (SIEM)" in required_features else 0

    # buying motion
    if stage in ["Approvals in progress", "Budget approved / procurement engaged"]:
        score += 2
    elif stage == "Shortlisting vendors":
        score += 1

    if timeline in ["< 1 month", "1–3 months"]:
        score += 1

    # enterprise review involvement
    review_teams = set(review_teams or [])
    if "Legal" in review_teams:
        score += 1
    if "Information Security" in review_teams or "Compliance / Risk" in review_teams:
        score += 1

    if score >= 7:
        return "strong"
    if score >= 4:
        return "moderate"
    return "exploratory"


def build_summary(
    organization,
    industry,
    company_size,
    regions,
    users_in_scope,
    idp,
    required_features,
    data_residency,
    siem_tool,
    compliance_frameworks,
    content_types,
    review_teams,
    decision_makers,
    stage,
    timeline,
    call_success_criteria,
    open_questions,
):
    summary = {
        "organization": (organization or "").strip(),
        "industry": industry,
        "company_size": company_size,
        "regions": regions or [],
        "estimated_users_in_scope": users_in_scope,
        "sso_provider": idp,
        "required_features": required_features or [],
        "data_residency": data_residency,
        "siem_tool": (siem_tool or "").strip(),
        "compliance_frameworks": compliance_frameworks or [],
        "content_types_in_scope": content_types or [],
        "review_teams": review_teams or [],
        "decision_makers": decision_makers or [],
        "evaluation_stage": stage,
        "timeline": timeline,
        "call_success_criteria": (call_success_criteria or "").strip(),
        "open_questions": (open_questions or "").strip(),
    }

    summary["qualification_signal"] = qualify_signal(
        users_in_scope=users_in_scope,
        required_features=required_features,
        stage=stage,
        timeline=timeline,
        review_teams=review_teams,
    )

    return summary


def format_briefing(s):
    rf = set(s.get("required_features", []) or [])

    briefing = f"""
ENTERPRISE HUB – PRE-CALL BRIEFING

Organization
- Name: {s.get('organization') or 'Not specified'}
- Industry: {s.get('industry') or 'Not specified'}
- Company size: {s.get('company_size') or 'Not specified'}
- Regions: {_join(s.get('regions'))}

Scope
- Estimated users: {s.get('estimated_users_in_scope') or 'Not specified'}
- SSO provider: {s.get('sso_provider') or 'Not specified'}
- Content in scope: {_join(s.get('content_types_in_scope'))}

Security & Governance (high-level)
- Mandatory SSO: {_yes_no("Mandatory SSO" in rf)}
- SCIM provisioning: {_yes_no("SCIM provisioning/deprovisioning" in rf)}
- Audit logs: {_yes_no("Audit logs" in rf)}
- Exportable logs (SIEM): {_yes_no("Exportable logs (SIEM)" in rf)}
- Team-based access (Resource Groups): {_yes_no("Team-based access (Resource Groups)" in rf)}
- Token lifecycle management: {_yes_no("Token lifecycle management" in rf)}
- Mandatory 2FA: {_yes_no("Mandatory 2FA" in rf)}
- Data residency: {s.get('data_residency') or 'Not specified'}
- SIEM tool (if applicable): {s.get('siem_tool') or 'Not specified'}

Legal / Compliance
- Frameworks: {_join(s.get('compliance_frameworks'))}
- Review teams: {_join(s.get('review_teams'))}

Buying Process
- Stage: {s.get('evaluation_stage') or 'Not specified'}
- Timeline: {s.get('timeline') or 'Not specified'}
- Decision makers: {_join(s.get('decision_makers'))}

Call Success Criteria
- {s.get('call_success_criteria') or 'Not specified'}

Open Questions (optional)
- {s.get('open_questions') or 'None provided'}

Qualification Signal
- {str(s.get('qualification_signal') or '').upper()}
""".strip()

    return briefing


def submit(*vals):
    summary = build_summary(*vals)
    briefing_text = format_briefing(summary)

    # Save JSON for download (optional)
    json_output = json.dumps(summary, indent=2, ensure_ascii=False)
    filename = f"enterprise_intake_{int(time.time())}.json"
    with open(filename, "w", encoding="utf-8") as f:
        f.write(json_output)

    return briefing_text, filename


# ---------- UI ----------

with gr.Blocks(title="Enterprise Hub – Pre-Call Intake") as demo:
    gr.Markdown(
        """
# Enterprise Hub – Pre-Call Intake
Short intake (β‰ˆ3–5 minutes). Generates a **human-readable pre-call briefing** + optional JSON download.
"""
    )

    with gr.Accordion("Organization & Scope", open=True):
        with gr.Row():
            organization = gr.Textbox(label="Organization name", placeholder="e.g., ACME Bank")
            industry = gr.Dropdown(
                label="Industry",
                choices=[
                    "Financial Services / Banking",
                    "Government / Public Sector",
                    "Healthcare / Life Sciences",
                    "Technology / Software",
                    "Telecommunications",
                    "Energy / Industrial",
                    "Retail / E-commerce",
                    "Other",
                ],
                value="Technology / Software",
            )

        company_size = gr.Radio(
            label="Company size (employees)",
            choices=["< 500", "500–2,000", "2,000–10,000", "10,000+"],
            value="500–2,000",
        )

        regions = gr.CheckboxGroup(
            label="Regions where the Hub would be used",
            choices=["North America", "Europe", "Middle East", "Asia-Pacific", "Global / Multi-region"],
        )

        users_in_scope = gr.Radio(
            label="Estimated number of Hub users in scope",
            choices=["< 50", "50–200", "200–1,000", "1,000+"],
            value="50–200",
        )

        content_types = gr.CheckboxGroup(
            label="What would be in scope on the Hub?",
            choices=[
                "Private model repos",
                "Private datasets",
                "Spaces (apps/demos)",
                "Internal forks of open-source models",
                "Fine-tuning artifacts",
                "Other / unsure",
            ],
        )

    with gr.Accordion("Security, Access & Governance", open=True):
        idp = gr.Dropdown(
            label="SSO identity provider",
            choices=["Azure AD / Entra ID", "Okta", "Google Workspace", "Ping", "Auth0", "Other"],
            value="Azure AD / Entra ID",
        )

        required_features = gr.CheckboxGroup(
            label="Required capabilities (check all that apply)",
            choices=[
                "Mandatory SSO",
                "SCIM provisioning/deprovisioning",
                "Audit logs",
                "Exportable logs (SIEM)",
                "Team-based access (Resource Groups)",
                "Token lifecycle management",
                "Mandatory 2FA",
            ],
        )

        data_residency = gr.Radio(
            label="Data residency requirement",
            choices=["No specific requirement", "Region-specific storage required", "Regulatory constraints apply"],
            value="No specific requirement",
        )

        siem_tool = gr.Textbox(
            label="If SIEM export is required, which SIEM do you use? (optional)",
            placeholder="e.g., Splunk, Sentinel, QRadar",
        )

    with gr.Accordion("Legal, Compliance & Process", open=False):
        compliance_frameworks = gr.CheckboxGroup(
            label="Compliance frameworks (if applicable)",
            choices=["SOC 2", "ISO 27001", "GDPR", "HIPAA", "Financial / banking regulations", "Other / unsure"],
        )

        review_teams = gr.CheckboxGroup(
            label="Teams involved in review",
            choices=["Legal", "Information Security", "Compliance / Risk", "IT", "Procurement", "Data / AI Leadership"],
        )

        decision_makers = gr.CheckboxGroup(
            label="Primary decision maker(s)",
            choices=["CISO / Head of Security", "CTO / Engineering leadership", "Head of Data / AI", "Procurement", "Shared committee"],
        )

        stage = gr.Radio(
            label="Evaluation stage",
            choices=["Early evaluation", "Shortlisting vendors", "Approvals in progress", "Budget approved / procurement engaged"],
            value="Early evaluation",
        )

        timeline = gr.Radio(
            label="Target decision timeline",
            choices=["< 1 month", "1–3 months", "3+ months", "No fixed timeline"],
            value="1–3 months",
        )

    with gr.Accordion("Call Preparation", open=True):
        call_success_criteria = gr.Textbox(
            label="What must we cover on the call for it to be successful?",
            lines=3,
            placeholder="e.g., confirm SSO + audit log coverage; clarify access model; align legal next steps",
        )

        open_questions = gr.Textbox(
            label="Any specific questions or concerns to address live? (optional)",
            lines=3,
            placeholder="e.g., license/IP questions; vulnerability concerns; approval steps; rollout approach",
        )

    submit_btn = gr.Button("Generate pre-call briefing", variant="primary")

    output_briefing = gr.Textbox(
        label="Pre-Call Briefing",
        lines=22,
        interactive=False,
        show_copy_button=True,
    )
    output_file = gr.File(label="Download JSON (optional)")

    submit_btn.click(
        fn=submit,
        inputs=[
            organization,
            industry,
            company_size,
            regions,
            users_in_scope,
            idp,
            required_features,
            data_residency,
            siem_tool,
            compliance_frameworks,
            content_types,
            review_teams,
            decision_makers,
            stage,
            timeline,
            call_success_criteria,
            open_questions,
        ],
        outputs=[output_briefing, output_file],
    )

demo.launch(share=True)