Liking cljdoc? Tell your friends :D

vaelii-agents

license release tests loc providers docstrings

Agent-facing code for vaelii: clients for the model providers, and the KB read tools a model calls, generated from the engine daemon's op table. The engine holds no AI- or model-specific code; this artifact does.

namespacewhat it holds
vaelii.agents.llm.protocolthe Provider protocol (complete, stream) and the neutral request and response maps
vaelii.agents.llm.providerbackend selection by keyword, lazily resolved, with the stub as the fallback
vaelii.agents.llm.stubthe deterministic, offline default provider, scripted per turn
vaelii.agents.llm.anthropicthe Messages API backend
vaelii.agents.llm.ollamathe local backend, over Ollama's chat API
vaelii.agents.llm.httpthe transport policy both HTTP backends share: deadlines, bounded error bodies
vaelii.agents.llm.poola fixed pool of providers across hosts, and a majority yes/no vote over it
vaelii.agents.toolsthe model's read tools: schemas generated from the daemon's read ops, and call, which dispatches a tool call back through them
vaelii.agents.enginethe engine vars outside vaelii.core that this repo reads, all in one namespace

docs/llm.md documents all of it: the tools, the providers, the environment variables and the refusal :types.

Using it

Leiningen [com.vaelii/vaelii-agents "0.32.0"], or deps.edn com.vaelii/vaelii-agents {:mvn/version "0.32.0"}, from Clojars. It depends on the engine at the version it was cut with, so a project naming only this one gets both.

(require '[vaelii.agents.llm.provider :as provider]
         '[vaelii.agents.tools :as tools])

(def p (provider/provider))   ; VAELII_LLM_PROVIDER's backend, or the stub
(tools/schemas)               ; the tool definitions to send with a request
(tools/call kb "kb_query" {"goal" "(dog ?x)" "context" "CxUniverse"})
;; => {:ok true :result "…"}

No tool writes. The tool set is the daemon's read ops minus every op that stores, holds the writer, names a path on the host or reads with no bound a call can carry (docs/llm.md § Tools).

Layout for a new component

A component that connects the engine to an agent (a protocol server, an agent runtime's adapter) goes in its own namespace tree, vaelii.agents.<component>.*, with its tests under test/vaelii/agents/<component>/ and its page at docs/<component>.md. An MCP server, for instance, is vaelii.agents.mcp.*. A component reuses vaelii.agents.tools for KB reads where the generated tools fit, and writes its own handlers where they do not.

Reaching into the engine. The engine's public API is vaelii.core. A component may call vaelii.host.* too, as vaelii.agents.tools does, and the engine is free to change that namespace tree in any release. Route each such call through vaelii.agents.engine, so an engine change is repaired in one namespace. A read the public API lacks and every caller would want belongs in vaelii.core, proposed upstream.

A component's own dependencies go in project.clj with a comment naming the namespace that needs them.

Setup

lein test

The engine resolves from Clojars, so a fresh clone needs nothing else. Working against an unreleased engine, a snapshot com.vaelii/vaelii comes out of ~/.m2:

git clone https://github.com/vaelii/vaelii ../vaelii
cd ../vaelii && lein install
cd -          && lein test

Working against live engine source instead of the installed jar:

./scripts/link-checkouts.sh   # checkouts/vaelii -> the engine beside this repo

Every KB the suite builds is on the engine's in-memory backend, so lein test runs beside the engine's own suite. No test calls a model: the stub answers every turn.

Development

lein lint          → versions + kondo + shellcheck + cljfmt + reflection + prose, not fail-fast
lein fix           → the only auto-repair: cljfmt rewrites in place
lein gate          → lint, then the suite; run this before opening a pull request
lein test :llm     → only the tests marked ^:llm, which call a model when VAELII_LLM_LIVE=1

lein lint needs clj-kondo and shellcheck on PATH. The reflection stage AOT-compiles src under *warn-on-reflection* and fails on any warning from this repo's own code.

scripts/update-badges.sh measures the repo and rewrites the badge block under the H1, fetching each badge from shields.io. Do not hand-edit the block.

License

Apache-2.0; see LICENSE. The engine itself is SSPL, and this artifact is part of the permissive layer around it.

Contributions: CONTRIBUTING.md (inbound = outbound, DCO sign-off, no CLA).

Can you improve this documentation?Edit on GitHub

cljdoc builds & hosts documentation for Clojure/Script libraries

Keyboard shortcuts
Ctrl+kJump to recent docs
←Move to previous article
→Move to next article
Ctrl+/Jump to the search field
× close