elja
Elja (Icelandic): relentless drive — the quality of working at something without letting up.
A fully-customizable LLM agent harness built on Pydantic AI, designed for local-first models (LM Studio / OpenAI-compatible endpoints) with first-class support for tools, skills, sub-agents, MCP servers, and custom context management.
Status: under active development.
Installation
pip install elja
Usage
Start LM Studio serving a model (default expectation: qwen/qwen3.8-27b at
http://localhost:1234/v1), then:
elja chat # interactive REPL (session persisted + resumed)
elja chat --once "list the files here and summarize them"
elja chat --once "what is in this screenshot?" --image shot.png
elja chat --config path/to/elja.toml --session mychat
# In the REPL, attach an image to a message with: /img <path> <prompt>
Or from Python:
from elja import EljaDeps, build_agent, build_usage_limits, load_settings
settings = load_settings()
agent = build_agent(settings)
result = agent.run_sync(
"What's in this directory?",
deps=EljaDeps.from_settings(settings),
usage_limits=build_usage_limits(settings),
)
print(result.output)
Configuration lives in elja.toml (all keys optional; ELJA_* env vars
override, e.g. ELJA_MODEL__BASE_URL):
[model]
provider = "openai" # "openai" (any OpenAI-compatible endpoint — the default,
# aimed at LM Studio), "anthropic", or "google".
# Native providers need: pip install 'elja[anthropic]' / 'elja[google]'
name = "qwen/qwen3.8-27b"
base_url = "http://localhost:1234/v1" # unset with provider="openai" = local LM Studio
temperature = 0.2
# api_key: set for cloud endpoints; native providers also honor
# ANTHROPIC_API_KEY / GOOGLE_API_KEY from the environment.
[limits]
request_limit = 25
[workspace]
root = "."
[tools]
run_shell = true
web_search = true # keyless DuckDuckGo search via ddgs (network egress!)
[agent]
instructions = "Optional: replace the default system instructions."
[compaction] # evidence-based tiered compaction (see elja/compaction.py)
# NB: 24000 is tuned for a local 27B; raise it for large-window
# cloud providers to avoid early masking + paid summarizer calls
enabled = true
target_tokens = 24000 # load the LM Studio model with at least this + headroom
keep_tool_pairs = 10 # recent tool results kept verbatim by the masking tier
keep_messages = 20 # verbatim tail if the summarization fallback fires
# Skills: markdown files in <workspace>/skills/ (or [skills] dir = "...") with
# YAML frontmatter (id, description) + an instructions body. The model loads
# them on demand, so a large skill library costs ~no context until used.
# Sub-agents: delegate tools with isolated context (results-only return).
[subagents.researcher]
description = "Researches a question and reports key facts."
instructions = "Answer tersely with sources."
tools = ["read_file", "web_search"] # subset of ENABLED built-ins; omit for all enabled
request_limit = 8 # per-delegation request budget (optional)
# Attach MCP servers; their tools become available to the agent.
[mcp.servers.mytools]
command = "python3" # stdio: launched as a subprocess
args = ["my_mcp_server.py"]
env = { API_KEY = "..." } # optional; NB the subprocess gets a minimal env
# (HOME/PATH/USER...) plus these — not your full shell env
[mcp.servers.remote]
transport = "http" # streamable-HTTP endpoint
url = "http://localhost:9000/mcp" # unauthenticated — localhost only
Development
poetry install --with dev
poetry run pre-commit install
Run checks:
poetry run ruff check src tests
poetry run mypy
poetry run pytest -m "not integration"
Integration tests (-m integration) require a running LM Studio server at
http://localhost:1234/v1.
License
MIT
Metadata
Release files for elja 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 | Provenance | |
|---|---|---|---|---|
| elja-0.3.0.tar.gz | 22.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| elja-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 49.4 kB
Release files / elja-0.3.0.tar.gz
| Download URL | elja-0.3.0.tar.gz |
|---|---|
| Size | 22.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4f6e703f19c54b84a4b50d2e27c573c196a3d5ddc1cd3b65677b941a431fef2f
|
|
BLAKE2b-256 checksum How to use checksums |
a48b32fa812e49db81007ac95d803f18ec35e376e9a65a9cf3d0ed4966c23d25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Release files / elja-0.3.0-py3-none-any.whl
| Download URL | elja-0.3.0-py3-none-any.whl |
|---|---|
| Size | 26.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
835d4be13a0253052e80676be04e83064641f9cd69d42f5c18a9f22d67d420e5
|
|
BLAKE2b-256 checksum How to use checksums |
77149777ab02e1e6ed0903e60161edfe287bdf31ff14cbbbd401a6d94b29ac71
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Security for elja 0.3.0
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.