Spaces:
Running
Running
| import gradio as gr | |
| from tomlkit import value | |
| 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) | |
| # === Custom theme configuration === | |
| custom_theme = gr.themes.Base( | |
| primary_hue="indigo", | |
| secondary_hue="gray", | |
| neutral_hue="zinc", | |
| ).set( | |
| body_background_fill="#f8f9fa", | |
| body_text_color="#222", | |
| block_background_fill="#ffffff", | |
| block_border_width="1px", | |
| block_border_color="#e5e7eb", | |
| button_primary_background_fill="#4f46e5", | |
| button_primary_text_color="white", | |
| button_primary_background_fill_hover="#4338ca", | |
| block_shadow="0 2px 6px rgba(0,0,0,0.05)", | |
| block_label_text_size="lg", | |
| block_label_text_weight="600", | |
| ) | |
| # === Interface === | |
| with gr.Blocks(theme=custom_theme, css=""" | |
| .gradio-container { | |
| max-width: 900px !important; | |
| margin: auto !important; | |
| font-family: 'Inter', sans-serif; | |
| } | |
| h2, h3, .gr-markdown { | |
| font-weight: 600; | |
| } | |
| .gr-button { | |
| border-radius: 6px !important; | |
| font-weight: 600 !important; | |
| letter-spacing: 0.2px; | |
| } | |
| """) as demo: | |
| gr.Markdown("## Investment Portfolio Analyzer") | |
| gr.Markdown( | |
| "A lightweight interface for analyzing and comparing investment portfolios with AI assistance.", | |
| 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, | |
| ) | |
| analyze_button = gr.Button("Run Analysis", variant="primary") | |
| analyze_output = gr.Textbox(label="Analysis Result", lines=15, value='3852a354-e66e-4bc5-97e9-55124e31e687') | |
| analyze_button.click(fn=analyzer.run, inputs=portfolio_input, outputs=analyze_output) | |
| # --- Comparison Tab --- | |
| with gr.TabItem("Comparison"): | |
| compare_input_1 = gr.Textbox(label="Portfolio A", value='3852a354-e66e-4bc5-97e9-55124e31e687') | |
| compare_input_2 = gr.Textbox(label="Portfolio B", value='b1ef37aa-5b9a-41b4-9394-8823f2de36bb') | |
| compare_button = gr.Button("Compare Portfolios", variant="primary") | |
| compare_output = gr.Textbox(label="Comparison Result", lines=20) | |
| compare_button.click(fn=comparer.run, inputs=[compare_input_1, compare_input_2], outputs=compare_output) | |
| # --- 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 --- | |
| 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") | |
| chart_button.click(fn=build_alpha_chart, inputs=chart_input, outputs=chart_output) | |
| gr.Markdown("---") | |
| gr.Markdown( | |
| "<center><small>Developed with Featherless.ai • Powered by OpenAI-compatible API</small></center>", | |
| elem_classes="footer", | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |