From 370007813d9153e5b5269448f557edd0a6175bb4 Mon Sep 17 00:00:00 2001 From: Brad Stein Date: Sat, 20 Dec 2025 23:52:49 -0300 Subject: [PATCH] feat(ai): refine chat UX and add AI roadmap view --- frontend/src/data/sample.js | 34 ++++++------ frontend/src/router.js | 5 +- frontend/src/views/AiPlanView.vue | 89 +++++++++++++++++++++++++++++++ frontend/src/views/AiView.vue | 29 +++++----- 4 files changed, 124 insertions(+), 33 deletions(-) create mode 100644 frontend/src/views/AiPlanView.vue diff --git a/frontend/src/data/sample.js b/frontend/src/data/sample.js index fc542fc..9ae5c3f 100644 --- a/frontend/src/data/sample.js +++ b/frontend/src/data/sample.js @@ -126,26 +126,26 @@ export function fallbackServices() { name: "AI Chat", category: "ai", summary: "LLM chat (public beta)", - link: "/ai", + link: "/ai/chat", host: "chat.ai.bstein.dev", status: "live", }, - { - name: "AI Image", - category: "ai", - summary: "Visualization tool - Planned", - link: "/ai", - host: "draw.ai.bstein.dev", - status: "planned", - }, - { - name: "AI Speech", - category: "ai", - summary: "Live Translation - Planned", - link: "/ai", - host: "talk.ai.bstein.dev", - status: "planned", - }, + { + name: "AI Image", + category: "ai", + summary: "Visualization tool - Planned", + link: "/ai/roadmap", + host: "draw.ai.bstein.dev", + status: "planned", + }, + { + name: "AI Speech", + category: "ai", + summary: "Live Translation - Planned", + link: "/ai/roadmap", + host: "talk.ai.bstein.dev", + status: "planned", + }, ], }; } diff --git a/frontend/src/router.js b/frontend/src/router.js index e26c1d6..4247e97 100644 --- a/frontend/src/router.js +++ b/frontend/src/router.js @@ -2,6 +2,7 @@ import { createRouter, createWebHistory } from "vue-router"; import HomeView from "./views/HomeView.vue"; import AboutView from "./views/AboutView.vue"; import AiView from "./views/AiView.vue"; +import AiPlanView from "./views/AiPlanView.vue"; import MoneroView from "./views/MoneroView.vue"; export default createRouter({ @@ -9,7 +10,9 @@ export default createRouter({ routes: [ { path: "/", name: "home", component: HomeView }, { path: "/about", name: "about", component: AboutView }, - { path: "/ai", name: "ai", component: AiView }, + { path: "/ai", redirect: "/ai/chat" }, + { path: "/ai/chat", name: "ai-chat", component: AiView }, + { path: "/ai/roadmap", name: "ai-roadmap", component: AiPlanView }, { path: "/monero", name: "monero", component: MoneroView }, ], }); diff --git a/frontend/src/views/AiPlanView.vue b/frontend/src/views/AiPlanView.vue new file mode 100644 index 0000000..e8a1857 --- /dev/null +++ b/frontend/src/views/AiPlanView.vue @@ -0,0 +1,89 @@ + + + diff --git a/frontend/src/views/AiView.vue b/frontend/src/views/AiView.vue index 21d4a9a..f0b8f9e 100644 --- a/frontend/src/views/AiView.vue +++ b/frontend/src/views/AiView.vue @@ -5,8 +5,8 @@

Atlas AI

Chat

- Lightweight LLM running on titan-24 (RTX 3080, 8GB). Anyone can chat without auth. The client streams responses and - shows round-trip latency for each turn. + Lightweight LLM running on local GPU accelerated hardware. Anyone can chat without auth. The client streams responses + and shows round-trip latency for each turn.

Online
@@ -17,7 +17,7 @@
GPU - titan-24 · 3080 (8GB) + local GPU (dynamic)
Endpoint @@ -30,7 +30,7 @@
-
{{ msg.role === 'assistant' ? 'ai' : 'you' }}
+
{{ msg.role === 'assistant' ? 'Atlas AI' : 'you' }}

{{ msg.content }}

streaming…
{{ msg.latency_ms }} ms
@@ -48,25 +48,17 @@ v-model="draft" placeholder="Ask anything about the lab or general topics..." rows="3" + @keydown="handleKeydown" :disabled="sending" />
- Shift+Enter for newline + Enter to send · Shift+Enter for newline
- -
-

Notes

-
    -
  • Backend proxies requests to Ollama inside the cluster; no external calls are made.
  • -
  • Short-term context: the chat history in this page is sent each turn. Refresh clears it.
  • -
  • Future: swap in larger models on the Jetsons, add streaming and rate limits.
  • -
-
@@ -80,7 +72,7 @@ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)); const messages = ref([ { role: "assistant", - content: "Hi! I'm the Titan Lab assistant running on titan-24. How can I help?", + content: "Hi! I'm Atlas AI. How can I help?", }, ]); const draft = ref(""); @@ -162,6 +154,13 @@ async function typeReveal(entry, text) { } entry.streaming = false; } + +function handleKeydown(e) { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault(); + sendMessage(); + } +}