Spaces:
Running
Running
File size: 6,949 Bytes
ab0a6c9 b2d5b74 985f897 ed8fc2e 985f897 4badfda b2d5b74 8370475 c279867 eb2bf76 c279867 8cab4b7 c279867 eb2bf76 c279867 eb2bf76 c279867 eb2bf76 c279867 6d49e02 e68a6e8 01a0a48 e68a6e8 eb2bf76 c279867 eb2bf76 c279867 eb2bf76 56da3ec eb2bf76 c279867 eb2bf76 c279867 eb2bf76 5c2eabd eb2bf76 56da3ec 3e9225c e68a6e8 3e9225c e68a6e8 3e9225c 56da3ec e68a6e8 3e9225c eb2bf76 4948018 eb2bf76 c279867 eb2bf76 c279867 eb2bf76 c279867 eb2bf76 6d49e02 8caee6c |
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 |
import gradio as gr
from services.llm_client import llm_service
from core.analyzer import PortfolioAnalyzer
from core.comparer import PortfolioComparer
from core.chat import ChatAssistant
from core.metrics import show_metrics_table
from core.visualization import build_alpha_chart
MODEL_NAME = "meta-llama/Meta-Llama-3.1-8B-Instruct"
analyzer = PortfolioAnalyzer(llm_service, MODEL_NAME)
comparer = PortfolioComparer(llm_service, MODEL_NAME)
chatbot = ChatAssistant(llm_service, MODEL_NAME)
# === Bloomberg-style dark theme ===
dark_theme = gr.themes.Base(
primary_hue="violet",
secondary_hue="gray",
neutral_hue="zinc",
).set(
body_background_fill="#0d1117", # main background (dark navy)
body_text_color="#e6edf3", # main text
block_background_fill="#161b22", # card background
block_border_color="#30363d", # subtle border
button_primary_background_fill="#4f46e5",# indigo-violet accent
button_primary_background_fill_hover="#6366f1",
button_primary_text_color="#ffffff",
input_background_fill="#0d1117",
block_shadow="0 2px 6px rgba(0,0,0,0.3)",
block_label_text_color="#9da5b4",
block_label_text_size="sm",
)
with gr.Blocks(theme=dark_theme, css="""
/* === Bloomberg / Dark Finance Style === */
.gradio-container {
max-width: 1000px !important;
margin: auto !important;
font-family: 'Inter', sans-serif;
background-color: #0d1117 !important;
}
/* === LLM Commentary Styling === */
#llm_comment_box textarea {
max-height: 420px !important; /* ограничение высоты */
overflow-y: auto !important; /* вертикальный скроллинг */
background-color: #161b22 !important;
color: #f0f6fc !important;
border: 1px solid #30363d !important;
border-radius: 6px !important;
font-family: 'JetBrains Mono', monospace !important;
font-size: 14px !important;
line-height: 1.5 !important;
padding: 12px !important;
}
/* === Comparison Table === */
#comparison_table {
margin-top: 8px !important;
}
h2, h3, .gr-markdown {
font-weight: 600;
color: #f0f6fc !important;
}
.gr-button {
border-radius: 6px !important;
font-weight: 600 !important;
letter-spacing: 0.3px;
box-shadow: 0 2px 4px rgba(0,0,0,0.25);
}
.gr-textbox, .gr-dataframe {
border-radius: 6px !important;
}
.gr-button.primary {
background: linear-gradient(90deg, #6366f1, #4f46e5);
border: none !important;
}
.gr-tab {
background-color: #161b22 !important;
color: #c9d1d9 !important;
}
.gr-tabs {
border-bottom: 1px solid #30363d !important;
}
.gr-plot {
background: #0d1117 !important;
}
/* Fix Gradio plot overlay */
#alpha_chart svg {
display: none !important;
}
#alpha_chart .wrap {
background: transparent !important;
box-shadow: none !important;
}
/* === Styled comparison table === */
.gr-dataframe table {
border-collapse: collapse !important;
width: 100% !important;
color: #c9d1d9 !important;
background-color: #161b22 !important;
}
.gr-dataframe th {
background-color: #21262d !important;
color: #f0f6fc !important;
font-weight: 600 !important;
text-transform: uppercase;
border-bottom: 1px solid #30363d !important;
}
.gr-dataframe td {
border-top: 1px solid #30363d !important;
padding: 8px !important;
}
""") as demo:
gr.Markdown("## Investment Portfolio Analyzer")
gr.Markdown(
"A professional dashboard for analyzing and comparing investment portfolios using AI insights.",
elem_classes="subtitle",
)
with gr.Tabs():
# --- Analysis Tab ---
with gr.TabItem("Analysis"):
portfolio_input = gr.Textbox(
label="Portfolio ID or Link",
placeholder="Enter a portfolio ID (e.g. ea856c1b-...)",
lines=1,
value='b1ef37aa-5b9a-41b4-9394-8823f2de36bb',
)
analyze_button = gr.Button("Run Analysis", variant="primary")
analyze_output = gr.Textbox(label="Analysis Result", lines=15)
analyze_button.click(fn=analyzer.run, inputs=portfolio_input, outputs=analyze_output)
# --- Comparison Table Tab ---
with gr.TabItem("Comparison Table"):
comp_input_1 = gr.Textbox(label="Portfolio A", value="3852a354-e66e-4bc5-97e9-55124e31e687")
comp_input_2 = gr.Textbox(label="Portfolio B", value="b1ef37aa-5b9a-41b4-9394-8823f2de36bb")
comp_button = gr.Button("Load Comparison", variant="primary")
# комментарий теперь над таблицей
comp_output_comment = gr.Textbox(
label="AI Commentary",
lines=8,
interactive=False,
show_copy_button=True,
elem_id="llm_comment_box",
)
comp_output_table = gr.Dataframe(
label="Comparative Metrics",
wrap=True,
elem_id="comparison_table",
)
from core.comparison_table import show_comparison_table
comp_button.click(
fn=show_comparison_table,
inputs=[comp_input_1, comp_input_2],
outputs=[comp_output_table, comp_output_comment],
)
# --- Chat Assistant Tab ---
with gr.TabItem("Assistant"):
chat_input = gr.Textbox(label="Ask about investments or analysis")
chat_button = gr.Button("Send Question", variant="primary")
chat_output = gr.Textbox(label="AI Response", lines=8)
chat_button.click(fn=chatbot.run, inputs=chat_input, outputs=chat_output)
# --- Metrics Table Tab ---
with gr.TabItem("Metrics Table"):
metrics_input = gr.Textbox(label="Portfolio ID", value='b1ef37aa-5b9a-41b4-9394-8823f2de36bb')
metrics_button = gr.Button("Load Metrics", variant="primary")
metrics_output = gr.Dataframe(label="Portfolio Metrics", wrap=True)
metrics_button.click(fn=show_metrics_table, inputs=metrics_input, outputs=metrics_output)
# --- AlphaBTC Chart Tab (fixed overlay) ---
with gr.TabItem("AlphaBTC Chart"):
chart_input = gr.Textbox(label="Portfolio ID", value="3852a354-e66e-4bc5-97e9-55124e31e687")
chart_button = gr.Button("Generate Chart", variant="primary")
chart_output = gr.Plot(
label="Alpha vs BTC",
show_label=False,
elem_id="alpha_chart",
)
chart_button.click(fn=build_alpha_chart, inputs=chart_input, outputs=chart_output)
gr.Markdown("---")
gr.Markdown(
"<center><small style='color:#6e7681;'>Developed with Featherless.ai • Powered by OpenAI-compatible API</small></center>",
elem_classes="footer",
)
if __name__ == "__main__":
demo.launch()
|