Documentation
¶
Overview ¶
Package elelemstream bridges elelem's streaming callbacks to essessey's content-block protocol.
An elelem round streams deltas, then (optionally) tool calls and their results, with no notion of "content block index" of its own. Adapter is the one place that arithmetic lives: get it wrong and a tool result renders into the wrong card client-side. Every caller wiring elelem to essessey binds one Adapter instead of reimplementing this.
Index ¶
- Variables
- func MapStopReason(finishReason elelem.FinishReason, hasToolCalls bool) essessey.StopReason
- type Adapter
- func (a *Adapter) Bind(req *elelem.Request) *elelem.Request
- func (a *Adapter) OnAssistantMessage(ctx context.Context, message elelem.Message) error
- func (a *Adapter) OnDelta(ctx context.Context, delta elelem.Delta) error
- func (a *Adapter) OnRoundEnd(_ context.Context, event *elelem.RoundEvent) error
- func (a *Adapter) OnRoundStart(_ context.Context, _ *elelem.RoundEvent) error
- func (a *Adapter) OnToolCallStart(_ context.Context, event elelem.ToolCallEvent) error
- func (a *Adapter) OnToolResult(_ context.Context, event elelem.ToolCallEvent) error
- func (a *Adapter) Rounds() int
Constants ¶
This section is empty.
Variables ¶
var ( // ErrRoundStreamNotInitialized means a delta or assistant message arrived // before OnRoundStart opened a round. It signals a callback wiring bug — // Bind registers OnRoundStart, so reaching this means the request was // built without it. ErrRoundStreamNotInitialized = errors.New("round stream is not initialized") // ErrToolResultMissing means OnToolResult fired with no result attached. // The block cannot be emitted without one, and inventing an empty result // would render an empty card as though the tool had genuinely returned // nothing. ErrToolResultMissing = errors.New("tool result is missing") )
Functions ¶
func MapStopReason ¶
func MapStopReason( finishReason elelem.FinishReason, hasToolCalls bool, ) essessey.StopReason
MapStopReason maps elelem's finish reason and whether the round produced tool calls onto essessey's StopReason.
A truncated finish always wins over tool calls: the client must not treat a cut-off answer as a clean tool-use round just because calls happened to be present in it.
Types ¶
type Adapter ¶
type Adapter struct {
// contains filtered or unexported fields
}
Adapter binds elelem's streaming callbacks to an essessey Publisher, translating each round's deltas, tool calls, and tool results into correctly-indexed content blocks.
Build one Adapter per in-flight elelem.Request — its fields track the current round's state and are not safe for concurrent Bind targets.
func (*Adapter) Bind ¶
Bind registers the Adapter's callbacks on req and returns req, so callers can chain it into the rest of the elelem.Request build.
An app with per-round concerns of its own just registers them as well — since elelem v0.3.0 the On* setters append to a chain rather than replace, so Bind and the app's own OnRoundStart both run, in registration order:
adapter.Bind(req).
OnRoundStart(func(context.Context, *elelem.RoundEvent) error {
heartbeat.Touch()
return nil
})
Every callback below is exported anyway, for the case where the app wants its hook to run at an exact point relative to the Adapter's, or wants to wire only some of them — without reimplementing the block arithmetic.
func (*Adapter) OnAssistantMessage ¶ added in v0.2.0
OnAssistantMessage closes out the round's thinking/text blocks and derives the tool block base: toolBase is wherever the round's content left off, and every tool_use/tool_result index for this round is computed relative to it.
func (*Adapter) OnDelta ¶ added in v0.2.0
OnDelta forwards a streamed chunk to the round's thinking/text streamers.
func (*Adapter) OnRoundEnd ¶ added in v0.2.0
OnRoundEnd tracks the completed round count.
func (*Adapter) OnRoundStart ¶ added in v0.2.0
OnRoundStart opens a fresh roundStream at the block index the previous round (or the run's start) left off at. Nothing is emitted here — blocks open lazily, on first content.
func (*Adapter) OnToolCallStart ¶ added in v0.2.0
OnToolCallStart emits the tool_use block for one call. Parallel calls in the same round each get their own slot: toolBase + the call's index.
func (*Adapter) OnToolResult ¶ added in v0.2.0
OnToolResult emits the tool_result block for one call, after every tool_use block in the round — hence the +toolCallCount offset — then, once the last result of the round has landed, advances blockIndex past all of them (2 blocks per tool: one use, one result) so the next round starts clean.