* 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>
* feat(chat): add direct live badge to session rows
* fix(live): use session DB for conversations monitor
* docs: add chat vs live monitor direction plan
* fix(search): avoid numeric session search 500 without FTS table
* 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>
* feat(chat): polish syntax highlighting and tool payload rendering (#94)
* [verified] feat(chat): polish syntax highlighting and tool payload rendering
* [verified] fix(chat): tighten large tool payload rendering
* docs: update data volume path in Docker docs
Align documentation with docker-compose.yml change:
hermes-web-ui-data -> hermes-web-ui, /app/dist/data -> /root/.hermes-web-ui
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: bundle server build and restructure service modules
- Add build-server.mjs script for standalone server compilation
- Add logger service with structured output
- Restructure auth, gateway-manager, hermes-cli, hermes services
- Update docker-compose volume mount path
- Update tsconfig and entry point for bundled server
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: separate controllers from routes and centralize route registration
- Extract business logic from route handlers into controllers/
- Add centralized route registry in routes/index.ts with public/auth/protected layers
- Replace global auth whitelist with sequential middleware registration
- Extract shared helpers to services/config-helpers.ts
- Allow custom provider name to be user-editable in ProviderFormModal
- Deduplicate custom providers by poolKey instead of base_url in getAvailable
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: auth bypass via path case, SPA serving, and provider improvements
- Fix auth bypass: path case-insensitive check for /api, /v1, /upload
- Fix SPA returning 401: skip auth for non-API paths (static files)
- Fix profile switch: use local loading state instead of shared store ref
- Auto-append /v1 to base_url when fetching models (frontend + backend)
- Guard .env writing to built-in providers only
- Add builtin field to provider presets, enable base_url input in form
- Print auth token to console on startup (pino only writes to file)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Zhicheng Han <43314240+hanzckernel@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Replace static top-level import with runtime version check and dynamic
import() so Node < 22.5 gracefully falls back to CLI path instead of
crashing at module load time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
SQLite path was returning null title for sessions without an explicit
title, while the CLI path derives it from the first user message.
Now uses the preview (first user message content) as title fallback,
matching the original CLI behavior.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix#25: job update sends schedule as plain string but upstream expects
{ kind, expr, display } object, causing "'str' object has no attribute 'get'"
- Move hermes-cli.ts, hermes.ts, hermes-profile.ts into services/hermes/
for multi-agent namespacing consistency
- Fix ts-node Set spread compatibility in filesystem.ts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Set up Vitest with jsdom for client tests, node for server tests
- Add tests for auth service, proxy handler, API client, and profiles store
- Strip Authorization header in proxy to prevent web-ui token leaking to gateway
- Distinguish local BFF vs proxied gateway 401s to avoid false logouts
- Remove unused hero.png asset
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>