Packages
llm_db
2026.3.1
2026.7.3
2026.7.2
2026.7.1
2026.7.0
2026.6.4
2026.6.3
2026.6.2
2026.6.1
2026.6.0
2026.5.2
2026.5.1
2026.5.0
2026.4.8
2026.4.7
2026.4.6
2026.4.5
2026.4.4
2026.4.3
2026.4.2
2026.4.1
2026.4.0
2026.3.3
2026.3.2
2026.3.1
2026.3.0
2026.2.9
2026.2.8
2026.2.7
2026.2.6
2026.2.5
2026.2.4
2026.2.3
2026.2.2
2026.2.1
2026.2.0
2026.1.5
2026.1.4
2026.1.3
2026.1.2
2026.1.1
2026.1.0
2025.12.4
2025.12.3
2025.12.2
2025.12.1
2025.11.18-preview
2025.11.14-preview
2025.11.7-preview
LLM model metadata catalog with fast, capability-aware lookups.
Current section
Files
Jump to
Current section
Files
AGENTS.md
# AGENTS.md
## Commands
- **Setup**: `mix setup` (install deps, git hooks auto-install on compile)
- **Test all**: `mix test`
- **Test single file**: `mix test test/path/to/file_test.exs`
- **Test single test**: `mix test test/path/to/file_test.exs:12` (line number)
- **Test with coverage**: `mix test --cover`
- **Format code**: `mix format`
- **Compile**: `mix compile`
- **Quality check**: `mix quality` (format, compile warnings, dialyzer, credo)
- **Update model data**: `mix llm_db.pull` (fetches from configured remote sources and regenerates snapshot)
- **Backfill model history (one-time)**: `mix llm_db.history.backfill --force` (generates `priv/llm_db/history/events/*.ndjson` from git snapshot history)
- **Sync model history (incremental)**: `mix llm_db.history.sync`
- **Check history drift**: `mix llm_db.history.check`
- **Dependencies**: `mix deps.get`
- **Release**: `mix llm_db.version && mix git_ops.release && git push && git push --tags` (bumps to date-based version, updates CHANGELOG, tags, and pushes)
## Git Hooks
Hooks auto-install via `git_hooks` on `mix compile` in dev:
| Hook | Action |
|------|--------|
| **commit-msg** | Validates conventional commit format via `git_ops.check_message` |
| **pre-commit** | `mix format --check-formatted` |
| **pre-push** | `mix quality` |
Conventional commit types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
## Configuration
### Development/Test (default in dev.exs and test.exs)
```elixir
config :llm_db,
compile_embed: false, # Load from file at runtime
integrity_policy: :warn # Warn on hash mismatch instead of failing
```
With `:warn` policy, snapshot regeneration via `mix llm_db.build` triggers automatic recompilation on next `mix test` or `mix compile` - no need for manual `mix clean`.
### Production
Use compile-time embedded snapshot to eliminate runtime atom creation and file I/O:
```elixir
# config/prod.exs
config :llm_db,
compile_embed: true, # Embed snapshot at compile time
integrity_policy: :strict, # Fail on any hash mismatch (default)
filter: %{
allow: :all, # or restrict to specific providers
deny: %{}
}
```
## Architecture
- **Type**: Elixir library providing fast, persistent_term-backed LLM model metadata catalog
- **Core modules**: `LLMDB` (main API), `LLMDB.Engine` (ETL pipeline), `LLMDB.Store` (persistent_term storage)
- **Data structures**: `LLMDB.Provider`, `LLMDB.Model` with Zoi validation schemas in `lib/llm_db/schema/`
- **Storage**: O(1) lock-free queries via `:persistent_term`, snapshot in `priv/llm_db/snapshot.json`
- **ETL Pipeline**: Ingest → Normalize → Validate → Merge → Enrich → Filter → Index + Publish (7 stages)
- **Startup**: Catalog automatically loads on application start via `LLMDB.Application` (no manual `load()` needed in IEx or runtime)
## Code Style
- **Validation**: Use `Zoi.parse/2` for all schema validation and defaulting (not NimbleOptions or typed_struct)
- **Format**: Run `mix format` before committing (configured in .formatter.exs)
- **Naming**: Snake_case for functions/vars, PascalCase for modules, atoms for provider IDs (`:openai`, `:anthropic`)
- **Error handling**: Return `{:ok, result}` or `{:error, reason}` tuples, use `:error` atom for simple failures
- **Specs**: Provider IDs are atoms, model IDs are strings, spec format is `"provider:model"`
- **Tests**: Use `async: false` for tests that modify Store, `setup` blocks to clear state with `Store.clear!()`
- **Atom safety**: Use `String.to_existing_atom/1` for runtime conversions; `String.to_atom/1` only in build-time code (mix tasks, Engine normalization with `unsafe: true` flag)