Liking cljdoc? Tell your friends :D

vaelii.impl.llm.tools

The model's read surface over a KB — generated, not hand-written.

vaelii.impl.serve/ops is already an allowlisted, EDN-typed map of vaelii.core calls: the exact surface the browser and the daemon reach a KB through. So the tool schemas are derived from its read subset rather than transcribed, and the tool calls are dispatched back through the same table. A read added to serve/ops becomes a tool with no edit here; a read renamed there cannot rot a copy here, because there is no copy.

The model never writes. write-ops names every mutating op, and anything resolving to a ! var is treated as one whatever the table says, so the exposed set is reads only. The model's output is a proposed batch, reviewed and applied by a human (vaelii.impl.llm.session) — there is no write tool and no write path.

Argument shapes come from the vaelii.core var's own :arglists (minus the leading kb) and its docstring, so a signature change is picked up on the next build. JSON carries no symbols, so a sentence / context / term argument is a string holding an EDN s-expression"(dog ?x)", "CxWell" — read back with clojure.edn/read-string (never read-string: EDN has no reader-eval, so a model's output cannot evaluate code).

The model's read surface over a KB — **generated**, not hand-written.

`vaelii.impl.serve/ops` is already an allowlisted, EDN-typed map of `vaelii.core`
calls: the exact surface the browser and the daemon reach a KB through.  So the
tool schemas are derived from its **read subset** rather than transcribed, and the
tool calls are dispatched back through the same table.  A read added to `serve/ops`
becomes a tool with no edit here; a read renamed there cannot rot a copy here,
because there is no copy.

**The model never writes.**  `write-ops` names every mutating op, and anything
resolving to a `!` var is treated as one whatever the table says, so the exposed set
is reads only.  The model's *output* is a proposed batch, reviewed and applied by a
human (`vaelii.impl.llm.session`) — there is no write tool and no write path.

Argument shapes come from the `vaelii.core` var's own `:arglists` (minus the leading
`kb`) and its docstring, so a signature change is picked up on the next build.  JSON
carries no symbols, so a sentence / context / term argument is a **string holding an
EDN s-expression** — `"(dog ?x)"`, `"CxWell"` — read back with
`clojure.edn/read-string` (never `read-string`: EDN has no reader-eval, so a model's
output cannot evaluate code).
raw docstring

callclj

(call kb tname input)
(call kb tname input {:keys [max-result-chars] :or {max-result-chars 4000}})

Run one tool call against kb and return {:ok true :result "…"} or {:ok false :error "…"} — the string a tool_result block carries back.

input is the provider's JSON object (string keys). The longest signature the input fully satisfies decides the call, so an op with several shapes (why-not takes a handle or a sentence and a context) dispatches to the one the model actually supplied. Dispatch goes through serve/ops, the same table the schemas were generated from.

An argument the chosen signature does not take is refused, never dropped. The shapes nest — query takes (goal), (goal, context), (goal, context, opts) — so an input of goal and opts with no context satisfies only the first, and passing it on would answer facts-only with the depth discarded, which reads exactly like a goal no rule can reach. That is opts/check!'s failure one level out: an argument nothing reads takes the default in silence. So the refusal names the shape the input selected and the shapes the op has, and the model supplies the argument in between.

Never throws: a bad argument, an unknown tool, or a refusal from the KB comes back as {:ok false :error "…"}, which is what a tool_result block wants — the model reads the error and tries again.

opts: :max-result-chars (default 4000) bounds what a broad read can push into the context window.

Run one tool call against `kb` and return `{:ok true :result "…"}` or
`{:ok false :error "…"}` — the string a `tool_result` block carries back.

`input` is the provider's JSON object (string keys).  The **longest signature the
input fully satisfies** decides the call, so an op with several shapes (`why-not`
takes a handle *or* a sentence and a context) dispatches to the one the model
actually supplied.  Dispatch goes through `serve/ops`, the same table the schemas
were generated from.

**An argument the chosen signature does not take is refused, never dropped.**  The
shapes nest — `query` takes `(goal)`, `(goal, context)`, `(goal, context, opts)` —
so an input of goal *and* opts with no context satisfies only the first, and passing
it on would answer facts-only with the depth discarded, which reads exactly like a
goal no rule can reach.  That is `opts/check!`'s failure one level out: an argument
nothing reads takes the default in silence.  So the refusal names the shape the
input selected and the shapes the op has, and the model supplies the argument in
between.

Never throws: a bad argument, an unknown tool, or a refusal from the KB comes back
as `{:ok false :error "…"}`, which is what a `tool_result` block wants — the model
reads the error and tries again.

`opts`: `:max-result-chars` (default 4000) bounds what a broad read can push into
the context window.
sourceraw docstring

op-ofclj

(op-of tname)

The op keyword a tool name came from, or nil if it names no exposed read.

The op keyword a tool name came from, or nil if it names no exposed read.
sourceraw docstring

read-opsclj

(read-ops)

The op keywords the model may call: serve/ops minus the writes, minus anything that does not resolve to a non-variadic vaelii.core var. Sorted, so the generated tool list is byte-stable and the prompt cache survives a rebuild.

The op keywords the model may call: `serve/ops` minus the writes, minus anything
that does not resolve to a non-variadic `vaelii.core` var.  Sorted, so the generated
tool list is byte-stable and the prompt cache survives a rebuild.
sourceraw docstring

schemaclj

(schema op)

The tool schema for one op keyword.

The tool schema for one op keyword.
sourceraw docstring

schemasclj

(schemas)
(schemas {:keys [only exclude]})

Every exposed read as a tool schema, in read-ops order. opts:

:only a set of op keywords to keep (default: all reads) :exclude a set of op keywords to drop

Every exposed read as a tool schema, in `read-ops` order.  `opts`:

:only     a set of op keywords to keep (default: all reads)
:exclude  a set of op keywords to drop
sourceraw docstring

tool-nameclj

(tool-name op)

The tool name for an op keyword — :find-sentexes -> kb_find_sentexes, :ask? -> kb_ask_p.

The tool name for an op keyword — `:find-sentexes` -> `kb_find_sentexes`,
`:ask?` -> `kb_ask_p`.
sourceraw docstring

write-opsclj

The ops in serve/ops the model may not reach. A new mutating op must be listed here — the exposed tool set is (keys serve/ops) minus this, so an omission would hand the model a write. Ops resolving to a ! var are excluded independently, which catches the ones spelled with the warning already.

That second mechanism is a backstop, not the rule: ! means irreversible (docs/api.md), and a write that merely mutates is spelled without one. So every mutating op is listed here explicitly, including the ones the ! sweep cannot see — :edit and :edit-with-consequences both store, and neither carries the suffix. :preview stores nothing but belongs here all the same: it applies its batch and rolls it back, so it holds the process's single writer, advances the handle counter and moves the chain and settle statistics — serve and access both file it with the writes for that reason. :clear-caches mutates the process's measurement state, which is nothing to hand a model that is being measured through it.

The ops in `serve/ops` the model may not reach.  A new mutating op **must** be
listed here — the exposed tool set is `(keys serve/ops)` minus this, so an omission
would hand the model a write.  Ops resolving to a `!` var are excluded
independently, which catches the ones spelled with the warning already.

That second mechanism is a backstop, not the rule: `!` means *irreversible*
(`docs/api.md`), and a write that merely mutates is spelled without one.  So every
mutating op is listed here explicitly, including the ones the `!` sweep cannot see —
`:edit` and `:edit-with-consequences` both store, and neither carries the suffix.
`:preview` stores nothing but belongs here all the same: it applies its batch and
rolls it back, so it holds the process's single writer, advances the handle counter
and moves the chain and settle statistics — `serve` and `access` both file it with
the writes for that reason.  `:clear-caches` mutates the process's measurement
state, which is nothing to hand a model that is being measured through it.
sourceraw docstring

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