protocol

package
v0.0.0-...-5ed4770 Latest Latest
Warning

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

Go to latest
Published: Jun 30, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package protocol provides envelope structs and SDK functions for the Sequify WebSocket protocol.

Package protocol provides payload structs for all 10 protocol methods.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func IsNonPersistent

func IsNonPersistent(kind string) bool

IsNonPersistent reports whether the given update kind is non-persistent (seq=0, skipped during gap fill). Returns true for typing, retry, and streaming. Returns false for all persistent kinds.

func NeedsMsgID

func NeedsMsgID(kind string) bool

NeedsMsgID reports whether the given update kind requires a message ID for seq allocation. Returns true for tool_call, result, reply, error (persistent updates tied to messages). Returns false for read_receipt, conversation_created, conversation_destroyed, conversation_switched, typing, retry.

func ValidateRequest

func ValidateRequest(req *Request) error

ValidateRequest checks that a Request has a non-empty ID (within max length) and a valid method.

func ValidateResponse

func ValidateResponse(resp *Response) error

ValidateResponse checks that a Response has a non-empty ID, valid code, and non-empty message.

func ValidateUpdate

func ValidateUpdate(u *Update) error

ValidateUpdate checks that an Update has a valid kind and that non-persistent kinds (typing, retry, streaming) have seq == 0.

func ValidateUpdates

func ValidateUpdates(u *Updates) error

ValidateUpdates checks that an Updates envelope contains at least one Update and does not exceed the maximum batch size.

Types

type CancelPayload

type CancelPayload struct {
	ConversationID string `json:"conversation_id" validate:"required"`
}

CancelPayload is the payload for cancel method.

type ConversationMeta

type ConversationMeta struct {
	ID            string `json:"id"`
	Title         string `json:"title"`
	CreatedAt     int64  `json:"created_at"`      // milliseconds
	LastMessageAt int64  `json:"last_message_at"` // milliseconds
	ReadMsgID     uint64 `json:"read_msg_id"`
	LastMessageID uint64 `json:"last_message_id"`
}

ConversationMeta is a conversation summary for list_conversations response.

type CreateConversationPayload

type CreateConversationPayload struct {
	Title string `json:"title,omitempty"`
}

CreateConversationPayload is the payload for create_conversation method.

type DestroyConversationPayload

type DestroyConversationPayload struct {
	ConversationID string `json:"conversation_id" validate:"required"`
}

DestroyConversationPayload is the payload for destroy_conversation method.

type Direction

type Direction string

Direction indicates whether a method is initiated by client or server.

const (
	DirectionClientToServer Direction = "client_to_server"
	DirectionServerToClient Direction = "server_to_client"
)

Direction constants for method routing.

type EditMessagePayload

type EditMessagePayload struct {
	ConversationID string `json:"conversation_id" validate:"required"`
	MessageID      uint64 `json:"message_id" validate:"required"`
	Content        string `json:"content" validate:"required"`
}

EditMessagePayload is the payload for edit_message method.

type FetchUpdatesPayload

type FetchUpdatesPayload struct {
	FromSeq uint64 `json:"from_seq" validate:"required"`
	ToSeq   uint64 `json:"to_seq" validate:"required"`
}

FetchUpdatesPayload is the payload for fetch_updates method.

type FetchUpdatesResponse

type FetchUpdatesResponse struct {
	Updates []Update `json:"updates"`
	MaxSeq  uint64   `json:"max_seq"`
}

FetchUpdatesResponse is the response payload for fetch_updates method.

type GetMaxSeqPayload

type GetMaxSeqPayload struct{}

GetMaxSeqPayload is the payload for get_max_seq method (no request params).

type GetMaxSeqResponse

type GetMaxSeqResponse struct {
	Channels []MaxSeqChannel `json:"channels"`
}

GetMaxSeqResponse is the response payload for get_max_seq method.

type IntentPayload

type IntentPayload struct {
	ConversationID string          `json:"conversation_id" validate:"required"`
	Content        string          `json:"content" validate:"required"`
	Context        json.RawMessage `json:"context,omitempty"`
	IdempotencyKey string          `json:"idempotency_key,omitempty"`
}

IntentPayload is the payload for intent method.

type ListConversationsPayload

type ListConversationsPayload struct {
	Cursor string `json:"cursor,omitempty"` // composite cursor: "{last_message_at_ms}_{id}"
	Limit  int    `json:"limit,omitempty"`  // default 20, max 100
}

ListConversationsPayload is the payload for list_conversations method.

type ListConversationsResponse

type ListConversationsResponse struct {
	Conversations []ConversationMeta `json:"conversations"`
	NextCursor    string             `json:"next_cursor,omitempty"` // empty = no more
}

ListConversationsResponse is the response for list_conversations method.

type MaxSeqChannel

type MaxSeqChannel struct {
	Channel string `json:"channel"`
	MaxSeq  uint64 `json:"max_seq"`
}

MaxSeqChannel represents a channel's current max sequence number.

type MethodConfig

type MethodConfig struct {
	PayloadType reflect.Type
	Direction   Direction
	Description string
}

MethodConfig holds metadata for a registered protocol method.

type ParseResult

type ParseResult struct {
	// contains filtered or unexported fields
}

ParseResult holds the raw bytes and type of a parsed protocol message. The actual unmarshaling into Request/Response/Updates is deferred until the corresponding As*() method is called.

IMPORTANT: The raw bytes are NOT copied. The caller must ensure that the input data slice remains valid and unmodified for the lifetime of the ParseResult. If the data may be modified or reused, the caller should copy it before passing to Parse().

func Parse

func Parse(data []byte) (*ParseResult, error)

Parse decodes the message type from data without fully unmarshaling the payload. It rejects messages larger than 1MB, invalid JSON, and missing type fields.

Design note: This function performs a lightweight unmarshal to extract only the type and version fields. The full unmarshal is deferred to AsRequest/AsResponse/AsUpdates. This two-phase approach is intentional: it allows early rejection of invalid messages before committing to the full unmarshal cost. The double unmarshal overhead is acceptable because (1) the initial peek only extracts two fields, and (2) it enables streaming scenarios where we need to route messages by type before full parsing.

func (*ParseResult) AsRequest

func (r *ParseResult) AsRequest() (*Request, error)

AsRequest unmarshals the raw data into a Request struct. Returns an error if the message type is not "Request".

func (*ParseResult) AsResponse

func (r *ParseResult) AsResponse() (*Response, error)

AsResponse unmarshals the raw data into a Response struct. Returns an error if the message type is not "Response".

func (*ParseResult) AsUpdates

func (r *ParseResult) AsUpdates() (*Updates, error)

AsUpdates unmarshals the raw data into an Updates struct. Returns an error if the message type is not "Updates".

func (*ParseResult) Type

func (r *ParseResult) Type() string

Type returns the message type string ("Request", "Response", or "Updates").

type ReadReceiptPayload

type ReadReceiptPayload struct {
	ConversationID string `json:"conversation_id" validate:"required"`
	MessageID      uint64 `json:"message_id" validate:"required"`
	Timestamp      int64  `json:"timestamp"` // server-set, milliseconds
}

ReadReceiptPayload is the payload for read_receipt method.

type Request

type Request struct {
	Type    string          `json:"type"`
	Version int             `json:"version"`
	ID      string          `json:"id"`
	Method  string          `json:"method"`
	Payload json.RawMessage `json:"payload"`
}

Request represents a request message envelope.

type RequestBuilder

type RequestBuilder struct {
	// contains filtered or unexported fields
}

RequestBuilder provides a fluent API for constructing Request messages.

func NewRequest

func NewRequest(method string) *RequestBuilder

NewRequest creates a new RequestBuilder for the given method. The default payload is an empty JSON object (not null).

func (*RequestBuilder) Build

func (b *RequestBuilder) Build() *Request

Build returns the constructed Request.

func (*RequestBuilder) ID

ID sets the request ID.

func (*RequestBuilder) Marshal

func (b *RequestBuilder) Marshal() ([]byte, error)

Marshal serializes the Request to JSON bytes.

func (*RequestBuilder) Payload

func (b *RequestBuilder) Payload(p []byte) *RequestBuilder

Payload sets the request payload.

type Response

type Response struct {
	Type    string          `json:"type"`
	Version int             `json:"version"`
	ID      string          `json:"id"`
	Code    int             `json:"code"`
	Message string          `json:"message"`
	Payload json.RawMessage `json:"payload,omitempty"`
	Updates []Update        `json:"updates,omitempty"`
}

Response represents a response message envelope.

type ResponseBuilder

type ResponseBuilder struct {
	// contains filtered or unexported fields
}

ResponseBuilder provides a fluent API for constructing Response messages.

func NewResponse

func NewResponse(id string, code int, message string) *ResponseBuilder

NewResponse creates a new ResponseBuilder with the given id, code, and message.

func (*ResponseBuilder) Build

func (b *ResponseBuilder) Build() *Response

Build returns the constructed Response.

func (*ResponseBuilder) Marshal

func (b *ResponseBuilder) Marshal() ([]byte, error)

Marshal serializes the Response to JSON bytes.

func (*ResponseBuilder) Payload

func (b *ResponseBuilder) Payload(p []byte) *ResponseBuilder

Payload sets the response payload.

func (*ResponseBuilder) Updates

func (b *ResponseBuilder) Updates(updates []Update) *ResponseBuilder

Updates sets the response updates.

type ResultPayload

type ResultPayload struct {
	RequestID string          `json:"request_id" validate:"required"`
	Result    json.RawMessage `json:"result" validate:"required"`
}

ResultPayload is the payload for result method (client -> server).

type Router

type Router struct {
	// contains filtered or unexported fields
}

Router maps protocol method strings to their MethodConfig.

func NewRouter

func NewRouter() *Router

NewRouter creates a Router with all 14 protocol methods registered.

func (*Router) Get

func (r *Router) Get(method string) (MethodConfig, bool)

Get returns the MethodConfig for the given method string. Returns false if the method is not registered.

func (*Router) ListByDirection

func (r *Router) ListByDirection(d Direction) []string

ListByDirection returns method strings that match the given direction.

func (*Router) Methods

func (r *Router) Methods() []string

Methods returns all registered method strings.

func (*Router) PayloadType

func (r *Router) PayloadType(method string) reflect.Type

PayloadType returns the reflect.Type for the method's payload. Returns nil if the method is not registered.

func (*Router) Validate

func (r *Router) Validate(method string) error

Validate checks whether the given method is registered. Returns nil if valid, or an errcode error (code 4004) if unknown.

type SwitchConversationPayload

type SwitchConversationPayload struct {
	ConversationID string `json:"conversation_id" validate:"required"`
}

SwitchConversationPayload is the payload for switch_conversation method.

type ToolCallPayload

type ToolCallPayload struct {
	RequestID string          `json:"request_id" validate:"required"`
	Name      string          `json:"name" validate:"required"`
	Arguments json.RawMessage `json:"arguments" validate:"required"`
}

ToolCallPayload is the payload for tool_call method (server -> client).

type Update

type Update struct {
	Kind    string          `json:"kind"`
	Seq     uint64          `json:"seq"`
	Payload json.RawMessage `json:"payload"`
}

Update represents a single update within an Updates envelope.

func FillGaps

func FillGaps(updates []Update, fromSeq, toSeq uint64) []Update

FillGaps returns a new slice of Updates covering the range [fromSeq, toSeq] inclusive. For seq values not present in the input, placeholder Updates with Kind="" and Payload=nil are inserted. The input slice is never modified. Returns an empty slice if fromSeq > toSeq.

func NewConversationCreatedUpdate

func NewConversationCreatedUpdate(seq uint64, payload []byte) Update

NewConversationCreatedUpdate creates a persistent conversation_created Update with the given seq and payload.

func NewConversationDestroyedUpdate

func NewConversationDestroyedUpdate(seq uint64, payload []byte) Update

NewConversationDestroyedUpdate creates a persistent conversation_destroyed Update with the given seq and payload.

func NewConversationSwitchedUpdate

func NewConversationSwitchedUpdate(seq uint64, payload []byte) Update

NewConversationSwitchedUpdate creates a persistent conversation_switched Update with the given seq and payload.

func NewErrorUpdate

func NewErrorUpdate(seq uint64, payload []byte) Update

NewErrorUpdate creates a persistent error Update with the given seq and payload.

func NewReadReceiptUpdate

func NewReadReceiptUpdate(seq uint64, payload []byte) Update

NewReadReceiptUpdate creates a persistent read_receipt Update with the given seq and payload.

func NewReplyUpdate

func NewReplyUpdate(seq uint64, payload []byte) Update

NewReplyUpdate creates a persistent reply Update with the given seq and payload.

func NewResultUpdate

func NewResultUpdate(seq uint64, payload []byte) Update

NewResultUpdate creates a persistent result Update with the given seq and payload.

func NewRetryUpdate

func NewRetryUpdate(payload []byte) Update

NewRetryUpdate creates a non-persistent retry Update with seq=0.

func NewStreamingUpdate

func NewStreamingUpdate(payload []byte) Update

NewStreamingUpdate creates a non-persistent streaming Update with seq=0.

func NewToolCallUpdate

func NewToolCallUpdate(seq uint64, payload []byte) Update

NewToolCallUpdate creates a persistent tool_call Update with the given seq and payload.

func NewTypingUpdate

func NewTypingUpdate(payload []byte) Update

NewTypingUpdate creates a non-persistent typing Update with seq=0.

type Updates

type Updates struct {
	Type    string   `json:"type"`
	Version int      `json:"version"`
	Updates []Update `json:"updates"`
}

Updates represents an updates message envelope containing multiple Update entries.

type UpdatesBuilder

type UpdatesBuilder struct {
	// contains filtered or unexported fields
}

UpdatesBuilder provides a fluent API for constructing Updates messages.

func NewUpdates

func NewUpdates() *UpdatesBuilder

NewUpdates creates a new UpdatesBuilder with an empty (non-nil) updates slice.

func (*UpdatesBuilder) Add

Add appends an Update to the builder.

func (*UpdatesBuilder) Build

func (b *UpdatesBuilder) Build() *Updates

Build returns the constructed Updates.

func (*UpdatesBuilder) Marshal

func (b *UpdatesBuilder) Marshal() ([]byte, error)

Marshal serializes the Updates to JSON bytes.

Jump to

Keyboard shortcuts

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