Update app.py
#1
by petter2025 - opened
app.py
CHANGED
|
@@ -1752,6 +1752,20 @@ def create_enhanced_ui():
|
|
| 1752 |
label="Predictive Forecasts",
|
| 1753 |
value={}
|
| 1754 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1755 |
|
| 1756 |
gr.Markdown("### π Recent Events (Last 15)")
|
| 1757 |
events_table = gr.Dataframe(
|
|
@@ -1784,7 +1798,7 @@ def create_enhanced_ui():
|
|
| 1784 |
)
|
| 1785 |
|
| 1786 |
gr.Markdown("\n\n".join(policy_info))
|
| 1787 |
-
|
| 1788 |
# FIXED: Native async handler (no event loop creation needed)
|
| 1789 |
async def submit_event_enhanced_async(
|
| 1790 |
component, latency, error_rate, throughput, cpu_util, memory_util
|
|
@@ -1801,7 +1815,7 @@ def create_enhanced_ui():
|
|
| 1801 |
allowed, rate_msg = rate_limiter.is_allowed()
|
| 1802 |
if not allowed:
|
| 1803 |
logger.warning(f"Rate limit exceeded")
|
| 1804 |
-
return rate_msg, {}, {}, gr.Dataframe(value=[])
|
| 1805 |
|
| 1806 |
# Type conversion
|
| 1807 |
try:
|
|
@@ -1813,7 +1827,7 @@ def create_enhanced_ui():
|
|
| 1813 |
except (ValueError, TypeError) as e:
|
| 1814 |
error_msg = f"β Invalid input types: {str(e)}"
|
| 1815 |
logger.warning(error_msg)
|
| 1816 |
-
return error_msg, {}, {}, gr.Dataframe(value=[])
|
| 1817 |
|
| 1818 |
# Input validation
|
| 1819 |
is_valid, error_msg = validate_inputs(
|
|
@@ -1821,7 +1835,7 @@ def create_enhanced_ui():
|
|
| 1821 |
)
|
| 1822 |
if not is_valid:
|
| 1823 |
logger.warning(f"Invalid input: {error_msg}")
|
| 1824 |
-
return error_msg, {}, {}, gr.Dataframe(value=[])
|
| 1825 |
|
| 1826 |
# FIXED: Direct async call - no event loop creation needed
|
| 1827 |
result = await enhanced_engine.process_event_enhanced(
|
|
@@ -1830,7 +1844,7 @@ def create_enhanced_ui():
|
|
| 1830 |
|
| 1831 |
# Handle errors
|
| 1832 |
if 'error' in result:
|
| 1833 |
-
return f"β {result['error']}", {}, {}, gr.Dataframe(value=[])
|
| 1834 |
|
| 1835 |
# Build table data (THREAD-SAFE)
|
| 1836 |
table_data = []
|
|
@@ -1865,7 +1879,7 @@ def create_enhanced_ui():
|
|
| 1865 |
if result.get("business_impact"):
|
| 1866 |
impact = result["business_impact"]
|
| 1867 |
output_msg += (
|
| 1868 |
-
f"π° **Business Impact**: ${impact['revenue_loss_estimate']:.2f} | "
|
| 1869 |
f"π₯ {impact['affected_users_estimate']} users | "
|
| 1870 |
f"π¨ {impact['severity_level']}\n"
|
| 1871 |
)
|
|
@@ -1877,10 +1891,26 @@ def create_enhanced_ui():
|
|
| 1877 |
agent_insights_data = result.get("multi_agent_analysis", {})
|
| 1878 |
predictive_insights_data = agent_insights_data.get('predictive_insights', {})
|
| 1879 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1880 |
return (
|
| 1881 |
output_msg,
|
| 1882 |
agent_insights_data,
|
| 1883 |
predictive_insights_data,
|
|
|
|
| 1884 |
gr.Dataframe(
|
| 1885 |
headers=["Timestamp", "Component", "Latency", "Error Rate", "Throughput", "Severity", "Analysis"],
|
| 1886 |
value=table_data,
|
|
@@ -1891,13 +1921,13 @@ def create_enhanced_ui():
|
|
| 1891 |
except Exception as e:
|
| 1892 |
error_msg = f"β Error processing event: {str(e)}"
|
| 1893 |
logger.error(error_msg, exc_info=True)
|
| 1894 |
-
return error_msg, {}, {}, gr.Dataframe(value=[])
|
| 1895 |
|
| 1896 |
# FIXED: Use async handler directly
|
| 1897 |
submit_btn.click(
|
| 1898 |
-
fn=submit_event_enhanced_async,
|
| 1899 |
inputs=[component, latency, error_rate, throughput, cpu_util, memory_util],
|
| 1900 |
-
outputs=[output_text, agent_insights, predictive_insights, events_table]
|
| 1901 |
)
|
| 1902 |
|
| 1903 |
return demo
|
|
|
|
| 1752 |
label="Predictive Forecasts",
|
| 1753 |
value={}
|
| 1754 |
)
|
| 1755 |
+
|
| 1756 |
+
with gr.Accordion("π€ Claude AI Synthesis", open=True):
|
| 1757 |
+
gr.Markdown("""
|
| 1758 |
+
**Claude Opus 4.5 Executive Summary:**
|
| 1759 |
+
- π Incident synthesis from all agents
|
| 1760 |
+
- π― Root cause identification
|
| 1761 |
+
- π‘ Recommended recovery actions
|
| 1762 |
+
- β° Impact and recovery time estimates
|
| 1763 |
+
""")
|
| 1764 |
+
|
| 1765 |
+
claude_output = gr.Markdown(
|
| 1766 |
+
value="*Claude AI synthesis will appear here after incident analysis*",
|
| 1767 |
+
label="AI Executive Summary"
|
| 1768 |
+
)
|
| 1769 |
|
| 1770 |
gr.Markdown("### π Recent Events (Last 15)")
|
| 1771 |
events_table = gr.Dataframe(
|
|
|
|
| 1798 |
)
|
| 1799 |
|
| 1800 |
gr.Markdown("\n\n".join(policy_info))
|
| 1801 |
+
|
| 1802 |
# FIXED: Native async handler (no event loop creation needed)
|
| 1803 |
async def submit_event_enhanced_async(
|
| 1804 |
component, latency, error_rate, throughput, cpu_util, memory_util
|
|
|
|
| 1815 |
allowed, rate_msg = rate_limiter.is_allowed()
|
| 1816 |
if not allowed:
|
| 1817 |
logger.warning(f"Rate limit exceeded")
|
| 1818 |
+
return rate_msg, {}, {}, "*Rate limit exceeded*", gr.Dataframe(value=[])
|
| 1819 |
|
| 1820 |
# Type conversion
|
| 1821 |
try:
|
|
|
|
| 1827 |
except (ValueError, TypeError) as e:
|
| 1828 |
error_msg = f"β Invalid input types: {str(e)}"
|
| 1829 |
logger.warning(error_msg)
|
| 1830 |
+
return error_msg, {}, {}, "*Invalid input type*", gr.Dataframe(value=[])
|
| 1831 |
|
| 1832 |
# Input validation
|
| 1833 |
is_valid, error_msg = validate_inputs(
|
|
|
|
| 1835 |
)
|
| 1836 |
if not is_valid:
|
| 1837 |
logger.warning(f"Invalid input: {error_msg}")
|
| 1838 |
+
return error_msg, {}, {}, "*Validation failed*", gr.Dataframe(value=[])
|
| 1839 |
|
| 1840 |
# FIXED: Direct async call - no event loop creation needed
|
| 1841 |
result = await enhanced_engine.process_event_enhanced(
|
|
|
|
| 1844 |
|
| 1845 |
# Handle errors
|
| 1846 |
if 'error' in result:
|
| 1847 |
+
return f"β {result['error']}", {}, {}, "*Error occurred*", gr.Dataframe(value=[])
|
| 1848 |
|
| 1849 |
# Build table data (THREAD-SAFE)
|
| 1850 |
table_data = []
|
|
|
|
| 1879 |
if result.get("business_impact"):
|
| 1880 |
impact = result["business_impact"]
|
| 1881 |
output_msg += (
|
| 1882 |
+
f"π° **Business Impact**: \${impact['revenue_loss_estimate']:.2f} | "
|
| 1883 |
f"π₯ {impact['affected_users_estimate']} users | "
|
| 1884 |
f"π¨ {impact['severity_level']}\n"
|
| 1885 |
)
|
|
|
|
| 1891 |
agent_insights_data = result.get("multi_agent_analysis", {})
|
| 1892 |
predictive_insights_data = agent_insights_data.get('predictive_insights', {})
|
| 1893 |
|
| 1894 |
+
# Extract Claude synthesis for display
|
| 1895 |
+
claude_synthesis = result.get('claude_synthesis', {})
|
| 1896 |
+
claude_text = claude_synthesis.get('summary', '*No Claude synthesis available*')
|
| 1897 |
+
|
| 1898 |
+
# Format Claude output beautifully
|
| 1899 |
+
claude_display = f"""
|
| 1900 |
+
### π€ Claude Opus 4.5 Executive Analysis
|
| 1901 |
+
|
| 1902 |
+
{claude_text}
|
| 1903 |
+
|
| 1904 |
+
---
|
| 1905 |
+
*Generated: {claude_synthesis.get('timestamp', 'N/A')}*
|
| 1906 |
+
*Model: {claude_synthesis.get('source', 'claude-opus-4')}*
|
| 1907 |
+
"""
|
| 1908 |
+
|
| 1909 |
return (
|
| 1910 |
output_msg,
|
| 1911 |
agent_insights_data,
|
| 1912 |
predictive_insights_data,
|
| 1913 |
+
claude_display,
|
| 1914 |
gr.Dataframe(
|
| 1915 |
headers=["Timestamp", "Component", "Latency", "Error Rate", "Throughput", "Severity", "Analysis"],
|
| 1916 |
value=table_data,
|
|
|
|
| 1921 |
except Exception as e:
|
| 1922 |
error_msg = f"β Error processing event: {str(e)}"
|
| 1923 |
logger.error(error_msg, exc_info=True)
|
| 1924 |
+
return error_msg, {}, {}, "*Processing error*", gr.Dataframe(value=[])
|
| 1925 |
|
| 1926 |
# FIXED: Use async handler directly
|
| 1927 |
submit_btn.click(
|
| 1928 |
+
fn=submit_event_enhanced_async,
|
| 1929 |
inputs=[component, latency, error_rate, throughput, cpu_util, memory_util],
|
| 1930 |
+
outputs=[output_text, agent_insights, predictive_insights, claude_output, events_table]
|
| 1931 |
)
|
| 1932 |
|
| 1933 |
return demo
|