Commit Graph
11 Commits
Author SHA1 Message Date
junvandCopilot bb3fe1b554 jbot: disable local memory in Hermes Agent mode
In Hermes mode JBOT is a pure voice UI — memory is owned by the Agent:
- Backend: sys prompt excludes local memories when backend_mode=hermes
- Backend: config_view now returns backendMode so the frontend can adapt
- Frontend: App.jsx loads backendMode on mount via apiConfig()
- Frontend: memories not passed to apiChat() when isHermesMode
- Frontend: memory extraction (apiExtractMemory) skipped when isHermesMode
- Frontend: MemoryPanel hidden in Hermes mode; replaced by subtle
  '🧠 Hermes Agent 模式 · 记忆由 Agent 管理' badge

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 76603425a5 jbot: add Hermes Agent backend mode
- New DB fields: hermes_url, hermes_api_key, backend_mode (openrouter/hermes)
- Migration 0002 adds the three fields to JbotApiConfig
- _do_hermes_chat(): streams /v1/chat/completions from Hermes Agent,
  collects hermes.tool.progress SSE events, returns (final_text, tool_calls)
- chat_view branches on backend_mode; Hermes response includes toolCalls list
- Settings page: new '🧠 AI 后端模式' section — radio to toggle mode,
  conditional Hermes URL + API key fields, LLM model field moved under
  OpenRouter mode
- ChatPanel: ToolCallsList component renders collapsible '🔧 Hermes 使用了
  N 个工具' widget before the bot reply — tool calls are NOT spoken via TTS
- CSS: .tool-calls, .tool-calls-* styles for the tool progress widget

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot d944c3ecf9 jbot: remove right-footer wrapper — vbtn-wrap is direct flex child
right-footer served no purpose after hint text was removed. vbtn-wrap
is now a direct flex child of right-col: white bar at the bottom on
desktop, position:fixed on mobile — no stray white boxes anywhere.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 7cd36ad81b jbot: remove hint text from bottom footer — keep only the voice button
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 85da425c38 jbot: anchor voice button to bottom via unified right-footer
- Merged hint text + VoiceButton into a single .right-footer div
  (flex column, white bg, border-top) so they form one solid footer bar
  visually anchored to the bottom of the right column — no more floating
- .right-col gets min-height:0 so flex children can shrink properly
- .vbtn-wrap is now a transparent width:100% wrapper inside right-footer
  (desktop); mobile keeps its own fixed-position overlay
- .right-footer { display: none } on mobile (fixed vbtn-wrap takes over)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 90ebd68511 jbot: fix Settings scrollbar + remove redundant history link
- Remove 'overflow:hidden' from html/body in index.css — it was blocking
  scroll on all pages (Settings, History). The chat page is self-contained
  via .app {height:100dvh; overflow:hidden} so body lock is unnecessary.
  .app reverted back to height:100dvh (self-sufficient, not body-relative)
- Remove duplicate 历史记录 link from the right-column hint bar; it
  already appears in the ChatPanel header, so three links was redundant

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 3cbbaac083 jbot: reorganize layout — memory+hint to right, interval to settings
- Move MemoryPanel from bottom of left column to top of right column
  (above chat messages, with a clean border-bottom separator)
- Move hint text ('按住 Space 或按钮说话 · 音色') from left column
  to a compact bar on the right column between chat and voice button;
  hidden on mobile to save space
- Remove 切换间隔 slider from left column; add it to Settings page
  under 🤖 机器人身份 section with proper slider+value layout
- Add switchIntervalMs:10000 to DEFAULT_SETTINGS in settingsStore so
  the value persists across sessions; App.jsx reads it on mount
- Left column is now much leaner: face + interaction buttons + micro
  expression grid + auto-rotate toggle only

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 4870e1a6f4 jbot: hide left-col scrollbar + add home button
- Left column: scrollbar-width:none + ::-webkit-scrollbar:none to
  hide the scrollbar chrome while keeping overflow-y:auto for tall
  viewports; tightened padding (14→10px top, 20→14px bottom) and
  panel/section gaps (14→10px, 12→8px, h3 margin 7→5px) to help
  content fit without scrolling on typical laptop heights
- Header: added 🏠 home anchor linking to '/' (Links homepage) next
  to the JBOT logo; styled as a small icon button

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot 1efcebfd9b jbot: fix voice button visibility - chat-panel height overflow
.chat-panel was using height:100% which consumed all right-col space,
pushing VoiceButton out of view (clipped by overflow:hidden).

Fix: switch .chat-panel to flex:1 + min-height:0 so it participates
in flex layout and leaves room for the VoiceButton below it.

Also moved VoiceButton component outside App() to avoid React
component-identity churn on every render.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot cdb7efd61d jbot: add WeChat-style hold-to-talk voice button
- Added VoiceButton component (inline in App.jsx) with full
  mousedown/mouseup/mouseleave + touchstart/touchend/touchcancel support
- Shows context-aware label: 🎙 按住说话 /  准备中 / 🔴 松开发送 / ⚙ 思考中 / 🔊 播放中
- Pulsing red animation while recording, amber pulse while acquiring mic
- Disabled (gray) while AI is thinking or speaking
- Desktop: pill button docked at bottom of chat panel (max-width 380px)
- Mobile: fixed to bottom of viewport with safe-area-inset support,
  height 60px for easy thumb tap; right-col padded so messages aren't hidden
- Updated hint text and listening status to be input-agnostic

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00
junvandCopilot a87b4643fd feat: port JBOT AI robot face into links as Django app
- Add jbot Django app (jbot/__init__.py, apps.py, urls.py, api_urls.py)
- Python backend (jbot/views.py): TTS 2.0, ASR 1.0 BigASR, LLM/memory via OpenRouter
- React SPA frontend at /jbot/ (static_src/jbot/): RobotFace, ChatPanel, expressions,
  voices, push-to-talk, history, memory, settings pages
- Vite entry jbot: static_src/jbot/main.jsx → dist/jbot.js + dist/jbot.css
- react-router-dom added; BrowserRouter basename=/jbot for SPA routing
- core/settings.py: added jbot to INSTALLED_APPS
- core/urls.py: /jbot/ + /api/jbot/ URL includes
- pyproject.toml: websocket-client>=1.9.0 for BigASR binary WS protocol
- Dockerfile: ffmpeg added to production apt-get for WebM→PCM audio conversion
- k8s/manifest.yaml: VOLC_APP_ID, VOLC_ACCESS_TOKEN, OPENROUTER_API_KEY env vars
  via jbot-credentials Secret; LLM_MODEL, VOLC_TTS_VOICE, VOLC_ASR_RESOURCE defaults

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-17 14:13:37 +10:00