This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

strip prefixes from FTS

+62 -2
+62 -2
src/memory.ts
··· 117 117 eventQuery: boolean 118 118 } 119 119 120 + type MemoryHitSignal = { 121 + overlap: number 122 + strongOverlap: boolean 123 + } 124 + 120 125 function normalizeText(value: string): string { 121 126 return value.replace(/\r\n/g, "\n").replace(/\s+/g, " ").trim() 122 127 } ··· 295 300 } 296 301 297 302 function normalizeSearchInput(raw: string): string { 298 - return raw 299 - .replace(/^\[(wake|incoming|harness restarted)[^\n]*\]\s*/gi, "") 303 + const withoutWakeEnvelope = raw.replace(/^\[(wake|incoming|harness restarted)[^\n]*\]\s*/gi, "").trim() 304 + 305 + const blocks = withoutWakeEnvelope 306 + .split(/\n\s*\n/g) 307 + .map((block) => block.trim()) 308 + .filter(Boolean) 309 + 310 + const bodyCandidate = blocks.length > 0 ? blocks[blocks.length - 1]! : withoutWakeEnvelope 311 + 312 + return bodyCandidate 313 + .replace(/^\[discord\/[^\]]+\]\s*@\S+\s+in\s+\d+(?:\s+\(\d+\))?\s*/gi, "") 314 + .replace(/^\[[^\]]+\]\s*/g, "") 315 + .replace(/@[a-z0-9_.-]+/gi, " ") 316 + .replace(/\b\d{6,}\b/g, " ") 300 317 .replace(/[^\p{L}\p{N}\s'-]+/gu, " ") 301 318 .toLowerCase() 319 + .trim() 302 320 } 303 321 304 322 function searchTokens(raw: string): string[] { ··· 472 490 return score 473 491 } 474 492 493 + function hitSearchHaystack(hit: MemoryHit): string { 494 + return `${hit.documentTitle} ${hit.title} ${hit.headingPath ?? ""} ${basenameWithoutExt(hit.path)} ${hit.text}`.toLowerCase() 495 + } 496 + 497 + function memoryHitSignal(hit: MemoryHit, profile: MemorySearchProfile): MemoryHitSignal { 498 + const haystack = hitSearchHaystack(hit) 499 + let overlap = 0 500 + let strongOverlap = false 501 + 502 + for (const token of profile.tokens) { 503 + if (!haystack.includes(token)) continue 504 + overlap += 1 505 + if (token.length >= 5 || /[0-9]/.test(token)) strongOverlap = true 506 + } 507 + 508 + return { overlap, strongOverlap } 509 + } 510 + 511 + function shouldInjectHits(hits: MemoryHit[], profile: MemorySearchProfile): boolean { 512 + if (hits.length === 0) return false 513 + 514 + const topSignal = memoryHitSignal(hits[0]!, profile) 515 + 516 + if (profile.personQuery && !profile.eventQuery) { 517 + return topSignal.overlap >= 1 && hits.some((hit) => hit.kind === "people" || hit.kind === "core") 518 + } 519 + 520 + if (profile.eventQuery && !profile.personQuery) { 521 + return topSignal.overlap >= 1 && hits.some((hit) => hit.kind === "journal") 522 + } 523 + 524 + if (topSignal.overlap >= 2) return true 525 + if (topSignal.overlap >= 1 && topSignal.strongOverlap) return true 526 + return false 527 + } 528 + 475 529 function searchMemory( 476 530 profile: MemorySearchProfile, 477 531 cooldowns: Record<number, number>, ··· 581 635 582 636 const hits = searchMemory(profile, cooldowns, currentTurn, MEMORY_RECALL_MAX_CHUNKS) 583 637 if (hits.length === 0) return { messages: conversation, recalledChunkIds: [] } 638 + if (!shouldInjectHits(hits, profile)) { 639 + console.log( 640 + `[memory] skipped query=${JSON.stringify(trimForPrompt(normalizeText(latestUser), 120))} personQuery=${profile.personQuery} eventQuery=${profile.eventQuery} reason=weak-match`, 641 + ) 642 + return { messages: conversation, recalledChunkIds: [] } 643 + } 584 644 585 645 const recallContent = buildMemoryRecallMessage(hits) 586 646 console.log(