MCPcopy Create free account
hub / github.com/ChatLab/ChatLab / runWarmup

Function runWarmup

packages/node-runtime/src/semantic-index/warmup/runner.ts:60–186  ·  view source on GitHub ↗
(options: WarmupRunnerOptions)

Source from the content-addressed store, hash-verified

58}
59
60export async function runWarmup(options: WarmupRunnerOptions): Promise<WarmupResult> {
61 const { dbPathHash, modelId, embedder, store, stateStore, source, config, checkStop } = options
62
63 let chunksWritten = 0
64 try {
65 const messages = source.readAllMessages()
66 const total = source.countMessages()
67 const savedState = stateStore.getState(dbPathHash)
68 stateStore.updateProgress(dbPathHash, { indexStatus: 'running', totalMessages: total, error: null })
69
70 // 消息 id -> 流位置,用于进度计数(消息按 ts 排序,id 未必单调)
71 const streamIndexById = new Map<number, number>()
72 messages.forEach((m, i) => streamIndexById.set(m.id, i))
73
74 const resumeMessageId = savedState?.lastIndexedMessageId ?? null
75 const rawResumeIndex = resumeMessageId !== null ? (streamIndexById.get(resumeMessageId) ?? -1) : -1
76
77 // Detect non-append-only additions: if the cursor's new stream position doesn't match the
78 // saved indexed count, older messages were backfilled before the cursor. Clear vectors and
79 // re-index from scratch to avoid silently missing the backfilled messages.
80 const isNonAppendOnly = rawResumeIndex >= 0 && rawResumeIndex + 1 !== (savedState?.indexedMessages ?? 0)
81 if (isNonAppendOnly) {
82 store.deleteByDbPathHash(dbPathHash)
83 }
84 const { chunks, chunkerConfigHash } = chunkMessages({ messages, source: source.getSource(), config })
85
86 const chunkRanges = chunks.map((chunk) => ({
87 chunk,
88 startIndex: streamIndexById.get(chunk.startMessageId) ?? -1,
89 endIndex: streamIndexById.get(chunk.endMessageId) ?? -1,
90 }))
91
92 let resumeIndex = isNonAppendOnly ? -1 : rawResumeIndex
93 const hasAppendedMessages = !isNonAppendOnly && rawResumeIndex >= 0 && total > (savedState?.totalMessages ?? 0)
94 if (hasAppendedMessages) {
95 const cursorRange =
96 chunkRanges.find((range) => range.startIndex <= rawResumeIndex && rawResumeIndex <= range.endIndex) ??
97 chunkRanges.filter((range) => range.endIndex <= rawResumeIndex).sort((a, b) => b.endIndex - a.endIndex)[0]
98
99 if (cursorRange) {
100 const parentRanges = chunkRanges.filter((range) => range.chunk.parentId === cursorRange.chunk.parentId)
101 const rewindIndex = Math.min(...parentRanges.map((range) => range.startIndex).filter((index) => index >= 0))
102 const rewindMessage = messages[rewindIndex]
103 if (rewindMessage) {
104 store.deleteByModelFromPosition({
105 dbPathHash,
106 modelId,
107 startTs: rewindMessage.ts,
108 startMessageId: rewindMessage.id,
109 })
110 resumeIndex = rewindIndex - 1
111 }
112 }
113 }
114
115 // 续跑时统计已写入 chunk 数,保证 chunkCount 连续
116 let storedChunkCount = store.countChunks(dbPathHash, modelId)
117 if (resumeIndex < 0) storedChunkCount = 0

Callers 2

runJobMethod · 0.90
runner.test.tsFile · 0.90

Calls 15

chunkMessagesFunction · 0.90
composeChunkIdFunction · 0.90
resolveDocumentBatchSizeFunction · 0.85
readAllMessagesMethod · 0.80
countMessagesMethod · 0.80
getStateMethod · 0.80
updateProgressMethod · 0.80
setMethod · 0.80
deleteByDbPathHashMethod · 0.80
getSourceMethod · 0.80
countChunksMethod · 0.80

Tested by

no test coverage detected