File size: 15,693 Bytes
2bd4c2d
 
 
 
 
 
 
 
 
 
 
4b767d1
 
 
 
 
 
 
ed46db2
f061e68
1cf1e9a
721ec8a
a716ad6
7644e8f
31b5a64
 
688093f
7c7c6e4
 
 
 
 
 
 
 
 
 
 
31b5a64
 
 
 
2bd4c2d
 
 
 
4f76312
2bd4c2d
 
2b711ee
2bd4c2d
 
 
c783a1e
2bd4c2d
a114288
2bd4c2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1ab39b9
2bd4c2d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4b767d1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ed46db2
 
 
 
 
 
 
 
 
 
4b767d1
ed46db2
4b767d1
ed46db2
 
 
 
 
 
 
 
 
 
4b767d1
 
7d0abf0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ed46db2
e44c462
2bd4c2d
 
 
 
 
 
 
1cf1e9a
 
 
2bd4c2d
 
 
 
 
7ab3a9b
 
 
 
 
 
 
 
 
 
aed66e2
 
 
7ab3a9b
 
 
 
 
 
 
 
 
 
 
 
 
 
2bd4c2d
 
970098d
 
 
 
 
 
2bd4c2d
 
 
 
 
1ab39b9
2bd4c2d
 
 
 
 
 
 
e1ed9ed
 
 
 
 
 
647913a
2bd4c2d
a27b676
 
 
 
 
2bd4c2d
 
40bad55
2bd4c2d
a27b676
647913a
a716ad6
e1ed9ed
647913a
a716ad6
a27b676
647913a
e1ed9ed
a27b676
e1ed9ed
a27b676
c644610
e1ed9ed
2bd4c2d
 
f061e68
a716ad6
647913a
2bd4c2d
a716ad6
95c1934
2e1b034
95c1934
 
 
2bd4c2d
e1ed9ed
 
ae33c7e
 
2bd4c2d
 
dcb3baa
2bd4c2d
 
 
 
 
 
4b767d1
9dd4077
 
 
2bd4c2d
 
 
a51af63
 
10fdea1
7d14360
a51af63
10aa05e
 
 
 
 
 
10fdea1
e44c462
10fdea1
e44c462
10fdea1
e44c462
10fdea1
e44c462
 
 
 
 
 
 
 
 
c2855d4
e44c462
 
10fdea1
7d14360
 
 
 
 
 
 
 
 
10fdea1
7d14360
c6d3230
2bd4c2d
 
 
6d2db9f
a51af63
2bd4c2d
 
 
 
 
 
 
 
 
 
 
 
40bad55
2bd4c2d
 
 
 
 
b35fe14
 
 
 
2bd4c2d
 
 
ed46db2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2bd4c2d
 
 
 
 
 
 
 
 
 
 
 
 
 
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
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
import streamlit as st
import os
import groq
from dotenv import load_dotenv
import requests
import queue
import threading
import av
from deepgram import Deepgram
from streamlit_webrtc import webrtc_streamer, WebRtcMode
from pydub import AudioSegment
import matplotlib.pyplot as plt
import seaborn as sns
import plotly.express as px
import networkx as nx
import random
import json
import pandas as pd
import matplotlib.pyplot as plt
from llmformatter import format_llm_response
from classifyresponse import classify_response
from classifylikeconsultant import classify_response1
import re

st.markdown(
    """
    <link rel="manifest" href="manifest.json">
    <script>
      if ('serviceWorker' in navigator) {
        navigator.serviceWorker.register('service-worker.js')
          .then((registration) => {
            console.log('Service Worker registered with scope:', registration.scope);
          })
          .catch((error) => {
            console.log('Service Worker registration failed:', error);
          });
      }
    </script>
    """,
    unsafe_allow_html=True,
)

# Load environment variables
load_dotenv()
GROQ_API_KEY = os.getenv("GROQ_API_KEY")
DEEPGRAM_API_KEY = os.getenv("DEEPGRAM_API_KEY")

groq_client = groq.Client(api_key=GROQ_API_KEY)
deepgram = Deepgram(DEEPGRAM_API_KEY)

SYSTEM_PROMPT = """
You are a highly experienced McKinsey consultant specializing in Strategy & Business Transformation.
Provide structured, data-driven, and actionable recommendations.
Use right kind of frameworks that a big3 consultant use wherever applicable.
Your responses should be concise, strategic, and impactful.

"""

def query_llama(prompt):
    try:
        response = groq_client.chat.completions.create(
            model="llama3-8b-8192",
            messages=[{"role": "system", "content": SYSTEM_PROMPT},
                      {"role": "user", "content": prompt}],
            temperature=0.7
        )
        return response.choices[0].message.content
    except Exception as e:
        return f"Error: {e}"

# Function to transcribe audio using Deepgram
def transcribe_audio(audio_path):
    url = "https://api.deepgram.com/v1/listen"
    headers = {
        "Authorization": f"Token {DEEPGRAM_API_KEY}",
        "Content-Type": "audio/wav"
    }
    
    with open(audio_path, "rb") as audio_file:
        response = requests.post(url, headers=headers, data=audio_file)

    if response.status_code == 200:
        return response.json().get("results", {}).get("channels", [{}])[0].get("alternatives", [{}])[0].get("transcript", "")
    else:
        st.error(f"Deepgram STT Error: {response.json()}")
        return None

# Function to generate speech using Deepgram TTS
def generate_speech(text):
    url = "https://api.deepgram.com/v1/speak"
    headers = {
        "Authorization": f"Token {DEEPGRAM_API_KEY}",
        "Content-Type": "application/json"
    }
    data = {"text": text}  # Ensure only "text" or "url" is sent

    response = requests.post(url, headers=headers, json=data)

    if response.status_code == 200:
        return response.content
    else:
        st.error(f"Deepgram TTS Error: {response.json()}")
        return None

# Function to generate a line chart (Trend Analysis)
def generate_line_chart():
    data = pd.DataFrame({
        "Year": list(range(2018, 2025)),
        "Revenue": [random.randint(50, 100) for _ in range(7)]
    })
    
    fig = px.line(data, x="Year", y="Revenue", title="Market Trend Over Time")
    return fig

# Function to generate a bar chart (Comparison)
def generate_bar_chart():
    data = pd.DataFrame({
        "Category": ["Product A", "Product B", "Product C"],
        "Market Share": [random.randint(10, 50) for _ in range(3)]
    })
    
    fig = px.bar(data, x="Category", y="Market Share", title="Market Share Comparison", text_auto=True)
    return fig

# Function to generate a pie chart (Distribution)
def generate_pie_chart():
    data = pd.DataFrame({
        "Category": ["Segment A", "Segment B", "Segment C"],
        "Percentage": [30, 45, 25]
    })
    
    fig = px.pie(data, names="Category", values="Percentage", title="Market Segment Distribution")
    return fig

def generate_decision_tree():
    G = nx.DiGraph()
    
    # Define decision paths
    G.add_edges_from([
        ("Start", "Expand Market"),
        ("Expand Market", "Enter New Region"),
        ("Expand Market", "Target New Customer Segments"),
        ("Enter New Region", "Partner with Local Firms"),
        ("Enter New Region", "Build In-House Distribution"),
        ("Target New Customer Segments", "Develop New Products"),
        ("Target New Customer Segments", "Adjust Pricing Strategy")
    ])
    
    plt.figure(figsize=(8, 6))
    pos = nx.spring_layout(G)
    nx.draw(G, pos, with_labels=True, node_size=3000, node_color="lightblue", font_size=10, edge_color="gray")
    plt.title("Decision Tree for Market Expansion")
    return plt

def generate_growth_trends_chart():
    data = pd.DataFrame({
        "Year": [2020, 2021, 2022, 2023, 2024],
        "Revenue ($M)": [10, 15, 22, 30, 45]
    })
    fig = px.line(data, x="Year", y="Revenue ($M)", title="Revenue Growth Over Time")
    return fig

# Function to generate Porter's Five Forces diagram
def generate_porters_five_forces():
    st.image("porters_five_forces.png", caption="Porter's Five Forces Framework")

# Function to generate SWOT Matrix
def generate_swot_matrix():
    st.image("swot_matrix_example.png", caption="SWOT Analysis")

# Function to generate MECE structure
def generate_mece_structure():
    fig = px.treemap(
        names=["Market", "Customer Segments", "Pricing Strategies", "Product Lines"],
        parents=["", "Market", "Market", "Market"],
        title="MECE Framework Breakdown"
    )
    return fig



# Initialize session state variables
if "solution_approaches" not in st.session_state:
    st.session_state.solution_approaches = []
if "selected_bucket" not in st.session_state:
    st.session_state.selected_bucket = None
if "evaluations" not in st.session_state:
    st.session_state.evaluations = {}
# Initialize session state variables if they don't exist
if "approach_titles" not in st.session_state:
    st.session_state.approach_titles = []

# Streamlit UI
st.title("AI Strategy Consultant")
problem = st.text_area("Describe your business problem:", "How can we improve market penetration in Europe?")

# **Upload Audio for STT**
uploaded_audio = st.file_uploader("Upload an audio file (wav/mp3/m4a)", type=["wav", "mp3", "m4a"])
if uploaded_audio:
    file_path = f"temp_{uploaded_audio.name}"
    with open(file_path, "wb") as f:
        f.write(uploaded_audio.read())

    st.write("Transcribing...")
    transcribed_text = transcribe_audio(file_path)
    st.write(f"**Transcribed Text:** {transcribed_text}")
    if transcribed_text:
     problem = transcribed_text
     

    # **Send to AI Model**
    if st.button("Ask AI"):
        ai_response = query_llama(transcribed_text)
        st.write("### AI Response:")
        st.write(ai_response)

        # **Convert AI response to Speech**
        st.write("Generating Speech...")
        tts_file = generate_speech(ai_response)
        if isinstance(tts_file, str) and tts_file.endswith(".mp3"):
            st.audio(tts_file)
        else:
            st.error(f"Failed to generate speech: {tts_file}")

# Text-to-Speech Button
#if st.button("πŸ”Š Listen to Problem"):
 #   speech_file = text_to_speech(problem)
  #  if isinstance(speech_file, str) and speech_file.endswith(".mp3"):
   #     st.audio(speech_file)
    #else:
     #   st.error(f"Failed to generate speech: {speech_file}")

# Step-by-step structured process
if st.button("Interpret Problem"):
    interpret_prompt = f"Interpret and refine the following business problem: '{problem}'. Provide a structured breakdown."
    interpretation = query_llama(interpret_prompt)
    
    if interpretation:
        st.write("### Problem Interpretation:")
        st.write(interpretation)
    else:
        st.error("Could not interpret problem. Please refine your input.")


# βœ… Reset solutions when a new problem is entered
if "previous_problem" not in st.session_state or st.session_state.previous_problem != problem:
    st.session_state.previous_problem = problem
    st.session_state.solution_approaches = []
    st.session_state.approach_titles = []

# Step 2: Solution Buckets - Modularized Approach
if st.button("Suggest Solutions"):
    if st.session_state.get("previous_problem") != problem:
        st.session_state.previous_problem = problem
        st.session_state.solution_approaches = []
        st.session_state.approach_titles = []

    bucket_prompt = f"Given the problem: '{problem}', suggest 3-5 high-level solution approaches."
    solution_buckets = query_llama(bucket_prompt)
    
    if solution_buckets:
        approaches = [opt.strip() for opt in solution_buckets.split("\n") if opt.strip()]

        st.session_state.solution_approaches = []
        st.session_state.approach_titles = []

        for line in approaches:
            if re.match(r'^\d+\.|^-|\*', line):  # More flexible regex
                st.session_state.solution_approaches.append(f"### {line}")
                st.session_state.approach_titles.append(line)  # For dropdown
            else:
                st.session_state.solution_approaches.append(f"- {line}")  # Bullet points
        
        st.rerun()  # Force UI refresh

    else:
        st.error("No solutions found. Please try again.")

# βœ… Display structured solutions
if st.session_state.get("solution_approaches"):
    st.write("### Suggested Solution Approaches:")
    for approach in st.session_state.solution_approaches:
        if approach.startswith("### "):  # Approach titles
            st.markdown(f'<p style="font-size:16px; margin-top:10px;">{approach.replace("### ", "")}</p>', unsafe_allow_html=True)
        else:  # Bullet points
            st.markdown(f'<p style="font-size:16px;">{approach}</p>', unsafe_allow_html=True)


# βœ… Ensure dropdown appears consistently
if st.session_state.get("approach_titles"):
    selected_option = st.selectbox("Select a solution approach:", st.session_state.approach_titles, key="approach_selector")
    
    if selected_option:
        st.session_state.selected_bucket = selected_option
        st.write(f"**You selected:** {selected_option}")

# Step 3: Solution Evaluation
if st.session_state.selected_bucket:
    if st.button("Evaluate Solution"):
        eval_prompt = f"Evaluate the solution approach: '{st.session_state.selected_bucket}' using qualitative and quantitative metrics."
        evaluation = query_llama(eval_prompt)

        # Save evaluation in session state
        st.session_state["evaluation"] = evaluation  # Store it persistently
        
        if evaluation:
            st.session_state.evaluations[st.session_state.selected_bucket] = evaluation
            st.write("### Solution Evaluation:")
            
            # Classify response
            framework, vis_type1 = classify_response1(st.session_state["evaluation"])
            vis_type = classify_response(st.session_state["evaluation"])


            # Display selected consulting framework
            st.subheader("Consulting Framework Used:")
            st.write(f"**{framework}**")

            # Generate and display the correct visualization
            if vis_type1 == "market_size_graph":
               st.plotly_chart(generate_growth_trends_chart())
            elif vis_type1 == "decision_tree_visualization":
               st.pyplot(generate_decision_tree())
            elif vis_type1 == "cost_breakdown_bar":
               st.plotly_chart(generate_bar_chart())
            elif vis_type1 == "swot_matrix":
               generate_swot_matrix()  # Displays SWOT Analysis
            elif vis_type1 == "porters_five_forces":
               generate_porters_five_forces()  # Porter's Five Forces Diagram
            elif vis_type1 == "mece_structure":
               st.plotly_chart(generate_mece_structure())  # MECE Breakdown
            elif vis_type1 == "bcg_matrix":
               generate_bcg_matrix()  # BCG Growth-Share Matrix
            elif vis_type1 == "business_model_canvas":
               st.image("business_model_canvas.png", caption="Business Model Canvas")
            else:
               st.write("No visual aid required for this framework.")

                
             # Render appropriate visualization
            if vis_type == "line_chart":
               st.plotly_chart(generate_line_chart())
            elif vis_type == "bar_chart":
               st.plotly_chart(generate_bar_chart())
            elif vis_type == "pie_chart":
               st.plotly_chart(generate_pie_chart())
            elif vis_type == "decision_tree":
               st.pyplot(generate_decision_tree())
            else:
               st.write("No visual aid required for this response.")
            st.write(evaluation)
        else:
            st.error("Could not evaluate the solution.")



# **Inline Feedback for Refinement**
feedback_eval = st.text_area("Provide feedback on the evaluation (optional):")
if st.button("Refine Evaluation"):
    refined_eval_prompt = f"Refine the evaluation of '{st.session_state.selected_bucket}' considering this feedback: '{feedback_eval}'"
    refined_evaluation = query_llama(refined_eval_prompt)
        
    if refined_evaluation:
        st.session_state.evaluations[st.session_state.selected_bucket] = refined_evaluation
        st.write("### Refined Solution Evaluation:")
        st.write(refined_evaluation)
    else:
        st.error("Could not refine evaluation.")

# Step 4: Implementation Plan
if st.session_state.selected_bucket:
    if st.button("Generate Execution Plan"):
        exec_prompt = f"Create a step-by-step execution plan for '{st.session_state.selected_bucket}'."
        execution_plan = query_llama(exec_prompt)

        # Save evaluation in session state
        st.session_state["execution_plan"] = execution_plan  # Store it persistently
        
        
        if execution_plan:
            st.write("### Execution Plan:")
            framework, vis_type = classify_response1(st.session_state["execution_plan"])

            # Display selected consulting framework
            st.subheader("Consulting Framework Used:")
            st.write(f"**{framework}**")

            # Generate and display the correct visualization
            if vis_type == "market_size_graph":
               st.plotly_chart(generate_growth_trends_chart())
            elif vis_type == "decision_tree_visualization":
               st.pyplot(generate_decision_tree())
            elif vis_type == "cost_breakdown_bar":
               st.plotly_chart(generate_bar_chart())  # Assume this function exists
            elif vis_type == "swot_matrix":
               st.image("swot_matrix_example.png")  # Predefined SWOT image
            else:
               st.write("No visual aid required for this response.")
            st.write(execution_plan)
        else:
            st.error("Execution plan could not be generated.")
# **Inline Feedback for Execution Plan**
feedback_exec = st.text_area("Provide feedback on the execution plan (optional):")
if st.button("Refine Execution Plan"):
    refined_exec_prompt = f"Refine the execution plan for '{st.session_state.selected_bucket}' considering this feedback: '{feedback_exec}'"
    refined_execution_plan = query_llama(refined_exec_prompt)
        
    if refined_execution_plan:
        st.write("### Refined Execution Plan:")
        st.write(refined_execution_plan)
    else:
        st.error("Could not refine execution plan.")