- Hover over any message to reveal a copy icon button
- Click to copy the full message text to clipboard
- Shows success/error toast notification
- Skips tool messages (no copy button shown)
- i18n support for all 8 languages (EN/ZH/DE/ES/FR/JA/KO/PT)
- Dark mode compatible styling
Co-authored-by: 356252190-star <356252190-star@users.noreply.github.com>
* chore: add v0.4.8 changelog and improve scroll behavior
- Add v0.4.8 changelog entries for recent fixes
- Fix forced scroll to bottom when returning from other tabs
- Smooth session switch with loading transition overlay
- Auto-scroll to bottom after mermaid diagram rendering
- Bump version to 0.4.8
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace blob URLs with persistent download URLs and add image preview
- Replace blob URLs with /api/hermes/download URLs after upload so
attachments survive page refresh
- Add click-to-preview overlay for image attachments
- Move upload directory from /tmp to ~/.hermes-web-ui/upload
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: replace findLast with reverse+find for ES2022 compat
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: bump TypeScript lib target from ES2022 to ES2023
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add changelog entries for blob URL fix, image preview and upload dir
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: align group chat room sidebar background with session list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add v0.4.7 changelog and remove v0.4.3/v0.4.1 entries
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: remove unused video.mp4 asset
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: restore group chat system with Socket.IO and SQLite persistence
- GroupChatServer: Socket.IO server with room management, message history, typing indicators
- SQLite storage for rooms, messages, and agent configuration
- AgentClients: manages AI agent connections via socket.io-client, forwards @mentions to Hermes gateway
- REST API: room CRUD, agent management, invite codes
- Agent auto-restoration on server restart
- Tests for all REST endpoints
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* docs: add context-engine design document for group chat compression
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: handle special-character session search
* fix: keep unicode dotted session search on quoted FTS path
* feat: add context engine and group chat frontend UI
- Context engine: three-zone compression (head/tail/summary) with LLM
summarization, incremental updates, TTL cache, and graceful degradation
- Frontend: group chat page with Socket.IO client, room sidebar, message
list, agent/member display, create/join-by-code modals
- Integration: wire context engine into agent-clients before /v1/runs
- Refactor ChatStorage to use global DB (getDb/ensureTable) with gc_ prefix
- Add i18n keys for group chat to all 8 locales
- Add sidebar nav entry and router for group chat page
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: remove leftover main branch code from merge conflict resolution
The `isNumericQuery`, `hasUnsafeChars`, and `runLikeContentSearch` functions
no longer exist — they were replaced by HEAD's `shouldUseLiteralContentSearch`
and `runLiteralContentSearch`. This dead code block caused a TypeScript
compile error after the merge.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: install missing socket.io dep and type ack params
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: enable WebSocket proxy and fix socket.io transport for group chat
- Add ws: true to Vite proxy config so WebSocket upgrade requests
are forwarded to the backend
- Allow both polling and websocket transports on server and client
(polling as fallback when WebSocket upgrade fails through proxy)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: separate socket.io path from REST routes for group chat
socket.io was mounted at /api/hermes/group-chat which intercepted all
REST requests to /api/hermes/group-chat/rooms etc, returning
"Transport unknown". Changed socket.io path to /api/hermes/group-chat/ws
to avoid conflicts.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: improve group chat UI, agent management, and socket.io reliability
- Redesign GroupChatPanel with Naive UI, stacked agent avatars, and popover management
- Match GroupChatInput style with single chat input, add IME composition handling
- Add agent add/remove per room with profile selection and duplicate prevention
- Use @multiavatar for SVG avatar generation with caching
- Decouple joinRoom from socket.io, use REST API for data loading
- Switch socket.io to default path with /group-chat namespace to avoid proxy conflicts
- Restore agent connections after server is listening
- Add getRoomDetail REST endpoint and duplicate agent prevention (409)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: server-side @mention routing with context compression status and queue
- Move @mention detection from agent socket listeners to server-side processMentions()
- Add per-room processing lock to block mention dispatch during compression
- Queue mentions during processing, drain only the latest when ready
- Emit context_status events (compressing/replying/ready) to room via Socket.IO
- Frontend displays compression status indicator above input
- Token-based compression trigger (100k threshold) with CJK-aware estimation
- Fix compressor type errors (countTokens parameter type)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: improve group chat profile handling and session sync
Refine group chat room/session behavior with per-room compression controls, sidebar updates, and better stale session cleanup so multi-profile group chat state stays consistent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: group chat improvements — session lifecycle, typing recovery, mention highlighting
- Fix cross-profile session deletion with deferred delete queue
- Move saveSessionProfile to after gateway response confirmation
- Replace all console.log with logger in group-chat modules
- Add server-side typing/context_status state tracking for room rejoin
- Fix @ mention popup position to follow cursor
- Add @ mention highlighting (blue) in chat message content
- Fix mention regex to match all occurrences after HTML tags
- Enable esbuild minify and treeShaking
- Move @multiavatar/multiavatar to devDependencies
- Add i18n keys for group chat features
- Update tests for new functionality
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* chore: bump version to 0.4.5 and move @multiavatar to devDependencies
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Zhicheng Han <zhicheng.han@mathematik.uni-goettingen.de>
* fix: context-length API returns 200K instead of actual model context
Two bugs cause the /api/hermes/sessions/context-length endpoint to
always return DEFAULT_CONTEXT_LENGTH (200K):
1. getModelContextLength ignores config.yaml model.context_length
The function only checks models_dev_cache.json (which doesn't
exist in default installations) and falls back to the hardcoded
200K default, completely ignoring the user's explicit
model.context_length setting in config.yaml.
2. getDefaultModel regex fails when api_key/base_url come before default
The regex /^model:\s*\n\s+default:\s*(.+)$/m assumes 'default' is
the first child key under 'model:', but when api_key or base_url
appear first in the YAML, the match fails. This causes
getModelContextLength to short-circuit to DEFAULT_CONTEXT_LENGTH
before even reaching the cache lookup.
Fix:
- Add getDefaultModelRobust() that extracts the entire model: block
first, then searches for default: within it
- Add getConfigContextLength() that reads model.context_length from
config.yaml as a fallback (matching hermes-agent priority)
- Update getModelContextLength() resolution order:
1. models_dev_cache.json (existing)
2. config.yaml model.context_length (new)
3. DEFAULT_CONTEXT_LENGTH (existing fallback)
Closes#169
* refactor: rewrite model-context to use js-yaml, add context_length to provider form
- Replace fragile regex-based YAML parsing with js-yaml for reliable config.yaml reads
- Fix context_length resolution priority: config.yaml override > custom_providers > models_dev_cache > 200K default
- Add context_length input field when adding custom providers in ProviderFormModal
- Backend: persist context_length to custom_providers models.<model>.context_length in config.yaml
- Add i18n keys (contextLength, contextLengthPlaceholder) to all 8 locales
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: use NInputNumber instead of NInput type=number for context_length
NInput does not support type="number" in Naive UI.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: devilardis <53129661@qq.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat(models): add custom model name input with provider selector
- Add custom model input field at bottom of model selector modal
- Add provider dropdown to specify target provider for custom model
- Track custom models in app store and display with CUSTOM badge
- Merge custom model into provider group list
- Fix custom provider models being overwritten by API response (keep both)
* Upload screenshot
* fix(i18n): add i18n support for custom model feature in ModelSelector
Replace hardcoded English strings (CUSTOM badge, placeholder, hint) with
vue-i18n t() calls and add corresponding translation keys to all 8 locales
(en, zh, ja, ko, fr, es, de, pt).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: toller892 <892@users.noreply.github.com>
Co-authored-by: Tony <125938283+toller892@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* i18n: backfill files/download translations for de, es, fr, ja, ko, pt
Add nav.files, files.* (39 keys), and download.* (9 keys) so the file
browser UI is fully localized in these six locales instead of falling
back to English.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(files): close preview when navigating or affected file changes
Opening a preview and then navigating directories, deleting the
previewed file, or renaming it left the preview pane stuck on stale
content because previewFile was never cleared.
- stores/hermes/files.ts:
- fetchEntries clears previewFile on path change (in-place refresh
keeps the preview).
- deleteEntry / renameEntry clear preview/editor state when the
affected entry matches the previewed/edited file or its parent.
- Add isAffected(target, changed, isDir) helper.
- components/hermes/files/FilePreview.vue: replace the misleading
common.cancel close button with a dedicated files.closePreview key
plus an X icon and quaternary style.
- i18n: add files.closePreview to all 8 locales.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Display persistent warning bar when Node.js version < 23
- Fix provider model fetching to support non-v1 API versions (e.g. /v4)
- Add v0.4.4 changelog entries to frontend
- Bump version to 0.4.4
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add StepFun provider (API key auth, STEPFUN_API_KEY)
- Add Nous Portal provider with full OAuth device code flow
(device code request → poll for token → mint agent key → save to auth.json)
- Add NousLoginModal component for OAuth UI (user code display + verification link)
- Update ProviderFormModal to handle Nous OAuth flow (hide API key fields)
- Add nous-auth backend controller and routes
- Update PROVIDER_ENV_MAP with stepfun and nous entries
- Add i18n translations for Nous OAuth in all 8 locales
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add username/password login as additional auth mechanism alongside existing token
- First login must use token; password can be configured in Settings > Account
- Password login returns the existing static token (no auth middleware changes)
- Add account settings: setup, change password, change username, remove password
- Add logout button to sidebar footer
- Add version changelog popup (click version number in sidebar)
- Support all 8 locales (en, zh, de, es, fr, ja, ko, pt)
- Bump version to 0.4.3
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* fix: specify TS_NODE_PROJECT for dev:server script
ts-node/register resolves tsconfig from the entry file upward,
finding the root solution-style tsconfig.json (no compilerOptions).
This causes target to default to ES3, breaking MapIterator spread
syntax (TS2802). Set TS_NODE_PROJECT env var to point to the server
tsconfig which targets ES2024.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add token usage tracking, context display, and dynamic context length
- Intercept SSE proxy to capture run.completed events and persist token
usage (input_tokens, output_tokens) per session to SQLite/JSON store
- Display context usage bar in ChatInput showing used/total/remaining tokens
- Resolve actual context length from Hermes models_dev_cache.json based
on the active profile's default model (fallback 200K), with 5min in-memory cache
- Move sessions-db.ts to db/hermes/ for unified database layer
- Add usage store with SQLite + JSON fallback (auto-migration via ensureTable)
- Fix proxy SSE path regex to match rewritten upstream path
- Fix route ordering: /sessions/usage before /sessions/:id to avoid 404
- Fetch per-session usage on session enter instead of batch
- Add unit tests for usage-store, db index, and proxy SSE interception
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* feat: add single-page live session monitor and chat pinning
* fix: restore full test green after main merge
* fix: use Array.from instead of Set spread for ts-node compatibility
[...new Set()] requires downlevelIteration which isn't enabled in
ts-node dev mode, causing sonic-boom crash on startup.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: ekko <fqsy1416@gmail.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
- Add OpenAI Codex Device Code Flow login (backend polling + frontend modal)
- Codex provider integrated into preset dropdown (hides URL/API key fields)
- Sync provider model catalogs with Hermes system
- Fix channel config not displaying on first visit (wait for data load)
- Fix sidebar model list not refreshing after adding provider
- Add autocomplete="off" to API key input to prevent browser autofill
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Allow manual model name input when adding custom providers (NSelect tag mode)
- Sync provider model catalogs with Hermes _PROVIDER_MODELS
- Add new providers: kimi-coding-cn, moonshot, arcee
- Fix provider key naming to match Hermes (kilo→kilocode, vercel→ai-gateway, etc.)
- Ensure custom_providers from config.yaml always appear in available-models
- Append configured default model to model list if not in catalog
- Fix provider deletion with case-insensitive key matching
- Add selectOrInput i18n key to all 8 locales
Closes#24
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add Japanese, Korean, French, Spanish, German, Portuguese translations
- Improve session active state visibility in both themes
- Static language labels in LanguageSwitch component
- Dark theme: lighten chat input background for better contrast
- Fix system theme listener not toggling back to light
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>