diff --git a/.gitignore b/.gitignore index e617e9c..f225f24 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,7 @@ packages/server/data/ packages/server/node_modules/ .hermes-web-ui/ hermes_data/ - +hermes-dependencies.md # Editor directories and files .vscode/* !.vscode/extensions.json diff --git a/package.json b/package.json index 86abf14..c9bce05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hermes-web-ui", - "version": "0.3.5", + "version": "0.3.6", "description": "Web dashboard for Hermes Agent — multi-platform AI chat, session management, scheduled jobs, usage analytics & channel configuration (Telegram, Discord, Slack, WhatsApp)", "repository": { "type": "git", diff --git a/packages/client/src/api/hermes/system.ts b/packages/client/src/api/hermes/system.ts index 1eeddab..4835202 100644 --- a/packages/client/src/api/hermes/system.ts +++ b/packages/client/src/api/hermes/system.ts @@ -33,6 +33,7 @@ export interface AvailableModelGroup { export interface AvailableModelsResponse { default: string + default_provider: string groups: AvailableModelGroup[] } diff --git a/packages/client/src/components/hermes/chat/MessageList.vue b/packages/client/src/components/hermes/chat/MessageList.vue index 03a177e..f75f595 100644 --- a/packages/client/src/components/hermes/chat/MessageList.vue +++ b/packages/client/src/components/hermes/chat/MessageList.vue @@ -31,6 +31,12 @@ const currentToolCalls = computed(() => { return [...tools].reverse(); }); +function isNearBottom(threshold = 200): boolean { + const el = listRef.value; + if (!el) return true; + return el.scrollHeight - el.scrollTop - el.clientHeight < threshold; +} + function scrollToBottom() { nextTick(() => { if (listRef.value) { @@ -39,18 +45,37 @@ function scrollToBottom() { }); } -watch(() => chatStore.messages.length, scrollToBottom); +// Scroll to bottom once when messages are first loaded watch( - () => chatStore.messages[chatStore.messages.length - 1]?.content, - scrollToBottom, + () => chatStore.activeSessionId, + (id) => { + if (id) scrollToBottom(); + }, + { immediate: true }, ); + +// When a run starts (user just sent a message), always scroll to bottom once watch( () => chatStore.isRunActive, (v) => { if (v) scrollToBottom(); }, ); -watch(currentToolCalls, scrollToBottom); + +// During streaming, only auto-scroll if the user is already near the bottom +watch( + () => chatStore.messages[chatStore.messages.length - 1]?.content, + () => { + if (!chatStore.isStreaming) { scrollToBottom(); return; } + if (!isNearBottom()) return; + scrollToBottom(); + }, +); +watch(currentToolCalls, () => { + if (!chatStore.isStreaming) { scrollToBottom(); return; } + if (!isNearBottom()) return; + scrollToBottom(); +});