replacing static markdown with pretty info cards
Browse files
app.py
CHANGED
@@ -1082,6 +1082,158 @@ CSS_STYLES = """
|
|
1082 |
.gradio-container [role=\"tabpanel\"] h1::after {
|
1083 |
content: none !important;
|
1084 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1085 |
"""
|
1086 |
|
1087 |
# --- Kokoro TTS tab (text to speech) ---
|
@@ -1569,22 +1721,95 @@ with gr.Blocks(title="Nymbo/Tools MCP", theme="Nymbo/Nymbo_Theme", css=CSS_STYLE
|
|
1569 |
|
1570 |
# Collapsed Information accordion (appears below subtitle and above tabs)
|
1571 |
with gr.Accordion("Information", open=False):
|
1572 |
-
gr.
|
1573 |
"""
|
1574 |
-
|
1575 |
-
|
1576 |
-
|
1577 |
-
|
1578 |
-
|
1579 |
-
|
1580 |
-
|
1581 |
-
|
1582 |
-
|
1583 |
-
|
1584 |
-
|
1585 |
-
|
1586 |
-
|
1587 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1588 |
"""
|
1589 |
)
|
1590 |
|
|
|
1082 |
.gradio-container [role=\"tabpanel\"] h1::after {
|
1083 |
content: none !important;
|
1084 |
}
|
1085 |
+
|
1086 |
+
/* Information accordion - modern info cards */
|
1087 |
+
.info-accordion {
|
1088 |
+
margin: 8px 0 2px;
|
1089 |
+
}
|
1090 |
+
.info-grid {
|
1091 |
+
display: grid;
|
1092 |
+
gap: 12px;
|
1093 |
+
/* Force a 2x2 layout on medium+ screens */
|
1094 |
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
1095 |
+
align-items: stretch;
|
1096 |
+
}
|
1097 |
+
/* On narrow screens, stack into a single column */
|
1098 |
+
@media (max-width: 800px) {
|
1099 |
+
.info-grid {
|
1100 |
+
grid-template-columns: 1fr;
|
1101 |
+
}
|
1102 |
+
}
|
1103 |
+
.info-card {
|
1104 |
+
display: flex;
|
1105 |
+
gap: 14px;
|
1106 |
+
padding: 14px 16px;
|
1107 |
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
1108 |
+
background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.03));
|
1109 |
+
border-radius: 12px;
|
1110 |
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
1111 |
+
position: relative;
|
1112 |
+
overflow: hidden;
|
1113 |
+
backdrop-filter: blur(2px);
|
1114 |
+
}
|
1115 |
+
.info-card::before {
|
1116 |
+
content: "";
|
1117 |
+
position: absolute;
|
1118 |
+
inset: 0;
|
1119 |
+
border-radius: 12px;
|
1120 |
+
pointer-events: none;
|
1121 |
+
background: linear-gradient(90deg, rgba(99,102,241,0.06), rgba(59,130,246,0.05));
|
1122 |
+
}
|
1123 |
+
.info-card__icon {
|
1124 |
+
font-size: 24px;
|
1125 |
+
flex: 0 0 28px;
|
1126 |
+
line-height: 1;
|
1127 |
+
filter: saturate(1.1);
|
1128 |
+
}
|
1129 |
+
.info-card__body {
|
1130 |
+
min-width: 0;
|
1131 |
+
}
|
1132 |
+
.info-card__body h3 {
|
1133 |
+
margin: 0 0 6px;
|
1134 |
+
font-size: 1.05rem;
|
1135 |
+
}
|
1136 |
+
.info-card__body p {
|
1137 |
+
margin: 6px 0;
|
1138 |
+
opacity: 0.95;
|
1139 |
+
}
|
1140 |
+
/* Readable code blocks inside info cards */
|
1141 |
+
.info-card pre {
|
1142 |
+
margin: 8px 0;
|
1143 |
+
padding: 10px 12px;
|
1144 |
+
background: rgba(20, 20, 30, 0.55);
|
1145 |
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
1146 |
+
border-radius: 10px;
|
1147 |
+
overflow-x: auto;
|
1148 |
+
white-space: pre;
|
1149 |
+
}
|
1150 |
+
.info-card code {
|
1151 |
+
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
|
1152 |
+
font-size: 0.95em;
|
1153 |
+
}
|
1154 |
+
.info-card pre code {
|
1155 |
+
display: block;
|
1156 |
+
}
|
1157 |
+
.info-list {
|
1158 |
+
margin: 6px 0 0 18px;
|
1159 |
+
padding: 0;
|
1160 |
+
}
|
1161 |
+
.info-hint {
|
1162 |
+
margin-top: 8px;
|
1163 |
+
font-size: 0.9em;
|
1164 |
+
opacity: 0.9;
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
/* Light theme adjustments */
|
1168 |
+
@media (prefers-color-scheme: light) {
|
1169 |
+
.info-card {
|
1170 |
+
border-color: rgba(0, 0, 0, 0.08);
|
1171 |
+
background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(255,255,255,0.9));
|
1172 |
+
}
|
1173 |
+
.info-card::before {
|
1174 |
+
background: linear-gradient(90deg, rgba(99,102,241,0.08), rgba(59,130,246,0.06));
|
1175 |
+
}
|
1176 |
+
.info-card pre {
|
1177 |
+
background: rgba(245, 246, 250, 0.95);
|
1178 |
+
border-color: rgba(0, 0, 0, 0.08);
|
1179 |
+
}
|
1180 |
+
}
|
1181 |
+
|
1182 |
+
/* Tabs - modern, evenly distributed full-width buttons */
|
1183 |
+
.gradio-container [role="tablist"] {
|
1184 |
+
display: flex;
|
1185 |
+
gap: 8px;
|
1186 |
+
flex-wrap: nowrap;
|
1187 |
+
align-items: stretch;
|
1188 |
+
width: 100%;
|
1189 |
+
}
|
1190 |
+
.gradio-container [role="tab"] {
|
1191 |
+
flex: 1 1 0;
|
1192 |
+
min-width: 0; /* allow shrinking to fit */
|
1193 |
+
display: inline-flex;
|
1194 |
+
justify-content: center;
|
1195 |
+
align-items: center;
|
1196 |
+
padding: 10px 12px;
|
1197 |
+
border-radius: 10px;
|
1198 |
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
1199 |
+
background: linear-gradient(180deg, rgba(255,255,255,0.05), rgba(255,255,255,0.03));
|
1200 |
+
transition: background .2s ease, border-color .2s ease, box-shadow .2s ease, transform .06s ease;
|
1201 |
+
overflow: hidden;
|
1202 |
+
white-space: nowrap;
|
1203 |
+
text-overflow: ellipsis;
|
1204 |
+
}
|
1205 |
+
.gradio-container [role="tab"]:hover {
|
1206 |
+
border-color: rgba(99,102,241,0.28);
|
1207 |
+
background: linear-gradient(180deg, rgba(99,102,241,0.10), rgba(59,130,246,0.08));
|
1208 |
+
}
|
1209 |
+
.gradio-container [role="tab"][aria-selected="true"] {
|
1210 |
+
border-color: rgba(99,102,241,0.35);
|
1211 |
+
box-shadow: inset 0 0 0 1px rgba(99,102,241,0.25), 0 1px 2px rgba(0,0,0,0.25);
|
1212 |
+
background: linear-gradient(180deg, rgba(99,102,241,0.18), rgba(59,130,246,0.14));
|
1213 |
+
color: rgba(255, 255, 255, 0.95) !important;
|
1214 |
+
}
|
1215 |
+
.gradio-container [role="tab"]:active {
|
1216 |
+
transform: translateY(0.5px);
|
1217 |
+
}
|
1218 |
+
.gradio-container [role="tab"]:focus-visible {
|
1219 |
+
outline: none;
|
1220 |
+
box-shadow: 0 0 0 2px rgba(59,130,246,0.35);
|
1221 |
+
}
|
1222 |
+
@media (prefers-color-scheme: light) {
|
1223 |
+
.gradio-container [role="tab"] {
|
1224 |
+
border-color: rgba(0, 0, 0, 0.08);
|
1225 |
+
background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(255,255,255,0.90));
|
1226 |
+
}
|
1227 |
+
.gradio-container [role="tab"]:hover {
|
1228 |
+
border-color: rgba(99,102,241,0.25);
|
1229 |
+
background: linear-gradient(180deg, rgba(99,102,241,0.08), rgba(59,130,246,0.06));
|
1230 |
+
}
|
1231 |
+
.gradio-container [role="tab"][aria-selected="true"] {
|
1232 |
+
border-color: rgba(99,102,241,0.35);
|
1233 |
+
background: linear-gradient(180deg, rgba(99,102,241,0.16), rgba(59,130,246,0.12));
|
1234 |
+
color: rgba(0, 0, 0, 0.85) !important;
|
1235 |
+
}
|
1236 |
+
}
|
1237 |
"""
|
1238 |
|
1239 |
# --- Kokoro TTS tab (text to speech) ---
|
|
|
1721 |
|
1722 |
# Collapsed Information accordion (appears below subtitle and above tabs)
|
1723 |
with gr.Accordion("Information", open=False):
|
1724 |
+
gr.HTML(
|
1725 |
"""
|
1726 |
+
<div class="info-accordion">
|
1727 |
+
<div class="info-grid">
|
1728 |
+
<section class="info-card">
|
1729 |
+
<div class="info-card__icon">🔐</div>
|
1730 |
+
<div class="info-card__body">
|
1731 |
+
<h3>Enable Image & Video Generation</h3>
|
1732 |
+
<p>
|
1733 |
+
The <code>Generate_Image</code> and <code>Generate_Video</code> tools require a
|
1734 |
+
<code>HF_READ_TOKEN</code> set as a secret or environment variable.
|
1735 |
+
</p>
|
1736 |
+
<ul class="info-list">
|
1737 |
+
<li>Duplicate this Space and add a HF token with model read access.</li>
|
1738 |
+
<li>Or run locally with <code>HF_READ_TOKEN</code> in your environment.</li>
|
1739 |
+
</ul>
|
1740 |
+
<div class="info-hint">
|
1741 |
+
These tools are hidden as MCP tools without authentication to keep tool lists tidy, but remain visible in the UI.
|
1742 |
+
</div>
|
1743 |
+
</div>
|
1744 |
+
</section>
|
1745 |
+
|
1746 |
+
<section class="info-card">
|
1747 |
+
<div class="info-card__icon">🧠</div>
|
1748 |
+
<div class="info-card__body">
|
1749 |
+
<h3>Persistent Memories</h3>
|
1750 |
+
<p>
|
1751 |
+
In this public demo, memories are stored in the Space's running container and are cleared when the Space restarts.
|
1752 |
+
Content is visible to everyone—avoid personal data.
|
1753 |
+
</p>
|
1754 |
+
<p>
|
1755 |
+
When running locally, memories are saved to <code>memories.json</code> at the repo root for privacy.
|
1756 |
+
</p>
|
1757 |
+
</div>
|
1758 |
+
</section>
|
1759 |
+
|
1760 |
+
<section class="info-card">
|
1761 |
+
<div class="info-card__icon">🔗</div>
|
1762 |
+
<div class="info-card__body">
|
1763 |
+
<h3>Connecting from an MCP Client</h3>
|
1764 |
+
<p>
|
1765 |
+
This Space also runs as a Model Context Protocol (MCP) server. Point your client to:
|
1766 |
+
<br/>
|
1767 |
+
<code>https://nymbo-tools.hf.space/gradio_api/mcp/</code>
|
1768 |
+
</p>
|
1769 |
+
<p>Example client configuration:</p>
|
1770 |
+
<pre><code class="language-json">{
|
1771 |
+
"mcpServers": {
|
1772 |
+
"gradio": {
|
1773 |
+
"url": "https://nymbo-tools.hf.space/gradio_api/mcp/"
|
1774 |
+
}
|
1775 |
+
}
|
1776 |
+
}</code></pre>
|
1777 |
+
|
1778 |
+
</div>
|
1779 |
+
</section>
|
1780 |
+
|
1781 |
+
<section class="info-card">
|
1782 |
+
<div class="info-card__icon">🛠️</div>
|
1783 |
+
<div class="info-card__body">
|
1784 |
+
<h3>Tool Notes & Kokoro Voice Legend</h3>
|
1785 |
+
<p>
|
1786 |
+
No authentication required for: <code>Fetch_Webpage</code>, <code>Search_DuckDuckGo</code>,
|
1787 |
+
<code>Execute_Python</code>, and <code>Generate_Speech</code>.
|
1788 |
+
</p>
|
1789 |
+
<p><strong>Kokoro TTS voice prefixes</strong></p>
|
1790 |
+
<ul class="info-list" style="display:grid;grid-template-columns:repeat(2,minmax(160px,1fr));gap:6px 16px;">
|
1791 |
+
<li><code>af</code> — American female</li>
|
1792 |
+
<li><code>am</code> — American male</li>
|
1793 |
+
<li><code>bf</code> — British female</li>
|
1794 |
+
<li><code>bm</code> — British male</li>
|
1795 |
+
<li><code>ef</code> — European female</li>
|
1796 |
+
<li><code>em</code> — European male</li>
|
1797 |
+
<li><code>hf</code> — Hindi female</li>
|
1798 |
+
<li><code>hm</code> — Hindi male</li>
|
1799 |
+
<li><code>if</code> — Italian female</li>
|
1800 |
+
<li><code>im</code> — Italian male</li>
|
1801 |
+
<li><code>jf</code> — Japanese female</li>
|
1802 |
+
<li><code>jm</code> — Japanese male</li>
|
1803 |
+
<li><code>pf</code> — Portuguese female</li>
|
1804 |
+
<li><code>pm</code> — Portuguese male</li>
|
1805 |
+
<li><code>zf</code> — Chinese female</li>
|
1806 |
+
<li><code>zm</code> — Chinese male</li>
|
1807 |
+
<li><code>ff</code> — French female</li>
|
1808 |
+
</ul>
|
1809 |
+
</div>
|
1810 |
+
</section>
|
1811 |
+
</div>
|
1812 |
+
</div>
|
1813 |
"""
|
1814 |
)
|
1815 |
|