(input: ChunkMessagesInput)
| 291 | } |
| 292 | |
| 293 | export function chunkMessages(input: ChunkMessagesInput): ChunkResult { |
| 294 | const config = input.config ?? DEFAULT_CHUNKER_CONFIG |
| 295 | const chunkerConfigHash = computeChunkerConfigHash(config) |
| 296 | |
| 297 | const parents = segmentParents(input.messages, config) |
| 298 | const chunks: ChildChunk[] = [] |
| 299 | let skippedCount = 0 |
| 300 | |
| 301 | for (const parent of parents) { |
| 302 | const parentId = deriveParentId({ |
| 303 | startMessageId: parent[0].id, |
| 304 | endMessageId: parent[parent.length - 1].id, |
| 305 | gapSeconds: config.parentGapSeconds, |
| 306 | chunkerVersion: CHUNKER_VERSION, |
| 307 | chunkerConfigHash, |
| 308 | }) |
| 309 | |
| 310 | for (const draft of buildChildDrafts(parent, config)) { |
| 311 | const effectiveChars = sumEffectiveChars(draft) |
| 312 | if (effectiveChars < config.semanticVoidSkipThreshold) { |
| 313 | skippedCount++ |
| 314 | continue |
| 315 | } |
| 316 | const startMessageId = draft[0].id |
| 317 | const endMessageId = draft[draft.length - 1].id |
| 318 | const embeddingInput = buildEmbeddingInput(input.source, draft) |
| 319 | chunks.push({ |
| 320 | localChunkId: `${parentId}#${startMessageId}-${endMessageId}`, |
| 321 | parentId, |
| 322 | startMessageId, |
| 323 | endMessageId, |
| 324 | startTs: draft[0].ts, |
| 325 | endTs: draft[draft.length - 1].ts, |
| 326 | messageCount: draft.length, |
| 327 | effectiveChars, |
| 328 | rawContentHash: rawContentHashOf(draft), |
| 329 | embeddingInputHash: sha256Hex(embeddingInput), |
| 330 | embeddingInput, |
| 331 | }) |
| 332 | } |
| 333 | } |
| 334 | |
| 335 | return { chunkerVersion: CHUNKER_VERSION, chunkerConfigHash, chunks, skippedCount, parentCount: parents.length } |
| 336 | } |
no test coverage detected