Liking cljdoc? Tell your friends :D

com.blockether.vis.internal.gateway.state

Gateway session manager.

One process-global registry over the live session fleet: per-session ordered event log (monotonic :seq, ring-buffered), SSE subscriber fan-out, async turn submission with idempotency keys, cancellation, and turn/cost metrics.

The engine is reached ONLY through the same internal surfaces the TUI/Telegram channels use: loop/create!-send!-close! for the lifecycle, :hooks {:on-chunk ...} phased chunks for the live stream, ctx-loop/session-snapshot for the context. No engine state lives here - this namespace owns wire bookkeeping (events, turn records, subscribers), nothing else.

Gateway session manager.

One process-global registry over the live session fleet: per-session
ordered event log (monotonic `:seq`, ring-buffered), SSE subscriber
fan-out, async turn submission with idempotency keys, cancellation,
and turn/cost metrics.

The engine is reached ONLY through the same internal surfaces the
TUI/Telegram channels use: `loop/create!`-`send!`-`close!` for the
lifecycle, `:hooks {:on-chunk ...}` phased chunks for the live
stream, `ctx-loop/session-snapshot` for the context. No engine state
lives here - this namespace owns wire bookkeeping (events, turn
records, subscribers), nothing else.
raw docstring

append-event!clj

(append-event! sid type payload)
(append-event! sid type payload {:keys [store?]})

Append one event for sid, fan it out to LOCAL subscribers, and publish it on the cross-process bus so watchers in OTHER processes stream it too.

Assigns the next monotonic :seq atomically. :store? false events are fanned out live but kept OUT of the replay ring, so neither a cursor replay nor a /poll pull (both read the ring) re-delivers them - reserve it for genuinely ephemeral fan-out where SSE/poll divergence is acceptable (no current caller; :store? defaults true). A subscriber sink that throws is dropped - one dead SSE connection must never poison the appender or sibling subscribers.

Append one event for `sid`, fan it out to LOCAL subscribers, and publish
it on the cross-process bus so watchers in OTHER processes stream it too.

Assigns the next monotonic `:seq` atomically. `:store? false` events
are fanned out live but kept OUT of the replay ring, so neither a
cursor replay nor a `/poll` pull (both read the ring) re-delivers
them - reserve it for genuinely ephemeral fan-out where SSE/poll
divergence is acceptable (no current caller; `:store?` defaults true).
A subscriber sink that throws is dropped - one dead SSE connection
must never poison the appender or sibling subscribers.
sourceraw docstring

attach-turn-sync!clj

(attach-turn-sync! sid tid {:keys [on-event]})

Attach to an ALREADY-submitted turn tid on sid and block until it reaches a terminal event, returning the same engine-shaped result as submit-turn-sync!.

Creates NO new turn: it drives in-process (TUI) rendering for a turn the gateway queued and then auto-drains, so a busy-time submission becomes a real gateway queued record instead of a client-side shadow queue. Optional :on-event fires for every replay/live event of tid.

Attach to an ALREADY-submitted turn `tid` on `sid` and block until it reaches a
terminal event, returning the same engine-shaped result as `submit-turn-sync!`.

Creates NO new turn: it drives in-process (TUI) rendering for a turn the gateway
queued and then auto-drains, so a busy-time submission becomes a real gateway
queued record instead of a client-side shadow queue. Optional `:on-event` fires
for every replay/live event of `tid`.
sourceraw docstring

bus-wiringclj

source

cancel-turn!clj

(cancel-turn! sid tid)

Fire the cancellation token of a running turn. Returns {:status "cancelling"} or {:error ...}.

Fire the cancellation token of a running turn. Returns
`{:status "cancelling"}` or `{:error ...}`.
sourceraw docstring

close-session!clj

(close-session! sid)

DELETE a session: dispose the live environment, trash the session's draft clones (primary + auto-cloned filesystem roots — only DRAFTS have clones; a trunk workspace's roots are the user's real dirs and are never touched), then delete the session tree. Idempotent. NOTE: this is the DELETE path — merely quitting/closing a session (navigating away, no server call) keeps the draft intact so it can be resumed.

DELETE a session: dispose the live environment, trash the session's draft
clones (primary + auto-cloned filesystem roots — only DRAFTS have clones; a
trunk workspace's roots are the user's real dirs and are never touched),
then delete the session tree. Idempotent. NOTE: this is the DELETE path —
merely quitting/closing a session (navigating away, no server call) keeps
the draft intact so it can be resumed.
sourceraw docstring

context-snapshotclj

(context-snapshot sid)

The read-only ctx mirror the model sees as its bound session (ctx-loop/session-snapshot), for an existing session, ENRICHED for the USER with :session/archived (the GC'd/summarized entities that are no longer in the model's live ctx). Resolving the env through lp/env-for rehydrates an evicted session on demand. nil when the session does not exist.

The read-only ctx mirror the model sees as its bound `session`
(`ctx-loop/session-snapshot`), for an existing session, ENRICHED for
the USER with `:session/archived` (the GC'd/summarized entities that are
no longer in the model's live ctx). Resolving the env
through `lp/env-for` rehydrates an evicted session on demand.
nil when the session does not exist.
sourceraw docstring

create-session!clj

(create-session! {:keys [channel title external-id workspace-id]})

Create a fresh gateway-managed session. Defaults to :api, but in-process clients such as the TUI can pass :channel :tui and still use the same gateway turn/event machinery without pretending to be an HTTP client.

Create a fresh gateway-managed session. Defaults to `:api`, but in-process
clients such as the TUI can pass `:channel :tui` and still use the same
gateway turn/event machinery without pretending to be an HTTP client.
sourceraw docstring

current-seqclj

(current-seq sid)

Highest event :seq assigned for sid so far. Subscribing with this as the cursor yields a live-only stream (empty replay).

Highest event `:seq` assigned for `sid` so far. Subscribing with this
as the cursor yields a live-only stream (empty replay).
sourceraw docstring

delete-queued-turn!clj

(delete-queued-turn! sid tid)

Remove a queued turn before it starts. Returns deleted status or an error.

Remove a queued turn before it starts. Returns deleted status or an error.
sourceraw docstring

events-sinceclj

(events-since sid cursor)

Read-only peek at the replay ring: stored events with :seq > cursor, oldest first. Lets a page renderer locate the running turn's turn.started seq so its SSE reconnect can replay the WHOLE in-flight turn instead of only what happens after connect.

Read-only peek at the replay ring: stored events with `:seq` > cursor,
oldest first. Lets a page renderer locate the running turn's
`turn.started` seq so its SSE reconnect can replay the WHOLE in-flight
turn instead of only what happens after connect.
sourceraw docstring

get-turnclj

(get-turn sid tid)

Wire view of one turn record, or nil.

Wire view of one turn record, or nil.
sourceraw docstring

ingest-mirrored-event!clj

(ingest-mirrored-event! sid store? event)

Deliver a FOREIGN gateway event (produced in another process, arriving via the cross-process bus) into THIS process's registry so a web / Telegram / TUI watcher streams a turn running elsewhere in real time.

The foreign event is RE-SEQUENCED onto this process's OWN monotonic :seq, never the producer's. Each process runs an independent seq counter, but the SSE wire treats :seq as a single strictly-increasing per-connection cursor; adopting the producer's raw counter would let a watcher whose local seq is already past that value (e.g. it ran an earlier turn on this session) silently drop the entire foreign turn. Re-sequencing keeps THIS process's stream monotonic for its own subscribers regardless of the producer's counter — and is safe because only the producer persists the turn; the mirror is live-only.

Stored in the ring when store?; :current-turn mirrored so the session list lights up while the turn runs elsewhere. A running TURN ROW is materialized in :turns/:turn-order on turn.started (and marked terminal on turn.completed/turn.failed) so list-turns frames the mirrored turn exactly like a locally-started one — user bubble, running chip, correct live placement — instead of leaking bare deltas under the previous answer.

Ignores sessions this process has never touched (no local registry entry), so no state accrues for conversations nobody here is watching.

Deliver a FOREIGN gateway event (produced in another process, arriving via
the cross-process bus) into THIS process's registry so a web / Telegram /
TUI watcher streams a turn running elsewhere in real time.

The foreign event is RE-SEQUENCED onto this process's OWN monotonic `:seq`,
never the producer's. Each process runs an independent seq counter, but the
SSE wire treats `:seq` as a single strictly-increasing per-connection cursor;
adopting the producer's raw counter would let a watcher whose local seq is
already past that value (e.g. it ran an earlier turn on this session) silently
drop the entire foreign turn. Re-sequencing keeps THIS process's stream
monotonic for its own subscribers regardless of the producer's counter — and
is safe because only the producer persists the turn; the mirror is live-only.

Stored in the ring when `store?`; `:current-turn` mirrored so the session
list lights up while the turn runs elsewhere. A running TURN ROW is
materialized in `:turns`/`:turn-order` on `turn.started` (and marked terminal
on `turn.completed`/`turn.failed`) so `list-turns` frames the mirrored turn
exactly like a locally-started one — user bubble, running chip, correct live
placement — instead of leaking bare deltas under the previous answer.

Ignores sessions this process has never touched (no local registry entry), so
no state accrues for conversations nobody here is watching.
sourceraw docstring

list-sessionsclj

(list-sessions)
(list-sessions channel)

Wire souls for every persisted session.

CROSS-CHANNEL by default (channel = :all): a conversation started in the web is visible in the TUI and vice-versa. Pass a specific channel keyword only when a caller genuinely needs a single-channel slice (e.g. Telegram resolving a chat by external-id).

Wire souls for every persisted session.

CROSS-CHANNEL by default (`channel` = `:all`): a conversation started
in the web is visible in the TUI and vice-versa. Pass a specific
channel keyword only when a caller genuinely needs a single-channel
slice (e.g. Telegram resolving a chat by external-id).
sourceraw docstring

list-turnsclj

(list-turns sid)

Wire views of every turn for sid, newest first: persisted history hydrated from the engine DB (survives daemon restarts), plus only genuinely live gateway overlay rows (running/queued or terminal rows not yet visible in persistence).

DEDUP: the gateway's tid is NOT the engine's persisted row id - the engine mints its own id inside send!. Once the durable row is visible, prefer it: it owns the iteration trace. Keeping the completed gateway row alongside the persisted row rendered the last request/response twice after refresh, with the transient duplicate missing the iterations disclosure.

Wire views of every turn for `sid`, newest first: persisted history hydrated
from the engine DB (survives daemon restarts), plus only genuinely live gateway
overlay rows (running/queued or terminal rows not yet visible in persistence).

DEDUP: the gateway's `tid` is NOT the engine's persisted row id - the engine
mints its own id inside `send!`. Once the durable row is visible, prefer it:
it owns the iteration trace. Keeping the completed gateway row alongside the
persisted row rendered the last request/response twice after refresh, with the
transient duplicate missing the iterations disclosure.
sourceraw docstring

metrics-snapshotclj

(metrics-snapshot)

Global + per-session counters for /metrics.

Global + per-session counters for /metrics.
sourceraw docstring

reconcile-running-turns!clj

(reconcile-running-turns!)

Gateway facade for startup/client resume reconciliation of orphaned running turns.

Gateway facade for startup/client resume reconciliation of orphaned running turns.
sourceraw docstring

release-session!clj

(release-session! sid)

Release the live runtime for a session while keeping persisted data resumable.

This is the gateway facade for local clients that are merely closing a view (for example a TUI tab or process exit). Use close-session! for DELETE.

Release the live runtime for a session while keeping persisted data resumable.

This is the gateway facade for local clients that are merely closing a view
(for example a TUI tab or process exit). Use `close-session!` for DELETE.
sourceraw docstring

session-modelclj

(session-model sid)

The session's persisted model preference as {:provider :model} (DB-backed shared store), or nil for the router default.

The session's persisted model preference as `{:provider :model}`
(DB-backed shared store), or nil for the router default.
sourceraw docstring

session-model-cachedclj

(session-model-cached sid)

Cached variant of session-model for hot render paths. Still part of the gateway facade: callers do not reach into the session-model store directly.

Cached variant of `session-model` for hot render paths. Still part of the
gateway facade: callers do not reach into the session-model store directly.
sourceraw docstring

session-workspace-infoclj

(session-workspace-info sid)

Workspace state for a channel surface (the web footer AND the TUI directory picker): {:id :draft? :root :repo-root :label :fork-ms :filesystem-roots} for the session pinned to sid (soul id), or nil. :id is the workspace-id every filesystem-root mutation (add/remove-filesystem-root!) needs — WITHOUT it the TUI picker treats the session as read-only and C-a silently no-ops. :filesystem-roots is the normalized [{:trunk :clone :fork-ms}]. Lets the footer announce that the session — and its extra roots — are isolated drafts. Resolves soul → latest state → workspace; never throws.

Workspace state for a channel surface (the web footer AND the TUI
directory picker): `{:id :draft? :root :repo-root :label :fork-ms
:filesystem-roots}` for the session pinned to `sid` (soul id), or nil.
`:id` is the workspace-id every filesystem-root mutation
(`add/remove-filesystem-root!`) needs — WITHOUT it the TUI picker treats the
session as read-only and C-a silently no-ops. `:filesystem-roots` is the
normalized `[{:trunk :clone :fork-ms}]`. Lets the footer announce that the
session — and its extra roots — are isolated drafts. Resolves soul → latest
state → workspace; never throws.
sourceraw docstring

set-session-model!clj

(set-session-model! sid provider model)

Set (or clear, with blank model) the per-session PROVIDER + MODEL preference. Every turn submitted for sid routes through it (the engine reads it at turn start; router-for-model hoists the model, an unknown name degrades to the default order). Channel-agnostic: web + TUI + embedded callers all set it here, persisted in the DB and shared across channels.

Set (or clear, with blank model) the per-session PROVIDER + MODEL
preference. Every turn submitted for `sid` routes through it (the engine
reads it at turn start; `router-for-model` hoists the model, an unknown
name degrades to the default order). Channel-agnostic: web + TUI + embedded
callers all set it here, persisted in the DB and shared across channels.
sourceraw docstring

set-title!clj

(set-title! sid title)
source

soulclj

(soul sid)

Wire soul for one session: persisted record + live gateway status.

Wire soul for one session: persisted record + live gateway status.
sourceraw docstring

submit-turn!clj

(submit-turn! sid
              {:keys [request messages idempotency-key model reasoning-default
                      cancel-token extra-body turn-features workspace
                      engine-opts attachments]})

Submit one turn for sid. Async: starts immediately when idle, otherwise queues.

Returns {:turn record} (plus :idempotent? true on an idempotency replay) or {:error :session-not-found | :invalid-request, ...}. One engine turn still runs per session; busy submissions become visible queued records.

Submit one turn for `sid`. Async: starts immediately when idle, otherwise queues.

Returns `{:turn record}` (plus `:idempotent? true` on an idempotency
replay) or `{:error :session-not-found | :invalid-request, ...}`. One engine
turn still runs per session; busy submissions become visible queued records.
sourceraw docstring

submit-turn-sync!clj

(submit-turn-sync! sid {:keys [on-event] :as opts})

Submit one turn through the gateway and block until that turn reaches a terminal event.

Accepts the same request keys as submit-turn!; optional :on-event is called for every replay/live event for the submitted turn. Returns an engine-shaped result map for in-process clients (CLI/TUI/Telegram) that need a blocking call without bypassing the canonical gateway machinery.

Submit one turn through the gateway and block until that turn reaches a terminal event.

Accepts the same request keys as `submit-turn!`; optional `:on-event` is called
for every replay/live event for the submitted turn. Returns an engine-shaped
result map for in-process clients (CLI/TUI/Telegram) that need a blocking
call without bypassing the canonical gateway machinery.
sourceraw docstring

subscribe!clj

(subscribe! sid sub-id sink cursor)

Register an SSE sink and return the replay vector (events with :seq > cursor) ATOMICALLY with the registration, so no event can fall between replay and live fan-out. The caller serializes replay writes against live sink calls (see server.clj).

Before capturing replay, HYDRATE any turn currently running in a sibling process from the cross-process journal (bus/hydrate!) — but only when this process isn't already tracking a live turn (:current-turn unset), so an already-mirrored turn isn't re-delivered to existing subscribers. This materializes the running turn's row + ring HERE, so a watcher joining a turn in flight elsewhere replays it from turn.started (user bubble + running frame) instead of catching only the bare deltas after connect.

Register an SSE sink and return the replay vector (events with
`:seq` > `cursor`) ATOMICALLY with the registration, so no event can
fall between replay and live fan-out. The caller serializes replay
writes against live sink calls (see server.clj).

Before capturing replay, HYDRATE any turn currently running in a sibling
process from the cross-process journal (`bus/hydrate!`) — but only when this
process isn't already tracking a live turn (`:current-turn` unset), so an
already-mirrored turn isn't re-delivered to existing subscribers. This
materializes the running turn's row + ring HERE, so a watcher joining a turn
in flight elsewhere replays it from `turn.started` (user bubble + running
frame) instead of catching only the bare deltas after connect.
sourceraw docstring

title-listenerclj

source

transcriptclj

(transcript sid)

Rich persisted transcript rows for sid: turns oldest-first, each carrying its persisted iteration rows under :iterations. This is the gateway facade escape hatch for in-process renderers that need full historical trace detail without reaching around the gateway into persistence directly.

Rich persisted transcript rows for `sid`: turns oldest-first, each carrying
its persisted iteration rows under `:iterations`. This is the gateway facade
escape hatch for in-process renderers that need full historical trace detail
without reaching around the gateway into persistence directly.
sourceraw docstring

unsubscribe!clj

(unsubscribe! sid sub-id)
source

update-queued-turn!clj

(update-queued-turn! sid tid request)

Replace the prompt text for a queued turn. Returns the updated turn or an error.

Replace the prompt text for a queued turn. Returns the updated turn or an error.
sourceraw docstring

warm-db!clj

(warm-db!)

Force the persistence backend + shared connection on the CALLER's thread. The gateway runs this on its single-threaded boot path so the heavyweight backend namespace never lazy-loads under request concurrency (see require-backend-ns! in internal/persistance.clj).

Force the persistence backend + shared connection on the CALLER's
thread. The gateway runs this on its single-threaded boot path so
the heavyweight backend namespace never lazy-loads under request
concurrency (see require-backend-ns! in internal/persistance.clj).
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