Commit Graph

6 Commits

Author SHA1 Message Date
ekko ba72264542 feat: group chat session lifecycle, typing recovery, mention highlighting (#186)
* 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>
2026-04-24 20:41:14 +08:00
Zhicheng Han 5f40ae6258 feat(chat): add direct Live badge and harden Live monitor backend (#138)
* 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
2026-04-23 10:49:00 +08:00
ekko 6f69c69802 feat: add token usage tracking, context display, and dynamic context length (#132)
* 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>
2026-04-22 16:14:50 +08:00
cl1107 f27db3036a feat: add session search modal (#128) 2026-04-22 14:00:34 +08:00
Zhicheng Han 3f88553765 feat(web-ui): add pinned sessions and live monitor in Chat (#118)
* 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>
2026-04-22 08:09:58 +08:00
ekko 477af66232 fix: auth bypass, SPA serving, and provider improvements (#97)
* 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>
2026-04-21 12:35:48 +08:00