Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,258 +1,62 @@
|
|
| 1 |
-
from smolagents import CodeAgent
|
| 2 |
-
import
|
| 3 |
-
import
|
| 4 |
-
from tools.final_answer import FinalAnswerTool
|
| 5 |
-
from Gradio_UI import GradioUI
|
| 6 |
|
|
|
|
| 7 |
@tool
|
| 8 |
-
def
|
| 9 |
-
"""Provides investment recommendations based on the amount in shekels, risk profile, and age.
|
| 10 |
-
|
| 11 |
-
Args:
|
| 12 |
-
amount: Amount to invest in shekels
|
| 13 |
-
risk_profile: Risk profile (low, medium, high)
|
| 14 |
-
age: Age of the investor
|
| 15 |
-
|
| 16 |
-
Returns:
|
| 17 |
-
Investment recommendations as formatted text
|
| 18 |
"""
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
if
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
"low": [
|
| 35 |
-
{"name": "KSM Tel Bond 20", "ticker": "TELBOND20", "type": "Bonds", "risk": "Low", "min_investment": 1000, "description": "ETF tracking Tel Aviv corporate bond index"},
|
| 36 |
-
{"name": "Psagot Government Shekel Bonds", "ticker": "PSAGOT-GOV", "type": "Gov Bonds", "risk": "Low", "min_investment": 500, "description": "Israeli government bonds fund"},
|
| 37 |
-
{"name": "Migdal Foreign Currency", "ticker": "MIGDAL-FOREX", "type": "Currency", "risk": "Low-medium", "min_investment": 1000, "description": "Fund investing in foreign currency and money market instruments"},
|
| 38 |
-
{"name": "Harel Deposits Basket", "ticker": "HAREL-PIKADON", "type": "Deposits", "risk": "Very low", "min_investment": 500, "description": "Fixed income bank deposits fund"}
|
| 39 |
-
],
|
| 40 |
-
"medium": [
|
| 41 |
-
{"name": "Tachlit Tel Aviv 35", "ticker": "TA35ETF", "type": "Index", "risk": "Medium", "min_investment": 1000, "description": "ETF tracking the 35 largest companies on the Tel Aviv Stock Exchange"},
|
| 42 |
-
{"name": "Meitav Dash 50/50", "ticker": "MEITAV-50", "type": "Mixed", "risk": "Medium", "min_investment": 2000, "description": "Balanced fund with 50% stocks and 50% bonds"},
|
| 43 |
-
{"name": "Altshuler Shaham Global", "ticker": "ALTSHULER-GLOBAL", "type": "Global", "risk": "Medium", "min_investment": 5000, "description": "Fund with diversified global investments"},
|
| 44 |
-
{"name": "Analyst Corporate AA and Above", "ticker": "ANALYST-AA", "type": "Corp Bonds", "risk": "Medium", "min_investment": 2000, "description": "High-quality corporate bonds fund with AA rating and above"}
|
| 45 |
-
],
|
| 46 |
-
"high": [
|
| 47 |
-
{"name": "Tachlit NASDAQ 100", "ticker": "TACHLIT-NDX", "type": "Technology", "risk": "High", "min_investment": 3000, "description": "ETF tracking the NASDAQ 100 index of largest non-financial companies"},
|
| 48 |
-
{"name": "KSM S&P 500", "ticker": "KSM-SP500", "type": "US", "risk": "High", "min_investment": 3000, "description": "ETF tracking the S&P 500 index"},
|
| 49 |
-
{"name": "Mor Technologies", "ticker": "MOR-TECH", "type": "Sector", "risk": "Very high", "min_investment": 5000, "description": "Fund of Israeli technology companies"},
|
| 50 |
-
{"name": "Harel Foreign Stocks", "ticker": "HAREL-GLOBAL", "type": "International", "risk": "High", "min_investment": 5000, "description": "Fund of international stocks with high growth potential"}
|
| 51 |
-
]
|
| 52 |
-
}
|
| 53 |
-
|
| 54 |
-
# Asset allocation based on age and risk
|
| 55 |
-
def get_allocation(age, risk):
|
| 56 |
-
# Basic rule: 120 - age = % stocks (for medium risk)
|
| 57 |
-
base_stocks = max(0, min(100, 120 - age))
|
| 58 |
-
|
| 59 |
-
if risk == "low":
|
| 60 |
-
stocks = max(0, base_stocks - 20)
|
| 61 |
-
elif risk == "high":
|
| 62 |
-
stocks = min(100, base_stocks + 20)
|
| 63 |
-
else: # medium risk
|
| 64 |
-
stocks = base_stocks
|
| 65 |
-
|
| 66 |
-
bonds = min(100 - stocks, 80)
|
| 67 |
-
cash = 100 - stocks - bonds
|
| 68 |
-
|
| 69 |
-
return {
|
| 70 |
-
"stocks": stocks,
|
| 71 |
-
"bonds": bonds,
|
| 72 |
-
"cash": cash
|
| 73 |
-
}
|
| 74 |
-
|
| 75 |
-
# Get asset allocation
|
| 76 |
-
allocation = get_allocation(age, risk_profile)
|
| 77 |
-
|
| 78 |
-
# Find suitable funds based on available amount and allocation
|
| 79 |
-
suitable_funds = []
|
| 80 |
-
funds_for_profile = israeli_funds[risk_profile]
|
| 81 |
-
|
| 82 |
-
# Distribute amount by asset class
|
| 83 |
-
stock_amount = amount * allocation["stocks"] / 100
|
| 84 |
-
bond_amount = amount * allocation["bonds"] / 100
|
| 85 |
-
cash_amount = amount * allocation["cash"] / 100
|
| 86 |
-
|
| 87 |
-
# Fund recommendations
|
| 88 |
-
stock_funds = [f for f in funds_for_profile if f["type"] in ["Index", "Technology", "US", "International", "Sector"]]
|
| 89 |
-
bond_funds = [f for f in funds_for_profile if f["type"] in ["Bonds", "Gov Bonds", "Corp Bonds"]]
|
| 90 |
-
cash_funds = [f for f in funds_for_profile if f["type"] in ["Deposits", "Currency"]]
|
| 91 |
-
|
| 92 |
-
# Build recommendations
|
| 93 |
-
recommendations = []
|
| 94 |
-
|
| 95 |
-
if stock_amount >= 1000 and stock_funds:
|
| 96 |
-
for fund in stock_funds:
|
| 97 |
-
if fund["min_investment"] <= stock_amount:
|
| 98 |
-
amount_to_invest = min(stock_amount * 0.8, stock_amount)
|
| 99 |
-
recommendations.append({
|
| 100 |
-
"fund": fund,
|
| 101 |
-
"amount": math.floor(amount_to_invest / 100) * 100,
|
| 102 |
-
"asset_class": "Stocks"
|
| 103 |
-
})
|
| 104 |
-
break
|
| 105 |
-
|
| 106 |
-
if bond_amount >= 1000 and bond_funds:
|
| 107 |
-
for fund in bond_funds:
|
| 108 |
-
if fund["min_investment"] <= bond_amount:
|
| 109 |
-
amount_to_invest = min(bond_amount * 0.8, bond_amount)
|
| 110 |
-
recommendations.append({
|
| 111 |
-
"fund": fund,
|
| 112 |
-
"amount": math.floor(amount_to_invest / 100) * 100,
|
| 113 |
-
"asset_class": "Bonds"
|
| 114 |
-
})
|
| 115 |
-
break
|
| 116 |
-
|
| 117 |
-
if cash_amount >= 500 and cash_funds:
|
| 118 |
-
for fund in cash_funds:
|
| 119 |
-
if fund["min_investment"] <= cash_amount:
|
| 120 |
-
amount_to_invest = min(cash_amount * 0.9, cash_amount)
|
| 121 |
-
recommendations.append({
|
| 122 |
-
"fund": fund,
|
| 123 |
-
"amount": math.floor(amount_to_invest / 100) * 100,
|
| 124 |
-
"asset_class": "Cash"
|
| 125 |
-
})
|
| 126 |
-
break
|
| 127 |
-
|
| 128 |
-
# Format response
|
| 129 |
-
response = f"## Investment Recommendations\n\n"
|
| 130 |
-
response += f"**Amount:** {amount:,} ₪\n"
|
| 131 |
-
response += f"**Age:** {age} years\n"
|
| 132 |
-
response += f"**Risk Profile:** {risk_profile.capitalize()}\n\n"
|
| 133 |
-
|
| 134 |
-
response += "### Recommended Asset Allocation\n"
|
| 135 |
-
response += f"- Stocks: {allocation['stocks']}% ({int(stock_amount):,} ₪)\n"
|
| 136 |
-
response += f"- Bonds: {allocation['bonds']}% ({int(bond_amount):,} ₪)\n"
|
| 137 |
-
response += f"- Cash: {allocation['cash']}% ({int(cash_amount):,} ₪)\n\n"
|
| 138 |
-
|
| 139 |
-
if recommendations:
|
| 140 |
-
response += "### Recommended Investments\n\n"
|
| 141 |
-
total_invested = 0
|
| 142 |
-
|
| 143 |
-
for rec in recommendations:
|
| 144 |
-
fund = rec["fund"]
|
| 145 |
-
amount_to_invest = rec["amount"]
|
| 146 |
-
total_invested += amount_to_invest
|
| 147 |
-
|
| 148 |
-
response += f"**{fund['name']}** ({fund['ticker']})\n"
|
| 149 |
-
response += f"- Type: {fund['type']} ({rec['asset_class']})\n"
|
| 150 |
-
response += f"- Risk: {fund['risk']}\n"
|
| 151 |
-
response += f"- Recommended amount: {amount_to_invest:,} ₪\n"
|
| 152 |
-
response += f"- Description: {fund['description']}\n\n"
|
| 153 |
-
|
| 154 |
-
remaining = amount - total_invested
|
| 155 |
-
if remaining > 0:
|
| 156 |
-
response += f"**Remaining funds:** {remaining:,} ₪ recommended to keep in a savings account for unexpected expenses.\n\n"
|
| 157 |
else:
|
| 158 |
-
|
| 159 |
-
|
| 160 |
-
response += "### Important Information\n"
|
| 161 |
-
response += "- These are general recommendations based on the information provided.\n"
|
| 162 |
-
response += "- Before investing, it is recommended to consult with a licensed financial advisor.\n"
|
| 163 |
-
response += "- Past performance does not guarantee future returns.\n"
|
| 164 |
-
response += "- Investments involve risks, including possible loss of principal.\n"
|
| 165 |
-
|
| 166 |
-
return response
|
| 167 |
-
|
| 168 |
-
# Setup agent
|
| 169 |
-
final_answer = FinalAnswerTool()
|
| 170 |
-
|
| 171 |
-
model = HfApiModel(
|
| 172 |
-
max_tokens=2096,
|
| 173 |
-
temperature=0.5,
|
| 174 |
-
model_id='Qwen/Qwen2.5-Coder-32B-Instruct'
|
| 175 |
-
)
|
| 176 |
-
|
| 177 |
-
# Configure templates for the investment advisor
|
| 178 |
-
investment_prompt_templates = {
|
| 179 |
-
"react-system": """You are an investment advisor who helps users make informed investment decisions in the Israeli market.
|
| 180 |
-
You have access to the following tools:
|
| 181 |
|
| 182 |
-
|
| 183 |
-
|
| 184 |
-
|
| 185 |
-
|
| 186 |
-
|
| 187 |
-
|
| 188 |
-
|
| 189 |
-
Use the investment_advisor tool to analyze these factors and formulate investment recommendations.
|
| 190 |
-
|
| 191 |
-
To use a tool, output an action in this format:
|
| 192 |
-
```py
|
| 193 |
-
action = tool_name(arg1=value1, arg2=value2, ...)
|
| 194 |
-
```
|
| 195 |
|
| 196 |
-
|
| 197 |
-
""",
|
| 198 |
-
"react-human": "{input_string}",
|
| 199 |
-
"react-assistant": "{agent_response}",
|
| 200 |
-
}
|
| 201 |
|
| 202 |
-
# Load prompt templates from file or use our templates
|
| 203 |
-
try:
|
| 204 |
-
with open("prompts.yaml", 'r') as stream:
|
| 205 |
-
prompt_templates = yaml.safe_load(stream)
|
| 206 |
-
prompt_templates.update(investment_prompt_templates)
|
| 207 |
-
except:
|
| 208 |
-
prompt_templates = investment_prompt_templates
|
| 209 |
|
| 210 |
-
#
|
| 211 |
agent = CodeAgent(
|
| 212 |
-
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
verbosity_level=1,
|
| 216 |
-
prompt_templates=prompt_templates
|
| 217 |
)
|
| 218 |
|
| 219 |
-
#
|
| 220 |
-
|
| 221 |
-
|
| 222 |
-
|
| 223 |
-
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
| 228 |
-
|
| 229 |
-
|
| 230 |
-
|
| 231 |
-
|
| 232 |
-
|
| 233 |
-
|
| 234 |
-
|
| 235 |
-
with gr.Row():
|
| 236 |
-
with gr.Column():
|
| 237 |
-
recommendation_output = gr.Markdown(label="Investment Recommendations")
|
| 238 |
-
|
| 239 |
-
def get_recommendations(amount, risk, age):
|
| 240 |
-
if not amount or amount < 100:
|
| 241 |
-
return "Please enter an amount of at least 100 shekels."
|
| 242 |
-
if not risk:
|
| 243 |
-
return "Please select a risk profile."
|
| 244 |
-
if not age or age < 18:
|
| 245 |
-
return "Please provide a valid age (18 years or older)."
|
| 246 |
-
|
| 247 |
-
try:
|
| 248 |
-
recommendations = investment_advisor(int(amount), risk.lower(), int(age))
|
| 249 |
-
return recommendations
|
| 250 |
-
except Exception as e:
|
| 251 |
-
return f"Error generating recommendations: {str(e)}"
|
| 252 |
-
|
| 253 |
-
submit_btn.click(get_recommendations, inputs=[amount_input, risk_input, age_input], outputs=recommendation_output)
|
| 254 |
-
|
| 255 |
-
demo.launch(**kwargs)
|
| 256 |
|
| 257 |
-
|
| 258 |
-
|
|
|
|
| 1 |
+
from smolagents.agent import CodeAgent
|
| 2 |
+
from smolagents.tools.core import tool
|
| 3 |
+
import gradio as gr
|
|
|
|
|
|
|
| 4 |
|
| 5 |
+
# 🔧 Объявляем функцию как инструмент
|
| 6 |
@tool
|
| 7 |
+
def udp_learning_advisor(experience_level: int, learning_style: str, age: int) -> str:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
"""
|
| 9 |
+
Personalized learning recommendations for Unified Development Platform based on experience, learning style, and age.
|
| 10 |
+
"""
|
| 11 |
+
# 🧠 Определение подхода к обучению по стилю
|
| 12 |
+
if learning_style.lower() == 'intensive':
|
| 13 |
+
plan = "Focus on hands-on projects and advanced features of the platform."
|
| 14 |
+
elif learning_style.lower() == 'balanced':
|
| 15 |
+
plan = "Combine structured tutorials with practical exercises."
|
| 16 |
+
else: # slow or cautious
|
| 17 |
+
plan = "Start with guided walkthroughs and foundational concepts."
|
| 18 |
+
|
| 19 |
+
# 🧠 Советы по уровню опыта
|
| 20 |
+
if experience_level < 30:
|
| 21 |
+
experience_note = "Begin with basic modules like UI components and workflow automation."
|
| 22 |
+
elif experience_level < 70:
|
| 23 |
+
experience_note = "Explore integration, APIs, and process orchestration."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 24 |
else:
|
| 25 |
+
experience_note = "Dive into customization, DevOps integration, and performance tuning."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
+
# 🧠 Подстройка по возрасту
|
| 28 |
+
if age < 25:
|
| 29 |
+
age_note = "Incorporate gamified challenges to keep engagement high."
|
| 30 |
+
elif age < 50:
|
| 31 |
+
age_note = "Use real-world business cases to reinforce concepts."
|
| 32 |
+
else:
|
| 33 |
+
age_note = "Include step-by-step explanations and documentation-heavy resources."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
|
| 35 |
+
return f"{plan} {experience_note} {age_note}"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 36 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
+
# 🧠 Агент
|
| 39 |
agent = CodeAgent(
|
| 40 |
+
name="UDP Learning Advisor",
|
| 41 |
+
description="Advises users on learning strategies for the Unified Development Platform based on experience level, learning style, and age.",
|
| 42 |
+
tools=[udp_learning_advisor]
|
|
|
|
|
|
|
| 43 |
)
|
| 44 |
|
| 45 |
+
# 🎛️ Интерфейс
|
| 46 |
+
def advisor_ui(experience_level, learning_style, age):
|
| 47 |
+
return udp_learning_advisor(experience_level, learning_style, age)
|
| 48 |
+
|
| 49 |
+
demo = gr.Interface(
|
| 50 |
+
fn=advisor_ui,
|
| 51 |
+
inputs=[
|
| 52 |
+
gr.Slider(0, 100, label="Experience Level"),
|
| 53 |
+
gr.Dropdown(["intensive", "balanced", "slow"], label="Learning Style"),
|
| 54 |
+
gr.Number(label="Your Age")
|
| 55 |
+
],
|
| 56 |
+
outputs="text",
|
| 57 |
+
title="UDP Learning Advisor",
|
| 58 |
+
description="Get a personalized learning strategy for mastering the Unified Development Platform."
|
| 59 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 60 |
|
| 61 |
+
if __name__ == "__main__":
|
| 62 |
+
demo.launch()
|