Bounded, ownerless lifecycle events for host-observed tool invocations.
Events are presentation input, never operation control. Construction redacts before measuring, collectors reject broken lifecycle order, and a sink failure must never change the value or exception the Python caller observes.
Bounded, ownerless lifecycle events for host-observed tool invocations. Events are presentation input, never operation control. Construction redacts before measuring, collectors reject broken lifecycle order, and a sink failure must never change the value or exception the Python caller observes.
(accept! state event)Validate and append one event, rejecting duplicate or orphan lifecycle edges.
Validate and append one event, rejecting duplicate or orphan lifecycle edges.
(bounded-text value limit)UTF-8 truncate text to at most limit bytes, appending an omission marker.
ONE cut, on a code-point boundary, over a prefix of at most limit
CHARACTERS — UTF-8 spends at least one byte per character, so nothing past
that prefix can survive the limit anyway. The walk this replaced moved the cut
down ONE character at a time, re-subsing and re-encoding the WHOLE string on
every pass: quadratic, and event construction runs on the CALLING thread with
no interrupt point in it, so one tool result carrying a 3.2 MB single line (a
minified JSON blob under cat/grep) burned an hour of CPU — the block's
timeout fired while that thread kept running and every later block queued
behind it.
UTF-8 truncate text to at most `limit` bytes, appending an omission marker. ONE cut, on a code-point boundary, over a prefix of at most `limit` CHARACTERS — UTF-8 spends at least one byte per character, so nothing past that prefix can survive the limit anyway. The walk this replaced moved the cut down ONE character at a time, re-`subs`ing and re-encoding the WHOLE string on every pass: quadratic, and event construction runs on the CALLING thread with no interrupt point in it, so one tool result carrying a 3.2 MB single line (a minified JSON blob under `cat`/`grep`) burned an hour of CPU — the block's timeout fired while that thread kept running and every later block queued behind it.
(collector)Create a strict lifecycle collector. accept! returns each accepted event.
Create a strict lifecycle collector. `accept!` returns each accepted event.
(content-event ctx
invocation
{:keys [operation presenter activity workspace-root]}
presentation)Validate a whole presentation replacement; text and content never author lifecycle.
Validate a whole presentation replacement; text and content never author lifecycle.
(context)Create one concurrency-safe counter context for a single block's tool calls.
Ownerless by contract: the form this block becomes is the snapshot's only identity, so no evaluation, iteration or form coordinate is carried here.
Create one concurrency-safe counter context for a single block's tool calls. Ownerless by contract: the form this block becomes is the snapshot's only identity, so no evaluation, iteration or form coordinate is carried here.
(event-error event)Nil for a valid event, otherwise the lifecycle contract violation.
Nil for a valid event, otherwise the lifecycle contract violation.
(fit-event event)The event, shrunk to max-event-bytes by dropping WHOLE diff bodies, heaviest first.
A patch is evidence, and half of one is worse than none: a reader who meets a hunk
that stops mid-file cannot tell the cut from the change. So the ceiling that keeps a
pathological payload out of SSE and /poll replay is paid in whole bodies - the file
keeps its name, its counts and :is-truncated - never in a partial diff. Everything
else an event carries is already bounded to bytes where it is built.
The event, shrunk to `max-event-bytes` by dropping WHOLE diff bodies, heaviest first. A patch is evidence, and half of one is worse than none: a reader who meets a hunk that stops mid-file cannot tell the cut from the change. So the ceiling that keeps a pathological payload out of SSE and `/poll` replay is paid in whole bodies - the file keeps its name, its counts and `:is-truncated` - never in a partial diff. Everything else an event carries is already bounded to bytes where it is built.
(invocation ctx parent-id)Allocate stable identity and wrapper-entry sequence from ctx.
Allocate stable identity and wrapper-entry sequence from `ctx`.
(redact value)Remove credential-bearing values recursively before summaries or sizes exist.
Remove credential-bearing values recursively before summaries or sizes exist.
(start-event ctx
invocation
{:keys [operation presenter extension symbol label phrase args
classification group-token group-head summary-format
workspace-root]
:as details})(terminal-event ctx
invocation
{:keys [operation presenter started-at-ms outcome result error
classification group-token result-format]
:as details})(visible-event? event)Whether an internal event may publish progress. End-only calls still track every event.
Whether an internal event may publish progress. End-only calls still track every event.
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 |