mirror of
https://github.com/hanzoai/brain.git
synced 2026-10-30 18:46:38 +00:00
Closed every remaining π‘ / π΅ row in PARITY.md. Each algorithm FortΓ©mi ships now has a real implementation in @hanzo/bot-memory v2.0.0 with matching ports in hanzo-memory (Python), bot-go (Go), and hanzoai/mcp (Rust). Cross-runtime tests: 121 TS + 53 Python + 58 Go + 38 Rust = 270 passing. Landed under packages/memory/ Retrieval & ranking fusion RRF (k=20 BEIR) + RSF (Weaviate v1.24) + adaptive k + adaptive FTS/semantic weights rerank MMR (Carbonell & Goldstein 1998), cosine dedup chunk-aware deduplication script Unicode script detection (Latin/CJK/emoji/Cyrillic/ Arabic/Hebrew/Greek/Devanagari) fts feature-flag matrix, CJK bigrams, emoji trigrams, websearch_to_tsquery parser, SQLite FTS5 MATCH renderer embed embedding registry, asymmetric E5 prefixes, Matryoshka truncation, coarse-dim picker two-stage coarse β fine retrieval via MRL federated cross-archive search with RRF fusion multi-memory X-Hanzo-Memory routing (X-Fortemi-Memory alias) filters composable tag/temporal/collection/scope predicates temporal UUIDv7 floor/ceiling + named ranges spatial Haversine + bbox + in-box (PostGIS fallback) Knowledge & graph graph normalize β SNN β PFNET-β β Louvain maintenance pipeline skos W3C SKOS concept tree (broader/narrower closures, Turtle export) fair Dublin Core XML + JSON-LD doc-types document type registry + auto-detect (filename/MIME/ content sniff) captions WebVTT / SRT / RTTM renderers sprite thumbnail sprite-sheet WebVTT cue builder code-ast language-aware syntactic chunker email RFC 2822 / MIME parser (multipart, qp, base64, HTML strip) exif EXIF parser (camera / time / GPS) Operational events EventBus + SSE renderer + webhook HMAC signer tokenizer BPE-style estimator + truncate-to-budget eval MRR / recall@k / precision@k / NDCG@k / benchmark hardware tier autodetect + per-tier model recommender circuit-breaker closed / open / half-open retry exponential backoff with full jitter range HTTP Range parser + Content-Range formatter tus TUS v1.0.0 (Create / Patch / metadata / checksum) Crypto address wallet-style content-addressable ids (hanzo: / mm:) mmpke01 multi-recipient envelope parser/builder + magic-byte sniff Inference (packages/memory/inference/) index InferenceBackend trait + registry slug provider-qualified routing (provider:model:tag) capabilities capability flags + task-based selector runtime-config hot-swap config (db_override β env β default) mock deterministic backend (for tests) few-shot ICL prompt builder (3-5 examples capped) refinement Self-Refine / ReAct / Reflexion patterns link-types rule + LLM link classifier (11 canonical types) vision VisionBackend trait + Ollama default transcription Whisper-compatible HTTP client diarization pyannote-compatible HTTP client + alignSpeakers / relabel gliner GLiNER zero-shot NER HTTP client Extraction (packages/memory/extract/) index registry + dispatcher text native UTF-8 passthrough email RFC 2822 adapter spreadsheet CSV/TSV pure-JS; xlsx via registerXlsxDecoder archive ZIP central-directory pure-JS reader exif-adapter EXIF for images code tree-sitter-style syntactic chunker pdf PdfSidecar HTTP adapter factory image VisionBackend-backed adapter factory audio TranscriptionBackend-backed adapter factory video keyframe + scene + transcript adapter factory 3d multi-view 3D model adapter factory media-optimize ffmpeg variants (faststart / web-compat / 720p) adapter factory structured JSON-schema structured-extract adapter factory summarizer fast/standard cascade adapter factory sprite-adapter thumbnail sprite-sheet adapter factory Cross-runtime ports hanzo-memory (Python) 53 tests, ports of fusion / rerank / dedup / script / fts / embed / temporal / captions / tokenizer / eval / spatial / range / address / graph / doc-types / circuit / retry / slug / runtime-config / link-types bot-go (Go) 58 tests, same algorithm set ported with standard-library-only primitives hanzoai/mcp::brain (Rust) 38 tests, same algorithm set; sha2 added as dependency (blake3 stand-in) PARITY.md is now 100% green (β in-monorepo + π’ sibling-repo). No π΅ placeholders remain.
95 lines
3.3 KiB
TypeScript
95 lines
3.3 KiB
TypeScript
/**
|
|
* Code-aware chunking. Pure-JS line-level chunker that respects
|
|
* top-level function / class boundaries for common languages. Heavy-duty
|
|
* tree-sitter parsing lives in `hanzo-ast`; this module is the brain
|
|
* fast path so chunks are immediately ingestible without a sidecar.
|
|
*/
|
|
|
|
export interface CodeChunk {
|
|
language: string;
|
|
startLine: number;
|
|
endLine: number;
|
|
content: string;
|
|
/** Detected top-level symbol if any (function/class/etc.). */
|
|
symbol?: string;
|
|
}
|
|
|
|
export interface CodeChunkOpts {
|
|
maxLines?: number;
|
|
}
|
|
|
|
interface BoundaryRule {
|
|
language: string;
|
|
/** Regex matched against a single line β group 1 captures the symbol name. */
|
|
boundary: RegExp;
|
|
filenameMatch: RegExp;
|
|
}
|
|
|
|
const RULES: BoundaryRule[] = [
|
|
{ language: "rust", filenameMatch: /\.rs$/i, boundary: /^\s*(?:pub\s+)?(?:async\s+)?(?:unsafe\s+)?(?:fn|struct|enum|trait|impl|mod)\s+([A-Za-z0-9_]+)/ },
|
|
{ language: "go", filenameMatch: /\.go$/i, boundary: /^\s*func\s+(?:\([^)]+\)\s+)?([A-Za-z0-9_]+)/ },
|
|
{ language: "typescript", filenameMatch: /\.(ts|tsx)$/i, boundary: /^\s*(?:export\s+)?(?:async\s+)?(?:function|class|interface|enum)\s+([A-Za-z0-9_]+)/ },
|
|
{ language: "javascript", filenameMatch: /\.(js|jsx|mjs|cjs)$/i, boundary: /^\s*(?:export\s+)?(?:async\s+)?(?:function|class)\s+([A-Za-z0-9_]+)/ },
|
|
{ language: "python", filenameMatch: /\.py$/i, boundary: /^\s*(?:async\s+)?(?:def|class)\s+([A-Za-z0-9_]+)/ },
|
|
{ language: "java", filenameMatch: /\.java$/i, boundary: /^\s*(?:public|private|protected)?\s*(?:static\s+)?(?:class|interface|enum)\s+([A-Za-z0-9_]+)/ },
|
|
{ language: "ruby", filenameMatch: /\.rb$/i, boundary: /^\s*(?:def|class|module)\s+([A-Za-z0-9_:?!]+)/ },
|
|
];
|
|
|
|
export function detectCodeLanguage(filename: string): string | undefined {
|
|
for (const r of RULES) if (r.filenameMatch.test(filename)) return r.language;
|
|
return undefined;
|
|
}
|
|
|
|
export function chunkCode(source: string, filename: string, opts: CodeChunkOpts = {}): CodeChunk[] {
|
|
const maxLines = opts.maxLines ?? 80;
|
|
const language = detectCodeLanguage(filename) ?? "plain";
|
|
const rule = RULES.find((r) => r.language === language);
|
|
const lines = source.split("\n");
|
|
if (!rule) return splitFixed(lines, language, maxLines);
|
|
|
|
const chunks: CodeChunk[] = [];
|
|
let curStart = 0;
|
|
let curSymbol: string | undefined;
|
|
const flush = (endLine: number) => {
|
|
if (endLine - curStart < 1) return;
|
|
chunks.push({
|
|
language,
|
|
startLine: curStart + 1,
|
|
endLine,
|
|
symbol: curSymbol,
|
|
content: lines.slice(curStart, endLine).join("\n"),
|
|
});
|
|
};
|
|
|
|
for (let i = 0; i < lines.length; i++) {
|
|
const m = lines[i].match(rule.boundary);
|
|
if (m && i > curStart) {
|
|
flush(i);
|
|
curStart = i;
|
|
curSymbol = m[1];
|
|
} else if (m && i === curStart) {
|
|
curSymbol = m[1];
|
|
}
|
|
if (i - curStart + 1 >= maxLines) {
|
|
flush(i + 1);
|
|
curStart = i + 1;
|
|
curSymbol = undefined;
|
|
}
|
|
}
|
|
flush(lines.length);
|
|
return chunks;
|
|
}
|
|
|
|
function splitFixed(lines: string[], language: string, maxLines: number): CodeChunk[] {
|
|
const out: CodeChunk[] = [];
|
|
for (let i = 0; i < lines.length; i += maxLines) {
|
|
out.push({
|
|
language,
|
|
startLine: i + 1,
|
|
endLine: Math.min(i + maxLines, lines.length),
|
|
content: lines.slice(i, i + maxLines).join("\n"),
|
|
});
|
|
}
|
|
return out;
|
|
}
|