Helpers shared across the loop drivers (Loop, TextMode, PtcToolCall,
JsonHandler, StepAssembler).
These functions used to be copy-pasted into each driver and had begun to drift. Keeping a single definition here guarantees the drivers agree on memory accounting, error classification, final-text parsing, collected-message assembly, and schema usage metrics.
Summary
Functions
Annotate a usage map with schema-usage metrics (:schema_used and, when a
schema map is present, :schema_bytes).
Build the optional collected-message list returned to callers that requested
collect_messages: true. Prepends the current system prompt; returns nil
when collection is disabled.
Check whether memory exceeds limit bytes.
Map a Step.fail map onto a coarse error reason atom
(:parse_error, :timeout, :memory_limit, or :runtime_error).
Approximate in-memory byte size of the agent memory map.
Parse a piece of final text into a value of the expected return type.
Functions
Annotate a usage map with schema-usage metrics (:schema_used and, when a
schema map is present, :schema_bytes).
Build the optional collected-message list returned to callers that requested
collect_messages: true. Prepends the current system prompt; returns nil
when collection is disabled.
@spec check_memory_limit(map(), non_neg_integer() | nil) :: {:ok, non_neg_integer()} | {:error, :memory_limit_exceeded, non_neg_integer()}
Check whether memory exceeds limit bytes.
Returns {:ok, size} when within the limit (or when limit is nil), and
{:error, :memory_limit_exceeded, size} when exceeded.
Map a Step.fail map onto a coarse error reason atom
(:parse_error, :timeout, :memory_limit, or :runtime_error).
reason may be an atom or a string (PtcRunner.Step.fail/0 allows both).
No @spec is declared on purpose: the callers pass lisp_step.fail, whose
type is fail | nil, and dialyzer's success-typing narrowing constrains it
to the non-nil map here — which keeps the subsequent fail.message access
safe. A narrower explicit contract would break that narrowing.
@spec memory_size(map()) :: non_neg_integer()
Approximate in-memory byte size of the agent memory map.
Parse a piece of final text into a value of the expected return type.
:datetime accepts both JSON-quoted ISO-8601 ("\"2026-05-06T...\"") and a
bare ISO-8601 string. All other types parse via Jason.decode/1.