Liking cljdoc? Tell your friends :D

vaelii.impl.llm.page

The page-scoped prompt: the unit of work is the term the reader is looking at.

vaelii.impl.llm.selection prompts about lines the reader picked and asks for them back edited. This namespace prompts about a term page/term?q=penguin — and asks for knowledge the KB does not have yet:

  1. what the page already says about the term, as bare sentences,
  2. the vocabulary that term's genl neighbourhood licenses (vaelii.impl.llm.inventory) — arity and argument types included,
  3. the reader's free-text instruction ("flesh out the capabilities of this").

Three things differ from the edit path, each because it was measured:

  • The context is dropped. A page is already about one context, so the caller supplies it and the model writes bare sentences. That removes a whole class of answer the model gets wrong for no gain — and it shortens every line it writes.
  • Decoding is constrained (output-schema, Ollama's format). On generation this rescues models that otherwise answer in markdown prose; on the edit path the same parameter silently drops lines, so the two contracts are deliberately different and are not unified.
  • The content is type-level. Common sense about a kind is a genl edge or a rule, not a fact about an individual, so the prompt asks for those shapes and shows them.

The prompt's one job beyond the shape is to stop the model coining vocabulary — see vaelii.impl.llm.inventory, which is where both guards against that live.

The page-scoped prompt: **the unit of work is the term the reader is looking at.**

`vaelii.impl.llm.selection` prompts about lines the reader picked and asks for them
back edited.  This namespace prompts about a *term page* — `/term?q=penguin` — and asks
for knowledge the KB does not have yet:

1. what the page already says about the term, as bare sentences,
2. the vocabulary that term's `genl` neighbourhood licenses
   (`vaelii.impl.llm.inventory`) — arity and argument types included,
3. the reader's free-text instruction ("flesh out the capabilities of this").

Three things differ from the edit path, each because it was measured:

* **The context is dropped.**  A page is already about one context, so the caller
  supplies it and the model writes bare sentences.  That removes a whole class of
  answer the model gets wrong for no gain — and it shortens every line it writes.
* **Decoding is constrained** (`output-schema`, Ollama's `format`).  On generation this
  *rescues* models that otherwise answer in markdown prose; on the edit path the same
  parameter silently drops lines, so the two contracts are deliberately different and
  are not unified.
* **The content is type-level.**  Common sense about a *kind* is a `genl` edge or a
  rule, not a fact about an individual, so the prompt asks for those shapes and shows
  them.

The prompt's one job beyond the shape is to stop the model coining vocabulary — see
`vaelii.impl.llm.inventory`, which is where both guards against that live.
raw docstring

assertion-entryclj

(assertion-entry sentence context strength)

One read sentence -> the [sentence context opts?] entry vaelii.core/edit! takes, with the caller's context supplied. strength rides across as {:strength :monotonic} when the model claimed the assertion is known-true; a default needs no opts, since that is assert's own default.

One read sentence -> the `[sentence context opts?]` entry `vaelii.core/edit!` takes,
with the caller's context supplied.  `strength` rides across as
`{:strength :monotonic}` when the model claimed the assertion is known-true; a default
needs no opts, since that is `assert`'s own default.
sourceraw docstring

output-schemaclj

The JSON schema Ollama's format constrains decoding to — the contract on this path, unlike the edit path where it is an opt-in optimization.

Measured: constrained decoding is what makes generation work at all on a local model. Models that answered a generation request with a markdown essay produce clean s-expressions under this schema, and the strongest coder model went from nothing usable to a full answer. An object per assertion, never a bare string, so the sampler cannot choose its own line shape; sentence is one s-expression and carries no context — the caller supplies that.

The JSON schema Ollama's `format` constrains decoding to — **the contract on this
path**, unlike the edit path where it is an opt-in optimization.

Measured: constrained decoding is what makes generation work at all on a local model.
Models that answered a generation request with a markdown essay produce clean
s-expressions under this schema, and the strongest coder model went from nothing usable
to a full answer.  An **object per assertion**, never a bare string, so the sampler
cannot choose its own line shape; `sentence` is one s-expression and carries **no
context** — the caller supplies that.
sourceraw docstring

page-contextclj

(page-context rows given)

The context new assertions are filed in: the caller's :context when given, else the context most of the page's own sentexes are in, else UniverseContext.

A modal context is the honest default — a page about penguin whose sentexes sit in OrganismContext is a page about OrganismContext — and ties break on the context name so the choice cannot depend on arrival order. The vocabulary head is never chosen: a term carries derived bookkeeping there ((arity penguin 1), (unaryPredicate penguin)) which can outnumber its definitional sentexes, and new domain knowledge does not belong in the context that defines the vocabulary. Reported back by vaelii.impl.llm.session/propose-page, because which context knowledge lands in is a decision a reviewer must see.

The context new assertions are filed in: the caller's `:context` when given, else the
context most of the page's own sentexes are in, else `UniverseContext`.

A modal context is the honest default — a page about `penguin` whose sentexes sit in
`OrganismContext` is a page about `OrganismContext` — and ties break on the context name so
the choice cannot depend on arrival order.  The **vocabulary head is never chosen**: a term
carries derived bookkeeping there (`(arity penguin 1)`, `(unaryPredicate penguin)`) which can
outnumber its definitional sentexes, and new domain knowledge does not belong in the
context that defines the vocabulary.  Reported back by
`vaelii.impl.llm.session/propose-page`, because which context knowledge lands in is a
decision a reviewer must see.
sourceraw docstring

stored-headingclj

(stored-heading rows)

How many of the term's stored lines the prompt is showing — 40, 40 of 137, or 40 of more than 137.

A bare count of what is on screen reads as the whole of what is stored, and the model is asked in the same breath not to repeat anything already there. Where the cut or stored-lines' scan bound bit, saying so is what keeps that instruction honest: a model shown a sample and told it is one writes about the gaps rather than assuming it has seen them. Reads stored-lines' metadata, and answers the plain count for rows built without it.

How many of the term's stored lines the prompt is showing — `40`, `40 of 137`, or
`40 of more than 137`.

A bare count of what is on screen reads as the whole of what is stored, and the model
is asked in the same breath not to repeat anything already there.  Where the cut or
`stored-lines`' scan bound bit, saying so is what keeps that instruction honest: a
model shown a sample and told it is one writes about the gaps rather than assuming it
has seen them.  Reads `stored-lines`' metadata, and answers the plain count for rows
built without it.
sourceraw docstring

stored-linesclj

(stored-lines kb term)
(stored-lines kb
              term
              {:keys [max-lines max-scan] :or {max-lines 40 max-scan 4000}})

What the term page shows, as [{:handle :sentence :context :line} …] — the stored sentexes mentioning the term, deduped and sorted by content before :max-lines (40) cuts, so which of what was scanned the model is shown is a function of the KB rather than of the order the knowledge arrived in.

Rendered as bare sentences: the context is deliberately absent, because the answer shape has no context in it either and showing one invites the model to write one. A rule keeps its set/*Rule wrappers, since that is how its direction and defeasibility are written. An exceptWhen meta-sentex is left out — it names the rule it qualifies by raw handle, which is engine bookkeeping and not something to show a model, let alone ask it to imitate.

:max-scan (4000) is the cost bound, and it is the one thing here that is not a content choice. Content order is what a cap has to key on, so the sort must happen over everything the cut chooses between — which means fetching it. Below the bound the page is therefore a function of the knowledge alone: the same sentences loaded in any order give the same lines. At the bound it is a sample, and scanned decides which one — the term's earliest mentions, since what a sentence says cannot be known without fetching it and fetching all of them is the cost the bound refuses. A page term mentioned more often than that is a term whose page is already a sample, so the scan stops and the answer says so: the metadata carries :found (distinct lines within the scan) and :truncated?, and user-turn writes both into the heading rather than letting 40 lines read as the whole of what is stored. Ten record fetches per line shown is noise beside the model call this prompt is built for; a million is not.

What the term page shows, as `[{:handle :sentence :context :line} …]` — the stored
sentexes mentioning the term, deduped and **sorted by content before `:max-lines` (40)
cuts**, so which of what was scanned the model is shown is a function of the KB rather
than of the order the knowledge arrived in.

Rendered as **bare sentences**: the context is deliberately absent, because the answer
shape has no context in it either and showing one invites the model to write one.  A
rule keeps its `set/*Rule` wrappers, since that is how its direction and defeasibility
are written.  An `exceptWhen` meta-sentex is left out — it names the rule it qualifies by
raw handle, which is engine bookkeeping and not something to show a model, let alone ask
it to imitate.

**`:max-scan` (4000) is the cost bound, and it is the one thing here that is not a
content choice.**  Content order is what a cap has to key on, so the sort must happen
over everything the cut chooses between — which means fetching it.  Below the bound the
page is therefore a function of the knowledge alone: the same sentences loaded in any
order give the same lines.  At the bound it is a **sample**, and `scanned` decides which
one — the term's earliest mentions, since what a sentence says cannot be known without
fetching it and fetching all of them is the cost the bound refuses.  A page term
mentioned more often than that is a term whose page is already a sample, so the scan
stops and the answer says so: the metadata carries `:found` (distinct lines within the
scan) and `:truncated?`, and `user-turn` writes both into the heading rather than
letting 40 lines read as the whole of what is stored.  Ten record fetches per line shown
is noise beside the model call this prompt is built for; a million is not.
sourceraw docstring

system-promptclj

The instruction half of the page-scoped turn — static, because everything KB-specific rides in the user turn.

It carries four things the model gets wrong without them: that a claim about a kind is a rule or a genl edge rather than a sentence with a loose variable, that the context is not the model's to write, that detail belongs in arguments and not in predicate names, and that the vocabulary on the card is there to be reused.

The instruction half of the page-scoped turn — static, because everything KB-specific
rides in the user turn.

It carries four things the model gets wrong without them: that a claim about a *kind*
is a rule or a `genl` edge rather than a sentence with a loose variable, that the
context is not the model's to write, that detail belongs in **arguments** and not in
predicate names, and that the vocabulary on the card is there to be reused.
sourceraw docstring

user-turnclj

(user-turn kb term rows context instruction)
(user-turn kb
           term
           rows
           context
           instruction
           {:keys [max-assertions] :or {max-assertions 24} :as opts})

The volatile half: the page's term, its own stored sentences, the vocabulary card, the context new assertions land in, and the reader's instruction — instruction last, so it is the newest thing in the window.

opts is passed through to vaelii.impl.llm.inventory/inventory and render (:max-predicates, :max-types, :max-tokens, …) and to stored-lines (:max-lines, :max-scan). :max-assertions (24) caps what is asked for, which is what bounds the answer's length and so its latency.

The stored block's heading is stored-heading's rather than a bare count, so a capped page reads as capped.

The volatile half: the page's term, its own stored sentences, the vocabulary card, the
context new assertions land in, and the reader's instruction — instruction last, so it
is the newest thing in the window.

`opts` is passed through to `vaelii.impl.llm.inventory/inventory` and `render`
(`:max-predicates`, `:max-types`, `:max-tokens`, …) and to `stored-lines`
(`:max-lines`, `:max-scan`).  `:max-assertions` (24) caps what is asked for, which is
what bounds the answer's length and so its latency.

The stored block's heading is `stored-heading`'s rather than a bare count, so a capped
page reads as capped.
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