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.
129 lines
3.7 KiB
TypeScript
129 lines
3.7 KiB
TypeScript
/**
|
|
* Capability flags + task-based model selection.
|
|
*
|
|
* Different brain operations have different requirements. The selector
|
|
* picks the best provider+model for a given task from registered
|
|
* profiles.
|
|
*/
|
|
import { parseSlug } from "./slug.js";
|
|
|
|
export type Capability =
|
|
| "embedding"
|
|
| "generation"
|
|
| "vision"
|
|
| "transcription"
|
|
| "diarization"
|
|
| "structured"
|
|
| "thinking"
|
|
| "fast"
|
|
| "long-context";
|
|
|
|
export type Task =
|
|
| "title-generation"
|
|
| "content-revision"
|
|
| "summarization"
|
|
| "embedding"
|
|
| "link-typing"
|
|
| "chat"
|
|
| "structured-extract"
|
|
| "vision-description"
|
|
| "transcription"
|
|
| "diarization";
|
|
|
|
export interface ModelProfile {
|
|
slug: string; // provider-qualified
|
|
capabilities: Set<Capability>;
|
|
/** Higher = stronger for general tasks. */
|
|
generalScore?: number;
|
|
/** Tokens per second β informational. */
|
|
tps?: number;
|
|
/** Max context tokens. */
|
|
contextTokens?: number;
|
|
}
|
|
|
|
const PROFILES = new Map<string, ModelProfile>();
|
|
|
|
export function registerProfile(p: ModelProfile): void {
|
|
PROFILES.set(p.slug, p);
|
|
}
|
|
|
|
export function getProfile(slug: string): ModelProfile | undefined {
|
|
return PROFILES.get(slug);
|
|
}
|
|
|
|
// ββ Bootstrap profiles for common models ββββββββββββββββββββββββββββββ
|
|
|
|
registerProfile({
|
|
slug: "ollama:qwen3.5:9b",
|
|
capabilities: new Set(["generation", "vision", "thinking", "structured"]),
|
|
generalScore: 8,
|
|
contextTokens: 32_768,
|
|
});
|
|
registerProfile({
|
|
slug: "ollama:qwen3.5:7b",
|
|
capabilities: new Set(["generation", "fast", "structured"]),
|
|
generalScore: 7,
|
|
contextTokens: 32_768,
|
|
});
|
|
registerProfile({
|
|
slug: "ollama:qwen3.5:27b",
|
|
capabilities: new Set(["generation", "vision", "thinking", "structured", "long-context"]),
|
|
generalScore: 9,
|
|
contextTokens: 65_536,
|
|
});
|
|
registerProfile({
|
|
slug: "ollama:nomic-embed-text",
|
|
capabilities: new Set(["embedding"]),
|
|
});
|
|
registerProfile({
|
|
slug: "openai:gpt-4o",
|
|
capabilities: new Set(["generation", "vision", "structured", "long-context"]),
|
|
generalScore: 9,
|
|
contextTokens: 128_000,
|
|
});
|
|
registerProfile({
|
|
slug: "openai:text-embedding-3-small",
|
|
capabilities: new Set(["embedding"]),
|
|
});
|
|
registerProfile({
|
|
slug: "openai:text-embedding-3-large",
|
|
capabilities: new Set(["embedding"]),
|
|
});
|
|
|
|
// ββ Task β required capability set ββββββββββββββββββββββββββββββββββββ
|
|
|
|
const TASK_REQUIREMENTS: Record<Task, Capability[]> = {
|
|
"title-generation": ["generation", "fast"],
|
|
"content-revision": ["generation"],
|
|
"summarization": ["generation"],
|
|
"embedding": ["embedding"],
|
|
"link-typing": ["generation", "structured"],
|
|
"chat": ["generation"],
|
|
"structured-extract": ["generation", "structured"],
|
|
"vision-description": ["vision"],
|
|
"transcription": ["transcription"],
|
|
"diarization": ["diarization"],
|
|
};
|
|
|
|
export interface SelectOpts {
|
|
/** Prefer cheap / fast models even at quality cost. */
|
|
preferFast?: boolean;
|
|
/** Force this provider (e.g. when offline). */
|
|
pinProvider?: string;
|
|
}
|
|
|
|
/** Pick the best registered profile for a task. */
|
|
export function selectModel(task: Task, opts: SelectOpts = {}): ModelProfile | undefined {
|
|
const need = TASK_REQUIREMENTS[task];
|
|
let best: ModelProfile | undefined;
|
|
let bestScore = -Infinity;
|
|
for (const p of PROFILES.values()) {
|
|
if (opts.pinProvider && parseSlug(p.slug).provider !== opts.pinProvider) continue;
|
|
if (!need.every((c) => p.capabilities.has(c))) continue;
|
|
let score = p.generalScore ?? 5;
|
|
if (opts.preferFast && p.capabilities.has("fast")) score += 3;
|
|
if (score > bestScore) { bestScore = score; best = p; }
|
|
}
|
|
return best;
|
|
}
|