Spaces:
Running on Zero
Running on Zero
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,9 +1,7 @@
|
|
| 1 |
"""Tiny Aya — streaming multilingual chat, built for the Build Small Hackathon.
|
| 2 |
-
|
| 3 |
A gr.Server app: custom HTML/JS frontend (Cohere Labs + Build Small styling)
|
| 4 |
backed by Gradio's queue + ZeroGPU. The browser talks to the `/chat` route
|
| 5 |
through the Gradio JS client, so it streams token-by-token.
|
| 6 |
-
|
| 7 |
Deploy on Hugging Face Spaces:
|
| 8 |
- sdk: gradio (in README.md frontmatter)
|
| 9 |
- add HF_TOKEN as a Space secret (tiny-aya-global is a gated model)
|
|
@@ -107,7 +105,6 @@ FRONTEND_HTML = f"""
|
|
| 107 |
body {{ margin:0; height:100vh; display:flex; flex-direction:column;
|
| 108 |
background:var(--cream); color:var(--ink);
|
| 109 |
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }}
|
| 110 |
-
|
| 111 |
/* brand bar — Cohere Labs front and center */
|
| 112 |
header {{ position:relative; display:flex; flex-direction:column; align-items:center;
|
| 113 |
gap:6px; padding:22px 22px 16px; background:var(--panel);
|
|
@@ -120,7 +117,6 @@ FRONTEND_HTML = f"""
|
|
| 120 |
header .badge {{ position:absolute; right:18px; top:18px; font-size:12px; font-weight:600;
|
| 121 |
color:var(--blue); background:#EDF0FB; border:1px solid #D8DEF6;
|
| 122 |
padding:5px 11px; border-radius:999px; }}
|
| 123 |
-
|
| 124 |
/* chat — banner sits faded in the background */
|
| 125 |
#chat {{ flex:1; overflow-y:auto; padding:26px; display:flex; flex-direction:column;
|
| 126 |
gap:14px; max-width:840px; width:100%; margin:0 auto;
|
|
@@ -138,9 +134,11 @@ FRONTEND_HTML = f"""
|
|
| 138 |
.bot {{ align-self:flex-start; background:var(--bot); color:var(--ink);
|
| 139 |
border:1px solid var(--border); border-bottom-left-radius:5px; }}
|
| 140 |
.typing {{ color:var(--muted); font-style:italic; }}
|
| 141 |
-
|
|
|
|
|
|
|
|
|
|
| 142 |
.empty h2 {{ color:var(--ink); margin:0 0 6px; }}
|
| 143 |
-
|
| 144 |
/* composer */
|
| 145 |
form {{ display:flex; gap:10px; padding:16px 22px; background:var(--panel);
|
| 146 |
border-top:1px solid var(--border); max-width:840px; width:100%; margin:0 auto; }}
|
|
@@ -163,39 +161,31 @@ FRONTEND_HTML = f"""
|
|
| 163 |
<div class="sub">Multilingual chat · 70+ languages</div>
|
| 164 |
<span class="badge">Build Small Hackathon</span>
|
| 165 |
</header>
|
| 166 |
-
|
| 167 |
<div id="chat">
|
| 168 |
<div class="empty" id="empty">
|
| 169 |
<h2>👋 Hola · नमस्ते · Bonjour · مرحبا</h2>
|
| 170 |
<p>Chat with <b>Tiny Aya</b>, Cohere Labs' 3.35B multilingual model. Ask in any of 70+ languages.</p>
|
| 171 |
</div>
|
| 172 |
</div>
|
| 173 |
-
|
| 174 |
<form id="form">
|
| 175 |
<textarea id="input" rows="1" placeholder="Message Tiny Aya… (Enter to send, Shift+Enter for newline)"></textarea>
|
| 176 |
<button id="send" type="submit">Send</button>
|
| 177 |
</form>
|
| 178 |
-
|
| 179 |
<footer>
|
| 180 |
Powered by <a href="https://huggingface.co/CohereLabs/tiny-aya-global" target="_blank">Cohere Labs · Tiny Aya</a>
|
| 181 |
+ <a href="https://www.gradio.app/guides/server-mode" target="_blank">gr.Server</a>
|
| 182 |
· built for the <a href="https://huggingface.co/build-small-hackathon" target="_blank">Build Small Hackathon</a>
|
| 183 |
</footer>
|
| 184 |
-
|
| 185 |
<script type="module">
|
| 186 |
import {{ Client }} from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
|
| 187 |
-
|
| 188 |
const chat = document.getElementById("chat");
|
| 189 |
const empty = document.getElementById("empty");
|
| 190 |
const form = document.getElementById("form");
|
| 191 |
const input = document.getElementById("input");
|
| 192 |
const send = document.getElementById("send");
|
| 193 |
const history = [];
|
| 194 |
-
|
| 195 |
const client = await Client.connect(window.location.origin);
|
| 196 |
-
|
| 197 |
const scroll = () => {{ chat.scrollTop = chat.scrollHeight; }};
|
| 198 |
-
|
| 199 |
function bubble(role, text, extra = "") {{
|
| 200 |
const el = document.createElement("div");
|
| 201 |
el.className = `msg ${{role === "user" ? "user" : "bot"}} ${{extra}}`;
|
|
@@ -204,7 +194,6 @@ FRONTEND_HTML = f"""
|
|
| 204 |
scroll();
|
| 205 |
return el;
|
| 206 |
}}
|
| 207 |
-
|
| 208 |
input.addEventListener("input", () => {{
|
| 209 |
input.style.height = "auto";
|
| 210 |
input.style.height = input.scrollHeight + "px";
|
|
@@ -212,18 +201,15 @@ FRONTEND_HTML = f"""
|
|
| 212 |
input.addEventListener("keydown", (e) => {{
|
| 213 |
if (e.key === "Enter" && !e.shiftKey) {{ e.preventDefault(); form.requestSubmit(); }}
|
| 214 |
}});
|
| 215 |
-
|
| 216 |
form.addEventListener("submit", async (e) => {{
|
| 217 |
e.preventDefault();
|
| 218 |
const text = input.value.trim();
|
| 219 |
if (!text) return;
|
| 220 |
if (empty) empty.remove();
|
| 221 |
-
|
| 222 |
bubble("user", text);
|
| 223 |
history.push({{ role: "user", content: text }});
|
| 224 |
input.value = ""; input.style.height = "auto";
|
| 225 |
send.disabled = true; input.disabled = true;
|
| 226 |
-
|
| 227 |
const botEl = bubble("assistant", "▍", "typing");
|
| 228 |
let full = "";
|
| 229 |
try {{
|
|
@@ -251,4 +237,4 @@ FRONTEND_HTML = f"""
|
|
| 251 |
"""
|
| 252 |
|
| 253 |
if __name__ == "__main__":
|
| 254 |
-
server.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
|
|
|
|
| 1 |
"""Tiny Aya — streaming multilingual chat, built for the Build Small Hackathon.
|
|
|
|
| 2 |
A gr.Server app: custom HTML/JS frontend (Cohere Labs + Build Small styling)
|
| 3 |
backed by Gradio's queue + ZeroGPU. The browser talks to the `/chat` route
|
| 4 |
through the Gradio JS client, so it streams token-by-token.
|
|
|
|
| 5 |
Deploy on Hugging Face Spaces:
|
| 6 |
- sdk: gradio (in README.md frontmatter)
|
| 7 |
- add HF_TOKEN as a Space secret (tiny-aya-global is a gated model)
|
|
|
|
| 105 |
body {{ margin:0; height:100vh; display:flex; flex-direction:column;
|
| 106 |
background:var(--cream); color:var(--ink);
|
| 107 |
font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif; }}
|
|
|
|
| 108 |
/* brand bar — Cohere Labs front and center */
|
| 109 |
header {{ position:relative; display:flex; flex-direction:column; align-items:center;
|
| 110 |
gap:6px; padding:22px 22px 16px; background:var(--panel);
|
|
|
|
| 117 |
header .badge {{ position:absolute; right:18px; top:18px; font-size:12px; font-weight:600;
|
| 118 |
color:var(--blue); background:#EDF0FB; border:1px solid #D8DEF6;
|
| 119 |
padding:5px 11px; border-radius:999px; }}
|
|
|
|
| 120 |
/* chat — banner sits faded in the background */
|
| 121 |
#chat {{ flex:1; overflow-y:auto; padding:26px; display:flex; flex-direction:column;
|
| 122 |
gap:14px; max-width:840px; width:100%; margin:0 auto;
|
|
|
|
| 134 |
.bot {{ align-self:flex-start; background:var(--bot); color:var(--ink);
|
| 135 |
border:1px solid var(--border); border-bottom-left-radius:5px; }}
|
| 136 |
.typing {{ color:var(--muted); font-style:italic; }}
|
| 137 |
+
/* empty state sits just BELOW the banner: the banner scales with the chat
|
| 138 |
+
column width (max 840px), so the top margin tracks the viewport width
|
| 139 |
+
and is clamped for wide screens. Tune 42vw / 380px to taste. */
|
| 140 |
+
.empty {{ margin:min(42vw, 380px) auto 0; text-align:center; color:var(--muted); max-width:420px; }}
|
| 141 |
.empty h2 {{ color:var(--ink); margin:0 0 6px; }}
|
|
|
|
| 142 |
/* composer */
|
| 143 |
form {{ display:flex; gap:10px; padding:16px 22px; background:var(--panel);
|
| 144 |
border-top:1px solid var(--border); max-width:840px; width:100%; margin:0 auto; }}
|
|
|
|
| 161 |
<div class="sub">Multilingual chat · 70+ languages</div>
|
| 162 |
<span class="badge">Build Small Hackathon</span>
|
| 163 |
</header>
|
|
|
|
| 164 |
<div id="chat">
|
| 165 |
<div class="empty" id="empty">
|
| 166 |
<h2>👋 Hola · नमस्ते · Bonjour · مرحبا</h2>
|
| 167 |
<p>Chat with <b>Tiny Aya</b>, Cohere Labs' 3.35B multilingual model. Ask in any of 70+ languages.</p>
|
| 168 |
</div>
|
| 169 |
</div>
|
|
|
|
| 170 |
<form id="form">
|
| 171 |
<textarea id="input" rows="1" placeholder="Message Tiny Aya… (Enter to send, Shift+Enter for newline)"></textarea>
|
| 172 |
<button id="send" type="submit">Send</button>
|
| 173 |
</form>
|
|
|
|
| 174 |
<footer>
|
| 175 |
Powered by <a href="https://huggingface.co/CohereLabs/tiny-aya-global" target="_blank">Cohere Labs · Tiny Aya</a>
|
| 176 |
+ <a href="https://www.gradio.app/guides/server-mode" target="_blank">gr.Server</a>
|
| 177 |
· built for the <a href="https://huggingface.co/build-small-hackathon" target="_blank">Build Small Hackathon</a>
|
| 178 |
</footer>
|
|
|
|
| 179 |
<script type="module">
|
| 180 |
import {{ Client }} from "https://cdn.jsdelivr.net/npm/@gradio/client/dist/index.min.js";
|
|
|
|
| 181 |
const chat = document.getElementById("chat");
|
| 182 |
const empty = document.getElementById("empty");
|
| 183 |
const form = document.getElementById("form");
|
| 184 |
const input = document.getElementById("input");
|
| 185 |
const send = document.getElementById("send");
|
| 186 |
const history = [];
|
|
|
|
| 187 |
const client = await Client.connect(window.location.origin);
|
|
|
|
| 188 |
const scroll = () => {{ chat.scrollTop = chat.scrollHeight; }};
|
|
|
|
| 189 |
function bubble(role, text, extra = "") {{
|
| 190 |
const el = document.createElement("div");
|
| 191 |
el.className = `msg ${{role === "user" ? "user" : "bot"}} ${{extra}}`;
|
|
|
|
| 194 |
scroll();
|
| 195 |
return el;
|
| 196 |
}}
|
|
|
|
| 197 |
input.addEventListener("input", () => {{
|
| 198 |
input.style.height = "auto";
|
| 199 |
input.style.height = input.scrollHeight + "px";
|
|
|
|
| 201 |
input.addEventListener("keydown", (e) => {{
|
| 202 |
if (e.key === "Enter" && !e.shiftKey) {{ e.preventDefault(); form.requestSubmit(); }}
|
| 203 |
}});
|
|
|
|
| 204 |
form.addEventListener("submit", async (e) => {{
|
| 205 |
e.preventDefault();
|
| 206 |
const text = input.value.trim();
|
| 207 |
if (!text) return;
|
| 208 |
if (empty) empty.remove();
|
|
|
|
| 209 |
bubble("user", text);
|
| 210 |
history.push({{ role: "user", content: text }});
|
| 211 |
input.value = ""; input.style.height = "auto";
|
| 212 |
send.disabled = true; input.disabled = true;
|
|
|
|
| 213 |
const botEl = bubble("assistant", "▍", "typing");
|
| 214 |
let full = "";
|
| 215 |
try {{
|
|
|
|
| 237 |
"""
|
| 238 |
|
| 239 |
if __name__ == "__main__":
|
| 240 |
+
server.launch(server_name="0.0.0.0", server_port=7860, show_error=True)
|