Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
|
@@ -54,11 +54,9 @@ OUTPUTS_DIR.mkdir(exist_ok=True)
|
|
| 54 |
# Set these in your Space: Settings β Variables and Secrets
|
| 55 |
# MISTRAL_API_KEY β your Mistral key (sk-...)
|
| 56 |
# GEMINI_API_KEY β your Google key (AIza...)
|
| 57 |
-
# ANTHROPIC_API_KEY β your Anthropic key (sk-ant-...)
|
| 58 |
# ---------------------------------------------------------------------------
|
| 59 |
-
MISTRAL_API_KEY
|
| 60 |
-
GEMINI_API_KEY
|
| 61 |
-
ANTHROPIC_API_KEY = os.environ.get("ANTHROPIC_API_KEY", "")
|
| 62 |
|
| 63 |
# ---------------------------------------------------------------------------
|
| 64 |
# Custom CSS β Light, readable theme that works on HuggingFace Spaces
|
|
@@ -1653,23 +1651,21 @@ with gr.Blocks(
|
|
| 1653 |
# TAB B β Agentic Council (Phase 6.5)
|
| 1654 |
# ==================================================================
|
| 1655 |
with gr.Tab("π§ Agentic Council"):
|
| 1656 |
-
gr.Markdown("## Phase 6.5:
|
| 1657 |
gr.Markdown(
|
| 1658 |
-
"
|
| 1659 |
"- **Mistral** (Panel A) β pragmatic applied IS perspective\n"
|
| 1660 |
-
"- **Gemini** (Panel B) β broad technology futures perspective\n"
|
| 1661 |
-
"- **Claude** (Synthesis Judge) β consensus arbitration and final recommendation\n\n"
|
| 1662 |
"API keys are loaded automatically from HuggingFace Secrets "
|
| 1663 |
-
"(`MISTRAL_API_KEY`, `GEMINI_API_KEY`
|
| 1664 |
"Configure them in your Space under **Settings β Variables and Secrets**."
|
| 1665 |
)
|
| 1666 |
|
| 1667 |
# Key-status indicator β shows which secrets are present at load time
|
| 1668 |
_key_lines = ["**π Secret Status (loaded at startup):**"]
|
| 1669 |
for _label, _val in [
|
| 1670 |
-
("MISTRAL_API_KEY",
|
| 1671 |
-
("GEMINI_API_KEY",
|
| 1672 |
-
("ANTHROPIC_API_KEY", ANTHROPIC_API_KEY),
|
| 1673 |
]:
|
| 1674 |
_icon = "β
present" if _val else "β missing"
|
| 1675 |
_key_lines.append(f"- `{_label}`: {_icon}")
|
|
@@ -1683,7 +1679,7 @@ with gr.Blocks(
|
|
| 1683 |
gr.Markdown("### π’ Panel A β Mistral")
|
| 1684 |
mistral_output = gr.Textbox(
|
| 1685 |
label="Mistral Assessment",
|
| 1686 |
-
lines=
|
| 1687 |
interactive=False,
|
| 1688 |
show_label=True,
|
| 1689 |
)
|
|
@@ -1691,27 +1687,11 @@ with gr.Blocks(
|
|
| 1691 |
gr.Markdown("### π΅ Panel B β Gemini")
|
| 1692 |
gemini_output = gr.Textbox(
|
| 1693 |
label="Gemini Assessment",
|
| 1694 |
-
lines=
|
| 1695 |
interactive=False,
|
| 1696 |
show_label=True,
|
| 1697 |
)
|
| 1698 |
|
| 1699 |
-
gr.Markdown("### βοΈ Claude Synthesis β Consensus, Divergence & Final Recommendation")
|
| 1700 |
-
synthesis_output = gr.Textbox(
|
| 1701 |
-
label="Synthesised Council Verdict",
|
| 1702 |
-
lines=18,
|
| 1703 |
-
interactive=False,
|
| 1704 |
-
show_label=True,
|
| 1705 |
-
)
|
| 1706 |
-
|
| 1707 |
-
with gr.Row():
|
| 1708 |
-
findings_summary_box = gr.Textbox(
|
| 1709 |
-
label="Findings Sent to Council",
|
| 1710 |
-
lines=8,
|
| 1711 |
-
interactive=False,
|
| 1712 |
-
show_label=True,
|
| 1713 |
-
)
|
| 1714 |
-
|
| 1715 |
dl_council = gr.DownloadButton("β¬ council_report.json", value=None)
|
| 1716 |
|
| 1717 |
# ---- Handler ----
|
|
@@ -1723,14 +1703,14 @@ with gr.Blocks(
|
|
| 1723 |
if not taxonomy_map:
|
| 1724 |
return (
|
| 1725 |
"<div class='error-box'>β Run taxonomy mapping first (Tab 3 or full pipeline).</div>",
|
| 1726 |
-
"", "",
|
| 1727 |
)
|
| 1728 |
-
if not any([MISTRAL_API_KEY, GEMINI_API_KEY
|
| 1729 |
return (
|
| 1730 |
"<div class='error-box'>β No API keys found. "
|
| 1731 |
-
"Add MISTRAL_API_KEY
|
| 1732 |
"in your Space Settings β Variables and Secrets.</div>",
|
| 1733 |
-
"", "",
|
| 1734 |
)
|
| 1735 |
|
| 1736 |
try:
|
|
@@ -1741,38 +1721,28 @@ with gr.Blocks(
|
|
| 1741 |
topic_df=topic_df,
|
| 1742 |
mistral_api_key=MISTRAL_API_KEY,
|
| 1743 |
gemini_api_key=GEMINI_API_KEY,
|
| 1744 |
-
anthropic_api_key=ANTHROPIC_API_KEY,
|
| 1745 |
)
|
| 1746 |
progress(0.9, desc="Saving reportβ¦")
|
| 1747 |
saved = _safe_save_json(result, "council_report.json")
|
| 1748 |
progress(1.0, desc="Council complete!")
|
| 1749 |
|
| 1750 |
-
status = "<div class='success-box'>β
Council complete. See
|
| 1751 |
return (
|
| 1752 |
status,
|
| 1753 |
result.get("mistral", ""),
|
| 1754 |
result.get("gemini", ""),
|
| 1755 |
-
result.get("synthesis", ""),
|
| 1756 |
-
result.get("findings_summary", ""),
|
| 1757 |
gr.update(value=saved),
|
| 1758 |
)
|
| 1759 |
except Exception as e:
|
| 1760 |
return (
|
| 1761 |
f"<div class='error-box'>β Council failed: {e}</div>",
|
| 1762 |
-
"", "",
|
| 1763 |
)
|
| 1764 |
|
| 1765 |
btn_run_council.click(
|
| 1766 |
fn=handle_run_council,
|
| 1767 |
-
inputs=[
|
| 1768 |
-
|
| 1769 |
-
],
|
| 1770 |
-
outputs=[
|
| 1771 |
-
council_status,
|
| 1772 |
-
mistral_output, gemini_output, synthesis_output,
|
| 1773 |
-
findings_summary_box,
|
| 1774 |
-
dl_council,
|
| 1775 |
-
]
|
| 1776 |
)
|
| 1777 |
|
| 1778 |
# Auto-fill if council already ran (e.g. via full pipeline)
|
|
@@ -1780,11 +1750,9 @@ with gr.Blocks(
|
|
| 1780 |
fn=lambda cr: (
|
| 1781 |
cr.get("mistral", "") if cr else "",
|
| 1782 |
cr.get("gemini", "") if cr else "",
|
| 1783 |
-
cr.get("synthesis", "") if cr else "",
|
| 1784 |
-
cr.get("findings_summary", "") if cr else "",
|
| 1785 |
),
|
| 1786 |
inputs=[state_council_result],
|
| 1787 |
-
outputs=[mistral_output, gemini_output
|
| 1788 |
)
|
| 1789 |
|
| 1790 |
# ==================================================================
|
|
@@ -1897,14 +1865,14 @@ via a weighted vote (configurable abstract weight). Large clusters are
|
|
| 1897 |
recursively bisected; tiny clusters with fewer than min_membership documents
|
| 1898 |
are reassigned to their nearest valid cluster or marked as noise.
|
| 1899 |
### Agentic Research Council
|
| 1900 |
-
The council convenes
|
| 1901 |
to assess the gap analysis findings from complementary epistemological
|
| 1902 |
perspectives. Each panel member produces a structured assessment of the
|
| 1903 |
most publishable gaps, methodological recommendations, and regional focus.
|
| 1904 |
-
|
| 1905 |
-
|
| 1906 |
---
|
| 1907 |
-
*Built
|
| 1908 |
"""
|
| 1909 |
)
|
| 1910 |
|
|
|
|
| 54 |
# Set these in your Space: Settings β Variables and Secrets
|
| 55 |
# MISTRAL_API_KEY β your Mistral key (sk-...)
|
| 56 |
# GEMINI_API_KEY β your Google key (AIza...)
|
|
|
|
| 57 |
# ---------------------------------------------------------------------------
|
| 58 |
+
MISTRAL_API_KEY = os.environ.get("MISTRAL_API_KEY", "")
|
| 59 |
+
GEMINI_API_KEY = os.environ.get("GEMINI_API_KEY", "")
|
|
|
|
| 60 |
|
| 61 |
# ---------------------------------------------------------------------------
|
| 62 |
# Custom CSS β Light, readable theme that works on HuggingFace Spaces
|
|
|
|
| 1651 |
# TAB B β Agentic Council (Phase 6.5)
|
| 1652 |
# ==================================================================
|
| 1653 |
with gr.Tab("π§ Agentic Council"):
|
| 1654 |
+
gr.Markdown("## Phase 6.5: Dual-Model Research Council")
|
| 1655 |
gr.Markdown(
|
| 1656 |
+
"Two AI models independently assess the PAJAIS research gap findings:\n"
|
| 1657 |
"- **Mistral** (Panel A) β pragmatic applied IS perspective\n"
|
| 1658 |
+
"- **Gemini** (Panel B) β broad technology futures perspective\n\n"
|
|
|
|
| 1659 |
"API keys are loaded automatically from HuggingFace Secrets "
|
| 1660 |
+
"(`MISTRAL_API_KEY`, `GEMINI_API_KEY`). "
|
| 1661 |
"Configure them in your Space under **Settings β Variables and Secrets**."
|
| 1662 |
)
|
| 1663 |
|
| 1664 |
# Key-status indicator β shows which secrets are present at load time
|
| 1665 |
_key_lines = ["**π Secret Status (loaded at startup):**"]
|
| 1666 |
for _label, _val in [
|
| 1667 |
+
("MISTRAL_API_KEY", MISTRAL_API_KEY),
|
| 1668 |
+
("GEMINI_API_KEY", GEMINI_API_KEY),
|
|
|
|
| 1669 |
]:
|
| 1670 |
_icon = "β
present" if _val else "β missing"
|
| 1671 |
_key_lines.append(f"- `{_label}`: {_icon}")
|
|
|
|
| 1679 |
gr.Markdown("### π’ Panel A β Mistral")
|
| 1680 |
mistral_output = gr.Textbox(
|
| 1681 |
label="Mistral Assessment",
|
| 1682 |
+
lines=18,
|
| 1683 |
interactive=False,
|
| 1684 |
show_label=True,
|
| 1685 |
)
|
|
|
|
| 1687 |
gr.Markdown("### π΅ Panel B β Gemini")
|
| 1688 |
gemini_output = gr.Textbox(
|
| 1689 |
label="Gemini Assessment",
|
| 1690 |
+
lines=18,
|
| 1691 |
interactive=False,
|
| 1692 |
show_label=True,
|
| 1693 |
)
|
| 1694 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1695 |
dl_council = gr.DownloadButton("β¬ council_report.json", value=None)
|
| 1696 |
|
| 1697 |
# ---- Handler ----
|
|
|
|
| 1703 |
if not taxonomy_map:
|
| 1704 |
return (
|
| 1705 |
"<div class='error-box'>β Run taxonomy mapping first (Tab 3 or full pipeline).</div>",
|
| 1706 |
+
"", "", gr.update()
|
| 1707 |
)
|
| 1708 |
+
if not any([MISTRAL_API_KEY, GEMINI_API_KEY]):
|
| 1709 |
return (
|
| 1710 |
"<div class='error-box'>β No API keys found. "
|
| 1711 |
+
"Add MISTRAL_API_KEY and/or GEMINI_API_KEY "
|
| 1712 |
"in your Space Settings β Variables and Secrets.</div>",
|
| 1713 |
+
"", "", gr.update()
|
| 1714 |
)
|
| 1715 |
|
| 1716 |
try:
|
|
|
|
| 1721 |
topic_df=topic_df,
|
| 1722 |
mistral_api_key=MISTRAL_API_KEY,
|
| 1723 |
gemini_api_key=GEMINI_API_KEY,
|
|
|
|
| 1724 |
)
|
| 1725 |
progress(0.9, desc="Saving reportβ¦")
|
| 1726 |
saved = _safe_save_json(result, "council_report.json")
|
| 1727 |
progress(1.0, desc="Council complete!")
|
| 1728 |
|
| 1729 |
+
status = "<div class='success-box'>β
Council complete. See assessments below.</div>"
|
| 1730 |
return (
|
| 1731 |
status,
|
| 1732 |
result.get("mistral", ""),
|
| 1733 |
result.get("gemini", ""),
|
|
|
|
|
|
|
| 1734 |
gr.update(value=saved),
|
| 1735 |
)
|
| 1736 |
except Exception as e:
|
| 1737 |
return (
|
| 1738 |
f"<div class='error-box'>β Council failed: {e}</div>",
|
| 1739 |
+
"", "", gr.update()
|
| 1740 |
)
|
| 1741 |
|
| 1742 |
btn_run_council.click(
|
| 1743 |
fn=handle_run_council,
|
| 1744 |
+
inputs=[state_taxonomy_map, state_topic_df],
|
| 1745 |
+
outputs=[council_status, mistral_output, gemini_output, dl_council]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1746 |
)
|
| 1747 |
|
| 1748 |
# Auto-fill if council already ran (e.g. via full pipeline)
|
|
|
|
| 1750 |
fn=lambda cr: (
|
| 1751 |
cr.get("mistral", "") if cr else "",
|
| 1752 |
cr.get("gemini", "") if cr else "",
|
|
|
|
|
|
|
| 1753 |
),
|
| 1754 |
inputs=[state_council_result],
|
| 1755 |
+
outputs=[mistral_output, gemini_output]
|
| 1756 |
)
|
| 1757 |
|
| 1758 |
# ==================================================================
|
|
|
|
| 1865 |
recursively bisected; tiny clusters with fewer than min_membership documents
|
| 1866 |
are reassigned to their nearest valid cluster or marked as noise.
|
| 1867 |
### Agentic Research Council
|
| 1868 |
+
The council convenes two independent AI models (Mistral and Gemini)
|
| 1869 |
to assess the gap analysis findings from complementary epistemological
|
| 1870 |
perspectives. Each panel member produces a structured assessment of the
|
| 1871 |
most publishable gaps, methodological recommendations, and regional focus.
|
| 1872 |
+
Their independent outputs can be compared side-by-side to identify
|
| 1873 |
+
consensus positions and productive disagreements.
|
| 1874 |
---
|
| 1875 |
+
*Built for PAJAIS Research Intelligence*
|
| 1876 |
"""
|
| 1877 |
)
|
| 1878 |
|