Skip to content
skyl

EventType

What a StreamEvent carries.

Four values. Two are emitted by every adapter, one by all four with different fidelity, and one by exactly one adapter.

Reference#

type EventType string
ConstantValueMeaning
EventTextDeltatext_deltaThe next fragment of assistant text, in StreamEvent.Text. The event most callers want.
EventThinkingDeltathinking_deltaA fragment of the model's reasoning, when the provider discloses it. Only Anthropic ever emits this.
EventToolCalltool_callA completed tool call. skyl buffers partial arguments and emits this once, when the call's JSON is whole — a half-parsed tool call is not actionable.
EventDonedoneThe final event of a successful stream, carrying Usage and StopReason.

Caveats

  • EventThinkingDelta is Anthropic-only. A UI driven by it stays empty on the other three.
  • EventToolCall fires once per call, when the arguments are whole. skyl buffers the fragments for you.
  • EventDone is the terminal event. A stream that ends without it is reported as truncated through Stream.Err().
  • Provider events carrying no actionable information are dropped rather than surfaced.

Usage#

Text only, the common case

goCompiles
for stream.Next() {
	if ev := stream.Event(); ev.Type == skyl.EventTextDelta {
		fmt.Print(ev.Text)
	}
}
for stream.Next() {
	if ev := stream.Event(); ev.Type == skyl.EventTextDelta {
		fmt.Print(ev.Text)
	}
}

Detecting the terminal event

goCompiles
var sawDone bool
for stream.Next() {
	if stream.Event().Type == skyl.EventDone {
		sawDone = true
	}
}
// Redundant in practice — Err() already reports a missing terminal event —
// but explicit if you are asserting on it in a test.
if err := stream.Err(); err != nil || !sawDone {
	return fmt.Errorf("incomplete stream: %w", err)
}
var sawDone bool
for stream.Next() {
	if stream.Event().Type == skyl.EventDone {
		sawDone = true
	}
}
// Redundant in practice — Err() already reports a missing terminal event —
// but explicit if you are asserting on it in a test.
if err := stream.Err(); err != nil || !sawDone {
	return fmt.Errorf("incomplete stream: %w", err)
}

Troubleshooting#

Should I handle event types I do not recognise?

There are only four, and they are stable. A default branch that ignores anything unknown is safe — skyl drops provider events that carry no actionable information rather than passing them through as new types.

Edit this page on GitHub