mixle.telemetry package¶
Local-first telemetry for model, placement, routing, and reasoning decisions.
Telemetry records typed decision events with features, choices, outcomes, tags,
and timestamps. These records support dashboards, auditing, and learned
orchestration policies. Only kind is a closed vocabulary; the log itself is
JSONL, and a rewrite preserves every row already in it, including rows another
writer put there.
Nothing here filters what a caller records, and the log is an ordinary local
file. features, choice, outcome and tags are serialized as
given: there is no per-kind schema, no allowlist, no redaction, no size limit,
no classification, no encryption, no access control and no retention policy. A
prompt, an answer, an API key or a customer record passed through the normal API
therefore lands verbatim in a long-lived file on disk. Recording only derived,
non-identifying quantities – counts, sizes, durations, costs, method names –
is a convention this package expects of its callers, not a property it enforces
on their behalf; a caller handling sensitive material must minimize or redact
before calling record(), and must govern the log file’s location,
permissions and lifetime itself.
A process-global recorder makes record(...) convenient, while tests and
isolated workflows can use their own Telemetry instance.
- dashboard(telemetry)[source]
Fold the telemetry stream into a receipt summary (see module docstring).
- render_dashboard(telemetry)[source]
The dashboard as plain markdown – printable in a terminal, embeddable in a report.
- class Event(kind, features=<factory>, choice=None, outcome=<factory>, tags=<factory>, ts=0.0)[source]
Bases:
objectOne typed, timestamped decision record. Features/choice describe the decision; outcome scores it.
outcomeis deliberately mutable after the fact – that is the documented “close the loop later” patternTelemetry.record()describes. The event’s identity is not:kindandtsare re-validated on every assignment, not only at construction. Because a flush rewrites the whole log from the current field values, an event mutated into an invalid state would otherwise rewrite already-persisted history as something no reader can load back.- Parameters:
- class Telemetry(path=None, *, flush_every=1)[source]
Bases:
objectA local-first event recorder: buffer in memory, append to a JSONL log, read back for training.
record(kind, features=..., choice=..., outcome=..., tags=...)appends oneEvent.events(kind=...)yields the buffer (optionally filtered).training_rows(kind)yields the(features, choice, outcome)triples the learned-orchestration models consume.- record(kind, *, features=None, choice=None, outcome=None, tags=None, when=None)[source]
Record one decision event; returns it (mutate
.outcomelater to close the loop).The mutation updates this recorder’s in-memory buffer immediately and is captured by the next flush – an explicit
flush()call, or the next automatic flush onceflush_everymore events have been recorded – because every flush rewrites the full buffered log rather than only appending whatever is new. Until that next flush, the JSONL file on disk (and any other reader with it open) still shows the pre-mutation value.
- events(*, kind=None)[source]
Yield recorded events, optionally filtered by kind.
- training_rows(kind)[source]
The
(features, choice, outcome)triples for a decision kind.
- flush()[source]
Flush any buffered events to the configured JSONL log.
- Return type:
None
- record(kind, **kw)[source]
Record an event on the process-global recorder (see
Telemetry.record()).
- get_default_recorder()[source]
The process-global recorder (a no-path in-memory buffer until one is configured).
- Return type:
Telemetry
- set_default_recorder(recorder)[source]
Install (or clear) the process-global recorder – e.g. point it at the user’s telemetry log.
- Parameters:
recorder (Telemetry | None)
- Return type:
None