SuperPi.Event.Renderer behaviour (super_pi v0.1.0)

Copy Markdown View Source

Turns SuperPi.Events into the output of one protocol.

A renderer is a pure state machine, not a process. The transport process owns the socket and the renderer owns only its projection state, so a renderer needs no socket to be tested. This is the shape of SuperPi.RPC.Server.handle_rpc_payload/2, which is pure for the same reason.

Cross-event state is why init/1 exists. AG-UI must open and close a text message around a run of bare deltas, and ACP tracks a tool call from pending to completed.

state = Renderer.OpenAI.init(id: "chatcmpl-1", model: "super-pi-code")
{chunks, state} = Renderer.OpenAI.render(event, state)
{tail, _state} = Renderer.OpenAI.flush(state)
RendererOutput per call
SuperPi.Event.Renderer.OpenAIchat completion chunk maps
SuperPi.Event.Renderer.RPCthe wire map (identity)
SuperPi.Event.Renderer.TUIterminal lines
SuperPi.Event.Renderer.ACPsession/update notification params
SuperPi.Event.Renderer.AGUIAG-UI event maps

Summary

Callbacks

Ends the stream: output that closes what is open. Returns the final output and state.

Builds the initial state from options.

Renders one event. Returns the output items, possibly none, and the next state.

Functions

Renders a list of events and flushes, for tests and for replay of a stored history.

Callbacks

flush(state)

@callback flush(state :: term()) :: {[term()], term()}

Ends the stream: output that closes what is open. Returns the final output and state.

init(opts)

@callback init(opts :: keyword()) :: term()

Builds the initial state from options.

render(t, state)

@callback render(SuperPi.Event.t(), state :: term()) :: {[term()], term()}

Renders one event. Returns the output items, possibly none, and the next state.

Functions

render_all(renderer, events, opts \\ [])

@spec render_all(module(), [SuperPi.Event.t()], keyword()) :: [term()]

Renders a list of events and flushes, for tests and for replay of a stored history.