Execution of one model-written block in the session's persistent Python interpreter.
Rejects blocks that are not code, runs a block with timing and Activity
reporting, interrupts and unwinds a runaway block, and retires a worker that
does not unwind. policy-reload-epoch counts /reloads; an environment built
under an older epoch is replaced unless the reload left its policy unchanged.
Execution of one model-written block in the session's persistent Python interpreter. Rejects blocks that are not code, runs a block with timing and Activity reporting, interrupts and unwinds a runaway block, and retires a worker that does not unwind. `policy-reload-epoch` counts `/reload`s; an environment built under an older epoch is replaced unless the reload left its policy unchanged.
(attachment-descriptor a)One session_attachment row as the compact DESCRIPTOR list_attachments() and
get_attachment(id) hand the model: identity, provenance and shape, and never
any bytes.
PROVENANCE STARTS AT THE TURN. Every row carries session_turn_soul_id, so
every descriptor carries :turn-id — a user image and a tool artifact are
placed the same way and a rail can be grouped by turn without a second
lookup. :iteration-id / :tool-call-id are the FINER grain only a tool
artifact has, so a user image omits both instead of carrying nils that say
nothing.
:is-pending is false here by construction: a stored row is stored. The
sandbox reader answers the same key true for an artifact the RUNNING block
just attached, which is not in the database yet.
One `session_attachment` row as the compact DESCRIPTOR `list_attachments()` and `get_attachment(id)` hand the model: identity, provenance and shape, and never any bytes. PROVENANCE STARTS AT THE TURN. Every row carries `session_turn_soul_id`, so every descriptor carries `:turn-id` — a user image and a tool artifact are placed the same way and a rail can be grouped by turn without a second lookup. `:iteration-id` / `:tool-call-id` are the FINER grain only a tool artifact has, so a user image omits both instead of carrying nils that say nothing. `:is-pending` is false here by construction: a stored row is stored. The sandbox reader answers the same key `true` for an artifact the RUNNING block just attached, which is not in the database yet.
(execute-code environment code & {:keys [timeout-ms tool-event-fn]})Run a single :code block through the Python sandbox.
Optional kwargs: :timeout-ms - hard-cap eval time, clamped at the rt/eval-timeout-ms bounds.
Every call performs a real Python eval. There is no result cache: forms with side effects MUST run their bodies on every invocation, and forms without side effects re-run cheaply enough that caching them is not worth the correctness footgun.
Run a single :code block through the Python sandbox.
Optional kwargs:
:timeout-ms - hard-cap eval time, clamped at the
rt/*eval-timeout-ms* bounds.
Every call performs a real Python eval. There is no result cache:
forms with side effects MUST run their bodies on every
invocation, and forms without side effects re-run cheaply enough
that caching them is not worth the correctness footgun.(get-locals _environment)User-defined sandbox vars surface. Live-vars introspection is cosmetic-off for the Python engine (the agent uses its own Python scope + stdlib), so this returns an empty map. Kept as a stable seam for the trailer/renderer callers.
User-defined sandbox vars surface. Live-vars introspection is cosmetic-off for the Python engine (the agent uses its own Python scope + stdlib), so this returns an empty map. Kept as a stable seam for the trailer/renderer callers.
Monotonic /reload epoch. Every /reload bumps it (via a reload hook).
The hook reads the policy of each live env again. An env with the same policy
takes the new epoch and keeps its sandbox (#408). For the other envs, stale idle
sandboxes close immediately and busy ones close after their turn. The next turn
rebuilds the immutable security-policy snapshot from the freshly-reloaded vis.yml.
The snapshot drives the Python session, egress proxy, and process jail at
env-creation time, so it can only change by rebuilding the env, never by an
in-place reseat.
Monotonic `/reload` epoch. Every `/reload` bumps it (via a reload hook). The hook reads the policy of each live env again. An env with the same policy takes the new epoch and keeps its sandbox (#408). For the other envs, stale idle sandboxes close immediately and busy ones close after their turn. The next turn rebuilds the immutable security-policy snapshot from the freshly-reloaded vis.yml. The snapshot drives the Python session, egress proxy, and process jail at env-creation time, so it can only change by rebuilding the env, never by an in-place reseat.
(retire-python-context-once! python-context environment reason error)Kill one abandoned environment's Python process at most once. Process teardown does not enter the interpreter, so it is safe even while the turn thread still owns the environment lock.
Kill one abandoned environment's Python process at most once. Process teardown does not enter the interpreter, so it is safe even while the turn thread still owns the environment lock.
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 |