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.
97 lines
3.6 KiB
TypeScript
97 lines
3.6 KiB
TypeScript
/**
|
|
* Wallet-style content-addressable identifiers.
|
|
*
|
|
* hanzo:<version-byte><blake3-20><checksum-4> base58 encoded
|
|
*
|
|
* Matches Fortémi's `mm:` format exactly, only the prefix differs. Bridges
|
|
* both directions so MMPKE01 files keyed to a fortemi `mm:` address can
|
|
* be read by Hanzo and vice versa.
|
|
*/
|
|
import { blake3 } from "@noble/hashes/blake3.js";
|
|
|
|
const VERSION_V1 = 0x01;
|
|
const BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
|
|
export interface AddressOpts {
|
|
prefix?: "hanzo" | "mm";
|
|
}
|
|
|
|
/** Encode a 32-byte public key as a wallet-style address. */
|
|
export function encodeAddress(publicKey: Uint8Array, opts: AddressOpts = {}): string {
|
|
if (publicKey.length !== 32) throw new Error("public key must be 32 bytes");
|
|
const prefix = opts.prefix ?? "hanzo";
|
|
const hash = blake3(publicKey).subarray(0, 20);
|
|
const versioned = new Uint8Array(1 + hash.length);
|
|
versioned[0] = VERSION_V1;
|
|
versioned.set(hash, 1);
|
|
const checksum = blake3(versioned).subarray(0, 4);
|
|
const payload = new Uint8Array(versioned.length + checksum.length);
|
|
payload.set(versioned, 0);
|
|
payload.set(checksum, versioned.length);
|
|
return `${prefix}:${base58Encode(payload)}`;
|
|
}
|
|
|
|
/** Parse a wallet-style address. Throws on malformed input. */
|
|
export function decodeAddress(address: string): { prefix: string; version: number; hash: Uint8Array } {
|
|
const colon = address.indexOf(":");
|
|
if (colon === -1) throw new Error("address: missing prefix");
|
|
const prefix = address.slice(0, colon);
|
|
const decoded = base58Decode(address.slice(colon + 1));
|
|
if (decoded.length !== 25) throw new Error("address: wrong length");
|
|
const version = decoded[0];
|
|
const hash = decoded.subarray(1, 21);
|
|
const checksum = decoded.subarray(21, 25);
|
|
const versioned = decoded.subarray(0, 21);
|
|
const expected = blake3(versioned).subarray(0, 4);
|
|
if (!bytesEqual(checksum, expected)) throw new Error("address: bad checksum");
|
|
return { prefix, version, hash: new Uint8Array(hash) };
|
|
}
|
|
|
|
function bytesEqual(a: Uint8Array, b: Uint8Array): boolean {
|
|
if (a.length !== b.length) return false;
|
|
for (let i = 0; i < a.length; i++) if (a[i] !== b[i]) return false;
|
|
return true;
|
|
}
|
|
|
|
function base58Encode(bytes: Uint8Array): string {
|
|
if (bytes.length === 0) return "";
|
|
let zeros = 0;
|
|
while (zeros < bytes.length && bytes[zeros] === 0) zeros++;
|
|
const digits: number[] = [0];
|
|
for (let i = zeros; i < bytes.length; i++) {
|
|
let carry = bytes[i];
|
|
for (let j = 0; j < digits.length; j++) {
|
|
carry += digits[j] << 8;
|
|
digits[j] = carry % 58;
|
|
carry = (carry / 58) | 0;
|
|
}
|
|
while (carry) { digits.push(carry % 58); carry = (carry / 58) | 0; }
|
|
}
|
|
let out = "";
|
|
for (let i = 0; i < zeros; i++) out += BASE58_ALPHABET[0];
|
|
for (let i = digits.length - 1; i >= 0; i--) out += BASE58_ALPHABET[digits[i]];
|
|
return out;
|
|
}
|
|
|
|
function base58Decode(s: string): Uint8Array {
|
|
if (s.length === 0) return new Uint8Array(0);
|
|
let zeros = 0;
|
|
while (zeros < s.length && s[zeros] === BASE58_ALPHABET[0]) zeros++;
|
|
const bytes: number[] = [0];
|
|
for (let i = zeros; i < s.length; i++) {
|
|
const v = BASE58_ALPHABET.indexOf(s[i]);
|
|
if (v < 0) throw new Error(`base58: invalid char ${s[i]}`);
|
|
let carry = v;
|
|
for (let j = 0; j < bytes.length; j++) {
|
|
carry += bytes[j] * 58;
|
|
bytes[j] = carry & 0xff;
|
|
carry >>= 8;
|
|
}
|
|
while (carry) { bytes.push(carry & 0xff); carry >>= 8; }
|
|
}
|
|
const out = new Uint8Array(zeros + bytes.length);
|
|
for (let i = 0; i < zeros; i++) out[i] = 0;
|
|
for (let i = 0; i < bytes.length; i++) out[zeros + i] = bytes[bytes.length - 1 - i];
|
|
return out;
|
|
}
|