mirror of
https://github.com/memohai/Memoh.git
synced 2026-04-25 07:00:48 +09:00
168 lines
6.7 KiB
Go
168 lines
6.7 KiB
Go
// Package pipeline implements the Deterministic Context Pipeline (DCP) for
|
|
// assembling LLM context from canonical IM events. It provides Adaptation
|
|
// types, Projection (reduce), and Rendering (RC) layers.
|
|
package pipeline
|
|
|
|
// EventKind classifies a canonical event.
|
|
type EventKind string
|
|
|
|
const (
|
|
EventMessage EventKind = "message"
|
|
EventEdit EventKind = "edit"
|
|
EventDelete EventKind = "delete"
|
|
EventService EventKind = "service"
|
|
)
|
|
|
|
// CanonicalUser is a platform-agnostic sender identity.
|
|
type CanonicalUser struct {
|
|
// ID is the channel_identity_id (Memoh UUID).
|
|
ID string `json:"id"`
|
|
DisplayName string `json:"display_name"`
|
|
Username string `json:"username,omitempty"`
|
|
IsBot bool `json:"is_bot,omitempty"`
|
|
}
|
|
|
|
// ContentNode represents a rich-text tree node, parsed from platform-specific
|
|
// encodings (e.g. Telegram entities, Discord markdown).
|
|
type ContentNode struct {
|
|
Type string `json:"type"`
|
|
Text string `json:"text,omitempty"`
|
|
Language string `json:"language,omitempty"`
|
|
URL string `json:"url,omitempty"`
|
|
UserID string `json:"user_id,omitempty"`
|
|
Children []ContentNode `json:"children,omitempty"`
|
|
}
|
|
|
|
// Attachment is a platform-agnostic media attachment.
|
|
type Attachment struct {
|
|
Type string `json:"type"`
|
|
MimeType string `json:"mime_type,omitempty"`
|
|
FileName string `json:"file_name,omitempty"`
|
|
Width int `json:"width,omitempty"`
|
|
Height int `json:"height,omitempty"`
|
|
Duration int `json:"duration,omitempty"`
|
|
ThumbnailB64 string `json:"thumbnail_b64,omitempty"`
|
|
AltText string `json:"alt_text,omitempty"`
|
|
// FilePath is the workspace path where the attachment is stored.
|
|
FilePath string `json:"file_path,omitempty"`
|
|
// ContentHash is the media-store content hash for persisted attachments.
|
|
ContentHash string `json:"content_hash,omitempty"`
|
|
}
|
|
|
|
// ForwardInfo describes a forwarded message origin.
|
|
type ForwardInfo struct {
|
|
FromUserID string `json:"from_user_id,omitempty"`
|
|
FromChatID string `json:"from_chat_id,omitempty"`
|
|
Sender *CanonicalUser `json:"sender,omitempty"`
|
|
SenderName string `json:"sender_name,omitempty"`
|
|
Date int64 `json:"date,omitempty"`
|
|
}
|
|
|
|
// ConversationMeta carries session-level context embedded in every event,
|
|
// so each rendered message is self-contained.
|
|
type ConversationMeta struct {
|
|
Channel string `json:"channel"`
|
|
ConversationName string `json:"conversation_name,omitempty"`
|
|
ConversationType string `json:"conversation_type"`
|
|
Target string `json:"target,omitempty"`
|
|
}
|
|
|
|
// --- Concrete event types ---
|
|
|
|
// MessageEvent represents a new message in a session.
|
|
type MessageEvent struct {
|
|
SessionID string `json:"session_id"`
|
|
EventID string `json:"event_id,omitempty"`
|
|
MessageID string `json:"message_id"`
|
|
Sender *CanonicalUser `json:"sender,omitempty"`
|
|
ReceivedAtMs int64 `json:"received_at_ms"`
|
|
TimestampSec int64 `json:"timestamp_sec"`
|
|
UTCOffsetMin int `json:"utc_offset_min"`
|
|
Content []ContentNode `json:"content"`
|
|
ReplyToMessageID string `json:"reply_to_message_id,omitempty"`
|
|
ReplyToSender string `json:"reply_to_sender,omitempty"`
|
|
ReplyToPreview string `json:"reply_to_preview,omitempty"`
|
|
ForwardInfo *ForwardInfo `json:"forward_info,omitempty"`
|
|
Attachments []Attachment `json:"attachments"`
|
|
IsSelfSent bool `json:"is_self_sent,omitempty"`
|
|
Conversation ConversationMeta `json:"conversation"`
|
|
}
|
|
|
|
func (MessageEvent) Kind() EventKind { return EventMessage }
|
|
func (e MessageEvent) GetSessionID() string { return e.SessionID }
|
|
func (e MessageEvent) GetReceivedAtMs() int64 { return e.ReceivedAtMs }
|
|
|
|
// EditEvent represents a message edit.
|
|
type EditEvent struct {
|
|
SessionID string `json:"session_id"`
|
|
EventID string `json:"event_id,omitempty"`
|
|
MessageID string `json:"message_id"`
|
|
Sender *CanonicalUser `json:"sender,omitempty"`
|
|
ReceivedAtMs int64 `json:"received_at_ms"`
|
|
TimestampSec int64 `json:"timestamp_sec"`
|
|
UTCOffsetMin int `json:"utc_offset_min"`
|
|
Content []ContentNode `json:"content"`
|
|
Attachments []Attachment `json:"attachments"`
|
|
}
|
|
|
|
func (EditEvent) Kind() EventKind { return EventEdit }
|
|
func (e EditEvent) GetSessionID() string { return e.SessionID }
|
|
func (e EditEvent) GetReceivedAtMs() int64 { return e.ReceivedAtMs }
|
|
|
|
// DeleteEvent represents one or more deleted messages.
|
|
type DeleteEvent struct {
|
|
SessionID string `json:"session_id"`
|
|
EventID string `json:"event_id,omitempty"`
|
|
MessageIDs []string `json:"message_ids"`
|
|
ReceivedAtMs int64 `json:"received_at_ms"`
|
|
TimestampSec int64 `json:"timestamp_sec"`
|
|
UTCOffsetMin int `json:"utc_offset_min"`
|
|
}
|
|
|
|
func (DeleteEvent) Kind() EventKind { return EventDelete }
|
|
func (e DeleteEvent) GetSessionID() string { return e.SessionID }
|
|
func (e DeleteEvent) GetReceivedAtMs() int64 { return e.ReceivedAtMs }
|
|
|
|
// ServiceAction classifies a group lifecycle event.
|
|
type ServiceAction string
|
|
|
|
const (
|
|
ServiceMembersJoined ServiceAction = "members_joined"
|
|
ServiceMemberLeft ServiceAction = "member_left"
|
|
ServiceChatRenamed ServiceAction = "chat_renamed"
|
|
ServiceChatPhotoChanged ServiceAction = "chat_photo_changed"
|
|
ServiceChatPhotoDeleted ServiceAction = "chat_photo_deleted"
|
|
ServiceMessagePinned ServiceAction = "message_pinned"
|
|
)
|
|
|
|
// ServiceEvent represents a group lifecycle event (join, leave, rename, etc.).
|
|
type ServiceEvent struct {
|
|
SessionID string `json:"session_id"`
|
|
EventID string `json:"event_id,omitempty"`
|
|
Action ServiceAction `json:"action"`
|
|
Actor *CanonicalUser `json:"actor,omitempty"`
|
|
ReceivedAtMs int64 `json:"received_at_ms"`
|
|
TimestampSec int64 `json:"timestamp_sec"`
|
|
UTCOffsetMin int `json:"utc_offset_min"`
|
|
|
|
// Action-specific fields
|
|
Members []CanonicalUser `json:"members,omitempty"`
|
|
Member *CanonicalUser `json:"member,omitempty"`
|
|
NewTitle string `json:"new_title,omitempty"`
|
|
OldTitle string `json:"old_title,omitempty"`
|
|
// For message_pinned
|
|
PinnedMessageID string `json:"pinned_message_id,omitempty"`
|
|
PinnedPreview string `json:"pinned_preview,omitempty"`
|
|
}
|
|
|
|
func (ServiceEvent) Kind() EventKind { return EventService }
|
|
func (e ServiceEvent) GetSessionID() string { return e.SessionID }
|
|
func (e ServiceEvent) GetReceivedAtMs() int64 { return e.ReceivedAtMs }
|
|
|
|
// CanonicalEvent is the interface satisfied by all event types.
|
|
type CanonicalEvent interface {
|
|
Kind() EventKind
|
|
GetSessionID() string
|
|
GetReceivedAtMs() int64
|
|
}
|