Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.extension.aggregate

Extension-owned durable sidecar API.

Public ext-* helpers are for code running inside an extension callback. They never accept :extension-id from callers; the currently executing extension identity is supplied by com.blockether.vis.internal.extension.

The db-* persistence facade remains the privileged/admin surface for inspecting rows across extensions.

Extension-owned durable sidecar API.

Public ext-* helpers are for code running inside an extension callback.
They never accept :extension-id from callers; the currently executing
extension identity is supplied by com.blockether.vis.internal.extension.

The db-* persistence facade remains the privileged/admin surface for
inspecting rows across extensions.
raw docstring

com.blockether.vis.internal.extension.capability

What THIS machine can actually run, asked once and answered as data.

A pack that REGISTERED exists in this process. Whether the machine behind it works is a different question, asked at a different time: landing a pack costs an atom write and happens in manifest order for every session, while a capability costs whatever its probe costs and is paid by the FIRST caller that needs it — so a session that never speaks never loads sherpa's 8-13 MB of natives, and a session that never speaks never waits for them either.

No heuristic decides this. maxMemory, an OS name and an arch say nothing about a glibc version, a missing libstdc++, or a CPU without the instructions a wheel was built for: they refuse machines that would have worked and admit machines that die inside the linker. The probe asks the real question by doing the real thing, once.

A verdict is remembered only when asking again cannot answer differently:

  • :ready — it worked, and nothing in this process will unwork it.
  • :unavailable :kind :terminal — the JVM already froze this answer. A class whose static initializer failed can NEVER load again in the same process, so probing again can only re-download a library and reprint a linker error nobody can act on. That state is the reported "voice only works after restarting Vis", which is why the verdict, not the caller, is what says so.
  • :unavailable :kind :transient — no network, a missing file, a full disk. NOT remembered: the next ask retries.

The state atom starts EMPTY and stays empty at load. graal-build-time initializes every Clojure namespace inside the BUILDER, so a value computed by a top-level form is baked into the image heap of every installed binary: a probed verdict would ship the BUILD machine's answer to every user. That cost is already paid for once — sherpa/default-native-dir is a function for this reason, and TTYDeviceControl is the single --initialize-at-run-time in build.clj after a build-time SUPPORTED=true SIGSEGV'd v0.1.33-35.

What THIS machine can actually run, asked once and answered as data.

A pack that REGISTERED exists in this process. Whether the machine behind it
works is a different question, asked at a different time: landing a pack costs
an atom write and happens in manifest order for every session, while a
capability costs whatever its probe costs and is paid by the FIRST caller that
needs it — so a session that never speaks never loads sherpa's 8-13 MB of
natives, and a session that never speaks never waits for them either.

No heuristic decides this. `maxMemory`, an OS name and an arch say nothing
about a glibc version, a missing `libstdc++`, or a CPU without the instructions
a wheel was built for: they refuse machines that would have worked and admit
machines that die inside the linker. The probe asks the real question by doing
the real thing, once.

A verdict is remembered only when asking again cannot answer differently:

- `:ready` — it worked, and nothing in this process will unwork it.
- `:unavailable` `:kind :terminal` — the JVM already froze this answer. A class
  whose static initializer failed can NEVER load again in the same process, so
  probing again can only re-download a library and reprint a linker error
  nobody can act on. That state is the reported "voice only works after
  restarting Vis", which is why the verdict, not the caller, is what says so.
- `:unavailable` `:kind :transient` — no network, a missing file, a full disk.
  NOT remembered: the next ask retries.

The state atom starts EMPTY and stays empty at load. `graal-build-time`
initializes every Clojure namespace inside the BUILDER, so a value computed by
a top-level form is baked into the image heap of every installed binary: a
probed verdict would ship the BUILD machine's answer to every user. That cost
is already paid for once — `sherpa/default-native-dir` is a function for this
reason, and `TTYDeviceControl` is the single `--initialize-at-run-time` in
`build.clj` after a build-time `SUPPORTED=true` SIGSEGV'd v0.1.33-35.
raw docstring

com.blockether.vis.internal.extension.core

Extension subsystem: spec, builders, hook execution, the global registry, and parse-error rescue.

An extension is the SINGLE entry point for everything a third-party bundle contributes to vis. Whatever surfaces it populates - Python sandbox symbols, CLI commands, channels, providers, persistence backends - it does so by listing them in the matching :ext/<surface> slot, and register-extension! dispatches each slot to its concrete sub-registry. The same data feeds:

  • the active-extensions list every iteration consults
  • the system-prompt block rendered from :ext.engine/symbols
  • the per-iteration :ext/hooks checks
  • the parse-error rescue chain

Channel and provider registries live in internal.registry; the persistence backend table lives in internal.persistance. The one ordered distribution manifest invokes each extension's explicit registration function.

Extension subsystem: spec, builders, hook execution, the global registry,
and parse-error rescue.

An extension is the SINGLE entry point for everything a third-party
bundle contributes to vis. Whatever surfaces it populates - Python
sandbox symbols, CLI commands, channels, providers, persistence
backends - it does so by listing them in the matching `:ext/<surface>`
slot, and `register-extension!` dispatches each slot to its concrete
sub-registry. The same data feeds:

  - the active-extensions list every iteration consults
  - the system-prompt block rendered from `:ext.engine/symbols`
  - the per-iteration `:ext/hooks` checks
  - the parse-error rescue chain

Channel and provider registries live in `internal.registry`; the persistence
backend table lives in `internal.persistance`. The one ordered distribution manifest invokes
each extension's explicit registration function.
raw docstring

com.blockether.vis.internal.extension.manifest

The ordered registration list for Vis' built-in modules, not a user extension loader.

META-INF/vis/manifest.edn has one key, :initialization. Each entry is a qualified registration symbol, or {:register qualified.ns/register! :apropos "META-INF/vis/apropos/docs.edn"} when the module owns static docs. Keeping documents beside their owner preserves discovery order.

Every built-in is required. Registration runs once in dependency order; a failure stops initialization rather than leaving a partial engine. Successful entries are remembered so a retry does not register them again. User extensions are Python files, loaded separately by internal.python.extensions.

Nothing scans the classpath and there is no alternate manifest format.

The ordered registration list for Vis' built-in modules, not a user extension loader.

`META-INF/vis/manifest.edn` has one key, `:initialization`. Each entry is a
qualified registration symbol, or `{:register qualified.ns/register!
:apropos "META-INF/vis/apropos/docs.edn"}` when the module owns static docs.
Keeping documents beside their owner preserves discovery order.

Every built-in is required. Registration runs once in dependency order; a failure
stops initialization rather than leaving a partial engine. Successful entries are
remembered so a retry does not register them again. User extensions are Python
files, loaded separately by `internal.python.extensions`.

Nothing scans the classpath and there is no alternate manifest format.
raw docstring

com.blockether.vis.internal.extension.native-preload

Build-time reachability for everything the engine loads DYNAMICALLY.

The manifest resolves an entrypoint with requiring-resolve, a pack reaches its own optional half the same way (voice's ASR), and a native image contains only what the BUILDER saw. A namespace nobody loads while the image is built therefore has no class in the binary, and the first command that wants it dies with "Could not locate ...__init.class on classpath" - on a binary whose JVM run is perfectly healthy. Loading them here puts them in clojure.lang.RT's namespace map, which IS part of the image heap, so the same resolve at run time finds them already loaded.

NOTHING requires this namespace. Vis' native-image.properties names its __init class in --initialize-at-build-time, so the builder loads it outside any other namespace's load: an entrypoint requiring the engine back would otherwise create a cycle. A JVM run never loads this file, so manifest registration stays lazy.

The engine namespace list is derived from the manifest's entrypoints and the compiled namespace tree. Formatter and analyzer dependencies are required here: JVM registration defers them, but the native image must retain their code.

Build-time reachability for everything the engine loads DYNAMICALLY.

The manifest resolves an entrypoint with `requiring-resolve`, a pack reaches
its own optional half the same way (voice's ASR), and a
native image contains only what the BUILDER saw. A namespace nobody loads
while the image is built therefore has no class in the binary, and the first
command that wants it dies with "Could not locate ...__init.class on
classpath" - on a binary whose JVM run is perfectly healthy. Loading them
here puts them in `clojure.lang.RT`'s namespace map, which IS part of the
image heap, so the same resolve at run time finds them already loaded.

NOTHING requires this namespace. Vis' `native-image.properties` names its
`__init` class in `--initialize-at-build-time`, so the builder loads it outside
any other namespace's load: an entrypoint requiring the engine back would
otherwise create a cycle. A JVM run never
loads this file, so manifest registration stays lazy.

The engine namespace list is derived from the manifest's entrypoints and the
compiled namespace tree. Formatter and analyzer dependencies are required here:
JVM registration defers them, but the native image must retain their code.
raw docstring

com.blockether.vis.internal.extension.registry

Three global registries in one place: channels, providers, commands.

Each descriptor is checked by a local predicate before entering its process registry.

Channel registry (:channel/id keyword): channel build + validate a descriptor register-channel! register, idempotent on :channel/id deregister-channel! remove by id registered-channels all entries, vec channel-by-id lookup by id by-cmd lookup by :channel/cmd

Provider registry (:provider/id keyword): provider build + validate a descriptor register-provider! register, idempotent on :provider/id deregister-provider! remove by id registered-providers all entries, vec provider-by-id lookup by id

Command registry ([:cmd/parent :cmd/name] tuple key): command build + validate a descriptor resolve-subcommands static vec or dynamic 0-arg fn -> vec register-cmd! register, idempotent on [parent name] deregister-cmd! remove by [parent name] registered-commands all entries, vec (registration order) registered-under filter by parent path

Channel mounting: channel-subcommands compose vis-agent channels subcommand vec from the channel registry + any commands registered with :cmd/parent ["channels"]. Loading this ns also registers the vis-agent channels parent itself. Parsing / help rendering / dispatch utilities live in com.blockether.vis.internal.commandline. The closed initialization manifest lives in com.blockether.vis.internal.extension.manifest.

Three global registries in one place: channels, providers, commands.

Each descriptor is checked by a local predicate before entering its process registry.

Channel registry (`:channel/id` keyword):
  channel                  build + validate a descriptor
  register-channel!        register, idempotent on :channel/id
  deregister-channel!      remove by id
  registered-channels      all entries, vec
  channel-by-id            lookup by id
  by-cmd                   lookup by :channel/cmd

Provider registry (`:provider/id` keyword):
  provider                 build + validate a descriptor
  register-provider!       register, idempotent on :provider/id
  deregister-provider!     remove by id
  registered-providers     all entries, vec
  provider-by-id           lookup by id

Command registry (`[:cmd/parent :cmd/name]` tuple key):
  command                  build + validate a descriptor
  resolve-subcommands      static vec or dynamic 0-arg fn -> vec
  register-cmd!            register, idempotent on [parent name]
  deregister-cmd!          remove by [parent name]
  registered-commands      all entries, vec (registration order)
  registered-under         filter by parent path

Channel mounting:
  channel-subcommands      compose `vis-agent channels` subcommand vec
                           from the channel registry + any commands
                           registered with `:cmd/parent ["channels"]`.
                           Loading this ns also registers the
                           `vis-agent channels` parent itself.
Parsing / help rendering / dispatch utilities live in
`com.blockether.vis.internal.commandline`. The closed initialization manifest
lives in `com.blockether.vis.internal.extension.manifest`.
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