Documentation
¶
Overview ¶
Package obsforward wires a remote aspect's funnel observability hook to the broker over the existing aspect WS connection.
Topology: nexus's observability.Hub lives in the broker process. The embedded Frame's funnel shares the heap with the Hub and feeds it directly (cmd/nexus/main.go). Remote aspects — agentfunnel on <operator-host>, dMon, etc — run their funnel in a different process, so their bridle events have to traverse the WS to reach the Hub.
This package provides:
- WSForwarder: implements funnel.ObservabilityHook by marshalling each call into an observe.begin / observe.event / observe.end frame and pushing through a Sender.
- The broker-side decoders live in nexus/broker/observe_inbound.go.
Send failures are logged (best-effort) but never block the funnel — observability is consumed for diagnostics, and a stalled WS write must not be allowed to wedge a deliberation turn.
Index ¶
Constants ¶
const ( EventKindModelChunk = "model_chunk" EventKindToolCallStart = "tool_call_start" EventKindToolCallResult = "tool_call_result" EventKindStepBoundary = "step_boundary" EventKindTurnDone = "turn_done" EventKindTurnError = "turn_error" )
Bridle event kind discriminators on the wire. Kept stable across agentfunnel versions so an old broker can decode a new agentfunnel (forward compat) and vice versa (back compat: a broker that sees an unknown EventKind drops the event with a warn, no crash).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Sender ¶
Sender is the minimal interface WSForwarder needs to push frames. Implemented by *wsasp.Client.SendBestEffort (use the agentfunnel-side best-effort path so observability frames don't pile up in the reconnect-replay buffer and surface minutes stale after a flip). Declared as an interface to keep this package decoupled from wsasp and to make the unit test trivial — a fake Sender records sent frames.
type SenderFunc ¶
SenderFunc adapts a function value to Sender so callers can pass methods like wsasp.Client.SendBestEffort directly without writing a wrapper struct.
type WSForwarder ¶
type WSForwarder struct {
// contains filtered or unexported fields
}
WSForwarder implements funnel.ObservabilityHook. It is safe to call from multiple goroutines — Send on the wsclient is goroutine-safe and each method here is a self-contained marshal + send.
func New ¶
func New(sender Sender, aspect string, log *slog.Logger) *WSForwarder
New constructs a forwarder for the named aspect. aspect is included in each frame's payload for receiver diagnostics, but the broker authoritatively tags events with the wsConn's registered identity (per keel-cli's caveat #236) — so a divergence here is harmless.
func (*WSForwarder) BeginTurn ¶
func (w *WSForwarder) BeginTurn(turnID, label, model, provider string, trigger int64)
BeginTurn forwards an observe.begin frame.
func (*WSForwarder) EndTurn ¶
func (w *WSForwarder) EndTurn()
EndTurn forwards an observe.end frame.
func (*WSForwarder) OnBridleEvent ¶
func (w *WSForwarder) OnBridleEvent(ev bridle.Event)
OnBridleEvent marshals one bridle.Event and forwards observe.event. Events whose Go type is unknown to this package are skipped (with a warn log) rather than panicking — bridle adding a new event type should not crash an older agentfunnel.