Record a short value history per message
The panel is going to sparkline how a value moved, and nothing kept more
than the latest one. Emissions now append to a capped list beside the
value — 120 points, enough to fill a sparkline without making Redis a
time-series store — and `/flows/{flow}/history/{message}` hands it back
oldest first.
Only numbers are recorded, bools included as neither, so a string
message costs nothing at all. The response carries `numeric` so an empty
series reads as "not plottable" rather than "nothing yet". The append is
one pipelined round-trip per emission batch and sits outside the lock,
since the list is append-only.
MemoryState keeps the same window in a deque, so the endpoint answers
without Redis too.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KkmeRiyeYmVZqJVwuyHq9o
This commit is contained in:
co-authored by
Claude Opus 5
parent
6156ad1150
commit
3b72d17ca7
@@ -26,11 +26,14 @@ from app.flow.schemas import (
|
||||
FlowsPublic,
|
||||
FlowStatePublic,
|
||||
FlowSummary,
|
||||
HistoryPoint,
|
||||
MessageHistory,
|
||||
MessageValue,
|
||||
NodeSource,
|
||||
NodeStatusPublic,
|
||||
NodeTypeInfo,
|
||||
)
|
||||
from app.flow.state import as_number
|
||||
from app.flow.store import FlowExists, FlowNotFound
|
||||
from app.models import Message
|
||||
|
||||
@@ -275,6 +278,29 @@ def read_flow_state(name: str, controller: FlowControllerDep) -> Any:
|
||||
return _flow_state(controller, name)
|
||||
|
||||
|
||||
@router.get("/{name}/history/{message}", response_model=MessageHistory)
|
||||
def read_message_history(
|
||||
name: str,
|
||||
message: str,
|
||||
controller: FlowControllerDep,
|
||||
) -> Any:
|
||||
"""The recent values of one message, for plotting.
|
||||
|
||||
``message`` may be given bare or qualified; a message that never carried a
|
||||
number comes back with an empty series.
|
||||
"""
|
||||
_read_flow(controller, name)
|
||||
key = qualify(name, message)
|
||||
return MessageHistory(
|
||||
message=key,
|
||||
numeric=as_number(controller.state.get(key)) is not None,
|
||||
points=[
|
||||
HistoryPoint(ts=ts, value=value)
|
||||
for ts, value in controller.state.history(key)
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Live updates
|
||||
# -----------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user