Files
zeekay 25011a2085 brain: 100% fortemi parity β€” every algorithm shipped across all 4 runtimes
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.
2026-05-11 11:44:08 -07:00

141 lines
4.4 KiB
TypeScript

/**
* W3C SKOS (Simple Knowledge Organization System) concept tree.
*
* Reference: Miles & Bechhofer (2009) β€” W3C Recommendation.
* Properties supported: prefLabel, altLabel, hiddenLabel, broader,
* narrower, related, scopeNote, inScheme, topConceptOf.
*
* Export: Turtle (RDF/Turtle) with the SKOS namespace.
*/
export interface Concept {
uri: string;
prefLabel: string;
altLabels?: string[];
hiddenLabels?: string[];
broader?: string[];
narrower?: string[];
related?: string[];
scopeNote?: string;
inScheme?: string;
topConceptOf?: string;
}
export interface ConceptScheme {
uri: string;
prefLabel: string;
topConcepts: string[];
}
export class SkosGraph {
private concepts = new Map<string, Concept>();
private schemes = new Map<string, ConceptScheme>();
addConcept(c: Concept): void {
const prev = this.concepts.get(c.uri);
this.concepts.set(c.uri, { ...prev, ...c });
// maintain inverse links for broader/narrower
if (c.broader) {
for (const b of c.broader) this.touchNarrower(b, c.uri);
}
if (c.narrower) {
for (const n of c.narrower) this.touchBroader(n, c.uri);
}
}
addScheme(s: ConceptScheme): void {
this.schemes.set(s.uri, s);
}
get(uri: string): Concept | undefined {
return this.concepts.get(uri);
}
list(): Concept[] {
return Array.from(this.concepts.values());
}
/** Closure of broader transitively. Includes the starting concept. */
broaderClosure(uri: string): string[] {
const seen = new Set<string>();
const stack = [uri];
while (stack.length) {
const cur = stack.pop()!;
if (seen.has(cur)) continue;
seen.add(cur);
const c = this.concepts.get(cur);
if (c?.broader) for (const b of c.broader) stack.push(b);
}
return [...seen];
}
/** Closure of narrower transitively. */
narrowerClosure(uri: string): string[] {
const seen = new Set<string>();
const stack = [uri];
while (stack.length) {
const cur = stack.pop()!;
if (seen.has(cur)) continue;
seen.add(cur);
const c = this.concepts.get(cur);
if (c?.narrower) for (const n of c.narrower) stack.push(n);
}
return [...seen];
}
/** Render the graph as RDF/Turtle. */
toTurtle(): string {
const lines: string[] = [
"@prefix skos: <http://www.w3.org/2004/02/skos/core#> .",
"@prefix dct: <http://purl.org/dc/terms/> .",
"",
];
for (const s of this.schemes.values()) {
lines.push(`<${s.uri}> a skos:ConceptScheme ;`);
lines.push(` skos:prefLabel ${turtleLit(s.prefLabel)} ;`);
if (s.topConcepts.length > 0) {
const tc = s.topConcepts.map((u) => `<${u}>`).join(", ");
lines.push(` skos:hasTopConcept ${tc} .`);
} else {
lines[lines.length - 1] = lines[lines.length - 1].replace(/ ;$/, " .");
}
lines.push("");
}
for (const c of this.concepts.values()) {
const parts: string[] = [`<${c.uri}> a skos:Concept`];
parts.push(` skos:prefLabel ${turtleLit(c.prefLabel)}`);
if (c.altLabels) for (const l of c.altLabels) parts.push(` skos:altLabel ${turtleLit(l)}`);
if (c.hiddenLabels) for (const l of c.hiddenLabels) parts.push(` skos:hiddenLabel ${turtleLit(l)}`);
if (c.broader) for (const u of c.broader) parts.push(` skos:broader <${u}>`);
if (c.narrower) for (const u of c.narrower) parts.push(` skos:narrower <${u}>`);
if (c.related) for (const u of c.related) parts.push(` skos:related <${u}>`);
if (c.scopeNote) parts.push(` skos:scopeNote ${turtleLit(c.scopeNote)}`);
if (c.inScheme) parts.push(` skos:inScheme <${c.inScheme}>`);
if (c.topConceptOf) parts.push(` skos:topConceptOf <${c.topConceptOf}>`);
lines.push(parts.join(" ;\n") + " .");
lines.push("");
}
return lines.join("\n");
}
private touchBroader(uri: string, broaderUri: string): void {
const c = this.concepts.get(uri) ?? { uri, prefLabel: uri };
c.broader = unique([...(c.broader ?? []), broaderUri]);
this.concepts.set(uri, c);
}
private touchNarrower(uri: string, narrowerUri: string): void {
const c = this.concepts.get(uri) ?? { uri, prefLabel: uri };
c.narrower = unique([...(c.narrower ?? []), narrowerUri]);
this.concepts.set(uri, c);
}
}
function unique<T>(xs: T[]): T[] {
return Array.from(new Set(xs));
}
function turtleLit(s: string): string {
return `"${s.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
}