Source, budget and execution contracts
These contracts describe the implementation prepared for the 2.0 transition and 2.1 code-quality release. They do not announce a published package. See the migration guide before replacing an existing index.
Configuration and size
Chunker validates constructor options and per-call overrides. Unknown names,
internal _precomputed_* arguments and invalid combinations raise errors.
ChunkOptions is frozen; create another configuration instead of mutating it.
| Option | Default | Meaning |
|---|---|---|
max_chunk_size |
1500 |
Limit measured against the final rendered payload. |
min_chunk_size |
50 |
Packing preference, not a guaranteed lower bound. |
size_unit |
"chars" |
Unicode characters; alternatively "nws" or "tokens". |
tokenizer |
None |
Required for token sizing; named tokenizer or counting callable. |
coverage_policy |
"retrieval" |
Omit whitespace-only output; "lossless" retains all source bytes. |
overflow_policy |
"split" |
Split oversized spans; alternatives are "error" and "preserve". |
context_overflow |
"omit" |
If added context cannot fit, emit raw text and retain structured metadata; "error" rejects it. |
context_mode |
"full" |
Render structural context; alternatives are "minimal" and "none". |
algorithm_version |
"2.1" |
Recorded behavior version; no other algorithm version is currently implemented. |
When only a smaller max_chunk_size is supplied, Chunker reduces its default
minimum to fit. An explicitly supplied minimum greater than the maximum is invalid.
preserve_decorators, preserve_comments and include_header_in_sections retain
their True compatibility values; setting them to False raises an error.
The unused semantic_threshold_k and semantic_window_size options were removed.
from omnichunk import Chunker
chunker = Chunker(max_chunk_size=80, context_mode="none")
chunks = chunker.chunk("example.txt", "Merhaba dünya. " * 20)
assert all(len(chunk.contextualized_text) <= 80 for chunk in chunks)
assert all(chunk.metadata["budget"]["overflow"] == 0 for chunk in chunks)
For model tokens, install the matching tokenizer extra and pass its name, for
example Chunker(size_unit="tokens", tokenizer="cl100k_base"). A custom callable
must return a nonnegative integer count for the supplied string. Exactness then
depends on that callable matching the tokenizer used downstream. Unknown named
tokenizers raise errors; they do not silently become word counters.
tokenizer="approximate" explicitly opts into estimates. With character/NWS
sizing and no tokenizer, token_count is also an estimate, not a model guarantee.
Every finalized chunk has metadata["budget"] with unit, limit, rendered
size, raw_size, overflow, policy, token_accuracy and
rendered_token_count. metadata["context_omitted"] records omitted rendered
context. context_overflow="omit" does not erase Chunk.context.
overflow_policy="preserve" explicitly permits oversized payloads and reports
the excess plus metadata["overflow_reason"]. Strict splitting prefers fitting
declarations and lexical boundaries but can divide an oversized definition;
intersecting entity metadata is marked is_partial. A unit that cannot fit even
as one Unicode character raises ChunkingError in strict mode.
Source coordinates and coverage
Chunk.textis an exact slice of its declared canonical source.byte_rangeis a zero-based, half-open UTF-8 interval:[start, end).line_rangeis zero-based and inclusive; a trailing newline belongs to its preceding line. Entity and scope coordinates use the same canonical source.contextualized_textis derived text and has no source-slice guarantee.SourceDescriptorrecordssource_id, canonical-text SHA-256revision,encoding,normalization,format_nameand loader metadata.
For ordinary strings, source_id defaults to the filepath label. Supply a stable
logical ID when filename changes should not change identity. File APIs decode the
file before chunking; binary container bytes are not the canonical text.
from omnichunk import Chunker
source = "Türkçe 你好\n\nSecond paragraph.\n"
result = Chunker(
max_chunk_size=24,
context_mode="none",
coverage_policy="lossless",
).chunk_with_manifest("example.txt", source, source_id="guide:introduction")
raw = source.encode("utf-8")
assert not result.skipped_ranges
assert b"".join(chunk.text.encode("utf-8") for chunk in result.chunks) == raw
for chunk in result.chunks:
assert raw[chunk.byte_range.start:chunk.byte_range.end].decode("utf-8") == chunk.text
chunk_with_manifest() returns ChunkResult(source, chunks, skipped_ranges,
diagnostics), including omissions when retrieval output is empty. It accepts
canonical text with an ordinary text filepath, not .ipynb, .tex, .rst,
.pdf or .docx container paths. Direct concatenation reconstructs a lossless
partition only when numeric overlap is disabled. With overlap, use the union of
ranges; repeated bytes must not be counted twice.
Structured loaders produce LoadedDocument.text and character-indexed segments.
chunk_loaded_document(filepath, loaded, options) applies the same final source
and budget checks to an explicitly loaded document.
Notebook, PDF and DOCX chunk offsets refer to that extracted text, not JSON or
binary bytes. Preserve page/cell/element metadata for citations. See the notebook
reconstruction example in the migration guide.
Malformed notebooks raise ChunkingError when chunked. Nonfatal loader warnings
reach context.parse_errors and the source descriptor's warning metadata.
Overlap and iteration
overlap=20 requests overlap measured in the configured size unit;
overlap=0.1 requests a fraction of max_chunk_size. It repeats raw source spans,
and exact payload limits still apply. The actual retained overlap can be smaller
when the budget cannot accommodate both overlap and new source text.
overlap_lines=1 adds preceding lines to derived context only. Raw chunk ranges
retain their ordinary coverage behavior. It may be omitted under the context
budget policy. Nonzero numeric overlap and line overlap cannot be combined.
chunk() and stream() share finalization and supported options. chunk()
returns a list with known total_chunks; stream() yields total_chunks=-1.
stream_file() still reads source content; its name describes output iteration.
| Execution path | Resident data and output buffering |
|---|---|
| Ordinary code/prose/markup/hybrid | Complete source, UTF-8/NWS indexes, parser/window structures, occurrence-ID bookkeeping; output chunks are yielded. |
| Semantic | Sentence/window embeddings and candidate chunks can be retained for the document. |
| Structured documents | Canonical extracted text and segments remain resident; some loaders retain per-document candidates/results. PDF/DOCX stream_file() currently buffers the file's chunk list. |
astream(buffer_size=8) |
Above engine state plus a bounded output queue; producer backpressure and cooperative cancellation. A running parser/provider call must return before cleanup completes. |
stream_upsert(batch_size=100) |
Above per-document state plus a bounded chunk/embedding batch and enumerated file paths. The caller writes returned rows to its database. |
batch() / abatch() |
Concurrent per-file work; returned results remain in input order and are collected. |
No path promises constant total memory. Bound concurrency and document size for large corpora; asynchronous wrappers do not make CPU parsing parallel without cost.
Identity, persistence and embedding invalidation
stable_chunk_id() combines logical source identity, the raw text hash and its
source-order occurrence among equal chunks. Position and configuration are excluded.
A byte-identical block can retain its ID after movement; repeated equal blocks
can change occurrence numbers after insertions. This is not a general rename/move
matching engine. Preserve source_id explicitly to preserve document identity.
chunk_embedding_fingerprint() in omnichunk.serialization includes raw text,
rendered context and configuration fingerprint. Indexing clients must additionally
version the embedding model they use outside the chunker. chunk_diff() reports
same-ID payload changes in updated, which is a subset of added; those IDs also
appear in removed_ids. Apply deletes before upserts. Refresh location metadata
for unchanged chunks without re-embedding unchanged payloads.
Versioned JSON preserves every documented Chunk and ChunkContext field.
Legacy/unversioned JSON remains readable; unsupported schemas are rejected.
ChunkStore(path, collection="default") returns source-ordered chunks and commits
a complete sync atomically. Deletion is limited to missing files owned by a
previous completed scan with the same root and filters. Partial/new scans do not
delete unrelated data. Failed reads/parses/providers/writes roll back the sync.
The write transaction spans processing; large syncs can hold the write lock.
Persisted skips require known callback identities. Give custom callbacks a stable
fingerprint attribute, or semantic providers both semantic_cache_namespace and
semantic_model_revision; otherwise the store conservatively reprocesses files.
Use PluginRegistry(revision="your-parser-v1") with versioned custom parsers.
Change these identities when implementation, model or preprocessing changes.
The semantic embedding cache separately isolates provider objects, namespace, model revision and preprocessing. It serializes cache misses under a lock and validates vector shape, finite values and dimensions. Cache only providers whose outputs are reproducible under the declared identity.
Parsers, plugins and tool serving
language_capabilities() lists detected code languages, extensions, grammar
registration/loading, parser availability, bundled query availability and effective
extraction (ast, regex or none). Query availability is not proof of complete
language coverage. Install omnichunk[code] for the six primary grammars and
omnichunk[all-languages] for the full registered grammar set, including the primary six.
Chunker(registry=PluginRegistry()) uses an explicit plugin scope. Legacy global
registrations are snapshotted when a chunker is constructed. Parser failures are
reported in context.parse_errors; context.format_metadata["parser_backend"]
identifies the selected code parser/fallback.
omnichunk serve --rpc --allowed-root ./project starts the experimental HTTP
JSON-RPC service. --mcp remains a deprecated alias; MCP lifecycle and tool
discovery are not implemented. The server validates resolved file roots, Host and
Origin, request sizes and read timeouts. Non-loopback binding requires a bearer
token; --token-env names its environment variable. It uses stdlib HTTPServer,
without TLS or hard cancellation of an executing parser. A real MCP adapter
remains future work.