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
+27 -4
View File
@@ -5,8 +5,10 @@ const getConversationDetailFromDbMock = vi.fn()
const listConversationSummariesMock = vi.fn()
const getConversationDetailMock = vi.fn()
const getSessionDetailFromDbMock = vi.fn()
const getExactSessionDetailFromDbWithProfileMock = vi.fn()
const getUsageStatsFromDbMock = vi.fn()
const getSessionMock = vi.fn()
const deleteHermesSessionForProfileMock = vi.fn()
const localListSessionsMock = vi.fn()
const localGetSessionDetailMock = vi.fn()
const localSearchSessionsMock = vi.fn()
@@ -41,6 +43,7 @@ vi.mock('../../packages/server/src/services/hermes/hermes-cli', () => ({
listSessions: vi.fn(),
getSession: getSessionMock,
deleteSession: vi.fn(),
deleteSessionForProfile: deleteHermesSessionForProfileMock,
renameSession: vi.fn(),
}))
@@ -48,6 +51,7 @@ vi.mock('../../packages/server/src/db/hermes/sessions-db', () => ({
listSessionSummaries: vi.fn(),
searchSessionSummaries: vi.fn(),
getSessionDetailFromDb: getSessionDetailFromDbMock,
getExactSessionDetailFromDbWithProfile: getExactSessionDetailFromDbWithProfileMock,
getUsageStatsFromDb: getUsageStatsFromDbMock,
}))
@@ -79,6 +83,7 @@ vi.mock('../../packages/server/src/services/hermes/model-context', () => ({
vi.mock('../../packages/server/src/services/hermes/hermes-profile', () => ({
getActiveProfileName: getActiveProfileNameMock,
listProfileNamesFromDisk: () => ['default', 'travel'],
}))
vi.mock('../../packages/server/src/db/hermes/compression-snapshot', () => ({
@@ -96,10 +101,6 @@ vi.mock('../../packages/server/src/lib/context-compressor/export-compressor', ()
},
}))
vi.mock('../../packages/server/src/services/gateway-bootstrap', () => ({
getGatewayManagerInstance: () => null,
}))
describe('session conversations controller', () => {
beforeEach(() => {
vi.resetModules()
@@ -108,8 +109,10 @@ describe('session conversations controller', () => {
listConversationSummariesMock.mockReset()
getConversationDetailMock.mockReset()
getSessionDetailFromDbMock.mockReset()
getExactSessionDetailFromDbWithProfileMock.mockReset()
getUsageStatsFromDbMock.mockReset()
getSessionMock.mockReset()
deleteHermesSessionForProfileMock.mockReset()
localListSessionsMock.mockReset()
localGetSessionDetailMock.mockReset()
localSearchSessionsMock.mockReset()
@@ -319,6 +322,26 @@ describe('session conversations controller', () => {
expect(ctx.body).toEqual({ ok: true })
})
it('deletes a current-profile Hermes history session even when no local Web UI session exists', async () => {
getActiveProfileNameMock.mockReturnValue('travel')
getSessionMock.mockReturnValue(null)
getExactSessionDetailFromDbWithProfileMock.mockResolvedValue({ id: 'history-only', messages: [] })
deleteHermesSessionForProfileMock.mockResolvedValue(true)
const mod = await import('../../packages/server/src/controllers/hermes/sessions')
const ctx: any = { params: { id: 'history-only' }, body: null }
await mod.remove(ctx)
expect(getExactSessionDetailFromDbWithProfileMock).toHaveBeenCalledWith('history-only', 'travel')
expect(deleteHermesSessionForProfileMock).toHaveBeenCalledWith('history-only', 'travel')
expect(localDeleteSessionMock).not.toHaveBeenCalled()
expect(ctx.body).toEqual({
ok: true,
deleted: false,
hermes: { attempted: true, deleted: true, profile: 'travel', error: undefined },
})
})
describe('exportSession', () => {
it('returns session as JSON download with correct headers (full mode)', async () => {
const sessionData = { id: 'abc-123', title: 'Test Session', messages: [{ id: 1, role: 'user', content: 'hello' }] }