Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.context.agents

Project-guidance discovery — internal, no extension required.

STACKED context files, pi-style: guidance is collected from THREE layers and all of them ride into the PROJECT-INSTRUCTIONS system block, outermost first:

  1. user-global ~/.vis/AGENTS.md (or ~/.vis/CLAUDE.md)
  2. ancestors AGENTS.md / CLAUDE.md in every ancestor directory of the workspace root (outermost first)
  3. workspace AGENTS.md / CLAUDE.md at the workspace root
  4. added roots AGENTS.md / CLAUDE.md at each ADDED filesystem root's own directory (folders granted beyond the primary workspace — no ancestor walk)

Per DIRECTORY precedence is strict: AGENTS.md wins; CLAUDE.md is only consulted when AGENTS.md is absent in that directory. Across directories nothing is dropped — nearer files are rendered LATER so they positionally override outer rules on conflict.

Size policy: NO truncation. Every file goes into the system prompt verbatim. Provider prompt caching amortizes the cost across every iter in the session; trimming would risk dropping the very rule the user is testing. The cwd + per-file (path, mtime, length) marker cache below ensures files are re-read at most once per change.

Failure modes (file unreadable, permissions, I/O error) land in the read-warning vec, NOT in the rendered prompt. The model isn't bound by rules it can't see, but the host knows something is broken.

This namespace replaces the foundation-core/environment/agents.clj that used to live in the extension. Project-guidance discovery is core functionality (drives the system prompt + slim ctx digest); the extension layer no longer owns it.

Project-guidance discovery — internal, no extension required.

STACKED context files, pi-style: guidance is collected from THREE
layers and all of them ride into the PROJECT-INSTRUCTIONS system
block, outermost first:

  1. user-global   `~/.vis/AGENTS.md` (or `~/.vis/CLAUDE.md`)
  2. ancestors     `AGENTS.md` / `CLAUDE.md` in every ancestor
                   directory of the workspace root (outermost first)
  3. workspace     `AGENTS.md` / `CLAUDE.md` at the workspace root
4. added roots   `AGENTS.md` / `CLAUDE.md` at each ADDED filesystem
                 root's own directory (folders granted beyond the
                 primary workspace — no ancestor walk)

Per DIRECTORY precedence is strict: AGENTS.md wins; CLAUDE.md is
only consulted when AGENTS.md is absent in that directory. Across
directories nothing is dropped — nearer files are rendered LATER so
they positionally override outer rules on conflict.

Size policy: NO truncation. Every file goes into the system prompt
verbatim. Provider prompt caching amortizes the cost across every
iter in the session; trimming would risk dropping the very rule the
user is testing. The cwd + per-file (path, mtime, length) marker
cache below ensures files are re-read at most once per change.

Failure modes (file unreadable, permissions, I/O error) land in the
read-warning vec, NOT in the rendered prompt. The model isn't bound
by rules it can't see, but the host knows something is broken.

This namespace replaces the foundation-core/environment/agents.clj
that used to live in the extension. Project-guidance discovery is
core functionality (drives the system prompt + slim ctx digest); the
extension layer no longer owns it.
raw docstring

com.blockether.vis.internal.context.engine

Pure helpers for the model-facing context snapshot.

The mutable session state lives outside this namespace; these functions advance the turn/iteration cursor and compute utilization metadata.

Pure helpers for the model-facing context snapshot.

The mutable session state lives outside this namespace; these functions advance
the turn/iteration cursor and compute utilization metadata.
raw docstring

com.blockether.vis.internal.context.env-digest

Slim "session_env" digest. Internal, not extension-owned. STRING-KEYED — crosses the Python boundary as session["env"], so keys AND enum values (os/shell/kind/primary_language) are strings, never keywords.

Produces a bounded map the model reads each iter:

{"host" {"os" "shell" "clock"} ; cwd lives in session["workspace"]["root"] "project" {"kind" "primary_language"} "extensions" {"active_count" "aliases"}}

Each slice is small (~50 bytes), so the section costs <200 bytes/turn. Extensions deep-merge their own slices via :ext/ctx-fn returning {"session_env" {their-key {…}}}; the merge happens in ctx-loop/render-block! so internal owns the base section, extensions layer on top.

Heavy environment scans (full byte-counted language tables, polylith brick listings, multi-repo git status) live in the foundation-core focused project-shape helpers for explicit deep-dives. The digest never calls into extensions — host facts come from System/getProperty, project shape from a single directory peek. AGENTS.md / CLAUDE.md contents ride in their own system block (internal.prompt), not here.

Slim `"session_env"` digest. Internal, not extension-owned. STRING-KEYED —
crosses the Python boundary as `session["env"]`, so keys AND enum values
(os/shell/kind/primary_language) are strings, never keywords.

Produces a bounded map the model reads each iter:

  {"host"       {"os" "shell" "clock"}   ; cwd lives in session["workspace"]["root"]
   "project"    {"kind" "primary_language"}
   "extensions" {"active_count" "aliases"}}

Each slice is small (~50 bytes), so the section costs <200 bytes/turn.
Extensions deep-merge their own slices via `:ext/ctx-fn` returning
`{"session_env" {their-key {…}}}`; the merge happens in
`ctx-loop/render-block!` so internal owns the base section, extensions
layer on top.

Heavy environment scans (full byte-counted language tables, polylith
brick listings, multi-repo git status) live in the foundation-core
focused project-shape helpers for explicit deep-dives. The digest never calls
into extensions — host facts come from `System/getProperty`,
project shape from a single directory peek. AGENTS.md / CLAUDE.md
contents ride in their own system block (`internal.prompt`), not here.
raw docstring

com.blockether.vis.internal.context.loop

Loop integration layer for context management.

The loop keeps a per-session :ctx-atom for stable model-facing context and a separate :turn-state-atom for live execution state and counters. Council publication identity and references live there only during execution; activation resources and retry input belong to the session runtime registry. This namespace stamps the cursor, enriches context with env/access/routing, and renders the standing context block. Live resources (background shells, managed REPLs) are deliberately NOT part of ctx: a handle or repl_status answers for them, so nothing about them is reprinted on every request.

Loop integration layer for context management.

The loop keeps a per-session `:ctx-atom` for stable model-facing context
and a separate `:turn-state-atom` for live execution state and counters.
Council publication identity and references live there only during execution;
activation resources and retry input belong to the session runtime registry.
This namespace stamps the cursor, enriches context with env/access/routing,
and renders the standing context block. Live resources (background shells,
managed REPLs) are deliberately NOT part of ctx: a handle or `repl_status`
answers for them, so nothing about them is reprinted on every request.
raw docstring

com.blockether.vis.internal.context.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

com.blockether.vis.internal.context.prompt-templates

File-based prompt templates — pi-style slash-expandable markdown prompts.

A template is a *.md file whose body becomes the user message when the user types /<name> [args…]. Discovery, project wins over global:

  1. <workspace>/.vis/prompts/*.md (project)
  2. ~/.vis/prompts/*.md (user-global)

Frontmatter is the same minimal --- fenced key: value block the harness discovery reads: name (defaults to the filename stem) and description. The body is the template.

Argument handling matches the common harness convention: when the body contains $ARGUMENTS every occurrence is substituted with the raw argument string (empty when none given); otherwise non-blank args are appended after the body on their own paragraph.

Extensions can contribute DYNAMIC templates through register-provider! — e.g. the harness extension exposes every discovered skill as /skill:<name>. File templates win on a name collision; among providers, registration order wins.

Dispatch: the engine consults expand ONLY for slash texts no registered extension slash claimed (slash/dispatch returned :reason :unknown), so real slash commands always win — same precedence pi uses.

File-based prompt templates — pi-style slash-expandable markdown prompts.

A template is a `*.md` file whose body becomes the user message when
the user types `/<name> [args…]`. Discovery, project wins over global:

  1. `<workspace>/.vis/prompts/*.md`   (project)
  2. `~/.vis/prompts/*.md`             (user-global)

Frontmatter is the same minimal `---` fenced `key: value` block the
harness discovery reads: `name` (defaults to the filename stem) and
`description`. The body is the template.

Argument handling matches the common harness convention: when the
body contains `$ARGUMENTS` every occurrence is substituted with the
raw argument string (empty when none given); otherwise non-blank
args are appended after the body on their own paragraph.

Extensions can contribute DYNAMIC templates through
`register-provider!` — e.g. the harness extension exposes every
discovered skill as `/skill:<name>`. File templates win on a name
collision; among providers, registration order wins.

Dispatch: the engine consults `expand` ONLY for slash texts no
registered extension slash claimed (`slash/dispatch` returned
`:reason :unknown`), so real slash commands always win — same
precedence pi uses.
raw docstring

com.blockether.vis.internal.context.renderer

Pure renderer for the standing agent-facing session snapshot.

render-ctx-static projects the session view and serializes it as a Python literal with pure JVM code. The live sandbox session dict is built from the same boundary projection, and render-ctx-delta emits executable updates.

Pure renderer for the standing agent-facing `session` snapshot.

`render-ctx-static` projects the session view and serializes it as a Python
literal with pure JVM code. The live sandbox `session` dict is built from the
same boundary projection, and `render-ctx-delta` emits executable updates.
raw 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