mirror of
https://github.com/hellodigua/ChatLab.git
synced 2026-10-25 17:54:34 +08:00
feat(sync): use incremental session index after pull sync
After pull-sync imports new messages, generate session index incrementally instead of full regeneration. This preserves existing sessions and their summaries, only processing newly imported (unindexed) messages. Adds generateIncremental method across the full stack: - core: already had generateIncrementalSessionIndex - node-runtime: expose generateIncrementalIndex - CLI: add POST /_web/sessions/:id/generate-incremental-index route - Electron: add session:generateIncremental IPC handler - Frontend: add generateIncremental to SessionIndexAdapter interface
This commit is contained in:
1 parent
fcfa5d0167
commit
a5bbff34e4
10 files changed
+59
-6
No files matched your search
@@ -11,6 +11,15 @@ export function registerSessionIndexRoutes(server: FastifyInstance, adapter: Ses
|
|||||||
return { sessionCount }
|
return { sessionCount }
|
||||||
})
|
})
|
||||||
|
|
||||||
|
server.post<{
|
||||||
|
Params: { id: string }
|
||||||
|
Body: { gapThreshold?: number }
|
||||||
|
}>('/_web/sessions/:id/generate-incremental-index', async (request) => {
|
||||||
|
const gapThreshold = (request.body as any)?.gapThreshold ?? 1800
|
||||||
|
const sessionCount = sessionIndexService.generateIncrementalIndex(adapter, request.params.id, gapThreshold)
|
||||||
|
return { sessionCount }
|
||||||
|
})
|
||||||
|
|
||||||
server.post<{ Params: { id: string } }>('/_web/sessions/:id/clear-index', async (request) => {
|
server.post<{ Params: { id: string } }>('/_web/sessions/:id/clear-index', async (request) => {
|
||||||
sessionIndexService.clearIndex(adapter, request.params.id)
|
sessionIndexService.clearIndex(adapter, request.params.id)
|
||||||
return { success: true }
|
return { success: true }
|
||||||
|
|||||||
@@ -803,6 +803,15 @@ export function registerChatHandlers(ctx: IpcContext): void {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ipcMain.handle('session:generateIncremental', async (_, sessionId: string, gapThreshold?: number) => {
|
||||||
|
try {
|
||||||
|
return await worker.generateIncrementalSessions(sessionId, gapThreshold)
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Failed to generate incremental session index:', error)
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否已生成会话索引
|
* 检查是否已生成会话索引
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -240,9 +240,10 @@ export const sessionApi = {
|
|||||||
return ipcRenderer.invoke('session:generate', sessionId, gapThreshold)
|
return ipcRenderer.invoke('session:generate', sessionId, gapThreshold)
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
generateIncremental: (sessionId: string, gapThreshold?: number): Promise<number> => {
|
||||||
* 检查是否已生成会话索引
|
return ipcRenderer.invoke('session:generateIncremental', sessionId, gapThreshold)
|
||||||
*/
|
},
|
||||||
|
|
||||||
hasIndex: (sessionId: string): Promise<boolean> => {
|
hasIndex: (sessionId: string): Promise<boolean> => {
|
||||||
return ipcRenderer.invoke('session:hasIndex', sessionId)
|
return ipcRenderer.invoke('session:hasIndex', sessionId)
|
||||||
},
|
},
|
||||||
|
|||||||
Vendored
+1
@@ -1107,6 +1107,7 @@ interface ChatSessionItem {
|
|||||||
|
|
||||||
interface SessionApi {
|
interface SessionApi {
|
||||||
generate: (sessionId: string, gapThreshold?: number) => Promise<number>
|
generate: (sessionId: string, gapThreshold?: number) => Promise<number>
|
||||||
|
generateIncremental: (sessionId: string, gapThreshold?: number) => Promise<number>
|
||||||
hasIndex: (sessionId: string) => Promise<boolean>
|
hasIndex: (sessionId: string) => Promise<boolean>
|
||||||
getStats: (sessionId: string) => Promise<SessionStats>
|
getStats: (sessionId: string) => Promise<SessionStats>
|
||||||
clear: (sessionId: string) => Promise<boolean>
|
clear: (sessionId: string) => Promise<boolean>
|
||||||
|
|||||||
@@ -24,7 +24,14 @@ export {
|
|||||||
export type { MembersPaginatedDTO } from './member-service'
|
export type { MembersPaginatedDTO } from './member-service'
|
||||||
|
|
||||||
// Session index service
|
// Session index service
|
||||||
export { generateIndex, clearIndex, getFtsStatus, searchFts, rebuildFts } from './session-index-service'
|
export {
|
||||||
|
generateIndex,
|
||||||
|
generateIncrementalIndex,
|
||||||
|
clearIndex,
|
||||||
|
getFtsStatus,
|
||||||
|
searchFts,
|
||||||
|
rebuildFts,
|
||||||
|
} from './session-index-service'
|
||||||
|
|
||||||
// Summary service
|
// Summary service
|
||||||
export { generateSummary, generateAllSummaries } from './summary-service'
|
export { generateSummary, generateAllSummaries } from './summary-service'
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
generateSessionIndex as coreGenerateSessionIndex,
|
generateSessionIndex as coreGenerateSessionIndex,
|
||||||
|
generateIncrementalSessionIndex as coreGenerateIncrementalSessionIndex,
|
||||||
clearSessionIndex as coreClearSessionIndex,
|
clearSessionIndex as coreClearSessionIndex,
|
||||||
} from '@openchatlab/core'
|
} from '@openchatlab/core'
|
||||||
import { hasFtsTable, searchByFts, rebuildFtsIndex } from '../fts'
|
import { hasFtsTable, searchByFts, rebuildFtsIndex } from '../fts'
|
||||||
@@ -16,6 +17,15 @@ export function generateIndex(adapter: SessionRuntimeAdapter, sessionId: string,
|
|||||||
return coreGenerateSessionIndex(db, gapThreshold)
|
return coreGenerateSessionIndex(db, gapThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function generateIncrementalIndex(
|
||||||
|
adapter: SessionRuntimeAdapter,
|
||||||
|
sessionId: string,
|
||||||
|
gapThreshold: number = 1800
|
||||||
|
): number {
|
||||||
|
const db = adapter.ensureWritable(sessionId)
|
||||||
|
return coreGenerateIncrementalSessionIndex(db, gapThreshold)
|
||||||
|
}
|
||||||
|
|
||||||
export function clearIndex(adapter: SessionRuntimeAdapter, sessionId: string): void {
|
export function clearIndex(adapter: SessionRuntimeAdapter, sessionId: string): void {
|
||||||
const db = adapter.ensureWritable(sessionId)
|
const db = adapter.ensureWritable(sessionId)
|
||||||
coreClearSessionIndex(db)
|
coreClearSessionIndex(db)
|
||||||
|
|||||||
@@ -16,6 +16,10 @@ export class ElectronSessionIndexAdapter implements SessionIndexAdapter {
|
|||||||
return window.sessionApi.generate(sessionId, gapThreshold)
|
return window.sessionApi.generate(sessionId, gapThreshold)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
generateIncremental(sessionId: string, gapThreshold?: number): Promise<number> {
|
||||||
|
return window.sessionApi.generateIncremental(sessionId, gapThreshold)
|
||||||
|
}
|
||||||
|
|
||||||
hasIndex(sessionId: string): Promise<boolean> {
|
hasIndex(sessionId: string): Promise<boolean> {
|
||||||
return window.sessionApi.hasIndex(sessionId)
|
return window.sessionApi.hasIndex(sessionId)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,17 @@ export class FetchSessionIndexAdapter implements SessionIndexAdapter {
|
|||||||
return result.sessionCount
|
return result.sessionCount
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async generateIncremental(sessionId: string, gapThreshold: number = 1800): Promise<number> {
|
||||||
|
const resp = await fetch(`/_web/sessions/${sessionId}/generate-incremental-index`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ gapThreshold }),
|
||||||
|
})
|
||||||
|
if (!resp.ok) throw new Error(`Failed to generate incremental session index: ${resp.status}`)
|
||||||
|
const result = (await resp.json()) as { sessionCount: number }
|
||||||
|
return result.sessionCount
|
||||||
|
}
|
||||||
|
|
||||||
async hasIndex(sessionId: string): Promise<boolean> {
|
async hasIndex(sessionId: string): Promise<boolean> {
|
||||||
const stats = await this.getStats(sessionId)
|
const stats = await this.getStats(sessionId)
|
||||||
return stats.hasIndex
|
return stats.hasIndex
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ export interface CanGenerateInfo {
|
|||||||
|
|
||||||
export interface SessionIndexAdapter {
|
export interface SessionIndexAdapter {
|
||||||
generate(sessionId: string, gapThreshold?: number): Promise<number>
|
generate(sessionId: string, gapThreshold?: number): Promise<number>
|
||||||
|
generateIncremental(sessionId: string, gapThreshold?: number): Promise<number>
|
||||||
hasIndex(sessionId: string): Promise<boolean>
|
hasIndex(sessionId: string): Promise<boolean>
|
||||||
getStats(sessionId: string): Promise<SessionStats>
|
getStats(sessionId: string): Promise<SessionStats>
|
||||||
clear(sessionId: string): Promise<boolean>
|
clear(sessionId: string): Promise<boolean>
|
||||||
|
|||||||
@@ -526,7 +526,7 @@ export const useApiServerStore = defineStore('apiServer', () => {
|
|||||||
const indexService = useSessionIndexService()
|
const indexService = useSessionIndexService()
|
||||||
const threshold = getSessionGapThreshold()
|
const threshold = getSessionGapThreshold()
|
||||||
for (const sess of targets) {
|
for (const sess of targets) {
|
||||||
indexService.generate(sess.targetSessionId, threshold).catch(() => {})
|
indexService.generateIncremental(sess.targetSessionId, threshold).catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,7 +536,7 @@ export const useApiServerStore = defineStore('apiServer', () => {
|
|||||||
for (const ds of dataSources.value) {
|
for (const ds of dataSources.value) {
|
||||||
for (const sess of ds.sessions) {
|
for (const sess of ds.sessions) {
|
||||||
if (sess.targetSessionId) {
|
if (sess.targetSessionId) {
|
||||||
indexService.generate(sess.targetSessionId, threshold).catch(() => {})
|
indexService.generateIncremental(sess.targetSessionId, threshold).catch(() => {})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user