bc-al-chunker
RAG-optimized chunking for Business Central AL files.
bc-al-chunker statically parses .al files and produces semantically-aware chunks optimized for embedding and retrieval-augmented generation (RAG). It understands the structure of every AL object type — tables, pages, codeunits, reports, queries, enums, interfaces, and all extension types — and splits large objects at natural semantic boundaries (sections, procedures, triggers) while keeping small objects whole.
Features
- Hierarchical chunking — small objects stay whole; large objects split at procedure/trigger/section boundaries
- Context headers — every sub-chunk gets a synthetic context comment so each chunk is self-contained for embedding
- All AL object types — table, page, codeunit, report, query, xmlport, enum, interface, permissionset, profile, controladdin, entitlement, and all extension variants
- Multiple data sources — local filesystem, GitHub API, Azure DevOps API
- Structured output — Python dataclasses with JSON and JSONL export
- Zero dependencies for core usage —
httpxonly needed for remote adapters - Fully typed — strict mypy, PEP 561
py.typedmarker
Installation
# Core (local filesystem only)
pip install bc-al-chunker
# With GitHub adapter
pip install bc-al-chunker[github]
# With Azure DevOps adapter
pip install bc-al-chunker[azure]
# Everything
pip install bc-al-chunker[all]
Quick Start
from bc_al_chunker import chunk
# Chunk all .al files in a directory
chunks = chunk("/path/to/al-repo")
# Multiple repositories
chunks = chunk(["/repo1", "/repo2"])
# Each chunk has content + rich metadata
for c in chunks:
print(c.metadata.object_type, c.metadata.object_name, c.metadata.chunk_type)
print(c.content[:100])
print(c.token_estimate)
Configuration
from bc_al_chunker import chunk, ChunkingConfig
chunks = chunk(
"/path/to/repo",
config=ChunkingConfig(
max_chunk_chars=2000, # Max characters per chunk (default: 1500)
min_chunk_chars=100, # Min characters per chunk (default: 100)
include_context_header=True, # Prepend object context to sub-chunks
estimate_tokens=True, # Include token estimate on each chunk
),
)
Remote Sources
from bc_al_chunker import chunk_source
from bc_al_chunker.adapters.github import GitHubAdapter
from bc_al_chunker.adapters.azure_devops import AzureDevOpsAdapter
# GitHub
chunks = chunk_source(
GitHubAdapter("microsoft/BCApps", token="ghp_...", paths=["src/"])
)
# Azure DevOps
chunks = chunk_source(
AzureDevOpsAdapter("myorg", "myproject", "myrepo", token="pat...")
)
Export
from bc_al_chunker import chunk, chunks_to_json, chunks_to_jsonl, chunks_to_dicts
chunks = chunk("/path/to/repo")
# JSON array
chunks_to_json(chunks, "output.json")
# JSONL (streaming-friendly)
chunks_to_jsonl(chunks, "output.jsonl")
# Python dicts (for programmatic use)
dicts = chunks_to_dicts(chunks)
Chunking Strategy
The chunker uses a hierarchical, AST-aware strategy:
- Parse — Each
.alfile is parsed into anALObjectAST with sections, procedures, triggers, and properties identified - Size check — If the object's source is ≤
max_chunk_chars, it becomes oneWholeObjectchunk - Split — Large objects are split:
- Header chunk — object declaration + top-level properties
- Section chunks —
fields,keys,layout,actions,views,dataset, etc. - Procedure/Trigger chunks — each procedure or trigger as its own chunk
- Context injection — Sub-chunks get a context header prepended:
// Object: codeunit 50100 "Address Management" // File: src/Codeunits/AddressManagement.al procedure ValidateAddress(var CustAddr: Record "Customer Address") begin ... end;
This ensures every chunk is self-contained and produces high-quality embeddings for code search.
Chunk Schema
Each Chunk contains:
content— the text to embedtoken_estimate— approximate token count (chars / 4)metadata:file_path,object_type,object_id,object_namechunk_type—whole_object,header,section,procedure,triggersection_name,procedure_nameextends— for extension objectssource_table— extracted from page/codeunit propertiesattributes— e.g.,[EventSubscriber(...)]line_start,line_endfile_hash— 16-character BLAKE2b hex digest of the source file content; use this to detect whether a file has changed before re-embedding
Detecting file changes with file_hash
Every chunk carries a file_hash computed from the file's source text using
BLAKE2b (8-byte digest — the fastest built-in hash algorithm in Python's
hashlib). Because the hash is derived from the normalized (BOM-stripped)
UTF-8 content, it is stable regardless of encoding variants.
from bc_al_chunker import chunk, hash_source
chunks = chunk("/path/to/al-repo")
# Group chunks by file; all chunks from the same file share the same hash
file_hashes = {c.metadata.file_path: c.metadata.file_hash for c in chunks}
# Later — re-read a file and compare before doing expensive work
with open("MyTable.al", encoding="utf-8-sig") as f:
current_hash = hash_source(f.read())
if current_hash != file_hashes.get("MyTable.al"):
# File changed — re-chunk and re-embed
...
Development
# Clone and install
git clone https://github.com/andrijantasevski/bc-al-chunker.git
cd bc-al-chunker
uv sync --all-extras --group dev
# Run tests
uv run pytest tests/ -v
# Lint + format
uv run ruff check src/ tests/
uv run ruff format src/ tests/
# Type check
uv run mypy src/
License
MIT
Metadata
Release files for bc-al-chunker 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| bc_al_chunker-0.1.3.tar.gz | 36.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| bc_al_chunker-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.9 kB
Release files / bc_al_chunker-0.1.3.tar.gz
| Download URL | bc_al_chunker-0.1.3.tar.gz |
|---|---|
| Size | 36.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7ea6b0f0b3541f333ea525793c356a32bfbb3dd8a75fd46a8800c3b6b67d1f23
|
|
BLAKE2b-256 checksum How to use checksums |
4a39123455063d055b269046fcd85c764cbc3a62e0e033a217b0bf1ec8718ece
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / bc_al_chunker-0.1.3-py3-none-any.whl
| Download URL | bc_al_chunker-0.1.3-py3-none-any.whl |
|---|---|
| Size | 26.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
28c13ff97c59dde7f64b875003acabf4d6a486bfadfdc0620d8d0beaad6259bc
|
|
BLAKE2b-256 checksum How to use checksums |
8ecb648b9638846380d92297b20d04a7fbb99ca00af874e5f125c0f79d55b132
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.10.6 {"installer":{"name":"uv","version":"0.10.6","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Security for bc-al-chunker 0.1.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.