| """
|
| AI STRATEGY CONSULTANT (Gradio) — Poe + Claude Opus 4.6
|
|
|
| CLAUDE AS STRATEGY CONSULTANT - 12 prompts that replace them completely !!!!!
|
|
|
| https://x.com/sukh_saroy/status/2025622908715024736?s=46
|
|
|
| EVERNOTE: CLAUDE AS STRATEGY CONSULTANT - 12 prompts that replace them completely
|
| !!!!! https://x.com/sukh_saroy/status/2025622908715024736?s=46
|
| https://share.evernote.com/note/79c713fd-c2ed-4b14-a3b1-b144ae553cf2
|
|
|
|
|
| What it does
|
| - User enters POE API key (required)
|
| - User can check remaining Poe points (Usage API)
|
| - User can run:
|
| (a) one of 12 strategy analyses
|
| (b) all 12 analyses at once
|
| - Each analysis is returned as Markdown
|
| - User can download each analysis as:
|
| - .md
|
| - .pdf (simple markdown-to-PDF rendering via ReportLab)
|
|
|
| References (Poe docs)
|
| - OpenAI-compatible endpoint: https://api.poe.com/v1 (docs: creator.poe.com)
|
| - Usage API (remaining points): GET https://api.poe.com/usage/current_balance
|
| (docs: https://creator.poe.com/docs/resources/usage-api)
|
|
|
| Install
|
| pip install gradio openai requests reportlab
|
|
|
| Run
|
| python app.py
|
|
|
| Notes
|
| - Uses Poe OpenAI-compatible Chat Completions API with model "Claude-Opus-4.6".
|
| (Poe model naming examples in docs include "Claude-Opus-4.5"; "Claude-Opus-4.6" is available on Poe.)
|
| """
|
|
|
| from __future__ import annotations
|
|
|
| import os
|
| import re
|
| import json
|
| import time
|
| import uuid
|
| import textwrap
|
| from dataclasses import dataclass
|
| from datetime import datetime
|
| from typing import Dict, List, Tuple, Optional
|
|
|
| import requests
|
| import gradio as gr
|
| from openai import OpenAI
|
| from reportlab.lib.pagesizes import LETTER
|
| from reportlab.pdfgen import canvas
|
|
|
|
|
|
|
|
|
|
|
| POE_BASE_URL = "https://api.poe.com/v1"
|
| POE_USAGE_BALANCE_URL = "https://api.poe.com/usage/current_balance"
|
|
|
|
|
| DEFAULT_MODEL = "Claude-Opus-4.6"
|
|
|
|
|
|
|
|
|
|
|
| ANALYSES = [
|
| "1/ Competitive Landscape Mapping",
|
| "2/ Porter's Five Forces Deep Dive",
|
| "3/ Competitor Teardown Analysis",
|
| "4/ Market Sizing & TAM/SAM/SOM Analysis",
|
| "5/ Win/Loss Competitive Analysis",
|
| "6/ Pricing Strategy & Competitive Benchmarking",
|
| "7/ Blue Ocean Strategy Analysis",
|
| "8/ Competitive Moat Assessment",
|
| "9/ Market Entry Strategy",
|
| "10/ Disruption Threat Assessment",
|
| "11/ Customer Segmentation & Battleground Analysis",
|
| "12/ Strategic Scenario Planning",
|
| ]
|
|
|
| PROMPT_TEMPLATES: Dict[str, str] = {
|
| ANALYSES[0]: """You are a Partner at Bain & Company. I need a complete competitive landscape analysis for:
|
| Company/Industry: {industry}
|
|
|
| Please provide (in a consulting-deck style Markdown deliverable):
|
| - Executive summary (5–8 bullets)
|
| - Market map: major players segmented by tier (leaders, challengers, niche, emerging)
|
| - Market share estimates: revenue-based share for top 10 competitors (state assumptions)
|
| - Positioning matrix: 2x2 grid (price vs differentiation) with short rationale for each competitor
|
| - Competitor profiles: business model, target customer, key strengths (each)
|
| - Strategic groups: cluster competitors by similar strategies
|
| - White space analysis: underserved segments no one is targeting
|
| - Threat assessment: rank competitors by threat level (High/Medium/Low) with reasoning
|
| - Entry barriers: what stops new competitors from entering each segment
|
| - Implications & recommended moves (top 5)
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[1]: """You are a Senior Strategy Consultant at McKinsey. I need a Porter's Five Forces analysis for:
|
| Industry: {industry}
|
|
|
| Please provide (strategy memo in Markdown):
|
| - Supplier power: number of suppliers, switching costs, input differentiation
|
| - Buyer power: customer concentration, price sensitivity, switching costs
|
| - Competitive rivalry: number of competitors, industry growth rate, exit barriers
|
| - Threat of substitutes: alternative solutions, price-performance tradeoff
|
| - Threat of new entrants: capital requirements, brand loyalty, regulatory barriers
|
| - Force ratings: score each force 1–5 with detailed justification
|
| - Overall industry attractiveness score: 1–10 (explain)
|
| - Strategic implications: pricing, investment, positioning
|
| - Top 3 recommendations based on the combined forces
|
|
|
| Industry + company position:
|
| {company_context}
|
| """,
|
| ANALYSES[2]: """You are a VP of Strategy at BCG. I need a full competitor teardown for:
|
| Competitor name: {focus_competitor}
|
|
|
| Provide a competitive intelligence briefing in Markdown:
|
| - Business model canvas: revenue streams, cost structure, key resources, channels
|
| - Financial analysis: revenue, growth rate, margins, burn rate (if available; otherwise infer & label)
|
| - Product analysis: core offering, pricing tiers, feature comparison vs us
|
| - Go-to-market: sales channels, marketing motions, acquisition approach
|
| - Leadership team: key executives, backgrounds, strategic tendencies (infer if needed)
|
| - Technology: known stack, platform bets, patents, R&D posture
|
| - Customer analysis: target segments, signals (reviews, sentiment themes), churn indicators
|
| - SWOT: strengths, weaknesses, opportunities, threats (specifics)
|
| - Recommended counter-strategies: 5–7 actions, prioritized, with “why now”
|
|
|
| Our company context:
|
| {company_context}
|
|
|
| Anything we know about the competitor:
|
| {competitor_context}
|
| """,
|
| ANALYSES[3]: """You are an Engagement Manager at Bain & Company. I need a rigorous market sizing for:
|
| Market: {market_definition}
|
|
|
| Provide an investor-ready sizing in Markdown:
|
| - TAM (top-down) with assumptions & transparent math
|
| - SAM (filtered by geography/segment/capability)
|
| - SOM (realistic share capture given GTM + competition)
|
| - Bottom-up validation (units × price × adoption)
|
| - Growth projections: 5-year CAGR with growth drivers
|
| - Segmentation: 4–6 segments with size & growth
|
| - Reconciliation: explain why top-down and bottom-up align or differ
|
| - Comparable benchmarks: similar markets/companies (no external browsing; use heuristics and label)
|
| - Sensitivity table: best/base/worst case
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[4]: """You are a Strategy Director at Deloitte. I need a win/loss analysis framework for:
|
| Company: {company_name}
|
|
|
| Provide a quarterly competitive review in Markdown:
|
| - Win pattern analysis: top 5 reasons customers choose us (with evidence proxies)
|
| - Loss pattern analysis: top 5 reasons customers choose competitors
|
| - Competitor-specific breakdown: win-rate/loss reasons per competitor
|
| - Deal stage analysis: where in funnel we lose most often and why
|
| - Pricing analysis: how often price vs features vs brand decides
|
| - Segment analysis: which segments we win most/least
|
| - Objection mapping: common objections and which competitor triggers them
|
| - Action plan: product/pricing/messaging changes to improve win rate 20%+
|
| - Metrics & instrumentation: what to track next quarter
|
|
|
| Company context:
|
| {company_context}
|
|
|
| Win/Loss notes (if any):
|
| {win_loss_context}
|
| """,
|
| ANALYSES[5]: """You are a Pricing Strategy Partner at Simon-Kucher. I need competitive pricing analysis for:
|
| Product: {product_name}
|
|
|
| Provide a pricing strategy deck in Markdown:
|
| - Competitor pricing map: tiers, features per tier, price points (use provided info; infer missing + label)
|
| - Value metric analysis: what unit competitors charge on
|
| - Price positioning: value vs price spectrum
|
| - Willingness-to-pay: estimate per segment (assumptions explicit)
|
| - Model comparison: freemium vs trial vs usage-based vs flat
|
| - Elasticity assessment: sensitivity to price changes
|
| - Monetization gaps: what we give free that others charge for (and vice versa)
|
| - Recommended pricing: 2–3 scenarios with expected revenue impact and risks
|
| - Packaging: suggested tiers & feature fences
|
|
|
| Company context:
|
| {company_context}
|
|
|
| Known competitor pricing (if any):
|
| {pricing_context}
|
| """,
|
| ANALYSES[6]: """You are a Senior Partner at Strategy& (PwC). I need a blue ocean strategy canvas for:
|
| Company: {company_name}
|
|
|
| Provide a strategy workshop output in Markdown:
|
| - Current strategy canvas: compare company vs top 3 competitors across 8–10 value factors
|
| - Industry assumptions: what everyone competes on that customers don't care about
|
| - ERRC grid:
|
| - Eliminate factors
|
| - Reduce factors
|
| - Raise factors
|
| - Create factors
|
| - New value curve: describe the differentiated curve and why it wins
|
| - Three tiers of non-customers and conversion plays
|
| - Implementation roadmap: 90 days / 6 months / 12 months with owners and KPIs
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[7]: """You are an Investment Strategist at Bridgewater Associates. I need a competitive moat analysis for:
|
| Company: {company_name}
|
|
|
| Provide an investment thesis memo in Markdown:
|
| - Network effects: strength and mechanisms
|
| - Switching costs: data, integrations, retraining, process
|
| - Cost advantages: scale, tech, supply chain, unit economics
|
| - Intangibles: brand, patents, regulatory licenses, proprietary data
|
| - Efficient scale: whether market supports multiple winners
|
| - Moat scorecard: each dimension 1–10 with evidence or explicit assumptions
|
| - Moat trajectory: widening or narrowing over 5 years
|
| - Vulnerability map: top 3 scenarios that destroy moat + mitigations
|
| - 5-year durability assessment + “do next” actions
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[8]: """You are a Global Strategy Partner at Roland Berger. I need a market entry analysis for:
|
| New market / geography: {new_market}
|
|
|
| Provide a market entry business case in Markdown:
|
| - Market attractiveness: size, growth, profitability, competitive intensity
|
| - Entry mode: build vs buy vs partner vs license (pros/cons + recommendation)
|
| - Incumbent response: how they will react + how to pre-empt
|
| - Regulatory landscape: key regs, compliance cost ranges, timeline risks (assumptions explicit)
|
| - Localization: product changes, pricing adjustments, cultural factors
|
| - GTM plan: first 12 months (milestones, resourcing, channels)
|
| - Financial model: investment, break-even, 3-year revenue projection (tables)
|
| - Risk matrix: top 10 risks (probability × impact) + mitigations
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[9]: """You are a Partner at Innosight. I need a disruption threat analysis for:
|
| Industry: {industry}
|
|
|
| Provide a board-level briefing in Markdown:
|
| - Incumbent vulnerability scan: where players over-serve or over-price
|
| - Low-end disruption threats: "good enough" at 50%+ lower price
|
| - New-market disruption threats: serving non-consumers we ignore
|
| - Technology shifts: emerging tech altering the value chain
|
| - Business model innovation: subscription/marketplace/AI-native/etc.
|
| - Startup radar: 10 plausible disruptors (no web browsing; generate archetypes and name them clearly as fictional archetypes unless user provides real ones)
|
| - Timeline: when each threat becomes critical (1, 3, 5+ years)
|
| - Strategic response: defend, acquire, pivot, or separate unit
|
| - Early moves: 5 actions with triggers
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[10]: """You are a Growth Strategy Lead at L.E.K. Consulting. I need competitive customer segmentation for:
|
| Market: {market_definition}
|
|
|
| Provide a segmentation strategy in Markdown:
|
| - Segment identification: 5–7 segments by needs/behavior/value
|
| - Segment sizing: revenue potential + customer count (assumptions explicit)
|
| - Competitive ownership: who dominates each and why
|
| - Battleground segments: where we fight hardest
|
| - Underserved segments: high-value segments no one serves well
|
| - Switching triggers: what causes switching (both directions)
|
| - Segment-specific positioning: tailored value prop for each winnable segment
|
| - Prioritization matrix: attractiveness × ability to win
|
| - Resource allocation: where to invest (sales, product, marketing)
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| ANALYSES[11]: """You are a Senior Advisor at Monitor Deloitte. I need scenario planning for:
|
| Industry: {industry}
|
| Horizon: {planning_horizon}
|
|
|
| Provide an executive offsite deliverable in Markdown:
|
| - Critical uncertainties: top 2 truly unpredictable forces
|
| - Four scenarios: name + narrative for each quadrant
|
| - Competitor behavior: how each major competitor behaves in each scenario
|
| - Impact assessment: revenue, share, margin impact for our company per scenario (table)
|
| - Early warning signals: 3–5 indicators per scenario
|
| - No-regret moves: actions that win across all scenarios
|
| - Scenario-specific bets: high-upside actions with triggers
|
| - Portfolio stress test: how current strategy performs + gaps
|
|
|
| Company context:
|
| {company_context}
|
| """,
|
| }
|
|
|
|
|
|
|
|
|
|
|
| def _safe_filename(name: str) -> str:
|
| name = name.strip().lower()
|
| name = re.sub(r"[^a-z0-9\-_. ]+", "", name)
|
| name = re.sub(r"\s+", "_", name)
|
| return name[:120] or "report"
|
|
|
|
|
| def md_to_pdf_simple(md_text: str, pdf_path: str, title: str) -> None:
|
| """
|
| Simple, dependency-light Markdown->PDF renderer:
|
| - Writes title
|
| - Writes markdown as wrapped plain text (monospace-ish layout)
|
| """
|
| c = canvas.Canvas(pdf_path, pagesize=LETTER)
|
| width, height = LETTER
|
|
|
| left_margin = 50
|
| right_margin = 50
|
| top_margin = 60
|
| bottom_margin = 50
|
| line_height = 12
|
|
|
| y = height - top_margin
|
|
|
|
|
| c.setFont("Helvetica-Bold", 14)
|
| c.drawString(left_margin, y, title)
|
| y -= 2 * line_height
|
|
|
|
|
| c.setFont("Courier", 9)
|
|
|
| max_width_chars = 100
|
| for raw_line in md_text.splitlines():
|
|
|
| if raw_line.strip() == "":
|
| y -= line_height
|
| if y < bottom_margin:
|
| c.showPage()
|
| c.setFont("Courier", 9)
|
| y = height - top_margin
|
| continue
|
|
|
| wrapped = textwrap.wrap(raw_line, width=max_width_chars, replace_whitespace=False, drop_whitespace=False)
|
| if not wrapped:
|
| wrapped = [""]
|
|
|
| for line in wrapped:
|
| if y < bottom_margin:
|
| c.showPage()
|
| c.setFont("Courier", 9)
|
| y = height - top_margin
|
| c.drawString(left_margin, y, line[:max_width_chars])
|
| y -= line_height
|
|
|
| c.save()
|
|
|
|
|
| def build_company_context(
|
| company_name: str,
|
| industry: str,
|
| business_model: str,
|
| product_name: str,
|
| product_desc: str,
|
| target_customers: str,
|
| geography: str,
|
| stage: str,
|
| pricing: str,
|
| top_competitors: str,
|
| differentiators: str,
|
| traction: str,
|
| constraints: str,
|
| ) -> str:
|
|
|
| parts = [
|
| f"Company name: {company_name}",
|
| f"Industry: {industry}",
|
| f"Stage: {stage}",
|
| f"Geography / markets served: {geography}",
|
| f"Product name: {product_name}",
|
| f"Product description: {product_desc}",
|
| f"Business model: {business_model}",
|
| f"Target customers: {target_customers}",
|
| f"Current pricing: {pricing}",
|
| f"Top competitors (known): {top_competitors}",
|
| f"Differentiators / strengths: {differentiators}",
|
| f"Traction / metrics (if any): {traction}",
|
| f"Constraints / risks / must-avoid: {constraints}",
|
| ]
|
| return "\n".join(f"- {p}" for p in parts if p and p.strip())
|
|
|
|
|
| def poe_client(poe_api_key: str) -> OpenAI:
|
| return OpenAI(api_key=poe_api_key, base_url=POE_BASE_URL)
|
|
|
|
|
| def get_remaining_points(poe_api_key: str) -> str:
|
| if not poe_api_key or not poe_api_key.strip():
|
| return "Please enter your POE API key first."
|
|
|
| try:
|
| resp = requests.get(
|
| POE_USAGE_BALANCE_URL,
|
| headers={"Authorization": f"Bearer {poe_api_key.strip()}"},
|
| timeout=20,
|
| )
|
| if resp.status_code == 401:
|
| return "Unauthorized (401). Your POE API key looks invalid."
|
| resp.raise_for_status()
|
| data = resp.json()
|
| points = data.get("current_point_balance", None)
|
| if points is None:
|
| return f"Unexpected response: {json.dumps(data, indent=2)}"
|
| return f"✅ Current Poe point balance: **{points}** points"
|
| except requests.RequestException as e:
|
| return f"Error calling Poe Usage API: {e}"
|
|
|
|
|
| def assemble_prompt(
|
| analysis_name: str,
|
| company_context: str,
|
| industry: str,
|
| company_name: str,
|
| product_name: str,
|
| market_definition: str,
|
| focus_competitor: str,
|
| competitor_context: str,
|
| pricing_context: str,
|
| win_loss_context: str,
|
| new_market: str,
|
| planning_horizon: str,
|
| ) -> str:
|
| template = PROMPT_TEMPLATES[analysis_name]
|
| return template.format(
|
| company_context=company_context or "(No company context provided)",
|
| industry=industry or "(Industry not provided)",
|
| company_name=company_name or "(Company not provided)",
|
| product_name=product_name or "(Product not provided)",
|
| market_definition=market_definition or "(Market definition not provided)",
|
| focus_competitor=focus_competitor or "(Competitor not specified)",
|
| competitor_context=competitor_context or "(No additional competitor notes provided)",
|
| pricing_context=pricing_context or "(No pricing notes provided)",
|
| win_loss_context=win_loss_context or "(No win/loss notes provided)",
|
| new_market=new_market or "(New market not specified)",
|
| planning_horizon=planning_horizon or "3–5 years",
|
| )
|
|
|
|
|
| def call_model_markdown(
|
| poe_api_key: str,
|
| model_name: str,
|
| system_prompt: str,
|
| user_prompt: str,
|
| temperature: float = 0.2,
|
| max_tokens: int = 6000,
|
| ) -> str:
|
| client = poe_client(poe_api_key)
|
|
|
|
|
| resp = client.chat.completions.create(
|
| model=model_name,
|
| messages=[
|
| {"role": "system", "content": system_prompt},
|
| {"role": "user", "content": user_prompt},
|
| ],
|
| temperature=temperature,
|
| max_tokens=max_tokens,
|
| )
|
| return resp.choices[0].message.content
|
|
|
|
|
| def system_instructions() -> str:
|
| return (
|
| "You are AI STRATEGY CONSULTANT — an elite strategy consultant. "
|
| "Produce crisp, CEO-ready deliverables in Markdown with clear headings, tables, and frameworks. "
|
| "Be explicit about assumptions and uncertainties. "
|
| "Do NOT claim you performed web research. If data is missing, infer cautiously and label it. "
|
| "Prefer actionable recommendations with prioritization, rationale, risks, and next steps."
|
| )
|
|
|
|
|
| def generate_single_analysis(
|
| poe_api_key: str,
|
| model_name: str,
|
| analysis_name: str,
|
|
|
| company_name: str,
|
| industry: str,
|
| business_model: str,
|
| product_name: str,
|
| product_desc: str,
|
| target_customers: str,
|
| geography: str,
|
| stage: str,
|
| pricing: str,
|
| top_competitors: str,
|
| differentiators: str,
|
| traction: str,
|
| constraints: str,
|
|
|
| market_definition: str,
|
| focus_competitor: str,
|
| competitor_context: str,
|
| pricing_context: str,
|
| win_loss_context: str,
|
| new_market: str,
|
| planning_horizon: str,
|
| ) -> Tuple[str, Optional[str], Optional[str]]:
|
| """
|
| Returns:
|
| (markdown, md_file_path, pdf_file_path)
|
| """
|
| if not poe_api_key or not poe_api_key.strip():
|
| return ("❌ Please enter your POE API key.", None, None)
|
|
|
| company_ctx = build_company_context(
|
| company_name=company_name,
|
| industry=industry,
|
| business_model=business_model,
|
| product_name=product_name,
|
| product_desc=product_desc,
|
| target_customers=target_customers,
|
| geography=geography,
|
| stage=stage,
|
| pricing=pricing,
|
| top_competitors=top_competitors,
|
| differentiators=differentiators,
|
| traction=traction,
|
| constraints=constraints,
|
| )
|
|
|
| user_prompt = assemble_prompt(
|
| analysis_name=analysis_name,
|
| company_context=company_ctx,
|
| industry=industry,
|
| company_name=company_name,
|
| product_name=product_name,
|
| market_definition=market_definition,
|
| focus_competitor=focus_competitor,
|
| competitor_context=competitor_context,
|
| pricing_context=pricing_context,
|
| win_loss_context=win_loss_context,
|
| new_market=new_market,
|
| planning_horizon=planning_horizon,
|
| )
|
|
|
|
|
| md = call_model_markdown(
|
| poe_api_key=poe_api_key.strip(),
|
| model_name=model_name.strip() or DEFAULT_MODEL,
|
| system_prompt=system_instructions(),
|
| user_prompt=user_prompt,
|
| temperature=0.2,
|
| max_tokens=6500,
|
| )
|
|
|
|
|
| ts = datetime.utcnow().strftime("%Y%m%d_%H%M%S")
|
| base = _safe_filename(f"{analysis_name}_{company_name}_{ts}_{uuid.uuid4().hex[:8]}")
|
| out_dir = os.path.join(os.getcwd(), "outputs")
|
| os.makedirs(out_dir, exist_ok=True)
|
|
|
| md_path = os.path.join(out_dir, f"{base}.md")
|
| pdf_path = os.path.join(out_dir, f"{base}.pdf")
|
|
|
| with open(md_path, "w", encoding="utf-8") as f:
|
| f.write(md)
|
|
|
| md_to_pdf_simple(md, pdf_path, title=f"{analysis_name} — {company_name or 'Company'}")
|
|
|
| return (md, md_path, pdf_path)
|
|
|
|
|
| def generate_all_analyses(
|
| poe_api_key: str,
|
| model_name: str,
|
|
|
| company_name: str,
|
| industry: str,
|
| business_model: str,
|
| product_name: str,
|
| product_desc: str,
|
| target_customers: str,
|
| geography: str,
|
| stage: str,
|
| pricing: str,
|
| top_competitors: str,
|
| differentiators: str,
|
| traction: str,
|
| constraints: str,
|
|
|
| market_definition: str,
|
| focus_competitor: str,
|
| competitor_context: str,
|
| pricing_context: str,
|
| win_loss_context: str,
|
| new_market: str,
|
| planning_horizon: str,
|
| ) -> Tuple[List[str], List[Optional[str]], List[Optional[str]]]:
|
| """
|
| Returns lists aligned to ANALYSES:
|
| (markdown_list, md_paths, pdf_paths)
|
| """
|
| mds: List[str] = []
|
| md_paths: List[Optional[str]] = []
|
| pdf_paths: List[Optional[str]] = []
|
|
|
| for a in ANALYSES:
|
| md, mdp, pdfp = generate_single_analysis(
|
| poe_api_key=poe_api_key,
|
| model_name=model_name,
|
| analysis_name=a,
|
| company_name=company_name,
|
| industry=industry,
|
| business_model=business_model,
|
| product_name=product_name,
|
| product_desc=product_desc,
|
| target_customers=target_customers,
|
| geography=geography,
|
| stage=stage,
|
| pricing=pricing,
|
| top_competitors=top_competitors,
|
| differentiators=differentiators,
|
| traction=traction,
|
| constraints=constraints,
|
| market_definition=market_definition,
|
| focus_competitor=focus_competitor,
|
| competitor_context=competitor_context,
|
| pricing_context=pricing_context,
|
| win_loss_context=win_loss_context,
|
| new_market=new_market,
|
| planning_horizon=planning_horizon,
|
| )
|
| mds.append(md)
|
| md_paths.append(mdp)
|
| pdf_paths.append(pdfp)
|
|
|
| return mds, md_paths, pdf_paths
|
|
|
|
|
|
|
|
|
|
|
| def build_app() -> gr.Blocks:
|
| with gr.Blocks(title="AI Strategy Consultant") as demo:
|
| gr.Markdown(
|
| "# AI STRATEGY CONSULTANT\n"
|
| "Run Bain/McKinsey/BCG-style strategy analyses using **Poe + Claude Opus 4.6**.\n\n"
|
| "**Flow:** (1) Enter POE API key → (2) Fill company context → (3) Choose 1 analysis or run all → (4) Download .md or .pdf.\n"
|
| )
|
|
|
| with gr.Row():
|
| poe_key = gr.Textbox(
|
| label="POE API Key",
|
| placeholder="Paste your POE API key (from https://poe.com/api_key)",
|
| type="password",
|
| )
|
| model_name = gr.Textbox(
|
| label="Model (Poe)",
|
| value=DEFAULT_MODEL,
|
| info='Example: "Claude-Opus-4.6"',
|
| )
|
|
|
| with gr.Row():
|
| btn_points = gr.Button("Show remaining Poe points")
|
| points_out = gr.Markdown()
|
|
|
| btn_points.click(fn=get_remaining_points, inputs=[poe_key], outputs=[points_out])
|
|
|
| gr.Markdown("## Company context (shared across all analyses)")
|
| with gr.Row():
|
| company_name = gr.Textbox(label="Company name", placeholder="e.g., Acme Analytics")
|
| industry = gr.Textbox(label="Industry", placeholder="e.g., B2B SaaS for supply chain visibility")
|
|
|
| with gr.Row():
|
| product_name = gr.Textbox(label="Product name", placeholder="e.g., Acme Control Tower")
|
| stage = gr.Dropdown(
|
| label="Company stage",
|
| choices=["Idea", "Pre-seed", "Seed", "Series A", "Series B+", "Growth", "Mature / Public"],
|
| value="Series A",
|
| )
|
|
|
| business_model = gr.Textbox(
|
| label="Business model",
|
| placeholder="How you make money (subscription, usage-based, services, marketplace take-rate, etc.)",
|
| lines=2,
|
| )
|
| product_desc = gr.Textbox(
|
| label="Product description",
|
| placeholder="What you sell + key jobs-to-be-done + key features (2–8 sentences)",
|
| lines=4,
|
| )
|
| target_customers = gr.Textbox(
|
| label="Target customers",
|
| placeholder="ICP, buyer/user personas, company size, verticals, etc.",
|
| lines=3,
|
| )
|
|
|
| with gr.Row():
|
| geography = gr.Textbox(label="Geography", placeholder="e.g., EU + UK (starting with NL/DE)")
|
| pricing = gr.Textbox(label="Current pricing", placeholder="tiers, price points, value metric", lines=2)
|
|
|
| top_competitors = gr.Textbox(
|
| label="Top competitors (known)",
|
| placeholder="Comma-separated list + short notes if you want",
|
| lines=2,
|
| )
|
| differentiators = gr.Textbox(
|
| label="Differentiators / strengths",
|
| placeholder="Why you win (tech, distribution, data, brand, cost, partnerships, etc.)",
|
| lines=3,
|
| )
|
| traction = gr.Textbox(
|
| label="Traction / metrics",
|
| placeholder="ARR, growth, logos, pipeline, retention, CAC/LTV, usage, etc. (optional but helpful)",
|
| lines=2,
|
| )
|
| constraints = gr.Textbox(
|
| label="Constraints / risks / must-avoid",
|
| placeholder="Budget limits, regulated constraints, brand constraints, timelines, etc.",
|
| lines=2,
|
| )
|
|
|
| gr.Markdown("## Optional inputs (used by specific analyses)")
|
| market_definition = gr.Textbox(
|
| label="Market definition (for sizing/segmentation)",
|
| placeholder="Define product/service + target customer + geography + price point",
|
| lines=2,
|
| )
|
| focus_competitor = gr.Textbox(
|
| label="Focus competitor name (for competitor teardown)",
|
| placeholder="e.g., MegaCorp Insights",
|
| )
|
| competitor_context = gr.Textbox(
|
| label="Competitor notes (for teardown)",
|
| placeholder="What you know about them: pricing, customers, channels, product strengths, etc.",
|
| lines=3,
|
| )
|
| pricing_context = gr.Textbox(
|
| label="Competitor pricing notes (for pricing analysis)",
|
| placeholder="Paste competitor tiers/prices/value metrics if you have them",
|
| lines=3,
|
| )
|
| win_loss_context = gr.Textbox(
|
| label="Win/loss notes (for win/loss analysis)",
|
| placeholder="Common objections, reasons for churn, lost deals, customer feedback, etc.",
|
| lines=3,
|
| )
|
| new_market = gr.Textbox(
|
| label="New market / geography (for market entry)",
|
| placeholder="e.g., US mid-market; or France enterprise; or Japan SMB",
|
| )
|
| planning_horizon = gr.Textbox(
|
| label="Scenario planning horizon",
|
| value="3–5 years",
|
| placeholder="e.g., 18 months; 3–5 years; 10 years",
|
| )
|
|
|
| gr.Markdown("## Run analyses")
|
|
|
| with gr.Row():
|
| analysis_choice = gr.Dropdown(
|
| label="Choose 1 analysis",
|
| choices=ANALYSES,
|
| value=ANALYSES[0],
|
| )
|
| btn_run_one = gr.Button("Run selected analysis")
|
| btn_run_all = gr.Button("Run ALL 12 analyses")
|
|
|
| gr.Markdown("### Selected analysis output")
|
| out_md_one = gr.Markdown()
|
| with gr.Row():
|
| dl_md_one = gr.File(label="Download .md (selected)")
|
| dl_pdf_one = gr.File(label="Download .pdf (selected)")
|
|
|
| def _run_one(
|
| poe_api_key: str,
|
| model_name: str,
|
| analysis_name: str,
|
| company_name: str,
|
| industry: str,
|
| business_model: str,
|
| product_name: str,
|
| product_desc: str,
|
| target_customers: str,
|
| geography: str,
|
| stage: str,
|
| pricing: str,
|
| top_competitors: str,
|
| differentiators: str,
|
| traction: str,
|
| constraints: str,
|
| market_definition: str,
|
| focus_competitor: str,
|
| competitor_context: str,
|
| pricing_context: str,
|
| win_loss_context: str,
|
| new_market: str,
|
| planning_horizon: str,
|
| ):
|
| md, md_path, pdf_path = generate_single_analysis(
|
| poe_api_key=poe_api_key,
|
| model_name=model_name,
|
| analysis_name=analysis_name,
|
| company_name=company_name,
|
| industry=industry,
|
| business_model=business_model,
|
| product_name=product_name,
|
| product_desc=product_desc,
|
| target_customers=target_customers,
|
| geography=geography,
|
| stage=stage,
|
| pricing=pricing,
|
| top_competitors=top_competitors,
|
| differentiators=differentiators,
|
| traction=traction,
|
| constraints=constraints,
|
| market_definition=market_definition,
|
| focus_competitor=focus_competitor,
|
| competitor_context=competitor_context,
|
| pricing_context=pricing_context,
|
| win_loss_context=win_loss_context,
|
| new_market=new_market,
|
| planning_horizon=planning_horizon,
|
| )
|
| return md, md_path, pdf_path
|
|
|
| btn_run_one.click(
|
| fn=_run_one,
|
| inputs=[
|
| poe_key,
|
| model_name,
|
| analysis_choice,
|
| company_name,
|
| industry,
|
| business_model,
|
| product_name,
|
| product_desc,
|
| target_customers,
|
| geography,
|
| stage,
|
| pricing,
|
| top_competitors,
|
| differentiators,
|
| traction,
|
| constraints,
|
| market_definition,
|
| focus_competitor,
|
| competitor_context,
|
| pricing_context,
|
| win_loss_context,
|
| new_market,
|
| planning_horizon,
|
| ],
|
| outputs=[out_md_one, dl_md_one, dl_pdf_one],
|
| )
|
|
|
| gr.Markdown("### ALL analyses output (single combined result)")
|
| run_all_result = gr.Markdown("", elem_id="run_all_result")
|
|
|
| def _run_all(
|
| poe_api_key: str,
|
| model_name: str,
|
| company_name: str,
|
| industry: str,
|
| business_model: str,
|
| product_name: str,
|
| product_desc: str,
|
| target_customers: str,
|
| geography: str,
|
| stage: str,
|
| pricing: str,
|
| top_competitors: str,
|
| differentiators: str,
|
| traction: str,
|
| constraints: str,
|
| market_definition: str,
|
| focus_competitor: str,
|
| competitor_context: str,
|
| pricing_context: str,
|
| win_loss_context: str,
|
| new_market: str,
|
| planning_horizon: str,
|
| progress=gr.Progress(),
|
| ):
|
| try:
|
| progress(0, desc="Running all 12 analyses... (this may take several minutes)")
|
| mds, _md_paths, _pdf_paths = generate_all_analyses(
|
| poe_api_key=poe_api_key,
|
| model_name=model_name,
|
| company_name=company_name,
|
| industry=industry,
|
| business_model=business_model,
|
| product_name=product_name,
|
| product_desc=product_desc,
|
| target_customers=target_customers,
|
| geography=geography,
|
| stage=stage,
|
| pricing=pricing,
|
| top_competitors=top_competitors,
|
| differentiators=differentiators,
|
| traction=traction,
|
| constraints=constraints,
|
| market_definition=market_definition,
|
| focus_competitor=focus_competitor,
|
| competitor_context=competitor_context,
|
| pricing_context=pricing_context,
|
| win_loss_context=win_loss_context,
|
| new_market=new_market,
|
| planning_horizon=planning_horizon,
|
| )
|
| parts = []
|
| for i, title in enumerate(ANALYSES):
|
| parts.append(f"## {title}\n\n{mds[i]}")
|
| return "\n\n---\n\n".join(parts)
|
| except Exception as e:
|
| return f"**Error:** {e}"
|
|
|
| btn_run_all.click(
|
| fn=_run_all,
|
| inputs=[
|
| poe_key,
|
| model_name,
|
| company_name,
|
| industry,
|
| business_model,
|
| product_name,
|
| product_desc,
|
| target_customers,
|
| geography,
|
| stage,
|
| pricing,
|
| top_competitors,
|
| differentiators,
|
| traction,
|
| constraints,
|
| market_definition,
|
| focus_competitor,
|
| competitor_context,
|
| pricing_context,
|
| win_loss_context,
|
| new_market,
|
| planning_horizon,
|
| ],
|
| outputs=[run_all_result],
|
| )
|
|
|
| gr.Markdown(
|
| "---\n"
|
| "### Tips\n"
|
| "- The more detail you give in **Company context**, the more “consulting-grade” the output.\n"
|
| "- If you run **Competitor Teardown**, fill *Focus competitor* + *Competitor notes*.\n"
|
| "- If you run **Pricing**, add competitor tier/pricing notes for best results.\n"
|
| )
|
|
|
| return demo
|
|
|
|
|
| if __name__ == "__main__":
|
| app = build_app()
|
|
|
| port = os.environ.get("GRADIO_SERVER_PORT")
|
| if port is not None:
|
| app.launch(server_name="0.0.0.0", server_port=int(port), share=False)
|
| else:
|
| for p in range(7860, 7871):
|
| try:
|
| app.launch(server_name="0.0.0.0", server_port=p, share=False)
|
| except OSError as e:
|
| err = str(e).lower()
|
| if "10048" in str(e) or "empty port" in err or "address already in use" in err:
|
| continue
|
| raise
|
| else:
|
| raise OSError("No free port in 7860–7870. Set GRADIO_SERVER_PORT or free port 7860.") |