LLM interaction utilities for structured and unstructured outputs.
SVAR = Structured Validated Automated Reasoning
Scope: structured LLM output + provider routing. Main functions:
ask! - Structured output using the spec DSLask-code! - native tool-calling completion (the model acts via tools)models! - Fetch available models from the LLM APIRe-exports the spec DSL (field, spec, str->data, str->data-with-spec,
data->str, validate-data, spec->prompt, build-ref-registry) and
make-router so users can require only this namespace. The provider
catalog, token counting, pricing and failure classification that routing
uses are public here too (KNOWN_PROVIDERS, count-tokens,
estimate-cost, classify-failure, ...).
Configuration: LLM calls route automatically via the router.
Example: (ask! router {:spec my-spec :messages [(system "Help the user.") (user "What is 2+2?")] :model "gpt-4o"})
LLM interaction utilities for structured and unstructured outputs.
SVAR = Structured Validated Automated Reasoning
Scope: structured LLM output + provider routing. Main functions:
- `ask!` - Structured output using the spec DSL
- `ask-code!` - native tool-calling completion (the model acts via tools)
- `models!` - Fetch available models from the LLM API
Re-exports the spec DSL (`field`, `spec`, `str->data`, `str->data-with-spec`,
`data->str`, `validate-data`, `spec->prompt`, `build-ref-registry`) and
`make-router` so users can require only this namespace. The provider
catalog, token counting, pricing and failure classification that routing
uses are public here too (`KNOWN_PROVIDERS`, `count-tokens`,
`estimate-cost`, `classify-failure`, ...).
Configuration:
LLM calls route automatically via the router.
Example:
(ask! router {:spec my-spec
:messages [(system "Help the user.")
(user "What is 2+2?")]
:model "gpt-4o"})Asks the LLM and returns structured Clojure data with token usage and cost.
Responses calls also return :request-accounting; see ask-code!.
With an explicit session, appends one native completion turn; {:history [...]}
replaces canonical history while retaining the physical provider connection.
Asks the LLM and returns structured Clojure data with token usage and cost.
Responses calls also return :request-accounting; see `ask-code!`.
With an explicit session, appends one native completion turn; `{:history [...]}`
replaces canonical history while retaining the physical provider connection.Native tool-calling completion. Sibling of ask! (structured :spec).
The model takes action by calling a :tool; no tool call ⇒ its text is the
final answer (:stop-reason :end). Returns {:stop-reason :tool-calls|:end
:tool-calls :content :assistant-message :reasoning :tokens :cost :duration-ms
:rate-limit :prompt-cache-context}. :rate-limit (when the provider sent quota
headers) carries {:resets-at-ms <epoch-ms> :remaining :limit :windows}.
Responses calls also return content-free :request-accounting on the result and final :on-chunk callback, even with :check-context? false or missing usage: {:source :svar-estimate :projection :prepared-request :model <actual model> :api-style :openai-compatible-responses :input-tokens N :components {:messages N :instructions N :tools N :output-format N :reply-priming N}}. Components sum to :input-tokens; messages/instructions include their framing. Counts cover the final attempt after replay filtering, tool shaping and body overrides, not discarded retries. For WebSocket continuation this is the full prepared context, not just the transmitted delta. Preflight and provider context-overflow ex-data carry the rejected request's :request-accounting. Other API styles omit it. No prompt, tool payload, signature or credential is included. Text/schema tokens use the model tokenizer; images, opaque reasoning and framing remain estimates. Provider usage (including cached input) stays authoritative; this API neither rescales usage nor sums retries.
:input-token-estimator optionally accepts a request map with :provider-id,
:model, :messages, opaque :prompt-cache-context, :tokenizer and :local-input-tokens.
Return a nonnegative input count only for a validated unchanged measured prefix
on this exact route/account/policy; return nil otherwise. Preflight then uses the
estimate instead of recounting that prefix. Provider usage is never overwritten.
Supported tokenizer declarations are o200k_base and cl100k_base; other names
retain the model-name/local fallback, so all local counts remain estimates.
Native tool-calling completion. Sibling of `ask!` (structured `:spec`).
The model takes action by calling a `:tool`; no tool call ⇒ its text is the
final answer (`:stop-reason :end`). Returns {:stop-reason :tool-calls|:end
:tool-calls :content :assistant-message :reasoning :tokens :cost :duration-ms
:rate-limit :prompt-cache-context}. `:rate-limit` (when the provider sent quota
headers) carries `{:resets-at-ms <epoch-ms> :remaining :limit :windows}`.
Responses calls also return content-free :request-accounting on the result and
final :on-chunk callback, even with :check-context? false or missing usage:
{:source :svar-estimate :projection :prepared-request :model <actual model>
:api-style :openai-compatible-responses :input-tokens N
:components {:messages N :instructions N :tools N :output-format N :reply-priming N}}.
Components sum to :input-tokens; messages/instructions include their framing.
Counts cover the final attempt after replay filtering, tool shaping and body
overrides, not discarded retries. For WebSocket continuation this is the full
prepared context, not just the transmitted delta. Preflight and provider
context-overflow ex-data carry the rejected request's :request-accounting.
Other API styles omit it. No prompt, tool payload, signature or credential is
included. Text/schema tokens use the model tokenizer; images, opaque reasoning
and framing remain estimates. Provider usage (including cached input) stays
authoritative; this API neither rescales usage nor sums retries.
`:input-token-estimator` optionally accepts a request map with :provider-id,
:model, :messages, opaque :prompt-cache-context, :tokenizer and :local-input-tokens.
Return a nonnegative input count only for a validated unchanged measured prefix
on this exact route/account/policy; return nil otherwise. Preflight then uses the
estimate instead of recounting that prefix. Provider usage is never overwritten.
Supported tokenizer declarations are o200k_base and cl100k_base; other names
retain the model-name/local fallback, so all local counts remain estimates.Builds a registry of referenced specs.
Builds a registry of referenced specs.
Wraps text in a cacheable content block. Anthropic emits cache_control.
GPT-5.6+ Responses emits explicit prompt-cache breakpoints, including a
rolling prior-turn boundary; older OpenAI-compatible styles strip the marker.
Wraps text in a cacheable content block. Anthropic emits `cache_control`. GPT-5.6+ Responses emits explicit prompt-cache breakpoints, including a rolling prior-turn boundary; older OpenAI-compatible styles strip the marker.
Cardinality: Vector of values.
Cardinality: Vector of values.
Classifies a provider or gateway failure into a stable shape:
{:category :retryable? :reached-model? :status :request-id :summary :next-step ...}.
Classifies a provider or gateway failure into a stable shape:
`{:category :retryable? :reached-model? :status :request-id :summary
:next-step ...}`.Closes an explicit LLM session; active transport aborts, idle transport closes gracefully. Idempotent.
Closes an explicit LLM session; active transport aborts, idle transport closes gracefully. Idempotent.
Resolve a route's input/output budget without inference. See internal.llm/context-budget.
Resolve a route's input/output budget without inference. See internal.llm/context-budget.
Estimates the tokens of a message vector for a model, including reasoning, tool payloads, text and images. Provider usage stays authoritative.
Estimates the tokens of a message vector for a model, including reasoning, tool payloads, text and images. Provider usage stays authoritative.
Counts the tokens of a text string with the model's tokenizer. A tokenizer's special tokens count as the plain text they are.
Counts the tokens of a text string with the model's tokenizer. A tokenizer's special tokens count as the plain text they are.
Serializes Clojure data to LLM-compatible string.
Serializes Clojure data to LLM-compatible string.
Field option: Human-readable field description.
Field option: Human-readable field description.
Estimates USD cost from input and output tokens, with separate uncached input, cached input, cache creation and output components. Rates are USD per 1M tokens.
Estimates USD cost from input and output tokens, with separate uncached input, cached input, cache creation and output components. Rates are USD per 1M tokens.
Creates a field definition for a spec.
Creates a field definition for a spec.
Creates an image attachment for use with user messages.
Creates an image attachment for use with `user` messages.
Spec option: Namespace prefix to add to keys during parsing.
Spec option: Namespace prefix to add to keys during parsing.
Svar's built-in provider catalog: provider id -> defaults such as :base-url,
:api-style, :env-keys, :default-models, rate limits and plan-tier policy.
Consumers layer their own provider metadata over these defaults.
Svar's built-in provider catalog: provider id -> defaults such as `:base-url`, `:api-style`, `:env-keys`, `:default-models`, rate limits and plan-tier policy. Consumers layer their own provider metadata over these defaults.
Creates a router from a vector of provider maps.
Creates a router from a vector of provider maps.
Credential-safe account/endpoint identity for persisting live model metadata.
Credential-safe account/endpoint identity for persisting live model metadata.
Flattened model name -> pricing table (USD per 1M tokens) that
estimate-cost uses when no pricing map is given. A model served by several
providers takes the cheapest total.
Flattened model name -> pricing table (USD per 1M tokens) that `estimate-cost` uses when no pricing map is given. A model served by several providers takes the cheapest total.
Fetch models with published :context (total window), :input-limit, :output-limit and :tokenizer metadata when available. Missing fields remain absent.
Fetch models with published :context (total window), :input-limit, :output-limit and :tokenizer metadata when available. Missing fields remain absent.
Field option: Field name as Datomic-style keyword.
Field option: Field name as Datomic-style keyword.
Normalizes one provider entry the way make-router does: fills :base-url
from KNOWN_PROVIDERS, derives :priority and :root, and merges model
metadata with provider-scoped pricing and context limits.
Takes the entry's position and the entry.
Normalizes one provider entry the way `make-router` does: fills `:base-url` from `KNOWN_PROVIDERS`, derives `:priority` and `:root`, and merges model metadata with provider-scoped pricing and context limits. Takes the entry's position and the entry.
Coerce any accepted spelling to canonical :low|:balanced|:deep. Also accepts :low/:medium/:high aliases for OpenAI-style migrations.
Coerce any accepted spelling to canonical :low|:balanced|:deep. Also accepts :low/:medium/:high aliases for OpenAI-style migrations.
Opens a sequential LLM session. OpenAI Codex uses a persistent Responses
WebSocket and server continuation, with no default request byte ceiling.
A cursorless request above :websocket-max-full-request-bytes or a
session-local ceiling learned from a 1009 close uses HTTP for that turn.
Smaller replays can re-enter WebSocket. Close the session with
close-session! or with-open.
Opens a sequential LLM session. OpenAI Codex uses a persistent Responses WebSocket and server continuation, with no default request byte ceiling. A cursorless request above `:websocket-max-full-request-bytes` or a session-local ceiling learned from a 1009 close uses HTTP for that turn. Smaller replays can re-enter WebSocket. Close the session with `close-session!` or `with-open`.
Returns Svar's opaque fixed-prefix/cache-namespace identity for routed tool calls.
Returns Svar's opaque fixed-prefix/cache-namespace identity for routed tool calls.
(prompt-cache-status router)(prompt-cache-status router cache-scope provider-id model)Returns Svar-owned, route-local provider prompt-cache telemetry.
Returns Svar-owned, route-local provider prompt-cache telemetry.
Sane default base-url svar knows for a provider id (plan-tier aware). Consumers (e.g. vis provider extensions) use it as the preset default and override only for local/custom endpoints.
Sane default base-url svar knows for a provider id (plan-tier aware). Consumers (e.g. vis provider extensions) use it as the preset default and override only for local/custom endpoints.
Sane default model NAMES (vec of strings) svar curates for a provider id
(plan-tier aware). The single source of truth — consumers use it as their
:default-models and override only for a different curated set.
Sane default model NAMES (vec of strings) svar curates for a provider id (plan-tier aware). The single source of truth — consumers use it as their `:default-models` and override only for a different curated set.
Metadata for one model as a provider serves it (capabilities, pricing,
context limits), without building a router. Takes a provider id and a model
map with at least :name.
Metadata for one model as a provider serves it (capabilities, pricing, context limits), without building a router. Takes a provider id and a model map with at least `:name`.
True when the provider's model filters allow model-name.
True when the provider's model filters allow `model-name`.
Translate abstract level → provider-specific extra-body map (or nil). Returns nil for non-reasoning models; callers can merge the result into their own extra-body.
Translate abstract level → provider-specific extra-body map (or nil). Returns nil for non-reasoning models; callers can merge the result into their own extra-body.
Abstract reasoning depths translated per provider api-style.
See com.blockether.svar.internal.router/REASONING_LEVELS.
Abstract reasoning depths translated per provider api-style. See `com.blockether.svar.internal.router/REASONING_LEVELS`.
Field option: Whether field is required (default: true).
Field option: Whether field is required (default: true).
Resets the router's token/cost budget counters to zero.
Resets the router's token/cost budget counters to zero.
Manually resets a provider's circuit breaker to :closed.
Manually resets a provider's circuit breaker to :closed.
The model descriptor a router would route to, optionally under routing
overrides such as :optimize, :provider or :model. Returns nil when no
provider is available.
The model descriptor a router would route to, optionally under routing overrides such as `:optimize`, `:provider` or `:model`. Returns nil when no provider is available.
Resolve exact provider-native high|max support and wire evidence.
No abstract reasoning aliases or automatic translations are applied.
Resolve exact provider-native `high|max` support and wire evidence. No abstract reasoning aliases or automatic translations are applied.
Returns cumulative + windowed stats for the router.
Returns cumulative + windowed stats for the router.
Returns an explicit session's canonical replay history.
Returns an explicit session's canonical replay history.
Returns provider-safe transport telemetry for an explicit session.
Returns provider-safe transport telemetry for an explicit session.
Creates a spec definition from field definitions.
Creates a spec definition from field definitions.
Generates LLM prompt from a spec.
Generates LLM prompt from a spec.
Parses LLM response string to Clojure data.
Parses LLM response string to Clojure data.
Parses LLM response with spec validation.
Parses LLM response with spec validation.
Typed stream aborts (time to first token, idle and semantic watchdogs) that are safe to retry only before visible output.
Typed stream aborts (time to first token, idle and semantic watchdogs) that are safe to retry only before visible output.
Field option: Reference target for :spec.type/ref fields.
Field option: Reference target for :spec.type/ref fields.
Type: Fixed-size double vector (1 element).
Type: Fixed-size double vector (1 element).
Type: Fixed-size double vector (10 elements).
Type: Fixed-size double vector (10 elements).
Type: Fixed-size double vector (11 elements).
Type: Fixed-size double vector (11 elements).
Type: Fixed-size double vector (12 elements).
Type: Fixed-size double vector (12 elements).
Type: Fixed-size double vector (2 elements).
Type: Fixed-size double vector (2 elements).
Type: Fixed-size double vector (3 elements).
Type: Fixed-size double vector (3 elements).
Type: Fixed-size double vector (4 elements).
Type: Fixed-size double vector (4 elements).
Type: Fixed-size double vector (5 elements).
Type: Fixed-size double vector (5 elements).
Type: Fixed-size double vector (6 elements).
Type: Fixed-size double vector (6 elements).
Type: Fixed-size double vector (7 elements).
Type: Fixed-size double vector (7 elements).
Type: Fixed-size double vector (8 elements).
Type: Fixed-size double vector (8 elements).
Type: Fixed-size double vector (9 elements).
Type: Fixed-size double vector (9 elements).
Type: Fixed-size int vector (1 element).
Type: Fixed-size int vector (1 element).
Type: Fixed-size int vector (10 elements).
Type: Fixed-size int vector (10 elements).
Type: Fixed-size int vector (11 elements).
Type: Fixed-size int vector (11 elements).
Type: Fixed-size int vector (12 elements).
Type: Fixed-size int vector (12 elements).
Type: Fixed-size int vector (2 elements).
Type: Fixed-size int vector (2 elements).
Type: Fixed-size int vector (3 elements).
Type: Fixed-size int vector (3 elements).
Type: Fixed-size int vector (4 elements).
Type: Fixed-size int vector (4 elements).
Type: Fixed-size int vector (5 elements).
Type: Fixed-size int vector (5 elements).
Type: Fixed-size int vector (6 elements).
Type: Fixed-size int vector (6 elements).
Type: Fixed-size int vector (7 elements).
Type: Fixed-size int vector (7 elements).
Type: Fixed-size int vector (8 elements).
Type: Fixed-size int vector (8 elements).
Type: Fixed-size int vector (9 elements).
Type: Fixed-size int vector (9 elements).
Type: Fixed-size string vector (1 element).
Type: Fixed-size string vector (1 element).
Type: Fixed-size string vector (10 elements).
Type: Fixed-size string vector (10 elements).
Type: Fixed-size string vector (11 elements).
Type: Fixed-size string vector (11 elements).
Type: Fixed-size string vector (12 elements).
Type: Fixed-size string vector (12 elements).
Type: Fixed-size string vector (2 elements).
Type: Fixed-size string vector (2 elements).
Type: Fixed-size string vector (3 elements).
Type: Fixed-size string vector (3 elements).
Type: Fixed-size string vector (4 elements).
Type: Fixed-size string vector (4 elements).
Type: Fixed-size string vector (5 elements).
Type: Fixed-size string vector (5 elements).
Type: Fixed-size string vector (6 elements).
Type: Fixed-size string vector (6 elements).
Type: Fixed-size string vector (7 elements).
Type: Fixed-size string vector (7 elements).
Type: Fixed-size string vector (8 elements).
Type: Fixed-size string vector (8 elements).
Type: Fixed-size string vector (9 elements).
Type: Fixed-size string vector (9 elements).
Field option: Set of allowed nil types.
Field option: Set of allowed nil types.
Creates a user message, optionally with images.
Creates a user message, optionally with images.
Validates parsed data against a spec.
Validates parsed data against a spec.
Field option: Enum values as map {value description}.
Field option: Enum values as map {value description}.
(with-log-context context & body)Evaluates body with context merged into the map svar adds to its HTTP
logs, e.g. {:query-id "abc" :iteration 0}.
Evaluates `body` with `context` merged into the map svar adds to its HTTP
logs, e.g. `{:query-id "abc" :iteration 0}`.cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |