aetherwire

package
v0.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 9, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

Documentation

Overview

Package aetherwire is the Aether transport binding for the chat-stream protocol: the task-message topic and the message envelope that wraps a spec stream event. It is the shared, authoritative encoder/decoder for this wire shape — every process that speaks chat over Aether (this harness, the sandbox sidecar, distribution servers) encodes through it rather than keeping a private copy, which is how the shape stays consistent across them.

The pure message spec lives in github.com/scitrera/ecosystem-messaging-spec/go; this package holds only the Aether-routing layer on top of it.

A few readers here (AuthorityGrantID, Ephemeral, SynthesizeSystemPrompt) decode meta keys that the Scitrera distribution sets. They are kept here, in the one authoritative codec, so a distribution does not need a forked copy to read them; nothing in oss requires those keys to be present, and every reader degrades to a zero value when they are absent.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AuthorityGrantID

func AuthorityGrantID(msg spec.ChatMessage) string

AuthorityGrantID extracts the OBO authority grant id from message meta, checking meta.scitrera.authority_grant_id then meta.authority_grant_id.

func ConcatText

func ConcatText(msg spec.ChatMessage) string

ConcatText concatenates the text of every text part (the user's prompt).

func Ephemeral

func Ephemeral(msg spec.ChatMessage) bool

Ephemeral reports whether the inbound message requests a one-shot EPHEMERAL turn (no durable history load, no memory recall/commit, no durable persist), read from meta.scitrera.ephemeral (bool). Mirrors AuthorityGrantID's nested scitrera-namespace convention. Absent/false when unset.

func ParseSessionFrame

func ParseSessionFrame(payload []byte) (frame spec.SessionFrame, ok bool, err error)

ParseSessionFrame recognizes the shared session-protocol frame on a multiplexed Aether topic. ok=false means the payload is another message shape. A recognized but invalid frame returns ok=true and an error so the receiver can return a correlated session error instead of treating it as a ChatMessage.

func SessionFramePayload

func SessionFramePayload(frame spec.SessionFrame) ([]byte, error)

SessionFramePayload validates and encodes one shared frame for Aether.

func StreamEnvelope

func StreamEnvelope(meta TurnMeta, event spec.StreamEvent) ([]byte, error)

StreamEnvelope wraps a spec stream event in the AIR message envelope and returns the JSON payload to publish on TaskMessageTopic. The shape mirrors the sandbox sidecar's emitter exactly so app-server's _on_air_message keys off options.chat_stream_event unchanged.

func StreamEventFor

func StreamEventFor(event channel.Event, agentName string) (spec.StreamEvent, bool)

StreamEventFor maps a harness stream event onto its wire form, stamping the assistant's display persona on the messages that carry one. ok is false for an event that has no wire representation — tool lifecycle and errors reach clients as part_appended, not as events of their own — and for a malformed event whose payload is missing.

This lives here, next to StreamEnvelope and ParseStreamEnvelope, because every transport that publishes a turn needs the identical mapping: which harness events cross the wire, which spec event each becomes, and where the agent name is stamped. Two transports maintaining their own copy is how the shape drifts.

func SynthesizeSystemPrompt

func SynthesizeSystemPrompt(msg spec.ChatMessage) string

SynthesizeSystemPrompt extracts the per-turn system-prompt text a one-shot (agent.synthesize) request carries in meta.scitrera.synthesize_options — the `system` and `instructions` keys, concatenated (system first). "" when absent. The harness renders it as the Request-instructions system-prompt section (contextpack.WithSystemPromptExtra). Other options keys (e.g. timeout_s) are bridge-side and ignored here.

func TaskMessageTopic

func TaskMessageTopic(workspace, taskID string) string

TaskMessageTopic is the per-turn message lane every UI client for the turn subscribes to: tk::<workspace>::<task_id>::msg.

func WithAgentName

func WithAgentName(msg spec.ChatMessage, name string) spec.ChatMessage

WithAgentName returns a copy of msg with the assistant's display persona name set at meta.scitrera.agent_name (nested, mirroring the authority_grant_id convention read by AuthorityGrantID). It merges into any existing scitrera meta object and preserves all other meta keys. No-op when name is empty.

Types

type InboundControl

type InboundControl struct {
	Kind   string
	TaskID string
	// RequestID + Scope carry the approve/deny decision for an approval_request.
	RequestID string
	Scope     string
}

InboundControl is an in-band control signal parsed from a turn payload.

func FirstControl

func FirstControl(msg spec.ChatMessage) *InboundControl

FirstControl returns the first control content part, or nil if none.

func ParseInbound

func ParseInbound(payload []byte) (spec.ChatMessage, *InboundControl, error)

ParseInbound decodes an inbound turn payload as a spec ChatMessage and surfaces the first control signal if present. When ctrl is non-nil the turn is a control message (e.g. cancel), not a normal user turn.

type TurnMeta

type TurnMeta struct {
	// AppWorkspace is the app-server workspace the turn belongs to (routing key).
	AppWorkspace string
	// TaskID is the Aether chat task for this turn.
	TaskID string
	// ThreadID is the conversation thread.
	ThreadID string
	// WindowID is the originating UI window (request_id).
	WindowID string
	// SourceAgent is the emitter identity string, e.g. "agent-harness:<sandbox_id>".
	SourceAgent string
}

TurnMeta is the routing/identity context for a turn's stream egress.

func ParseStreamEnvelope

func ParseStreamEnvelope(payload []byte) (meta TurnMeta, event spec.StreamEvent, ok bool, err error)

ParseStreamEnvelope is the decode half of StreamEnvelope: it unwraps a published envelope back into the routing meta and the spec stream event.

ok is false for a payload that is not a stream envelope at all (the topic can carry other traffic), which is not an error. An error means the payload looked like an envelope but its event could not be decoded.

Having this here, next to the encoder, is the point: a consumer that hand-rolls the unwrapping has to know that the discriminator is "event" (not "type") and that the event hangs off options.chat_stream_event — both easy to get wrong, and wrong in a way that silently yields no events rather than an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL