Skip to content

Commit 3bfb664

Browse files
committed
Added automatic embedding with pluggable providers and document ingestion functionality
1 parent fe3a1a0 commit 3bfb664

10 files changed

Lines changed: 829 additions & 57 deletions

File tree

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
11
from .client import Mnemos, Namespace
22
from ._mnemos import Hit, Memory, Stats, MnemosError
3+
from .embedder import Embedder, HashEmbedder
4+
from .chunker import chunk_text
35

4-
__all__ = ["Mnemos", "Namespace", "Hit", "Memory", "Stats", "MnemosError"]
6+
__all__ = [
7+
"Mnemos", "Namespace",
8+
"Hit", "Memory", "Stats", "MnemosError",
9+
"Embedder", "HashEmbedder",
10+
"chunk_text",
11+
]

crates/mnemos-py/mnemos/chunker.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
"""
2+
mnemos.chunker — deterministic fixed-window text splitter.
3+
4+
No external dependencies. Splits on character boundaries with word-boundary snapping
5+
so that chunks never cut mid-word.
6+
"""
7+
8+
from __future__ import annotations
9+
from typing import List
10+
11+
12+
def chunk_text(
13+
text: str,
14+
chunk_size: int = 512,
15+
overlap: int = 50,
16+
) -> List[str]:
17+
"""
18+
Split *text* into overlapping fixed-size windows.
19+
20+
The splitter works on characters (model-agnostic). It snaps to the nearest
21+
whitespace so chunks never split a word in two.
22+
23+
Args:
24+
text: The input text to chunk.
25+
chunk_size: Target size of each chunk in characters (default 512).
26+
overlap: Number of characters shared between consecutive chunks
27+
(default 50). Must be < chunk_size.
28+
29+
Returns:
30+
A list of non-empty string chunks.
31+
32+
Raises:
33+
ValueError: If chunk_size <= 0 or overlap >= chunk_size.
34+
"""
35+
if chunk_size <= 0:
36+
raise ValueError(f"chunk_size must be > 0, got {chunk_size}")
37+
if overlap < 0:
38+
raise ValueError(f"overlap must be >= 0, got {overlap}")
39+
if overlap >= chunk_size:
40+
raise ValueError(
41+
f"overlap ({overlap}) must be < chunk_size ({chunk_size})"
42+
)
43+
44+
text = text.strip()
45+
if not text:
46+
return []
47+
48+
chunks: List[str] = []
49+
start = 0
50+
step = chunk_size - overlap
51+
52+
while start < len(text):
53+
end = start + chunk_size
54+
55+
if end < len(text):
56+
# Snap backwards to the nearest whitespace to avoid mid-word cuts.
57+
snap = text.rfind(" ", start, end)
58+
if snap > start:
59+
end = snap
60+
61+
chunk = text[start:end].strip()
62+
if chunk:
63+
chunks.append(chunk)
64+
65+
start += step
66+
67+
return chunks

0 commit comments

Comments
 (0)