File size: 9,369 Bytes
045308a
 
 
66452f5
f6998b3
045308a
14b20cf
d9a824d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871e4cf
 
 
 
 
 
14b20cf
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
871e4cf
 
 
14b20cf
 
045308a
 
f6998b3
14b20cf
 
f6998b3
 
14b20cf
f6998b3
 
045308a
f6998b3
 
 
 
 
 
 
 
 
 
66452f5
1a24190
66452f5
d9a824d
 
66452f5
f6998b3
 
 
 
66452f5
1a24190
 
 
 
 
 
 
 
 
 
66452f5
d9a824d
f6998b3
d9a824d
 
 
 
14b20cf
f6998b3
d9a824d
66452f5
871e4cf
 
 
1a24190
 
 
f6998b3
66452f5
f6998b3
 
 
 
 
d9a824d
f6998b3
d9a824d
 
045308a
d9a824d
045308a
 
f6998b3
66452f5
d9a824d
14b20cf
66452f5
 
d9a824d
66452f5
 
 
d9a824d
66452f5
f6998b3
66452f5
 
045308a
f6998b3
1a24190
045308a
 
d9a824d
045308a
66452f5
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
import json
import gradio as gr
import os
from groq import Groq
from duckduckgo_search import DDGS

# List of Groq models
groq_models = [
    "qwen-2.5-32b",
    "qwen-2.5-coder-32b",
    "qwen-qwq-32b",
    "deepseek-r1-distill-qwen-32b",
    "deepseek-r1-distill-llama-70b",
    "gemma2-9b-it",
    "distil-whisper-large-v3-en",
    "llama-3-1-8b-instant",
    "llama-3-2-11b-vision-preview",
    "llama-3.2-1b-preview",
    "llama-3.2-3b-preview",
    "llama-3.2-90b-vision-preview",
    "llama-3.3-70b-specdec",
    "llama-3.3-70b-versatile",
    "llama-guard-3-8b",
    "llama3-70b-8192",
    "llama3-8b-8192",
    "mistral-saba-24b",
    "mixtral-8x7b-32768"
]

# Disclaimer note
DISCLAIMER = (
    "\n\n**Disclaimer**: This information is for informational purposes only and does not constitute investment advice. "
    "Please consult with a qualified financial advisor before making any investment decisions."
)

# Function to format JSON into readable Markdown
def format_json_to_markdown(data):
    markdown = "# Company Overview\n\n"

    # Profile Section
    profile = data.get("research", {}).get("profile", {})
    markdown += "## Company Profile\n"
    markdown += f"- **Company Name**: {profile.get('company_name', 'N/A')}\n"
    markdown += f"- **Business Description**: {profile.get('business_description', 'N/A')}\n"
    markdown += f"- **Headquarters**: {profile.get('headquarters', 'N/A')}\n"
    markdown += f"- **Founded Year**: {profile.get('founded_year', 'N/A')}\n"
    markdown += f"- **CEO**: {profile.get('ceo', 'N/A')}\n"
    markdown += f"- **Employees**: {profile.get('employees', 'N/A')}\n"
    markdown += f"- **Target Market**: {profile.get('target_market', 'N/A')}\n"
    markdown += f"- **Products/Services**: \n"
    for service in profile.get('products_services', []):
        markdown += f"  - {service}\n"
    markdown += f"- **Business Model**: {profile.get('business_model', 'N/A')}\n"
    markdown += f"- **Growth Strategy**: {profile.get('growth_strategy', 'N/A')}\n\n"

    # Financials Section
    financials = data.get("research", {}).get("financials", {})
    markdown += "## Financial Highlights\n"
    markdown += f"- **Revenue**: {financials.get('revenue', {}).get('₹ Crores', 'N/A') or financials.get('revenue', {}).get('total_revenue_2024', 'N/A')} ₹ Crores\n"
    markdown += f"- **Revenue Growth**: {financials.get('revenue_growth', 'N/A')}% \n"
    markdown += f"- **Net Income**: {financials.get('net_income', {}).get('₹ Crores', 'N/A') or financials.get('net_income', {}).get('2024', 'N/A')} ₹ Crores\n"
    markdown += f"- **Profit Margin**: {financials.get('profit_margin', 'N/A')}% \n"
    markdown += f"- **Debt to Equity**: {financials.get('debt_to_equity', 'N/A')}\n"

    # Key Ratios Table
    ratios = financials.get("key_ratios", {})
    if ratios:
        markdown += "\n### Key Financial Ratios\n"
        markdown += "| Ratio            | Value       |\n"
        markdown += "|-------------------|-------------|\n"
        for key, value in ratios.items():
            markdown += f"| {key.replace('_', ' ').title()} | {value} |\n"

    # IPO Details Section
    ipo = data.get("research", {}).get("ipo_details", {})
    markdown += "\n## IPO Details\n"
    markdown += f"- **IPO Date**: {ipo.get('ipo_date', 'N/A')}\n"
    markdown += f"- **Price Range**: {ipo.get('price_range', 'N/A')}\n"
    markdown += f"- **Final Price**: {ipo.get('final_price', 'N/A')} ₹\n"
    markdown += f"- **Shares Offered**: {ipo.get('shares_offered', 'N/A')}\n"
    markdown += f"- **Total Raised**: {ipo.get('total_raised', 'N/A')} ₹ Crores\n"
    markdown += f"- **Use of Proceeds**: {ipo.get('use_of_proceeds', 'N/A')}\n"
    markdown += f"- **Lock-Up Period**: {ipo.get('lock_up_period', 'N/A')}\n\n"

    # Recommendation Section
    recommendation = data.get("recommendation", {})
    markdown += "## Investment Recommendation\n"
    markdown += f"- **Recommendation**: {recommendation.get('recommendation', 'N/A')}\n"
    markdown += f"- **Confidence Level**: {recommendation.get('confidence_level', 'N/A')}/10\n"
    markdown += f"- **Price Targets**: Low: {recommendation.get('price_targets', {}).get('low', 'N/A')} | Base: {recommendation.get('price_targets', {}).get('base', 'N/A')} | High: {recommendation.get('price_targets', {}).get('high', 'N/A')} ₹\n"
    markdown += f"- **Investment Horizon**: {recommendation.get('investment_horizon', 'N/A')}\n"
    markdown += f"- **Key Metrics to Watch**: \n"
    for metric in recommendation.get('key_metrics_to_watch', []):
        markdown += f"  - {metric}\n"
    markdown += f"- **Entry Strategy**: {recommendation.get('entry_strategy', 'N/A')}\n"
    markdown += f"- **Exit Conditions**: \n"
    for condition in recommendation.get('exit_conditions', []):
        markdown += f"  - {condition}\n"
    markdown += f"- **Summary Rationale**: {recommendation.get('summary_rationale', 'N/A')}\n"

    # Add the disclaimer
    markdown += DISCLAIMER

    return markdown

# Function to convert JSON to formatted text
def json_to_text(filename):
    try:
        if not filename or filename == "No JSON files found":
            return "Please select a valid JSON file."
        with open(filename, 'r') as json_file:
            data = json.load(json_file)
        return format_json_to_markdown(data)
    except (FileNotFoundError, json.JSONDecodeError) as e:
        return f"Error: Could not load JSON file - {str(e)}"

# Function to search DuckDuckGo using DDGS
def search_duckduckgo(query):
    try:
        with DDGS() as ddgs:
            results = list(ddgs.text(query, max_results=3))
        if results:
            return "\n".join([f"[{result['title']}]({result['href']}): {result['body']}" for result in results])
        return "No results found on DuckDuckGo."
    except Exception as e:
        return f"Error during DuckDuckGo search: {str(e)}"

# Function to chat with JSON content using Groq API with smarter handling
def chat_with_json(api_key, model_name, filename, question):
    if not api_key or not model_name or not filename or not question:
        return "Please provide all required inputs: API key, model, JSON file, and question."

    try:
        client = Groq(api_key=api_key)
        with open(filename, 'r') as json_file:
            data = json.load(json_file)

        # Enhanced prompt to guide the LLM
        prompt = (
            f"Here is the JSON data about a company:\n{json.dumps(data, indent=2)}\n\n"
            f"User question: {question}\n\n"
            "Answer the question based solely on the provided JSON data. "
            "If the exact information is not available in the JSON, provide a thoughtful response using related information from the JSON. "
            "For example, if asked about the CEO and the CEO is not listed, state that the CEO is not specified and provide other relevant details like the company's headquarters, founded year, or business description. "
            "Do NOT suggest searching the web unless the user explicitly asks for a web search or the question is completely unrelated to the JSON content (e.g., asking about weather or unrelated topics). "
            "If a web search is needed, respond with 'I can search the web for this information if you'd like. Please confirm.'"
        )

        completion = client.chat.completions.create(
            model=model_name,
            messages=[{"role": "user", "content": prompt}],
            temperature=1,
            max_completion_tokens=1024,
            top_p=1,
            stream=False
        )
        answer = completion.choices[0].message.content

        # Add disclaimer to the chat response
        answer += DISCLAIMER

        # Check if the LLM suggests a web search
        if "I can search the web" in answer:
            return answer  # Let the user decide if they want a web search
        return answer

    except (FileNotFoundError, json.JSONDecodeError) as e:
        return f"Error: Could not load JSON file - {str(e)}"
    except Exception as e:
        return f"Error with Groq API: {str(e)}"

# Function to get list of JSON files dynamically
def get_json_files():
    json_files = [f for f in os.listdir('.') if f.endswith('.json')]
    return json_files if json_files else ["No JSON files found"]

# Gradio Interface for JSON to Text
iface = gr.Interface(
    fn=json_to_text,
    inputs=gr.Dropdown(choices=get_json_files(), label="Select JSON File"),
    outputs=gr.Markdown(),
    title="JSON to Text",
    description="Convert a JSON file to a formatted, readable overview."
)

# Gradio Interface for Chat with JSON
chat_iface = gr.Interface(
    fn=chat_with_json,
    inputs=[
        gr.Textbox(label="Enter Groq API Key", type="password"),
        gr.Dropdown(choices=groq_models, label="Select Model"),
        gr.Dropdown(choices=get_json_files(), label="Select JSON File"),
        gr.Textbox(label="Ask your question")
    ],
    outputs=gr.Markdown(),
    title="Chat with JSON and DuckDuckGo",
    description="Ask questions about a JSON file. The system will answer based on the JSON data, providing related insights if the exact answer is missing. Web searches are performed only if explicitly requested."
)

# Launch the tabbed interface
if __name__ == "__main__":
    gr.TabbedInterface([iface, chat_iface], ["JSON to Text", "Chat with JSON"]).launch()