Your agents deserve exact evidence.
Star us → Smritikosh on GitHub · PyPI · Benchmarks · Issues · Contributing
Smritikosh is a local-first indexing and retrieval tool for code, documents, and conversations. It incrementally indexes changes and returns precise, line-cited passages for agents, without API keys, hosted vector databases, or sending source data off-device.
Precise · line-level citations · Incremental · indexes only changes · Local · no API keys or cloud
Get started
No Python on the machine? uv brings its own.
curl -LsSf https://astral.sh/uv/install.sh | sh # Windows: docs.astral.sh/uv
uv tool install smritikosh
Or pipx install smritikosh. Where the command is missing from PATH, python -m smritikosh
is the same thing.
Index whatever the agent should know. It all lands in one ./smritikosh.duckdb and is
searched as a single corpus.
smritikosh index ./auth-svc # one repository, or fifty (repeat per repo)
smritikosh index ./docs # Markdown and MDX beside the code
smritikosh index ./slack-export # Slack threads and .docx (soon)
Then let the agent explore. explore tools hands it the workflow and the citation
contract, search returns locations, chunks reads only those ranges.
smritikosh explore tools
smritikosh explore search "authorization decision flow" "authorization tests"
smritikosh explore chunks --range src/auth/policy.py 176 193
Re-run index anytime: unchanged files are skipped, so only the Δ costs anything.
Add --watch to keep it live while you work.
On Apple silicon, Smritikosh automatically uses the GPU; elsewhere it uses its portable CPU runtime. The index remembers its vector format, so search always restores the compatible runtime without another option.
Retrieval: evidence you can point at
Ask why can't users log in? and Smritikosh looks at it from four sides: where the decision is made, what it checks, where it says no, and the tests that cover it.
It matches the idea and the exact names, keeps an answer from every side, drops near-copies, and widens each one to the whole thought plus one place that refers to it, so what comes back is the exact lines, not everything around them.
Why incremental?
Your agent is only as good as the lines it can trust. Code moves all day, and an index that doesn't move with it quietly points at the wrong ones. Smritikosh keeps up, and only ever re-reads what changed.
Benchmarks
Paired agent sessions, same question and same effective model per pair:
| Task | Smritikosh | Baseline | Effect |
|---|---|---|---|
| Multi-repo analysis | 105.3 s · $0.381 | 193.4 s · $1.634 | 45.6% faster · 76.7% cheaper · 90.0% fewer tokens |
| Single-repo analysis | 68.4 s · $0.230 | 55.8 s · $0.330 | 30.4% cheaper · 32.5% fewer tokens · 40% fewer tool calls |
| Curated architecture discovery | 56.6 s · $0.361 | 113.9 s · $1.259 | 50.3% faster · 71.3% cheaper · 80.4% fewer tokens |
These are individual exported sessions, not statistically controlled measurements, and cumulative token counts include repeated cache reads. The table keeps the cases that went the other way (the single-repo run was 12.6 seconds slower, and the multi-repo baseline covered more repositories), so the efficiency numbers can be read honestly.
How it extends: ports and adapters
The pipeline talks to contracts, never to what sits behind them:
ports defines them,
adapters is what exists
today.
| Plug point | Shipping today | Same contract, not yet written |
|---|---|---|
| Source | Local filesystem, .gitignore-aware |
Slack, Google Drive, S3, Confluence, meeting notes |
| Structure | Python, TypeScript, JavaScript, Java, Kotlin, Markdown, MDX, JSON, TOML | Go, Rust, C#; transcripts by speaker turn, tickets by field |
| Store | DuckDB, one local file | Postgres with pgvector, Qdrant, Neo4j |
| Embedder | CodeRankEmbed, automatically accelerated on Apple silicon | OpenAI, Voyage, or any hosted model |
| Retrieval | Dense vectors and BM25 | Call graph: callers and callees |
How it works
Indexing walks the tree once and writes everything into one DuckDB file. Search reads that same file back as a handful of line ranges.
What can you build?
The recipe never changes: index whatever the answer could live in, then let the agent
search and read only the ranges it picks. Only what you point it at is different.
Every card in the top row is measured under Benchmarks: the same question asked with the index and without it, time and cost recorded for both runs.
The bottom row is the honest half. Those sources have a port and no adapter behind it yet, so the citations on those cards are the shape they will take, not something you can run this week. Open an issue for the one you need first, or build it against the same contract.
Built something on top of Smritikosh? Tell us. We want to see it.
Prior art: the papers behind these choices
Three papers shaped decisions you can point at in the code. Citing one credits an idea we used; it does not mean its authors reviewed or endorsed Smritikosh, and where our implementation diverges from theirs, that is said out loud.
Chunk on structure, not on line counts. Zhang, Zhao, Wang, Yang, Wei and Wu,
cAST: Enhancing Code Retrieval-Augmented Generation with Structural Chunking via Abstract
Syntax Tree (arXiv:2506.15655, 2025), argues that
line-based chunking breaks functions apart and merges unrelated code, and that recursively
splitting oversized AST nodes while merging siblings under a size limit yields self-contained
units. That is the shape of
strategies/ast.py —
siblings grouped, a class carried together with its initializer — and of split_oversized in
strategies/_helpers.py.
We diverge on the oversized case: cAST recurses into the node, we cut it into overlapping line
windows.
Fuse independent channels by rank. Choudhary, Kandoi and Patel,
Hybrid GraphRAG for Cross-Lingual Legal Citation Retrieval: A Multi-Signal Fusion Approach
for Swiss Legal Information Systems
(IJECS, 2026), runs lexical, dense, and graph retrieval as separate families and combines them
with weighted Reciprocal Rank Fusion, reporting k = 60 as where top-rank emphasis balances
against rank dilution.
retrieval/hybrid.py
keeps that channel separation,
retrieval/fusion.py
defaults to that k, and the call-graph channel listed above as not yet written is their third
family. We weigh sources after fusion in
retrieval/priors.py
rather than weighting each signal inside RRF, and we run no cross-encoder or LLM verification
stage.
Measure an index by toggling only the index. Bhola, Krishnan, Kurmala and NS, Code Isn't Memory: A Structural Codebase Index Inside a Coding Agent (arXiv:2606.22417, 2026), holds the agent harness and the model fixed, switches only the index on and off, and reports cost per solved task against an agentic-grep comparator. Benchmarks borrows that framing. It does not borrow the rigour: their protocol adds multiple seeds, a leak audit, and statistical separation, which is why our table is offered as recorded sessions rather than a controlled result.
Reciprocal Rank Fusion, Okapi BM25, and Maximal Marginal Relevance all predate these three and belong to their own authors; the papers above are where we met them in this shape.
Built by Shantanu Vashishtha and Sarvesh Sawant.
Apache 2.0 · © Smritikosh contributors
Metadata
Release files for smritikosh 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| smritikosh-0.3.0.tar.gz | 103.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| smritikosh-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 212.8 kB
Release files / smritikosh-0.3.0.tar.gz
| Download URL | smritikosh-0.3.0.tar.gz |
|---|---|
| Size | 103.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ab8deadc45daa8e80792aeb05518ff0009b772135fc37b74a97a3c6ea4ed5336
|
|
BLAKE2b-256 checksum How to use checksums |
552e5889a45044053b58fb13ca92b0d1839915f54a2f6535115831a17d810729
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency logRelease files / smritikosh-0.3.0-py3-none-any.whl
| Download URL | smritikosh-0.3.0-py3-none-any.whl |
|---|---|
| Size | 109.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
dad3c5f7e06f787583864c886526f0da10b70a6d64f7356bc49d9457d1c286a4
|
|
BLAKE2b-256 checksum How to use checksums |
aa75c85066f1123ab9a78f680dc8217734ecd915239498bd04e5a1c5bb85aeb5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 7, 2026.
Transparency log