facemelter commited on
Commit
5194d41
·
verified ·
1 Parent(s): 0588003

Finalizing README.md

Browse files
Files changed (1) hide show
  1. app.py +288 -191
app.py CHANGED
@@ -645,6 +645,92 @@ footer a,
645
  transform: translateY(0);
646
  }
647
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
648
  """
649
 
650
  # ============================================================================
@@ -1475,198 +1561,209 @@ with gr.Blocks() as demo:
1475
 
1476
  # Step 3: Main App
1477
  with gr.Step("BirdScope AI", id=3):
1478
- with gr.Row():
1479
- # Left: Chat interface (scale=2)
1480
- with gr.Column(scale=2):
1481
- chatbot = gr.Chatbot(
1482
- show_label=False,
1483
- height=500,
1484
- elem_classes=["chatbot-container"]
1485
- )
1486
-
1487
- msg = gr.MultimodalTextbox(
1488
- placeholder="Ask about birds or upload an image...",
1489
- file_count="single",
1490
- file_types=["image"],
1491
- interactive=True,
1492
- show_label=False
1493
- )
1494
-
1495
  with gr.Row():
1496
- submit = gr.Button("Send", scale=3)
1497
- clear = gr.Button("Clear", scale=1)
1498
-
1499
- # Photo examples - always shown (static)
1500
- gr.Markdown("**Try uploading a bird photo:**")
1501
- gr.Examples(
1502
- examples=PHOTO_EXAMPLES,
1503
- inputs=msg,
1504
- cache_examples=False
1505
- )
1506
-
1507
- # Text examples - change based on agent mode (dynamic)
1508
- gr.Markdown("**Or try a text query:**")
1509
- text_examples = gr.Examples(
1510
- examples=MULTI_AGENT_TEXT_EXAMPLES, # Default to multi-agent text examples
1511
- inputs=msg,
1512
- cache_examples=False
1513
- )
1514
-
1515
- # Middle: Tool execution log (scale=1)
1516
- with gr.Column(scale=1):
1517
- tool_output = gr.Textbox(
1518
- value="*Waiting for tool calls...*",
1519
- elem_classes=["tool-log-panel"],
1520
- elem_id="tool-log-output",
1521
- autoscroll=True,
1522
- show_label=False,
1523
- interactive=False,
1524
- container=False
1525
- )
1526
-
1527
- # Right: Sidebar (scale=1)
1528
- with gr.Column(scale=1, elem_classes=["sidebar"]):
1529
-
1530
- # MCP Server Status Check
1531
- mcp_status_html = gr.HTML("""
1532
- <div class="mcp-badge online" style="margin-bottom: 16px; justify-content: center;">
1533
- <span class="mcp-pulse"></span>
1534
- <span>Powered by Modal MCP</span>
1535
- </div>
1536
- """)
1537
- check_mcp_btn = gr.Button("Check Modal MCP Server Status", size="sm", variant="secondary", elem_classes=["modal-check-btn"])
1538
-
1539
- gr.HTML("""
1540
- <p style="font-size: 0.75rem; color: #9ca3af; margin-top: 8px; margin-bottom: 16px; line-height: 1.4;">
1541
- Please be patient if the Modal MCP server needs to cold start
1542
- </p>
1543
- """)
1544
-
1545
- gr.Markdown("---")
1546
-
1547
- # Provider selection
1548
- gr.Markdown("### SELECT LLM PROVIDER")
1549
- provider = gr.Dropdown(
1550
- choices=["HuggingFace", "OpenAI", "Anthropic"],
1551
- value="OpenAI",
1552
- show_label=False,
1553
- container=False
1554
- )
1555
-
1556
- # Agent Mode Selector
1557
- gr.Markdown("**Agent Configuration**")
1558
- gr.Markdown("Choose between unified agent or specialized routing")
1559
- agent_mode = gr.Dropdown(
1560
- choices=[
1561
- "Supervisor (Multi-Agent)"
1562
- ],
1563
- value="Supervisor (Multi-Agent)",
1564
- show_label=False,
1565
- container=False
1566
- )
1567
-
1568
- gr.Markdown("---")
1569
-
1570
- # API Keys
1571
- gr.Markdown("### AUTHENTICATION")
1572
-
1573
- gr.HTML("""
1574
- <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1575
- <img src="https://cdn.brandfetch.io/idGqKHD5xE/theme/dark/symbol.svg?c=1bxid64Mup7aczewSAYMX&t=1668516030712"
1576
- alt="HuggingFace"
1577
- style="width: 20px; height: 20px;">
1578
- <strong style="color: #d1d5db;">HuggingFace API Key</strong>
1579
- </div>
1580
- """)
1581
- hf_key = gr.Textbox(
1582
- placeholder="hf_...",
1583
- type="password",
1584
- show_label=False,
1585
- container=False,
1586
- elem_classes=["hf-section"]
1587
- )
1588
- gr.Markdown("Get your key from [HF Settings](https://huggingface.co/settings/tokens)")
1589
-
1590
- gr.HTML("""
1591
- <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1592
- <img src="https://cdn.oaistatic.com/_next/static/media/apple-touch-icon.59f2e898.png"
1593
- alt="OpenAI"
1594
- style="width: 20px; height: 20px; border-radius: 4px;">
1595
- <strong style="color: #d1d5db;">OpenAI API Key</strong>
1596
- </div>
1597
- """)
1598
- openai_key = gr.Textbox(
1599
- placeholder="sk-...",
1600
- type="password",
1601
- show_label=False,
1602
- container=False,
1603
- elem_classes=["openai-section"]
1604
- )
1605
- gr.Markdown("Get your key from [OpenAI Platform](https://platform.openai.com/api-keys)")
1606
-
1607
- gr.HTML("""
1608
- <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1609
- <img src="https://cdn.brandfetch.io/idmJWF3N06/theme/dark/symbol.svg?c=1bxid64Mup7aczewSAYMX&t=1721803183716"
1610
- alt="Anthropic"
1611
- style="width: 20px; height: 20px; filter: invert(52%) sepia(48%) saturate(779%) hue-rotate(327deg) brightness(91%) contrast(88%);">
1612
- <strong style="color: #d1d5db;">Anthropic API Key</strong>
1613
- </div>
1614
- """)
1615
- anthropic_key = gr.Textbox(
1616
- placeholder="sk-ant-...",
1617
- type="password",
1618
- show_label=False,
1619
- container=False,
1620
- elem_classes=["anthropic-section"]
1621
- )
1622
- gr.Markdown("Get your key from [Anthropic Console](https://console.anthropic.com/settings/keys)")
1623
-
1624
- # Current Configuration Display
1625
- gr.Markdown("---")
1626
- gr.Markdown("### CURRENT CONFIG")
1627
-
1628
- # Generate initial config HTML
1629
- session_status = gr.HTML(
1630
- value=create_config_html(
1631
- provider_choice="OpenAI",
1632
- agent_mode_choice="Supervisor (Multi-Agent)",
1633
- hf_key_input="",
1634
- openai_key_input="",
1635
- anthropic_key_input=""
1636
- )
1637
- )
1638
-
1639
- # About
1640
- gr.Markdown("---")
1641
- gr.Markdown("""
1642
- ### ABOUT
1643
-
1644
- Built for the [Hugging Face MCP-1st-Birthday Hackathon](https://huggingface.co/MCP-1st-Birthday)
1645
- """)
1646
-
1647
- gr.HTML("""
1648
- <div style="text-align: center; margin: 16px 0;">
1649
- <img src="https://cdn-uploads.huggingface.co/production/uploads/60d2dc1007da9c17c72708f8/s4q7RzD3S-8xQ8ecXrSwb.png"
1650
- alt="Hugging Face MCP 1st Birthday"
1651
- style="max-width: 100%; height: auto; border-radius: 8px;">
1652
- </div>
1653
- """)
1654
-
1655
- gr.Markdown("""
1656
- **MCP Servers:**
1657
- - Modal GPU classifier (2 tools)
1658
- - Nuthatch species database (7 tools)
1659
-
1660
- **Capabilities:**
1661
- - Visual bird identification
1662
- - Species reference images (Unsplash)
1663
- - Audio recordings (xeno-canto)
1664
- - Conservation status data
1665
- - Taxonomic exploration
1666
- - Separate tool log panel
1667
- - Detailed execution tracking
1668
- - Tool input/output inspection
1669
- """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1670
 
1671
  # State for tool log
1672
  tool_log_state = gr.State("*Waiting for tool calls...*")
 
645
  transform: translateY(0);
646
  }
647
  }
648
+
649
+ /* ========================================================================
650
+ README TAB STYLING - BLACK TEXT ON WHITE BACKGROUND
651
+ ======================================================================== */
652
+
653
+ .readme-tab-container {
654
+ background-color: #ffffff !important;
655
+ padding: 2rem !important;
656
+ border-radius: 12px !important;
657
+ max-width: 1200px !important;
658
+ margin: 1rem auto !important;
659
+ box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08) !important;
660
+ }
661
+
662
+ .readme-markdown,
663
+ .readme-markdown *,
664
+ .readme-markdown h1,
665
+ .readme-markdown h2,
666
+ .readme-markdown h3,
667
+ .readme-markdown h4,
668
+ .readme-markdown h5,
669
+ .readme-markdown h6,
670
+ .readme-markdown p,
671
+ .readme-markdown li,
672
+ .readme-markdown span,
673
+ .readme-markdown div,
674
+ .readme-markdown strong,
675
+ .readme-markdown em,
676
+ .readme-markdown code {
677
+ color: #000000 !important;
678
+ background-color: transparent !important;
679
+ }
680
+
681
+ .readme-markdown a {
682
+ color: #2563eb !important;
683
+ text-decoration: underline !important;
684
+ }
685
+
686
+ .readme-markdown a:hover {
687
+ color: #1d4ed8 !important;
688
+ }
689
+
690
+ .readme-markdown code {
691
+ background-color: #f3f4f6 !important;
692
+ padding: 2px 6px !important;
693
+ border-radius: 4px !important;
694
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Consolas', monospace !important;
695
+ }
696
+
697
+ .readme-markdown pre {
698
+ background-color: #f3f4f6 !important;
699
+ padding: 1rem !important;
700
+ border-radius: 8px !important;
701
+ overflow-x: auto !important;
702
+ }
703
+
704
+ .readme-markdown pre code {
705
+ background-color: transparent !important;
706
+ padding: 0 !important;
707
+ }
708
+
709
+ .readme-markdown blockquote {
710
+ border-left: 4px solid #e5e7eb !important;
711
+ padding-left: 1rem !important;
712
+ color: #4b5563 !important;
713
+ }
714
+
715
+ .readme-markdown hr {
716
+ border-top: 1px solid #e5e7eb !important;
717
+ }
718
+
719
+ .readme-markdown table {
720
+ border-collapse: collapse !important;
721
+ width: 100% !important;
722
+ }
723
+
724
+ .readme-markdown table th,
725
+ .readme-markdown table td {
726
+ border: 1px solid #e5e7eb !important;
727
+ padding: 0.5rem !important;
728
+ }
729
+
730
+ .readme-markdown table th {
731
+ background-color: #f9fafb !important;
732
+ font-weight: 600 !important;
733
+ }
734
  """
735
 
736
  # ============================================================================
 
1561
 
1562
  # Step 3: Main App
1563
  with gr.Step("BirdScope AI", id=3):
1564
+ with gr.Tabs():
1565
+ with gr.Tab("💬 Chat"):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1566
  with gr.Row():
1567
+ # Left: Chat interface (scale=2)
1568
+ with gr.Column(scale=2):
1569
+ chatbot = gr.Chatbot(
1570
+ show_label=False,
1571
+ height=500,
1572
+ elem_classes=["chatbot-container"]
1573
+ )
1574
+
1575
+ msg = gr.MultimodalTextbox(
1576
+ placeholder="Ask about birds or upload an image...",
1577
+ file_count="single",
1578
+ file_types=["image"],
1579
+ interactive=True,
1580
+ show_label=False
1581
+ )
1582
+
1583
+ with gr.Row():
1584
+ submit = gr.Button("Send", scale=3)
1585
+ clear = gr.Button("Clear", scale=1)
1586
+
1587
+ # Photo examples - always shown (static)
1588
+ gr.Markdown("**Try uploading a bird photo:**")
1589
+ gr.Examples(
1590
+ examples=PHOTO_EXAMPLES,
1591
+ inputs=msg,
1592
+ cache_examples=False
1593
+ )
1594
+
1595
+ # Text examples - change based on agent mode (dynamic)
1596
+ gr.Markdown("**Or try a text query:**")
1597
+ text_examples = gr.Examples(
1598
+ examples=MULTI_AGENT_TEXT_EXAMPLES, # Default to multi-agent text examples
1599
+ inputs=msg,
1600
+ cache_examples=False
1601
+ )
1602
+
1603
+ # Middle: Tool execution log (scale=1)
1604
+ with gr.Column(scale=1):
1605
+ tool_output = gr.Textbox(
1606
+ value="*Waiting for tool calls...*",
1607
+ elem_classes=["tool-log-panel"],
1608
+ elem_id="tool-log-output",
1609
+ autoscroll=True,
1610
+ show_label=False,
1611
+ interactive=False,
1612
+ container=False
1613
+ )
1614
+
1615
+ # Right: Sidebar (scale=1)
1616
+ with gr.Column(scale=1, elem_classes=["sidebar"]):
1617
+
1618
+ # MCP Server Status Check
1619
+ mcp_status_html = gr.HTML("""
1620
+ <div class="mcp-badge online" style="margin-bottom: 16px; justify-content: center;">
1621
+ <span class="mcp-pulse"></span>
1622
+ <span>Powered by Modal MCP</span>
1623
+ </div>
1624
+ """)
1625
+ check_mcp_btn = gr.Button("Check Modal MCP Server Status", size="sm", variant="secondary", elem_classes=["modal-check-btn"])
1626
+
1627
+ gr.HTML("""
1628
+ <p style="font-size: 0.75rem; color: #9ca3af; margin-top: 8px; margin-bottom: 16px; line-height: 1.4;">
1629
+ Please be patient if the Modal MCP server needs to cold start
1630
+ </p>
1631
+ """)
1632
+
1633
+ gr.Markdown("---")
1634
+
1635
+ # Provider selection
1636
+ gr.Markdown("### SELECT LLM PROVIDER")
1637
+ provider = gr.Dropdown(
1638
+ choices=["HuggingFace", "OpenAI", "Anthropic"],
1639
+ value="OpenAI",
1640
+ show_label=False,
1641
+ container=False
1642
+ )
1643
+
1644
+ # Agent Mode Selector
1645
+ gr.Markdown("**Agent Configuration**")
1646
+ gr.Markdown("Choose between unified agent or specialized routing")
1647
+ agent_mode = gr.Dropdown(
1648
+ choices=[
1649
+ "Supervisor (Multi-Agent)"
1650
+ ],
1651
+ value="Supervisor (Multi-Agent)",
1652
+ show_label=False,
1653
+ container=False
1654
+ )
1655
+
1656
+ gr.Markdown("---")
1657
+
1658
+ # API Keys
1659
+ gr.Markdown("### AUTHENTICATION")
1660
+
1661
+ gr.HTML("""
1662
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1663
+ <img src="https://cdn.brandfetch.io/idGqKHD5xE/theme/dark/symbol.svg?c=1bxid64Mup7aczewSAYMX&t=1668516030712"
1664
+ alt="HuggingFace"
1665
+ style="width: 20px; height: 20px;">
1666
+ <strong style="color: #d1d5db;">HuggingFace API Key</strong>
1667
+ </div>
1668
+ """)
1669
+ hf_key = gr.Textbox(
1670
+ placeholder="hf_...",
1671
+ type="password",
1672
+ show_label=False,
1673
+ container=False,
1674
+ elem_classes=["hf-section"]
1675
+ )
1676
+ gr.Markdown("Get your key from [HF Settings](https://huggingface.co/settings/tokens)")
1677
+
1678
+ gr.HTML("""
1679
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1680
+ <img src="https://cdn.oaistatic.com/_next/static/media/apple-touch-icon.59f2e898.png"
1681
+ alt="OpenAI"
1682
+ style="width: 20px; height: 20px; border-radius: 4px;">
1683
+ <strong style="color: #d1d5db;">OpenAI API Key</strong>
1684
+ </div>
1685
+ """)
1686
+ openai_key = gr.Textbox(
1687
+ placeholder="sk-...",
1688
+ type="password",
1689
+ show_label=False,
1690
+ container=False,
1691
+ elem_classes=["openai-section"]
1692
+ )
1693
+ gr.Markdown("Get your key from [OpenAI Platform](https://platform.openai.com/api-keys)")
1694
+
1695
+ gr.HTML("""
1696
+ <div style="display: flex; align-items: center; gap: 8px; margin-bottom: 8px;">
1697
+ <img src="https://cdn.brandfetch.io/idmJWF3N06/theme/dark/symbol.svg?c=1bxid64Mup7aczewSAYMX&t=1721803183716"
1698
+ alt="Anthropic"
1699
+ style="width: 20px; height: 20px; filter: invert(52%) sepia(48%) saturate(779%) hue-rotate(327deg) brightness(91%) contrast(88%);">
1700
+ <strong style="color: #d1d5db;">Anthropic API Key</strong>
1701
+ </div>
1702
+ """)
1703
+ anthropic_key = gr.Textbox(
1704
+ placeholder="sk-ant-...",
1705
+ type="password",
1706
+ show_label=False,
1707
+ container=False,
1708
+ elem_classes=["anthropic-section"]
1709
+ )
1710
+ gr.Markdown("Get your key from [Anthropic Console](https://console.anthropic.com/settings/keys)")
1711
+
1712
+ # Current Configuration Display
1713
+ gr.Markdown("---")
1714
+ gr.Markdown("### CURRENT CONFIG")
1715
+
1716
+ # Generate initial config HTML
1717
+ session_status = gr.HTML(
1718
+ value=create_config_html(
1719
+ provider_choice="OpenAI",
1720
+ agent_mode_choice="Supervisor (Multi-Agent)",
1721
+ hf_key_input="",
1722
+ openai_key_input="",
1723
+ anthropic_key_input=""
1724
+ )
1725
+ )
1726
+
1727
+ # About
1728
+ gr.Markdown("---")
1729
+ gr.Markdown("""
1730
+ ### ABOUT
1731
+
1732
+ Built for the [Hugging Face MCP-1st-Birthday Hackathon](https://huggingface.co/MCP-1st-Birthday)
1733
+ """)
1734
+
1735
+ gr.HTML("""
1736
+ <div style="text-align: center; margin: 16px 0;">
1737
+ <img src="https://cdn-uploads.huggingface.co/production/uploads/60d2dc1007da9c17c72708f8/s4q7RzD3S-8xQ8ecXrSwb.png"
1738
+ alt="Hugging Face MCP 1st Birthday"
1739
+ style="max-width: 100%; height: auto; border-radius: 8px;">
1740
+ </div>
1741
+ """)
1742
+
1743
+ gr.Markdown("""
1744
+ **MCP Servers:**
1745
+ - Modal GPU classifier (2 tools)
1746
+ - Nuthatch species database (7 tools)
1747
+
1748
+ **Capabilities:**
1749
+ - Visual bird identification
1750
+ - Species reference images (Unsplash)
1751
+ - Audio recordings (xeno-canto)
1752
+ - Conservation status data
1753
+ - Taxonomic exploration
1754
+ - Separate tool log panel
1755
+ - Detailed execution tracking
1756
+ - Tool input/output inspection
1757
+ """)
1758
+
1759
+ with gr.Tab("📖 README"):
1760
+ with gr.Column(elem_classes=["readme-tab-container"]):
1761
+ try:
1762
+ with open("README.md", "r", encoding="utf-8") as f:
1763
+ readme_content = f.read()
1764
+ gr.Markdown(readme_content, elem_classes=["readme-markdown"])
1765
+ except FileNotFoundError:
1766
+ gr.Markdown("README.md not found", elem_classes=["readme-markdown"])
1767
 
1768
  # State for tool log
1769
  tool_log_state = gr.State("*Waiting for tool calls...*")