Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.gateway.wire

Wire encoding for the HTTP gateway.

One dumb, deterministic boundary: engine EDN -> JSON. Keyword/symbol keys become snake_case strings (namespace dropped), keyword values keep their full ns/name, non-JSON leaves fall back to str. The walker makes zero semantic or rendering decisions. Canonical message content is already a string-keyed vector of typed block maps before it reaches this boundary.

canonical is the SAME shape on the Clojure side: by definition what parse-jsonjson-str yields — snake_case STRING keys — serve it from a facade and in-process readers see exactly what a remote client sees.

Wire encoding for the HTTP gateway.

One dumb, deterministic boundary: engine EDN -> JSON. Keyword/symbol
keys become snake_case strings (namespace dropped), keyword values keep their
full `ns/name`, non-JSON leaves fall back to `str`. The walker makes zero
semantic or rendering decisions. Canonical message content is already a
string-keyed vector of typed block maps before it reaches this boundary.

`canonical` is the SAME shape on the Clojure side: by definition what
`parse-json` ∘ `json-str` yields — snake_case STRING keys — serve it from
a facade and in-process readers see exactly what a remote client sees.
raw docstring

->engineclj

(->engine x)

Recursively convert decoded wire data into the engine's keyword-keyed shape — the mirror of ->wire. Only KEYS are converted (via engine-key); values are data and are never re-typed.

Recursively convert decoded wire data into the engine's keyword-keyed shape —
the mirror of [[->wire]]. Only KEYS are converted (via [[engine-key]]); values
are data and are never re-typed.
sourceraw docstring

->wireclj

(->wire x)

Recursively convert an engine value into JSON-encodable data.

Recursively convert an engine value into JSON-encodable data.
sourceraw docstring

bounded-prclj

(bounded-pr x limit)

Bounded pr-str for tool results / errors riding events. Protects the event log and SSE frames from multi-megabyte values.

Bounded `pr-str` for tool results / errors riding events. Protects the
event log and SSE frames from multi-megabyte values.
sourceraw docstring

bounded-strclj

(bounded-str s limit)

Bounded plain-string clamp for an ALREADY-rendered value (e.g. the model-facing render-form-value string) — same megabyte protection as bounded-pr but WITHOUT re-pr-str'ing, so the string rides the wire verbatim instead of quoted/escaped.

Bounded plain-string clamp for an ALREADY-rendered value (e.g. the
model-facing `render-form-value` string) — same megabyte protection as
`bounded-pr` but WITHOUT re-`pr-str`'ing, so the string rides the wire
verbatim instead of quoted/escaped.
sourceraw docstring

canonicalclj

(canonical x)

THE canonical gateway value shape — snake_case STRING map keys, exactly what a remote client holds after parse-jsonjson-str. In-process and remote consumers therefore read the same role-labelled messages and typed content blocks.

Invariant: (canonical x) equals (parse-json (json-str x)).

THE canonical gateway value shape — snake_case STRING map keys, exactly
what a remote client holds after `parse-json` ∘ `json-str`. In-process and
remote consumers therefore read the same role-labelled messages and typed
content blocks.

Invariant: `(canonical x)` equals `(parse-json (json-str x))`.
sourceraw docstring

engine-keyclj

(engine-key k)

Wire key -> engine keyword: THE inverse of wire-key, and the only one. is_foo -> :is-foo, foo_bar -> :foo-bar.

It is total only because the engine spells a boolean :is-foo and never :foo?: wire-key collapses BOTH spellings onto is_foo, so while a :foo? key exists no rule can tell which one a wire key came from. That ambiguity is why every inbound seam used to grow its own hand-written list of exceptions, and why forgetting one entry was silent. A FOREIGN contract that insists on ? (svar's :tool-call?) maps through its own named table at its own seam — never by convention here.

Wire key -> engine keyword: THE inverse of [[wire-key]], and the only one.
`is_foo` -> `:is-foo`, `foo_bar` -> `:foo-bar`.

It is total only because the engine spells a boolean `:is-foo` and never
`:foo?`: [[wire-key]] collapses BOTH spellings onto `is_foo`, so while a
`:foo?` key exists no rule can tell which one a wire key came from. That
ambiguity is why every inbound seam used to grow its own hand-written list of
exceptions, and why forgetting one entry was silent. A FOREIGN contract that
insists on `?` (svar's `:tool-call?`) maps through its own named table at its
own seam — never by convention here.
sourceraw docstring

json-strclj

(json-str x)

Encode any engine value as a JSON string via ->wire.

Encode any engine value as a JSON string via [[->wire]].
sourceraw docstring

json-str-prettyclj

(json-str-pretty x)

Pretty-printed (2-space indent) JSON via ->wire — for HUMAN-facing surfaces (the web ctx rail's trailer view), never the wire itself.

Pretty-printed (2-space indent) JSON via [[->wire]] — for
HUMAN-facing surfaces (the web ctx rail's trailer view), never the
wire itself.
sourceraw docstring

parse-jsonclj

(parse-json s)

Parse a JSON string into the canonical wire shape: snake_case STRING map keys, identical to canonical. Returns nil on blank or malformed input (callers map that to 400).

Parse a JSON string into the canonical wire shape: snake_case STRING map
keys, identical to [[canonical]]. Returns nil on blank or malformed input
(callers map that to 400).
sourceraw docstring

queue-mirror-event-typesclj

Queue lifecycle event types every attached channel mirrors LIVE even when they belong to a DIFFERENT (queued) turn of the same session — the ONE set both transports forward (the in-process gateway.state subscriptions AND the SSE loop in gateway.client), so a message queued/edited/deleted in one channel shows up in every sibling. turn.queued.drained marks the queue head leaving the queue because the gateway auto-STARTED it, so mirrors drop the entry and a replayed history nets to zero (turn.queuedturn.queued.drained). queue.paused/queue.resumed carry the held count so every sibling shows the same paused banner and unpauses together.

Queue lifecycle event types every attached channel mirrors LIVE even when
they belong to a DIFFERENT (queued) turn of the same session — the ONE set
both transports forward (the in-process `gateway.state` subscriptions AND
the SSE loop in `gateway.client`), so a message queued/edited/deleted in
one channel shows up in every sibling. `turn.queued.drained` marks the
queue head leaving the queue because the gateway auto-STARTED it, so
mirrors drop the entry and a replayed history nets to zero
(`turn.queued` … `turn.queued.drained`). `queue.paused`/`queue.resumed` carry
the held count so every sibling shows the same paused banner and unpauses
together.
sourceraw docstring

sse-frameclj

(sse-frame event)

Render one canonical (string-keyed) event map as an SSE frame. The event's "seq" doubles as the SSE id: so Last-Event-ID reconnects resume losslessly.

Render one canonical (string-keyed) event map as an SSE frame. The event's
`"seq"` doubles as the SSE `id:` so `Last-Event-ID` reconnects resume
losslessly.
sourceraw docstring

turn-meta-keysclj

Wire keys of a settled turn's META (usage/routing/timing) — the fields terminal-event->result (both the in-process gateway.state impl and the SSE gateway.client twin) resolves for the sync submit/attach result. Terminal events are deliberately LEAN ({:turn_id :status}), so these are read primarily from the registry's turn row (merged by finish-turn!), with any event-carried value winning. ONE list so the two impls can't drift.

Wire keys of a settled turn's META (usage/routing/timing) — the fields
`terminal-event->result` (both the in-process `gateway.state` impl and the
SSE `gateway.client` twin) resolves for the sync submit/attach result.
Terminal events are deliberately LEAN (`{:turn_id :status}`), so these are
read primarily from the registry's turn row (merged by `finish-turn!`),
with any event-carried value winning. ONE list so the two impls can't
drift.
sourceraw docstring

turn-terminal-event-typesclj

Every event type that ENDS a turn — the ONE set both blocking readers use (gateway.state's in-process submit/attach subscriptions AND the SSE loop in gateway.client). turn.cancelled belongs here: a user stop (or a stall force-cancel) lands a turn exactly like a completion, and a reader that only watched for turn.completed/turn.failed parked on that turn FOREVER — its SSE connection stayed open, its channel kept a live spinner, and a queued turn draining behind it streamed into a tab whose previous stream had never closed.

Every event type that ENDS a turn — the ONE set both blocking readers use
(`gateway.state`'s in-process submit/attach subscriptions AND the SSE loop in
`gateway.client`). `turn.cancelled` belongs here: a user stop (or a stall
force-cancel) lands a turn exactly like a completion, and a reader that only
watched for `turn.completed`/`turn.failed` parked on that turn FOREVER —
its SSE connection stayed open, its channel kept a live spinner, and a
queued turn draining behind it streamed into a tab whose previous stream
had never closed.
sourceraw docstring

voice-job-eventclj

SSE event: name of EVERY frame on a transcription job's stream — the ONE discriminator that keeps a job's progress from being read as a session event.

The gateway speaks SSE on two unrelated resources and a consumer must never mistake one for the other. GET /v1/sessions/:sid/events is the session's ordered event LOG: every frame carries an id: cursor, its event: is the engine event TYPE, it replays from Last-Event-ID, and it stays open for the life of the session. GET /v1/sessions/:sid/voice/jobs/:job-id/events is ONE transcription's state: no cursor, no replay, exactly this event name on every frame, and the stream ENDS on the terminal one. /v1/capabilities publishes this string as features.voice.progress_event and the companion mirrors it as VOICE_JOB_EVENT (apps/vis-companion/src/lib/gateway.ts), so a client filters on a name it was told rather than guessing from the payload's shape.

SSE `event:` name of EVERY frame on a transcription job's stream — the ONE
discriminator that keeps a job's progress from being read as a session event.

The gateway speaks SSE on two unrelated resources and a consumer must never
mistake one for the other. `GET /v1/sessions/:sid/events` is the session's
ordered event LOG: every frame carries an `id:` cursor, its `event:` is the
engine event TYPE, it replays from `Last-Event-ID`, and it stays open for the
life of the session. `GET /v1/sessions/:sid/voice/jobs/:job-id/events` is ONE
transcription's state: no cursor, no replay, exactly this event name on every
frame, and the stream ENDS on the terminal one. `/v1/capabilities` publishes
this string as `features.voice.progress_event` and the companion mirrors it as
`VOICE_JOB_EVENT` (apps/vis-companion/src/lib/gateway.ts), so a client filters
on a name it was told rather than guessing from the payload's shape.
sourceraw docstring

voice-job-sse-frameclj

(voice-job-sse-frame job)

Render one transcription job as its own SSE frame.

Deliberately no id:: a job stream carries a RESOURCE's current state, not a replayable log, so there is no cursor to resume from — a reconnect is answered with the job as it is now (see voice-job-event).

Render one transcription job as its own SSE frame.

Deliberately no `id:`: a job stream carries a RESOURCE's current state, not a
replayable log, so there is no cursor to resume from — a reconnect is answered
with the job as it is now (see [[voice-job-event]]).
sourceraw docstring

wire-keyclj

(wire-key k)

Keyword/symbol map key -> snake_case string. A boolean-style foo? key becomes is_foo (already-is- prefixed keys just drop the ?). String keys (fact keys, scope strings, file paths) pass VERBATIM - rewriting them could corrupt user data that legitimately contains hyphens. ANY other key (the number/boolean/nil keys a decoded JSON or Python value can carry into a tool result) is rendered to its JSON key spelling: JSON has no non-string keys, and leaving one unrendered makes the whole event unencodable - which kills the transport, not just the field.

Keyword/symbol map key -> snake_case string. A boolean-style `foo?` key
becomes `is_foo` (already-`is-` prefixed keys just drop the `?`). String
keys (fact keys, scope strings, file paths) pass VERBATIM - rewriting
them could corrupt user data that legitimately contains hyphens. ANY
other key (the number/boolean/nil keys a decoded JSON or Python value can
carry into a tool result) is rendered to its JSON key spelling: JSON has
no non-string keys, and leaving one unrendered makes the whole event
unencodable - which kills the transport, not just the field.
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