collab

package
v0.3.1 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AgentStatusActive       = "active"
	AgentStatusIdle         = "idle"
	AgentStatusDisconnected = "disconnected"
)

AgentStatus constants

View Source
const (
	MessageTypeDirect    = "direct"
	MessageTypeBroadcast = "broadcast"
	MessageTypeSystem    = "system"
)

MessageType constants

View Source
const (
	ChangeTypeCreated  = "created"
	ChangeTypeModified = "modified"
	ChangeTypeDeleted  = "deleted"
)

ChangeType constants

View Source
const (
	WSMessageTypeAgentJoined    = "agent_joined"
	WSMessageTypeAgentLeft      = "agent_left"
	WSMessageTypeMessage        = "message"
	WSMessageTypeFileChanged    = "file_changed"
	WSMessageTypePresenceUpdate = "presence_update"
	WSMessageTypePing           = "ping"
	WSMessageTypePong           = "pong"
)

WSMessageType constants

View Source
const (
	MaxAgentIDLength    = 64
	MaxAgentNameLength  = 200
	MaxMessageBytes     = 64 * 1024 // 64 KB
	MaxFilePathLength   = 4096
	MaxAgentsPerSession = 32
)

Limits on agent-supplied values. Agent IDs become part of Redis key names and a Postgres unique key, so they are the most tightly constrained.

Variables

View Source
var (
	ErrAgentNotFound    = errors.New("agent not found")
	ErrSessionNotCollab = errors.New("session does not allow collaboration")
	ErrMaxAgentsReached = errors.New("maximum agents reached for session")
)

Functions

func ValidateAgentID added in v0.3.1

func ValidateAgentID(agentID string) error

ValidateAgentID checks an agent identifier before it is used in a Redis key or stored as part of the (session_id, agent_id) unique constraint.

func ValidateAgentName added in v0.3.1

func ValidateAgentName(name string) error

ValidateAgentName checks the human-readable agent name. Names are only ever displayed, so the constraint is length and valid UTF-8 rather than charset.

func ValidateAgentStatus added in v0.3.1

func ValidateAgentStatus(status string) error

ValidateAgentStatus rejects unknown presence states.

func ValidateFilePath added in v0.3.1

func ValidateFilePath(path string) error

ValidateFilePath bounds the presence "current file" field. The value is informational — it is never opened — so only length and encoding matter.

func ValidateMaxAgents added in v0.3.1

func ValidateMaxAgents(maxAgents int) error

ValidateMaxAgents bounds the per-session agent cap. Each agent holds a WebSocket connection and two goroutines, so an unbounded value is a resource-exhaustion vector.

func ValidateMessageBody added in v0.3.1

func ValidateMessageBody(body string) error

ValidateMessageBody bounds a message before it is written to Postgres and broadcast to every connected agent. Without a bound, one agent can exhaust the message table and saturate every peer's send buffer.

func ValidateMessageType added in v0.3.1

func ValidateMessageType(msgType string) error

ValidateMessageType rejects unknown types so that a client cannot invent a type that downstream consumers mishandle.

Types

type Agent

type Agent struct {
	ID           string    `json:"id"`           // Agent identifier (e.g., "agent_a")
	Name         string    `json:"name"`         // Human-readable name
	SessionID    uuid.UUID `json:"session_id"`   // Session this agent is connected to
	Status       string    `json:"status"`       // "active", "idle", "disconnected"
	CurrentFile  string    `json:"current_file"` // File currently being edited (nullable)
	LastActivity time.Time `json:"last_activity"`
	ConnectedAt  time.Time `json:"connected_at"`
}

Agent represents a connected agent in a collaborative session

type AgentJoinedPayload

type AgentJoinedPayload struct {
	Agent Agent `json:"agent"`
}

AgentJoinedPayload is sent when an agent joins

type AgentLeftPayload

type AgentLeftPayload struct {
	AgentID   string    `json:"agent_id"`
	Timestamp time.Time `json:"timestamp"`
}

AgentLeftPayload is sent when an agent disconnects

type Client

type Client struct {
	SessionID uuid.UUID
	AgentID   string
	AgentName string
	Conn      *websocket.Conn
	Manager   *Manager
	// contains filtered or unexported fields
}

Client represents a WebSocket client (agent connection)

func NewClient

func NewClient(sessionID uuid.UUID, agentID, agentName string, conn *websocket.Conn, manager *Manager) *Client

NewClient creates a new WebSocket client

func (*Client) ReadPump

func (c *Client) ReadPump(ctx context.Context)

ReadPump reads messages from the WebSocket connection

func (*Client) Send

func (c *Client) Send(message []byte)

Send queues a message to be sent to the client

func (*Client) WritePump

func (c *Client) WritePump(ctx context.Context)

WritePump sends messages to the WebSocket connection

type FileChange

type FileChange struct {
	SessionID  uuid.UUID `json:"session_id"`
	File       string    `json:"file"`
	ChangedBy  string    `json:"changed_by"`  // Agent ID
	ChangeType string    `json:"change_type"` // "created", "modified", "deleted"
	Version    int       `json:"version"`     // Incremental version number
	Timestamp  time.Time `json:"timestamp"`
}

FileChange represents a file modification event

type FileChangedPayload

type FileChangedPayload struct {
	Change FileChange `json:"change"`
}

FileChangedPayload is sent when a file is modified

type Hub

type Hub struct {
	Manager *Manager
	// contains filtered or unexported fields
}

Hub manages all active WebSocket connections

func NewHub

func NewHub(manager *Manager) *Hub

NewHub creates a new WebSocket hub

func (*Hub) BroadcastToSession

func (h *Hub) BroadcastToSession(sessionID uuid.UUID, message []byte)

BroadcastToSession sends a message to all clients in a session

func (*Hub) RegisterClient

func (h *Hub) RegisterClient(client *Client)

RegisterClient registers a new WebSocket client

func (*Hub) Run

func (h *Hub) Run(ctx context.Context)

Run starts the hub

func (*Hub) UnregisterClient

func (h *Hub) UnregisterClient(client *Client)

UnregisterClient unregisters a WebSocket client

type Manager

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

Manager handles multi-agent collaboration

func New

func New(db *sqlx.DB, redisClient *redis.Client) *Manager

New creates a new collaboration manager

func (*Manager) GetActiveAgents

func (m *Manager) GetActiveAgents(ctx context.Context, sessionID uuid.UUID) ([]Agent, error)

GetActiveAgents returns all active agents for a session

func (*Manager) GetFileVersion

func (m *Manager) GetFileVersion(ctx context.Context, sessionID uuid.UUID, filePath string) (int, error)

GetFileVersion returns the current version of a file

func (*Manager) GetMessages

func (m *Manager) GetMessages(ctx context.Context, sessionID uuid.UUID, limit int) ([]Message, error)

GetMessages retrieves recent messages for a session

func (*Manager) JoinSession

func (m *Manager) JoinSession(ctx context.Context, sessionID uuid.UUID, agentID, agentName string) (*Agent, error)

JoinSession registers an agent as active in a session

func (*Manager) LeaveSession

func (m *Manager) LeaveSession(ctx context.Context, sessionID uuid.UUID, agentID string) error

LeaveSession removes an agent from a session

func (*Manager) RecordFileChange

func (m *Manager) RecordFileChange(ctx context.Context, sessionID uuid.UUID, filePath, agentID, changeType, checksum string, sizeBytes int64) (*FileChange, error)

RecordFileChange records a file modification

func (*Manager) SendMessage

func (m *Manager) SendMessage(ctx context.Context, sessionID uuid.UUID, from, to, body string, msgType string) (*Message, error)

SendMessage sends a message from one agent to another (or broadcast)

func (*Manager) SubscribeToEvents

func (m *Manager) SubscribeToEvents(ctx context.Context, sessionID uuid.UUID) *redis.PubSub

SubscribeToEvents subscribes to session events

func (*Manager) UpdatePresence

func (m *Manager) UpdatePresence(ctx context.Context, sessionID uuid.UUID, agentID string, currentFile string, status string) error

UpdatePresence updates an agent's presence (current file, status)

type Message

type Message struct {
	ID        uuid.UUID              `json:"id"`
	SessionID uuid.UUID              `json:"session_id"`
	Type      string                 `json:"type"` // "direct", "broadcast", "system"
	From      string                 `json:"from"` // Agent ID
	To        string                 `json:"to"`   // Agent ID (empty for broadcast)
	Body      string                 `json:"body"`
	Metadata  map[string]interface{} `json:"metadata,omitempty"`
	Timestamp time.Time              `json:"timestamp"`
}

Message represents a message between agents

type MessagePayload

type MessagePayload struct {
	Message Message `json:"message"`
}

MessagePayload wraps a message

type PresenceUpdatePayload

type PresenceUpdatePayload struct {
	AgentID     string    `json:"agent_id"`
	Status      string    `json:"status"`
	CurrentFile string    `json:"current_file"`
	Timestamp   time.Time `json:"timestamp"`
}

PresenceUpdatePayload is sent when agent presence changes

type WSMessage

type WSMessage struct {
	Type    string      `json:"type"` // "agent_joined", "agent_left", "message", "file_changed", "presence_update"
	Payload interface{} `json:"payload"`
}

WSMessage is the wrapper for all WebSocket messages

Jump to

Keyboard shortcuts

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