Fix bridge history, profile models, and Windows gateway handling (#845)

* feat: support profile-aware group chat bridge flows

* feat: route cron jobs through hermes cli

* Fix group chat routing and isolate bridge tests

* Add Grok image-to-video media skill

* Default Grok videos to media directory

* Fix bridge profile fallback and cron repeat clearing

* Refine bridge chat and gateway platform handling

* Filter bridge tool-call text deltas

* Preserve structured bridge chat history

* Prepare beta release build artifacts

* Fix Windows run profile resolution

* Fix Windows path compatibility checks

* Fix profile-scoped model page display

* Hide Windows subprocess windows for jobs and updates

* Hide Windows file backend subprocess windows

* Avoid Windows gateway restart lock conflicts

* Treat Windows gateway lock as running on startup

* Force release Windows gateway lock on restart

* Tighten Windows gateway lock cleanup

* Update chat e2e source expectation

* Bump package version to 0.5.30

---------

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
ekko
2026-05-19 16:09:59 +08:00
committed by GitHub
parent 3d74d78698
commit 9a9416c99c
129 changed files with 7017 additions and 1838 deletions
@@ -11,7 +11,7 @@ import { copyToClipboard } from '@/utils/clipboard'
import HistoryMessageList from '@/components/hermes/chat/HistoryMessageList.vue'
import SessionListItem from '@/components/hermes/chat/SessionListItem.vue'
import OutlinePanel from '@/components/hermes/chat/OutlinePanel.vue'
import { fetchHermesSessions, fetchHermesSession, type SessionSummary } from '@/api/hermes/sessions'
import { deleteSession, fetchHermesSessions, fetchHermesSession, type SessionSummary } from '@/api/hermes/sessions'
const chatStore = useChatStore()
const appStore = useAppStore()
@@ -132,11 +132,13 @@ const collapsedGroups = ref<Set<string>>(new Set(JSON.parse(localStorage.getItem
function sessionSummaryToSession(summary: SessionSummary): Session {
return {
id: summary.id,
profile: summary.profile,
title: summary.title || '',
source: summary.source,
createdAt: summary.started_at * 1000,
updatedAt: (summary.last_active || summary.started_at) * 1000,
model: summary.model,
provider: summary.provider,
messageCount: summary.message_count,
inputTokens: summary.input_tokens,
outputTokens: summary.output_tokens,
@@ -269,6 +271,26 @@ async function copySessionId(id?: string) {
}
}
async function handleDeleteSession(id: string) {
const ok = await deleteSession(id)
if (!ok) {
message.error(t('common.deleteFailed'))
return
}
sessionBrowserPrefsStore.removePinned(id)
hermesSessions.value = hermesSessions.value.filter(s => s.id !== id)
if (historySessionId.value === id) {
historySessionId.value = null
historySession.value = null
const next = historySessions.value[0]
if (next) await handleSessionClick(next.id)
}
message.success(t('chat.sessionDeleted'))
}
</script>
<template>
@@ -301,9 +323,11 @@ async function copySessionId(id?: string) {
:session="s"
:active="s.id === historySessionId"
:pinned="true"
:can-delete="false"
:can-delete="true"
:streaming="false"
:show-profile="false"
@select="handleSessionClick(s.id)"
@delete="handleDeleteSession(s.id)"
/>
</template>
@@ -320,9 +344,11 @@ async function copySessionId(id?: string) {
:session="s"
:active="s.id === historySessionId"
:pinned="false"
:can-delete="false"
:can-delete="true"
:streaming="false"
:show-profile="false"
@select="handleSessionClick(s.id)"
@delete="handleDeleteSession(s.id)"
/>
</template>
</template>