Documentation
¶
Overview ¶
Package channel is the transport seam: how inbound turns arrive (Receiver) and how streaming events leave (Publisher). The Aether transport and the CLI are implementations. The types here are protocol-neutral (built only from messaging-spec types) so the core depends on this package, not on any concrete transport.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrNoTask = errors.New("channel: no task")
ErrNoTask signals that no inbound message is currently available; a Receiver returns it to indicate idle (the runtime loop treats it as "keep polling").
Functions ¶
func StreamEventFor ¶ added in v0.0.2
func StreamEventFor(event Event, mapMessage func(protocol.ChatMessage) protocol.ChatMessage) (stream spec.StreamEvent, ok bool)
StreamEventFor maps a harness event to the shared streaming vocabulary. mapMessage optionally decorates messages for a transport (for example, the Aether adapter adds the assistant display name). Non-wire or malformed events return ok=false.
Types ¶
type Enqueuer ¶
Enqueuer injects an inbound turn into the transport's ingress so the runtime loop drives a fresh turn for it. It is the ingress-write half that the web/tui channels already expose as Enqueue; naming it as an interface lets the turn layer push a turn (e.g. a background sub-agent's completion notice addressed to its parent thread) without importing a concrete transport. The Aether transport satisfies it by sending a MessageEnvelope to the target agent. cli (stdout-only) does not implement it, so a background push simply degrades to unavailable.
type Event ¶
type Event struct {
Type EventType `json:"type"`
Addr protocol.MessageAddress `json:"addr"`
Message *protocol.ChatMessage `json:"message,omitempty"`
MessageID string `json:"message_id,omitempty"`
Index int `json:"index,omitempty"`
Part *protocol.ContentPart `json:"part,omitempty"`
Delta string `json:"delta,omitempty"`
Patch map[string]json.RawMessage `json:"patch,omitempty"`
Payload json.RawMessage `json:"payload,omitempty"`
}
Event is an egress stream event. Different fields are populated per Type: Message for started/final; MessageID+Index+Part for part_appended; MessageID+Index+Delta for token_delta; MessageID+Index+Patch for part_updated.
type EventType ¶
type EventType string
EventType discriminates an egress stream event.
const ( EventMessageStarted EventType = "message_started" EventPartAppended EventType = "part_appended" EventTokenDelta EventType = "token_delta" EventPartUpdated EventType = "part_updated" EventMessageFinal EventType = "message_final" EventToolResult EventType = "tool_result" EventToolLifecycle EventType = "tool_lifecycle" EventMemoryRecall EventType = "memory_recall" EventError EventType = "error" )
type Inbound ¶
type Inbound struct {
Addr protocol.MessageAddress `json:"addr"`
Message protocol.ChatMessage `json:"message"`
Meta json.RawMessage `json:"meta,omitempty"`
}
Inbound is an inbound turn: an addressed message plus opaque transport meta.
type MemoryRecallStatus ¶ added in v0.0.2
type MemoryRecallStatus struct {
Provider string `json:"provider"`
WorkspaceID string `json:"workspace_id,omitempty"`
Scope string `json:"scope"`
ItemCount int `json:"item_count"`
LatencyMS int64 `json:"latency_ms"`
ResultCode string `json:"result_code"`
}
MemoryRecallStatus is a content-free account of one automatic memory lookup. It is safe to expose to operator/UI surfaces: recalled text and memory IDs are deliberately absent.
type Receiver ¶
Receiver delivers inbound turns. FetchTask blocks until one is available or returns ErrNoTask when idle.
type SteeringRejector ¶ added in v0.0.2
SteeringRejector tells the sender that a steering message never reached the turn it was aimed at.
A steering send is an interjection into a turn already in flight. When there is no such turn — it finished between the send and its arrival, or between being parked and the turn's last drain — the message cannot do what the user asked. Running it as a turn of its own would be a different action than the one requested, and on a host where task identity carries authority it would also be a turn with none: a steering send deliberately owns no task, so it has no per-message grant, tool-host route, or execution binding.
So the message is rejected and the sender is told, rather than quietly becoming something else. Implementations must be non-blocking. A transport that cannot reach the sender simply does not implement this.