mirror of
https://github.com/zooai/brain.git
synced 2026-10-30 14:50:48 +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.
116 lines
3.4 KiB
TypeScript
116 lines
3.4 KiB
TypeScript
/**
|
|
* Extraction registry β strategy dispatcher.
|
|
*
|
|
* Each adapter takes a `(filename, mime, bytes)` triple and produces an
|
|
* `ExtractionResult` (canonical text + structured metadata + derived
|
|
* children attachments). Heavy adapters (vision / audio / video / 3D)
|
|
* delegate to sidecars defined under `../inference/`.
|
|
*/
|
|
|
|
export type Strategy =
|
|
| "text"
|
|
| "email"
|
|
| "spreadsheet"
|
|
| "archive"
|
|
| "pdf"
|
|
| "image"
|
|
| "audio"
|
|
| "video"
|
|
| "3d"
|
|
| "media-optimize"
|
|
| "structured"
|
|
| "summarizer"
|
|
| "exif"
|
|
| "code"
|
|
| "sprite";
|
|
|
|
export interface ExtractionInput {
|
|
filename: string;
|
|
mimeType?: string;
|
|
bytes: Uint8Array;
|
|
/** Hints from the doc-type detector. */
|
|
strategy?: Strategy;
|
|
}
|
|
|
|
export interface ExtractionResult {
|
|
text: string;
|
|
metadata?: Record<string, unknown>;
|
|
/** Derived child attachments β thumbnails, transcripts, captions. */
|
|
derived?: Array<{
|
|
filename: string;
|
|
mimeType: string;
|
|
bytes: Uint8Array;
|
|
role: string;
|
|
}>;
|
|
}
|
|
|
|
export interface ExtractionAdapter {
|
|
strategy: Strategy;
|
|
extract(input: ExtractionInput): Promise<ExtractionResult>;
|
|
}
|
|
|
|
const ADAPTERS = new Map<Strategy, ExtractionAdapter>();
|
|
|
|
export function registerAdapter(a: ExtractionAdapter): void {
|
|
ADAPTERS.set(a.strategy, a);
|
|
}
|
|
|
|
export function getAdapter(s: Strategy): ExtractionAdapter | undefined {
|
|
return ADAPTERS.get(s);
|
|
}
|
|
|
|
export function listAdapters(): Strategy[] {
|
|
return Array.from(ADAPTERS.keys());
|
|
}
|
|
|
|
export async function extract(input: ExtractionInput): Promise<ExtractionResult> {
|
|
const strat = input.strategy ?? pickStrategy(input);
|
|
const a = ADAPTERS.get(strat);
|
|
if (!a) {
|
|
// Fallback to text adapter.
|
|
const text = ADAPTERS.get("text");
|
|
if (text) return text.extract(input);
|
|
return { text: "" };
|
|
}
|
|
return a.extract(input);
|
|
}
|
|
|
|
function pickStrategy(input: ExtractionInput): Strategy {
|
|
const mt = input.mimeType?.toLowerCase() ?? "";
|
|
if (mt.startsWith("image/")) return "image";
|
|
if (mt.startsWith("audio/")) return "audio";
|
|
if (mt.startsWith("video/")) return "video";
|
|
if (mt === "message/rfc822") return "email";
|
|
if (mt === "application/pdf") return "pdf";
|
|
if (mt === "application/zip" || mt === "application/x-tar" || mt === "application/gzip") return "archive";
|
|
if (mt.includes("spreadsheet") || mt === "text/csv" || mt === "text/tab-separated-values") return "spreadsheet";
|
|
return "text";
|
|
}
|
|
|
|
// ββ Built-in adapter registrations ββββββββββββββββββββββββββββββββββββ
|
|
import { textAdapter } from "./text.js";
|
|
import { emailAdapter } from "./email.js";
|
|
import { spreadsheetAdapter } from "./spreadsheet.js";
|
|
import { archiveAdapter } from "./archive.js";
|
|
import { exifAdapter } from "./exif-adapter.js";
|
|
import { codeAdapter } from "./code.js";
|
|
|
|
registerAdapter(textAdapter);
|
|
registerAdapter(emailAdapter);
|
|
registerAdapter(spreadsheetAdapter);
|
|
registerAdapter(archiveAdapter);
|
|
registerAdapter(exifAdapter);
|
|
registerAdapter(codeAdapter);
|
|
|
|
// Heavy adapters that need sidecars β call site registers them once a
|
|
// VisionBackend / TranscriptionBackend / etc. is available.
|
|
export * from "./pdf.js";
|
|
export * from "./image.js";
|
|
export * from "./audio.js";
|
|
export * from "./video.js";
|
|
export * from "./3d.js";
|
|
export * from "./media-optimize.js";
|
|
export * from "./structured.js";
|
|
export * from "./summarizer.js";
|
|
export * from "./sprite-adapter.js";
|