Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.prompt

Prompt assembly.

Provider messages are explicit blocks in send order: core system rules, project instructions (AGENTS.md / CLAUDE.md when present), extension fragments, current user message. Per-iteration user-role context is the engine snapshot rendered as a Python dict (session) by the loop.

Prompt assembly.

Provider messages are explicit blocks in send order: core system rules,
project instructions (AGENTS.md / CLAUDE.md when present), extension
fragments, current user message. Per-iteration user-role context is the
engine snapshot rendered as a Python dict (`session`) by the loop.
raw docstring

active-extensionsclj

(active-extensions environment)

Returns the seq of registered extensions whose :ext/activation-fn returns truthy for environment, in registration order. Single source of truth for activation; call ONCE at the top of a turn.

Returns the seq of registered extensions whose `:ext/activation-fn` returns
truthy for `environment`, in registration order. Single source of truth for
activation; call ONCE at the top of a turn.
sourceraw docstring

assemble-initial-messagesclj

(assemble-initial-messages {:keys [stable-prompt-messages initial-user-content
                                   previous-turn-context user-images
                                   skipped-images]})

Initial provider messages for one turn. Deliberately excludes full prior dialog transcript: Vis state flows through persisted iterations, defs, and DB-backed tools. The current user message is tagged as CURRENT-USER-MESSAGE.

One full previous-turn context block may be prepended so short follow-ups can inspect the prior exchange without replaying the whole session.

:user-images (from attachments/collect-user-images) turns the user message multimodal: svar image blocks ride ahead of the text block and an ATTACHED-IMAGES manifest inside the text names each one. :skipped-images entries appear in the manifest only.

Initial provider messages for one turn. Deliberately excludes full prior
dialog transcript: Vis state flows through persisted iterations,
defs, and DB-backed tools. The current user message is tagged as
`CURRENT-USER-MESSAGE`.

One full previous-turn context block may be prepended so short follow-ups
can inspect the prior exchange without replaying the whole session.

`:user-images` (from `attachments/collect-user-images`) turns the user
message multimodal: svar image blocks ride ahead of the text block and
an `ATTACHED-IMAGES` manifest inside the text names each one.
`:skipped-images` entries appear in the manifest only.
sourceraw docstring

assemble-stable-prompt-messagesclj

(assemble-stable-prompt-messages
  environment
  {:keys [system-prompt active-extensions session-context] :as opts})

Assemble provider-prefix messages.

Send order is explicit and tested: SYSTEM-PROMPT - CORE_SYSTEM_PROMPT + caller addendum PROJECT-INSTRUCTIONS - AGENTS.md / CLAUDE.md contents (when present) TURN-SYSTEM-CONTEXT - turn-scoped runtime capability context. Today it contains extension prompt fragments; future extension reloads should replace this one message, never append a second extension context.

Extension fragments are separate from the core system prompt and are not repeated in per-iteration trailers.

Required opts: :active-extensions - vec from (active-extensions env). Drives environment, extension prompt, and hint collection.

Optional opts: :system-prompt - caller addendum appended to CORE. :session-context - rendered fenced-Python session = {…} block (standing session state: workspace / env / routing / tools). Embedded ONCE here as a cached system message; the loop re-emits only the session[...] = … structural delta in the conversation when it changes mid-turn.

Assemble provider-prefix messages.

Send order is explicit and tested:
  `SYSTEM-PROMPT`         - CORE_SYSTEM_PROMPT + caller addendum
  `PROJECT-INSTRUCTIONS`  - AGENTS.md / CLAUDE.md contents (when present)
  `TURN-SYSTEM-CONTEXT`   - turn-scoped runtime capability context. Today
                            it contains extension prompt fragments; future
                            extension reloads should replace this one
                            message, never append a second extension
                            context.

Extension fragments are separate from the core system prompt and are not
repeated in per-iteration trailers.

Required opts:
  `:active-extensions` - vec from `(active-extensions env)`. Drives
     environment, extension prompt, and hint collection.

Optional opts:
  `:system-prompt`            - caller addendum appended to CORE.
  `:session-context`          - rendered fenced-Python `session = {…}` block
     (standing session state: workspace / env / routing / tools). Embedded
     ONCE here as a cached system message; the loop re-emits only the
     `session[...] = …` structural delta in the conversation when it changes
     mid-turn.
sourceraw docstring

build-system-promptclj

(build-system-prompt {:keys [system-prompt]})

Core system prompt + optional caller addendum + config prompt + SYSTEM.md / APPEND_SYSTEM.md file overrides.

Assembled in send order (later blocks positionally reinforce earlier): base, then the caller's :system-prompt addendum, then the :system-prompt pulled from Vis config (vis.edn / .vis/config.edn / ~/.vis/config.edn, deep-merged), then ~/.vis/APPEND_SYSTEM.md, then <workspace>/.vis/APPEND_SYSTEM.md. The config + file hooks let a project append house rules without any caller having to pass them.

Full rewrite precedence for the base: <workspace>/.vis/SYSTEM.md > ~/.vis/SYSTEM.md > config :system-prompt map with :replace? true > CORE_SYSTEM_PROMPT. When a file/config replaces the base, addenda and append files are still appended after it.

Core system prompt + optional caller addendum + config prompt +
SYSTEM.md / APPEND_SYSTEM.md file overrides.

Assembled in send order (later blocks positionally reinforce earlier):
base, then the caller's `:system-prompt` addendum, then the
`:system-prompt` pulled from Vis config (`vis.edn` / `.vis/config.edn` /
`~/.vis/config.edn`, deep-merged), then `~/.vis/APPEND_SYSTEM.md`, then
`<workspace>/.vis/APPEND_SYSTEM.md`. The config + file hooks let a project
append house rules without any caller having to pass them.

Full rewrite precedence for the base: `<workspace>/.vis/SYSTEM.md` >
`~/.vis/SYSTEM.md` > config `:system-prompt` map with `:replace? true` >
`CORE_SYSTEM_PROMPT`. When a file/config replaces the base, addenda and
append files are still appended after it.
sourceraw docstring

cli-autonomous-rulesclj

Override injected ONLY for the non-interactive :cli channel (headless bin/vis '<task>' one-shot runs). No human is in the loop, so the model must never wait for input — it makes reasonable assumptions and drives the work to a finished prose answer.

Override injected ONLY for the non-interactive `:cli` channel (headless
`bin/vis '<task>'` one-shot runs). No human is in the loop, so the model
must never wait for input — it makes reasonable assumptions and drives the
work to a finished prose answer.
sourceraw docstring

extensions-snapshotclj

(extensions-snapshot active-extensions)

Build the active extension summary placed under (:extensions ctx) from a precomputed active-extensions vec.

Returns a vec of compact, fully-realized data maps - NO functions, NO atoms, NO opaque runtime objects. The model walks this with a comprehension / filter / any exactly like any other Python list of dicts; never has to reach into an extensions() call just to discover what's loaded.

Per element: :alias - short symbol the model calls under ('v, 'z, 'git, ...). nil when the extension didn't declare an :ext.engine/alias. :namespace - fully-qualified ns symbol of the extension. :doc - one-line LLM description from :ext/description (when set). :kind - categorical bucket (providers, channels, foundation, languages, persistance, ...) used as the section label both in this snapshot and in vis extensions list (when set). :registry-id - canonical manifest id, usually the alias symbol. :symbols - vec of bare symbol names the extension intern'd into the sandbox.

The vec is bound ONCE at turn start (see iteration-loop) and stays frozen for the rest of the turn - every iteration sees the same value.

Build the active extension summary placed under `(:extensions ctx)` from a
precomputed active-extensions vec.

Returns a vec of compact, fully-realized data maps - NO functions,
NO atoms, NO opaque runtime objects. The model walks this with a
comprehension / `filter` / `any` exactly like any other Python list of
dicts; never has to reach into an `extensions()` call just to discover
what's loaded.

Per element:
  :alias     - short symbol the model calls under (`'v`, `'z`,
               `'git`, ...). nil when the extension didn't declare
               an `:ext.engine/alias`.
  :namespace - fully-qualified ns symbol of the extension.
  :doc       - one-line LLM description from `:ext/description` (when set).
  :kind      - categorical bucket (providers, channels, foundation,
               languages, persistance, ...) used as the section
               label both in this snapshot and in `vis extensions
               list` (when set).
  :registry-id - canonical manifest id, usually the alias symbol.
  :symbols   - vec of bare symbol names the extension intern'd into
               the sandbox.

The vec is bound ONCE at turn start (see `iteration-loop`) and
stays frozen for the rest of the turn - every iteration sees the
same value.
sourceraw docstring

previous-turn-context-blockclj

(previous-turn-context-block turns)

Cross-process RESUME context: every prior ANSWERED turn rendered oldest→newest as user asked → what you ran → you answered, so a fresh process reconstructs the conversation. Every prior answer is rendered in FULL — history is never truncated. nil when there are no prior turns.

Takes a VEC of {:user-request :answer :interrupted? :results} (results = [{:scope :src}]). An :interrupted? turn was cut off mid-flight (e.g. a process restart) with no answer — it's surfaced so a follow-up continue knows the pending work.

Cross-process RESUME context: every prior ANSWERED turn rendered oldest→newest
as `user asked → what you ran → you answered`, so a fresh process reconstructs
the conversation. Every prior answer is rendered in FULL — history is
never truncated. nil when there are no prior turns.

Takes a VEC of `{:user-request :answer :interrupted? :results}` (results =
`[{:scope :src}]`). An `:interrupted?` turn was cut off mid-flight (e.g. a
process restart) with no answer — it's surfaced so a follow-up `continue`
knows the pending work.
sourceraw docstring

reason-via-comments-instructionclj

Reasoning fallback for models with no native thinking channel. The host injects this (see with-reasoning-comments-nudge) only when a reasoning level was requested AND the resolved model is not :reasoning?-capable — giving weaker / local models (e.g. LM Studio) a scratchpad in the one channel they always have: the code itself.

Reasoning fallback for models with no native thinking channel. The host
injects this (see `with-reasoning-comments-nudge`) only when a reasoning
level was requested AND the resolved model is not `:reasoning?`-capable —
giving weaker / local models (e.g. LM Studio) a scratchpad in the one
channel they always have: the code itself.
sourceraw docstring

stable-prompt-textclj

(stable-prompt-text messages)

Join stable prompt message contents for token budgeting and debug bindings only. Provider sends the original message vector; this is not a send path.

Join stable prompt message contents for token budgeting and debug bindings only.
Provider sends the original message vector; this is not a send path.
sourceraw docstring

weak-model-operating-rulesclj

The few rules weaker / local models most often break, restated in plain imperative form. Injected (with reason-via-comments-instruction) only for non-:reasoning? models — the same audience that drowns in the full system prompt. Recency-weighted: it rides right before the conversation. Keep it SHORT; it reinforces, it does not re-teach the whole surface.

The few rules weaker / local models most often break, restated in plain
imperative form. Injected (with `reason-via-comments-instruction`) only for
non-`:reasoning?` models — the same audience that drowns in the full system
prompt. Recency-weighted: it rides right before the conversation. Keep it
SHORT; it reinforces, it does not re-teach the whole surface.
sourceraw docstring

with-reasoning-comments-nudgeclj

(with-reasoning-comments-nudge messages)

Append the reason-via-code-comments instruction PLUS the weak-model operating rules as a single turn-scoped system message, after any leading system messages and before the conversation. Use when a reasoning level was requested but the model cannot reason natively. No-op-safe: returns messages unchanged if the nudge can't build.

Append the reason-via-code-comments instruction PLUS the weak-model
operating rules as a single turn-scoped system message, after any leading
system messages and before the conversation. Use when a reasoning level was
requested but the model cannot reason natively. No-op-safe: returns
`messages` unchanged if the nudge can't build.
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