Documentation
¶
Index ¶
- Constants
- Variables
- func CheckMethod(w http.ResponseWriter, r *http.Request, allowed string) bool
- func CheckMethodGET(w http.ResponseWriter, r *http.Request) bool
- func CheckMethodPOST(w http.ResponseWriter, r *http.Request) bool
- func ChunkMessage(text string, cfg ChunkerConfig) []string
- func ChunkMessageSimple(text string, maxLen int) []string
- func CreateDefaultStrategy() storage.StorageStrategy
- func CreateSessionManager(namespace string) session.SessionManager
- func CreateStorageFromType(storageType string, config map[string]any) (storage.ChatAppMessageStore, error)
- func ExtractInt64FromMetadata(msg *ChatMessage, key string) int64
- func ExtractStringFromMetadata(msg *ChatMessage, key string) string
- func ProcessWebhook[T any](h *WebhookHandler, w http.ResponseWriter, r *http.Request, parse ParseFunc[T], ...) bool
- func ProcessWebhookNoVerify[T any](logger *slog.Logger, w http.ResponseWriter, r *http.Request, ...) bool
- func ReadBody(r *http.Request) ([]byte, error)
- func ReadBodyWithError(r *http.Request) ([]byte, error)
- func ReadBodyWithLog(w http.ResponseWriter, r *http.Request, logger *slog.Logger) ([]byte, bool)
- func ReadBodyWithLogAndClose(w http.ResponseWriter, r *http.Request, logger *slog.Logger) ([]byte, bool)
- func RespondWithError(w http.ResponseWriter, code int, message string)
- func RespondWithJSON(w http.ResponseWriter, code int, data any) error
- func RespondWithText(w http.ResponseWriter, code int, text string)
- func RuneCount(s string) int
- func TruncateByRune(s string, maxRunes int) string
- func TruncateWithEllipsis(s string, maxRunes int) string
- func VerifyRequest(verifier SignatureVerifier, r *http.Request, body []byte) bool
- type Adapter
- func (a *Adapter) AppendStream(ctx context.Context, channelID, messageTS, content string) error
- func (a *Adapter) DeleteMessage(ctx context.Context, channelID, messageTS string) error
- func (a *Adapter) FindSessionByUserAndChannel(userID, channelID string) *Session
- func (a *Adapter) GetOrCreateSession(userID, botUserID, channelID, threadID string) string
- func (a *Adapter) GetSession(key string) (*Session, bool)
- func (a *Adapter) HandleMessage(ctx context.Context, msg *ChatMessage) error
- func (a *Adapter) Handler() MessageHandler
- func (a *Adapter) Logger() *slog.Logger
- func (a *Adapter) Platform() string
- func (a *Adapter) SendMessage(ctx context.Context, sessionID string, msg *ChatMessage) error
- func (a *Adapter) SendThreadReply(ctx context.Context, channelID, threadTS, text string) error
- func (a *Adapter) SetAssistantStatus(ctx context.Context, channelID, threadTS, status string) error
- func (a *Adapter) SetHandler(handler MessageHandler)
- func (a *Adapter) SetLogger(logger *slog.Logger)
- func (a *Adapter) SetMessageStore(store *MessageStorePlugin)
- func (a *Adapter) SetProviderType(providerType string)
- func (a *Adapter) SetSessionManager(mgr session.SessionManager)
- func (a *Adapter) Start(ctx context.Context) error
- func (a *Adapter) StartStream(ctx context.Context, channelID, threadTS string) (string, error)
- func (a *Adapter) Stop() error
- func (a *Adapter) StopStream(ctx context.Context, channelID, messageTS string) error
- func (a *Adapter) SystemPrompt() string
- func (a *Adapter) UpdateMessage(ctx context.Context, channelID, messageTS string, msg *ChatMessage) error
- func (a *Adapter) WebhookHandler() http.Handler
- func (a *Adapter) WebhookPath() string
- type AdapterOption
- func WithCleanupInterval(interval time.Duration) AdapterOption
- func WithHTTPHandler(path string, handler http.HandlerFunc) AdapterOption
- func WithMessageParser(parser MessageParser) AdapterOption
- func WithMessageSender(sender MessageSender) AdapterOption
- func WithMetadataExtractor(extractor MetadataExtractor) AdapterOption
- func WithSessionIDGenerator(generator SessionIDGenerator) AdapterOption
- func WithSessionTimeout(timeout time.Duration) AdapterOption
- func WithoutServer() AdapterOption
- type Attachment
- type ChatAdapter
- type ChatMessage
- type ChunkerConfig
- type Config
- type DangerApprovalRegistry
- type EngineSupport
- type HMACSHA256Verifier
- type HTTPClient
- func (c *HTTPClient) Get(ctx context.Context, url string, headers map[string]string) ([]byte, error)
- func (c *HTTPClient) PostJSON(ctx context.Context, url string, payload any, headers map[string]string) ([]byte, error)
- func (c *HTTPClient) PostJSONWithResponse(ctx context.Context, url string, payload any, headers map[string]string, ...) error
- type HandlerFunc
- type MessageContext
- type MessageContextBuilder
- func (b *MessageContextBuilder) Build() (*MessageContext, error)
- func (b *MessageContextBuilder) WithChatSession(sessionID, platform, userID, botUserID, channelID, threadID string) *MessageContextBuilder
- func (b *MessageContextBuilder) WithEngineSession(sessionID uuid.UUID, namespace string) *MessageContextBuilder
- func (b *MessageContextBuilder) WithMessage(msgType types.MessageType, direction MessageDirection, content string) *MessageContextBuilder
- func (b *MessageContextBuilder) WithMetadata(key string, value any) *MessageContextBuilder
- func (b *MessageContextBuilder) WithProviderSession(sessionID, providerType string) *MessageContextBuilder
- type MessageDirection
- type MessageHandler
- type MessageOperations
- type MessageParser
- type MessageSender
- type MessageStoreInitializer
- type MessageStorePlugin
- func (p *MessageStorePlugin) Close() error
- func (p *MessageStorePlugin) GetSessionMeta(ctx context.Context, chatSessionID string) (*storage.SessionMeta, error)
- func (p *MessageStorePlugin) Initialize(ctx context.Context) error
- func (p *MessageStorePlugin) ListUserSessions(ctx context.Context, platform, userID string) ([]string, error)
- func (p *MessageStorePlugin) OnBotResponse(ctx context.Context, msgCtx *MessageContext) error
- func (p *MessageStorePlugin) OnStreamComplete(ctx context.Context, sessionID string, msgCtx *MessageContext) error
- func (p *MessageStorePlugin) OnUserMessage(ctx context.Context, msgCtx *MessageContext) error
- type MessageStorePluginConfig
- type MessageType
- type MetadataExtractor
- type NoOpVerifier
- type ParseFunc
- type ParseMode
- type PendingMessage
- type PendingMessageStore
- type RichContent
- type SenderFunc
- type SenderWithMutex
- type Session
- type SessionIDGenerator
- type SessionOperations
- type SignatureVerifier
- type SimpleKeyGenerator
- type StatusProvider
- type StatusType
- type StreamBuffer
- type StreamMessageStore
- func (s *StreamMessageStore) Close()
- func (s *StreamMessageStore) GetBuffer(sessionID string) *StreamBuffer
- func (s *StreamMessageStore) GetBufferCount() int
- func (s *StreamMessageStore) OnStreamChunk(ctx context.Context, sessionID, chunk string) error
- func (s *StreamMessageStore) OnStreamComplete(ctx context.Context, sessionID string, msg *storage.ChatAppMessage) error
- type StreamWriter
- type UUID5Generator
- type WebhookHandler
- type WebhookProvider
- type WebhookRunner
- type WebhookRunnerOption
Constants ¶
const ( DefaultDedupWindow = 5 * time.Second DefaultDedupCleanup = 10 * time.Second )
DefaultDedupWindow 默去重配置 (reduced from 30s to 5s per Issue #129) 30 second TTL was too long, causing legitimate messages to be incorrectly filtered as duplicates
const DefaultChunkLimit = 4000
DefaultChunkLimit is the default maximum chunk size.
const ErrSenderNotConfigured = "sender not configured"
ErrSenderNotConfigured is returned when SendMessage is called but no sender function has been configured.
Variables ¶
var ( ErrNilStore = errors.New("storage store is nil") ErrNilSessionManager = errors.New("session manager is nil") ErrMissingChatSessionID = errors.New("chat_session_id is required") ErrMissingEngineSessionID = errors.New("engine_session_id is required") ErrMissingProviderSessionID = errors.New("provider_session_id is required") ErrMissingContent = errors.New("content is required") )
消息存储相关错误定义
var ErrBufferFull = errors.New("stream buffer full, cannot accept new chunks")
ErrBufferFull 缓冲区已满错误
var ErrNotSupported = errors.New("operation not supported on this platform")
ErrNotSupported is returned by optional interface methods when the platform does not support the requested operation.
var GlobalDangerRegistry = &DangerApprovalRegistry{}
GlobalDangerRegistry is the singleton registry for danger block approvals.
Functions ¶
func CheckMethod ¶ added in v0.21.0
CheckMethod validates the HTTP method and sends error response if invalid. Returns true if method is valid, false otherwise (response already sent).
Usage:
if !base.CheckMethod(w, r, http.MethodPost) {
return
}
func CheckMethodGET ¶ added in v0.21.0
func CheckMethodGET(w http.ResponseWriter, r *http.Request) bool
CheckMethodGET is a convenience wrapper for GET method check.
func CheckMethodPOST ¶ added in v0.21.0
func CheckMethodPOST(w http.ResponseWriter, r *http.Request) bool
CheckMethodPOST is a convenience wrapper for POST method check.
func ChunkMessage ¶ added in v0.21.0
func ChunkMessage(text string, cfg ChunkerConfig) []string
ChunkMessage splits a text message into chunks that fit within the limit. It attempts to split at word boundaries to avoid breaking words. Each chunk is prefixed with chunkNum/totalChunks if numbering is enabled.
func ChunkMessageSimple ¶ added in v0.21.0
ChunkMessageSimple splits text by byte length without word boundary preservation. Use this for platforms that don't need word-aware splitting.
func CreateDefaultStrategy ¶ added in v0.21.0
func CreateDefaultStrategy() storage.StorageStrategy
CreateDefaultStrategy 创建默认存储策略
func CreateSessionManager ¶ added in v0.21.0
func CreateSessionManager(namespace string) session.SessionManager
CreateSessionManager 创建 SessionManager
func CreateStorageFromType ¶ added in v0.21.0
func CreateStorageFromType(storageType string, config map[string]any) (storage.ChatAppMessageStore, error)
CreateStorageFromType 根据类型创建存储后端
func ExtractInt64FromMetadata ¶
func ExtractInt64FromMetadata(msg *ChatMessage, key string) int64
ExtractInt64FromMetadata extracts an int64 value from message metadata. Returns 0 if the key doesn't exist or the value is not a numeric type.
func ExtractStringFromMetadata ¶
func ExtractStringFromMetadata(msg *ChatMessage, key string) string
ExtractStringFromMetadata extracts a string value from message metadata. Returns empty string if the key doesn't exist or the value is not a string.
func ProcessWebhook ¶ added in v0.21.0
func ProcessWebhook[T any]( h *WebhookHandler, w http.ResponseWriter, r *http.Request, parse ParseFunc[T], handle HandlerFunc[T], ) bool
ProcessWebhook executes the webhook processing pipeline: 1. Method validation (POST only) 2. Body reading 3. Signature verification (if configured) 4. Event parsing 5. Event handling
Returns true if processing was successful, false otherwise. Error responses are automatically written to the client.
func ProcessWebhookNoVerify ¶ added in v0.21.0
func ProcessWebhookNoVerify[T any]( logger *slog.Logger, w http.ResponseWriter, r *http.Request, parse ParseFunc[T], handle HandlerFunc[T], ) bool
ProcessWebhookNoVerify is like ProcessWebhook but skips signature verification.
func ReadBodyWithError ¶ added in v0.21.0
ReadBodyWithError reads the request body and returns an error on failure. This is the most basic form - just read and return.
func ReadBodyWithLog ¶ added in v0.21.0
ReadBodyWithLog reads the request body and logs errors using the provided logger. Returns (body, true) on success, (nil, false) on failure (response already sent).
Usage:
body, ok := base.ReadBodyWithLog(w, r, logger)
if !ok {
return // response already sent
}
func ReadBodyWithLogAndClose ¶ added in v0.21.0
func ReadBodyWithLogAndClose(w http.ResponseWriter, r *http.Request, logger *slog.Logger) ([]byte, bool)
ReadBodyWithLogAndClose is like ReadBodyWithLog but also closes the body. Use this when you don't need the body after reading.
Usage:
body, ok := base.ReadBodyWithLogAndClose(w, r, logger)
if !ok {
return
}
func RespondWithError ¶
func RespondWithError(w http.ResponseWriter, code int, message string)
func RespondWithJSON ¶
func RespondWithJSON(w http.ResponseWriter, code int, data any) error
func RespondWithText ¶
func RespondWithText(w http.ResponseWriter, code int, text string)
func TruncateByRune ¶ added in v0.18.0
TruncateByRune truncates string by rune count, not byte count (no ellipsis)
func TruncateWithEllipsis ¶ added in v0.18.0
TruncateWithEllipsis truncates string by rune count with ellipsis
func VerifyRequest ¶ added in v0.21.0
func VerifyRequest(verifier SignatureVerifier, r *http.Request, body []byte) bool
VerifyRequest is a convenience function that checks if a verifier is configured and verifies the request. Returns true if no verifier is configured or if verification passes.
Types ¶
type Adapter ¶
type Adapter struct {
// contains filtered or unexported fields
}
Adapter is the base adapter implementing common functionality
func NewAdapter ¶
func NewAdapter( platform string, config Config, logger *slog.Logger, opts ...AdapterOption, ) *Adapter
NewAdapter creates a new base adapter
func (*Adapter) AppendStream ¶ added in v0.18.0
AppendStream is a no-op by default, overridden by platforms that support it
func (*Adapter) DeleteMessage ¶ added in v0.15.5
DeleteMessage is a no-op by default, overridden by platforms that support it
func (*Adapter) FindSessionByUserAndChannel ¶ added in v0.12.0
FindSessionByUserAndChannel finds a session by matching user_id and channel_id This is useful for slash commands where we don't have the exact key Performance: O(1) using secondary index
func (*Adapter) GetOrCreateSession ¶
GetOrCreateSession gets or creates a session using deterministic session ID generation Parameters:
- userID: the user's ID on the platform
- botUserID: the bot's user ID (for multi-bot scenarios, empty for single bot)
- channelID: the channel/room ID (empty for DM)
- threadID: the thread/topic ID (empty if not applicable)
Returns the generated session ID (deterministic based on inputs)
func (*Adapter) GetSession ¶
GetSession retrieves a session by key
func (*Adapter) HandleMessage ¶
func (a *Adapter) HandleMessage(ctx context.Context, msg *ChatMessage) error
HandleMessage handles incoming message (stub for interface compliance)
func (*Adapter) Handler ¶
func (a *Adapter) Handler() MessageHandler
Handler returns the message handler (thread-safe)
func (*Adapter) SendMessage ¶
SendMessage sends a message (requires messageSender to be set)
func (*Adapter) SendThreadReply ¶ added in v0.18.0
SendThreadReply is a no-op by default, overridden by platforms that support it (Space Folding)
func (*Adapter) SetAssistantStatus ¶ added in v0.18.0
SetAssistantStatus is a no-op by default, overridden by platforms that support it
func (*Adapter) SetHandler ¶
func (a *Adapter) SetHandler(handler MessageHandler)
SetHandler sets the message handler (thread-safe)
func (*Adapter) SetMessageStore ¶ added in v0.21.0
func (a *Adapter) SetMessageStore(store *MessageStorePlugin)
SetMessageStore sets the message storage plugin (thread-safe)
func (*Adapter) SetProviderType ¶ added in v0.21.0
SetProviderType sets the provider type for storage (thread-safe)
func (*Adapter) SetSessionManager ¶ added in v0.21.0
func (a *Adapter) SetSessionManager(mgr session.SessionManager)
SetSessionManager sets the session manager (thread-safe)
func (*Adapter) StartStream ¶ added in v0.18.0
StartStream is a no-op by default, overridden by platforms that support it
func (*Adapter) StopStream ¶ added in v0.18.0
StopStream is a no-op by default, overridden by platforms that support it
func (*Adapter) SystemPrompt ¶
SystemPrompt returns the system prompt
func (*Adapter) UpdateMessage ¶ added in v0.15.5
func (a *Adapter) UpdateMessage(ctx context.Context, channelID, messageTS string, msg *ChatMessage) error
UpdateMessage is a no-op by default, overridden by platforms that support it
func (*Adapter) WebhookHandler ¶
WebhookHandler returns an http.Handler with all webhook endpoints registered
func (*Adapter) WebhookPath ¶
WebhookPath returns the primary webhook path for this adapter
type AdapterOption ¶
type AdapterOption func(*Adapter)
AdapterOption configures the base adapter
func WithCleanupInterval ¶ added in v0.21.0
func WithCleanupInterval(interval time.Duration) AdapterOption
WithCleanupInterval sets the session cleanup interval
func WithHTTPHandler ¶
func WithHTTPHandler(path string, handler http.HandlerFunc) AdapterOption
WithHTTPHandler adds an HTTP handler
func WithMessageParser ¶
func WithMessageParser(parser MessageParser) AdapterOption
WithMessageParser sets the message parser
func WithMessageSender ¶
func WithMessageSender(sender MessageSender) AdapterOption
WithMessageSender sets the message sender
func WithMetadataExtractor ¶
func WithMetadataExtractor(extractor MetadataExtractor) AdapterOption
WithMetadataExtractor sets the metadata extractor
func WithSessionIDGenerator ¶ added in v0.12.0
func WithSessionIDGenerator(generator SessionIDGenerator) AdapterOption
WithSessionIDGenerator sets the session ID generator Use this to customize session ID generation per platform
func WithSessionTimeout ¶
func WithSessionTimeout(timeout time.Duration) AdapterOption
WithSessionTimeout sets the session timeout
func WithoutServer ¶
func WithoutServer() AdapterOption
WithoutServer disables the embedded HTTP server Use this when running adapters under a unified server
type Attachment ¶
type ChatAdapter ¶
type ChatAdapter interface {
Platform() string
SystemPrompt() string
Start(ctx context.Context) error
Stop() error
SendMessage(ctx context.Context, sessionID string, msg *ChatMessage) error
HandleMessage(ctx context.Context, msg *ChatMessage) error
SetHandler(MessageHandler)
}
ChatAdapter is the core interface that ALL platform adapters MUST implement. This defines the minimum contract for a chat platform integration.
Required implementations:
- Platform() - Returns platform identifier
- SystemPrompt() - Returns system prompt for AI
- Start(ctx) - Starts the adapter
- Stop() - Stops the adapter
- SendMessage(ctx, sessionID, msg) - Sends a message
- HandleMessage(ctx, msg) - Handles incoming messages
- SetHandler(handler) - Sets the message handler
type ChatMessage ¶
type ChunkerConfig ¶ added in v0.21.0
type ChunkerConfig struct {
// MaxLen is the maximum character limit per chunk.
// If 0, defaults to DefaultChunkLimit.
MaxLen int
// PreserveWords attempts to break at word boundaries.
// If false, may break in the middle of words.
PreserveWords bool
// AddNumbering prefixes chunks with [1/N] notation.
AddNumbering bool
}
ChunkerConfig holds configuration for message chunking.
type DangerApprovalRegistry ¶ added in v0.18.0
type DangerApprovalRegistry struct {
// contains filtered or unexported fields
}
DangerApprovalRegistry manages pending danger block approvals. Used by chatapps to block on WAF interception until user approves/denies via Slack buttons.
func (*DangerApprovalRegistry) Cancel ¶ added in v0.18.0
func (r *DangerApprovalRegistry) Cancel(sessionID string)
Cancel removes a pending approval without resolving it (e.g. on context cancellation).
func (*DangerApprovalRegistry) Register ¶ added in v0.18.0
func (r *DangerApprovalRegistry) Register(sessionID string) chan bool
Register creates a pending approval channel for the given sessionID. Returns the channel to block on. The caller should select on ctx.Done() and this channel.
type EngineSupport ¶ added in v0.15.5
EngineSupport defines optional interface for adapters that need engine integration
type HMACSHA256Verifier ¶ added in v0.21.0
type HMACSHA256Verifier struct {
// Secret is the signing secret/key
Secret string
// SignatureHeader is the header name containing the signature
SignatureHeader string
// TimestampHeader is the header name containing the timestamp (optional)
TimestampHeader string
// Prefix is the signature prefix (e.g., "v0" for Slack, "" for others)
Prefix string
// IncludeTimestamp whether to include timestamp in signature computation
IncludeTimestamp bool
}
HMACSHA256Verifier implements HMAC-SHA256 signature verification. Used by: Slack, DingTalk, Feishu
type HTTPClient ¶
type HTTPClient struct {
// contains filtered or unexported fields
}
HTTPClient provides common HTTP request patterns for chat adapters. This eliminates the duplicate HTTP request building code across adapters.
func NewHTTPClient ¶
func NewHTTPClient() *HTTPClient
NewHTTPClient creates a new HTTPClient with the default http.Client.
func NewHTTPClientWithConfig ¶
func NewHTTPClientWithConfig(timeout time.Duration, maxRetries int) *HTTPClient
NewHTTPClientWithConfig creates a new HTTPClient with custom configuration.
func (*HTTPClient) Get ¶
func (c *HTTPClient) Get(ctx context.Context, url string, headers map[string]string) ([]byte, error)
Get sends a GET request and returns the response body.
type HandlerFunc ¶ added in v0.21.0
HandlerFunc is the function signature for handling parsed events.
type MessageContext ¶ added in v0.21.0
type MessageContext struct {
// ChatApp 层信息
ChatSessionID string
ChatPlatform string
ChatUserID string
ChatBotUserID string
ChatChannelID string
ChatThreadID string
EngineSessionID uuid.UUID
EngineNamespace string
ProviderSessionID string
ProviderType string
// 消息信息
MessageType types.MessageType
Direction MessageDirection
Content string
Metadata map[string]any
// 可选追踪信息
RequestID string
TraceID string
}
MessageContext 消息存储上下文
func (*MessageContext) Validate ¶ added in v0.21.0
func (mc *MessageContext) Validate() error
Validate 验证必填字段
type MessageContextBuilder ¶ added in v0.21.0
type MessageContextBuilder struct {
// contains filtered or unexported fields
}
MessageContextBuilder 构建器模式
func NewMessageContextBuilder ¶ added in v0.21.0
func NewMessageContextBuilder() *MessageContextBuilder
NewMessageContextBuilder 创建构建器
func (*MessageContextBuilder) Build ¶ added in v0.21.0
func (b *MessageContextBuilder) Build() (*MessageContext, error)
Build 构建并验证
func (*MessageContextBuilder) WithChatSession ¶ added in v0.21.0
func (b *MessageContextBuilder) WithChatSession(sessionID, platform, userID, botUserID, channelID, threadID string) *MessageContextBuilder
WithChatSession 设置 ChatApp 层 Session 信息
func (*MessageContextBuilder) WithEngineSession ¶ added in v0.21.0
func (b *MessageContextBuilder) WithEngineSession(sessionID uuid.UUID, namespace string) *MessageContextBuilder
WithEngineSession 设置 Engine 层 Session 信息
func (*MessageContextBuilder) WithMessage ¶ added in v0.21.0
func (b *MessageContextBuilder) WithMessage(msgType types.MessageType, direction MessageDirection, content string) *MessageContextBuilder
WithMessage 设置消息信息
func (*MessageContextBuilder) WithMetadata ¶ added in v0.21.0
func (b *MessageContextBuilder) WithMetadata(key string, value any) *MessageContextBuilder
WithMetadata 添加元数据
func (*MessageContextBuilder) WithProviderSession ¶ added in v0.21.0
func (b *MessageContextBuilder) WithProviderSession(sessionID, providerType string) *MessageContextBuilder
WithProviderSession 设置 Provider 层 Session 信息
type MessageDirection ¶ added in v0.21.0
type MessageDirection string
MessageDirection 消息方向
const ( DirectionUserToBot MessageDirection = "user_to_bot" DirectionBotToUser MessageDirection = "bot_to_user" )
type MessageHandler ¶
type MessageHandler func(ctx context.Context, msg *ChatMessage) error
MessageHandler is the function signature for handling incoming messages.
type MessageOperations ¶ added in v0.15.5
type MessageOperations interface {
DeleteMessage(ctx context.Context, channelID, messageTS string) error
UpdateMessage(ctx context.Context, channelID, messageTS string, msg *ChatMessage) error
// SetAssistantStatus sets the native assistant status text at the bottom of the thread
// Used to drive dynamic status hints (e.g., "Thinking...", "Searching code...")
SetAssistantStatus(ctx context.Context, channelID, threadTS, status string) error
// SendThreadReply sends a message as a reply inside a thread (Space Folding)
SendThreadReply(ctx context.Context, channelID, threadTS, text string) error
// StartStream starts a native streaming message, returns message_ts as anchor for subsequent updates
StartStream(ctx context.Context, channelID, threadTS string) (string, error)
// AppendStream incrementally pushes content to an existing stream
AppendStream(ctx context.Context, channelID, messageTS, content string) error
// StopStream ends the stream and finalizes the message
StopStream(ctx context.Context, channelID, messageTS string) error
}
MessageOperations is an OPTIONAL interface for advanced message operations. Implement this if your platform supports:
- Deleting messages
- Updating/editing messages
- Native streaming (start/append/stop)
- Thread replies
- Assistant status indicators
Platforms with limited support can implement partial methods and return ErrNotSupported for unsupported operations.
type MessageParser ¶
type MessageParser func(body []byte, metadata map[string]any) (*ChatMessage, error)
MessageParser parses incoming requests into ChatMessage
type MessageSender ¶
type MessageSender func(ctx context.Context, sessionID string, msg *ChatMessage) error
MessageSender sends messages to the platform
type MessageStoreInitializer ¶ added in v0.21.0
type MessageStoreInitializer struct {
// contains filtered or unexported fields
}
MessageStoreInitializer 消息存储插件初始化器
func NewMessageStoreInitializer ¶ added in v0.21.0
func NewMessageStoreInitializer(logger *slog.Logger) *MessageStoreInitializer
NewMessageStoreInitializer 创建初始化器
func (*MessageStoreInitializer) InitializeFromConfig ¶ added in v0.21.0
func (i *MessageStoreInitializer) InitializeFromConfig(ctx context.Context, cfg MessageStorePluginConfig) (*MessageStorePlugin, error)
InitializeFromConfig 从配置初始化消息存储插件
type MessageStorePlugin ¶ added in v0.21.0
type MessageStorePlugin struct {
// contains filtered or unexported fields
}
MessageStorePlugin 消息存储插件 (协调器,SRP)
func BuildMessageStorePlugin ¶ added in v0.21.0
func BuildMessageStorePlugin( storageType string, storageConfig map[string]any, namespace string, providerType string, streamEnabled bool, streamTimeout time.Duration, streamMaxBuffers int, ) (*MessageStorePlugin, error)
BuildMessageStorePlugin 从配置构建完整的消息存储插件
func NewMessageStorePlugin ¶ added in v0.21.0
func NewMessageStorePlugin(cfg MessageStorePluginConfig) (*MessageStorePlugin, error)
NewMessageStorePlugin 创建消息存储插件
func (*MessageStorePlugin) Close ¶ added in v0.21.0
func (p *MessageStorePlugin) Close() error
Close 关闭插件
func (*MessageStorePlugin) GetSessionMeta ¶ added in v0.21.0
func (p *MessageStorePlugin) GetSessionMeta(ctx context.Context, chatSessionID string) (*storage.SessionMeta, error)
GetSessionMeta 获取会话元数据
func (*MessageStorePlugin) Initialize ¶ added in v0.21.0
func (p *MessageStorePlugin) Initialize(ctx context.Context) error
Initialize 初始化插件
func (*MessageStorePlugin) ListUserSessions ¶ added in v0.21.0
func (p *MessageStorePlugin) ListUserSessions(ctx context.Context, platform, userID string) ([]string, error)
ListUserSessions 列出用户的所有会话
func (*MessageStorePlugin) OnBotResponse ¶ added in v0.21.0
func (p *MessageStorePlugin) OnBotResponse(ctx context.Context, msgCtx *MessageContext) error
OnBotResponse 处理机器人响应存储
func (*MessageStorePlugin) OnStreamComplete ¶ added in v0.21.0
func (p *MessageStorePlugin) OnStreamComplete(ctx context.Context, sessionID string, msgCtx *MessageContext) error
OnStreamComplete 标记流式消息完成并存储
func (*MessageStorePlugin) OnUserMessage ¶ added in v0.21.0
func (p *MessageStorePlugin) OnUserMessage(ctx context.Context, msgCtx *MessageContext) error
OnUserMessage 处理用户消息存储
type MessageStorePluginConfig ¶ added in v0.21.0
type MessageStorePluginConfig struct {
Store storage.ChatAppMessageStore
SessionManager session.SessionManager
Strategy storage.StorageStrategy
StreamEnabled bool
StreamTimeout time.Duration
StreamMaxBuffers int
Logger *slog.Logger
}
MessageStorePluginConfig 配置
type MessageType ¶ added in v0.13.0
type MessageType string
MessageType defines the normalized message types across all chat platforms
const ( // MessageTypeThinking indicates the AI is reasoning or thinking MessageTypeThinking MessageType = "thinking" // MessageTypeAnswer indicates text output from the AI MessageTypeAnswer MessageType = "answer" // MessageTypeToolUse indicates a tool invocation is starting MessageTypeToolUse MessageType = "tool_use" // MessageTypeToolResult indicates a tool execution result MessageTypeToolResult MessageType = "tool_result" // MessageTypeError indicates an error occurred MessageTypeError MessageType = "error" // MessageTypePlanMode indicates AI is in plan mode and generating a plan MessageTypePlanMode MessageType = "plan_mode" // MessageTypeExitPlanMode indicates AI completed planning and requests user approval MessageTypeExitPlanMode MessageType = "exit_plan_mode" // MessageTypeAskUserQuestion indicates AI is asking a clarifying question MessageTypeAskUserQuestion MessageType = "ask_user_question" // MessageTypeDangerBlock indicates a dangerous operation confirmation block MessageTypeDangerBlock MessageType = "danger_block" // MessageTypeSessionStats indicates session statistics MessageTypeSessionStats MessageType = "session_stats" // MessageTypeCommandProgress indicates a slash command is executing with progress updates MessageTypeCommandProgress MessageType = "command_progress" // MessageTypeCommandComplete indicates a slash command has completed MessageTypeCommandComplete MessageType = "command_complete" // MessageTypeSystem indicates a system-level message MessageTypeSystem MessageType = "system" // MessageTypeUser indicates a user message reflection MessageTypeUser MessageType = "user" // MessageTypeStepStart indicates a new step/milestone (OpenCode specific) MessageTypeStepStart MessageType = "step_start" // MessageTypeStepFinish indicates a step/milestone completed (OpenCode specific) MessageTypeStepFinish MessageType = "step_finish" // MessageTypeRaw indicates unparsed raw output (fallback) MessageTypeRaw MessageType = "raw" // MessageTypeSessionStart indicates a new session is starting (cold start) MessageTypeSessionStart MessageType = "session_start" // MessageTypeEngineStarting indicates the engine is starting up MessageTypeEngineStarting MessageType = "engine_starting" // MessageTypeUserMessageReceived indicates user message has been received MessageTypeUserMessageReceived MessageType = "user_message_received" // MessageTypePermissionRequest indicates a permission request from Claude Code MessageTypePermissionRequest MessageType = "permission_request" )
type MetadataExtractor ¶
MetadataExtractor extracts platform-specific metadata from incoming requests
type NoOpVerifier ¶ added in v0.21.0
type NoOpVerifier struct{}
NoOpVerifier is a verifier that always returns true. Use this when signature verification is disabled or not needed.
type ParseFunc ¶ added in v0.21.0
ParseFunc is the function signature for parsing request body into events.
type PendingMessage ¶ added in v0.15.7
type PendingMessage struct {
SessionID string
ChannelID string
MessageTS string
OriginalMsg *ChatMessage
CreatedAt time.Time
Reason string
}
PendingMessage represents a message pending approval
type PendingMessageStore ¶ added in v0.15.7
type PendingMessageStore struct {
// contains filtered or unexported fields
}
PendingMessageStore stores pending messages awaiting approval
func NewPendingMessageStore ¶ added in v0.15.7
func NewPendingMessageStore(ttl time.Duration) *PendingMessageStore
NewPendingMessageStore creates a new pending message store
func (*PendingMessageStore) Delete ¶ added in v0.15.7
func (s *PendingMessageStore) Delete(sessionID string)
Delete removes a pending message from the store
func (*PendingMessageStore) Get ¶ added in v0.15.7
func (s *PendingMessageStore) Get(sessionID string) (*PendingMessage, bool)
Get retrieves a pending message by session ID
func (*PendingMessageStore) Stop ¶ added in v0.17.0
func (s *PendingMessageStore) Stop()
Stop stops the cleanup goroutine
func (*PendingMessageStore) Store ¶ added in v0.15.7
func (s *PendingMessageStore) Store(sessionID string, msg *PendingMessage)
Store adds a pending message to the store
type RichContent ¶
type RichContent struct {
ParseMode ParseMode
InlineKeyboard any
Blocks []any
Embeds []any
Attachments []Attachment
}
type SenderFunc ¶
type SenderFunc func(ctx context.Context, sessionID string, msg *ChatMessage) error
SenderFunc is the function signature for sending messages to a platform.
type SenderWithMutex ¶
type SenderWithMutex struct {
// contains filtered or unexported fields
}
SenderWithMutex provides thread-safe sender management for chat adapters. This eliminates the duplicate sender/senderMu pattern across all adapters.
func NewSenderWithMutex ¶
func NewSenderWithMutex() *SenderWithMutex
NewSenderWithMutex creates a new SenderWithMutex with no sender configured.
func NewSenderWithMutexFunc ¶
func NewSenderWithMutexFunc(sender SenderFunc) *SenderWithMutex
NewSenderWithMutexFunc creates a new SenderWithMutex with an initial sender.
func (*SenderWithMutex) HasSender ¶
func (s *SenderWithMutex) HasSender() bool
HasSender returns true if a sender has been configured.
func (*SenderWithMutex) SendMessage ¶
func (s *SenderWithMutex) SendMessage(ctx context.Context, sessionID string, msg *ChatMessage) error
SendMessage sends a message using the configured sender. Thread-safe. Returns ErrSenderNotConfigured if no sender has been set.
func (*SenderWithMutex) Sender ¶
func (s *SenderWithMutex) Sender() SenderFunc
Sender returns the current sender function (may be nil). Note: This does not acquire the lock, so the caller should ensure thread-safety if the sender might be modified concurrently.
func (*SenderWithMutex) SetSender ¶
func (s *SenderWithMutex) SetSender(fn SenderFunc)
SetSender sets the sender function. Thread-safe.
type Session ¶
type Session struct {
SessionID string
UserID string
ChannelID string
Platform string
LastActive time.Time
}
Session represents a user session in a chat platform
type SessionIDGenerator ¶ added in v0.12.0
type SessionIDGenerator interface {
// Generate creates a deterministic session ID based on:
// - platform: the platform name (e.g., "slack", "telegram")
// - userID: the user's ID on the platform
// - botUserID: the bot's user ID (for multi-bot scenarios)
// - channelID: the channel/room ID (empty for DM)
// - threadID: the thread/topic ID (empty if not applicable)
Generate(platform, userID, botUserID, channelID, threadID string) string
}
SessionIDGenerator generates deterministic session IDs
type SessionOperations ¶ added in v0.15.5
type SessionOperations interface {
GetSession(key string) (*Session, bool)
FindSessionByUserAndChannel(userID, channelID string) *Session
}
SessionOperations is an OPTIONAL interface for session management. Implement this if your platform needs direct session access.
type SignatureVerifier ¶ added in v0.21.0
type SignatureVerifier interface {
// Verify checks if the request signature is valid.
// Returns true if valid, false otherwise.
Verify(r *http.Request, body []byte) bool
}
SignatureVerifier defines the interface for webhook signature verification. Different platforms implement different verification strategies.
type SimpleKeyGenerator ¶ added in v0.12.0
type SimpleKeyGenerator struct{}
SimpleKeyGenerator generates session IDs using a simple concatenated key This is useful for debugging or when you don't need UUID format
func NewSimpleKeyGenerator ¶ added in v0.12.0
func NewSimpleKeyGenerator() *SimpleKeyGenerator
NewSimpleKeyGenerator creates a new simple key generator
func (*SimpleKeyGenerator) Generate ¶ added in v0.12.0
func (g *SimpleKeyGenerator) Generate(platform, userID, botUserID, channelID, threadID string) string
Generate creates a session ID by concatenating all components Format: platform:userID:botUserID:channelID:threadID
type StatusProvider ¶ added in v0.18.0
type StatusProvider interface {
// SetStatus sets current status, adapter converts to native API or bubble message
// channelID and threadTS specify where to display the status
SetStatus(ctx context.Context, channelID, threadTS string, status StatusType, text string) error
// ClearStatus clears status indicator
ClearStatus(ctx context.Context, channelID, threadTS string) error
}
StatusProvider defines the abstraction for status notification Follows Dependency Inversion Principle - adapters decide the concrete implementation
type StatusType ¶ added in v0.18.0
type StatusType string
StatusType defines AI working states
const ( StatusInitializing StatusType = "initializing" StatusThinking StatusType = "thinking" StatusToolUse StatusType = "tool_use" StatusToolResult StatusType = "tool_result" StatusAnswering StatusType = "answering" StatusIdle StatusType = "idle" )
func MessageTypeToStatusType ¶ added in v0.18.0
func MessageTypeToStatusType(msgType MessageType) StatusType
MessageTypeToStatusType converts MessageType to StatusType for status notification Returns StatusIdle for unrecognized types
type StreamBuffer ¶ added in v0.21.0
type StreamBuffer struct {
SessionID string
Chunks []string
IsComplete bool
LastUpdated time.Time
// contains filtered or unexported fields
}
StreamBuffer 流式消息缓冲区 (内存)
func (*StreamBuffer) Append ¶ added in v0.21.0
func (b *StreamBuffer) Append(chunk string)
Append 追加 chunk 到缓冲区
func (*StreamBuffer) IsExpired ¶ added in v0.21.0
func (b *StreamBuffer) IsExpired(timeout time.Duration) bool
IsExpired 检查缓冲区是否超时
func (*StreamBuffer) Merge ¶ added in v0.21.0
func (b *StreamBuffer) Merge() string
Merge 合并所有 chunk 为完整消息
type StreamMessageStore ¶ added in v0.21.0
type StreamMessageStore struct {
// contains filtered or unexported fields
}
StreamMessageStore 流式消息存储管理器
func NewStreamMessageStore ¶ added in v0.21.0
func NewStreamMessageStore(store storage.ChatAppMessageStore, timeout time.Duration, maxBuffers int, logger *slog.Logger) *StreamMessageStore
NewStreamMessageStore 创建流式消息存储管理器
func (*StreamMessageStore) Close ¶ added in v0.21.0
func (s *StreamMessageStore) Close()
Close 停止清理 goroutine
func (*StreamMessageStore) GetBuffer ¶ added in v0.21.0
func (s *StreamMessageStore) GetBuffer(sessionID string) *StreamBuffer
GetBuffer 获取指定 session 的缓冲区 (用于调试/监控)
func (*StreamMessageStore) GetBufferCount ¶ added in v0.21.0
func (s *StreamMessageStore) GetBufferCount() int
GetBufferCount 获取当前活跃的缓冲区数量
func (*StreamMessageStore) OnStreamChunk ¶ added in v0.21.0
func (s *StreamMessageStore) OnStreamChunk(ctx context.Context, sessionID, chunk string) error
OnStreamChunk 接收流式消息块 (不存储,仅缓存)
func (*StreamMessageStore) OnStreamComplete ¶ added in v0.21.0
func (s *StreamMessageStore) OnStreamComplete(ctx context.Context, sessionID string, msg *storage.ChatAppMessage) error
OnStreamComplete 流式消息完成 (合并后存储)
type StreamWriter ¶ added in v0.18.0
type StreamWriter interface {
io.Writer
io.Closer
// MessageTS returns the message timestamp after stream starts
MessageTS() string
}
StreamWriter defines the interface for streaming message writes Platform-agnostic abstraction for native streaming support
type UUID5Generator ¶ added in v0.12.0
type UUID5Generator struct {
// contains filtered or unexported fields
}
UUID5Generator generates session IDs using UUID5 (SHA1 hash) This ensures the same inputs always produce the same session ID
func NewUUID5Generator ¶ added in v0.12.0
func NewUUID5Generator(namespace string) *UUID5Generator
NewUUID5Generator creates a new UUID5 generator with the given namespace
func (*UUID5Generator) Generate ¶ added in v0.12.0
func (g *UUID5Generator) Generate(platform, userID, botUserID, channelID, threadID string) string
Generate creates a deterministic session ID Format: UUID5(namespace + ":session:" + platform + ":" + userID + ":" + botUserID + ":" + channelID + ":" + threadID)
type WebhookHandler ¶ added in v0.21.0
type WebhookHandler struct {
Logger *slog.Logger
Verifier SignatureVerifier
}
WebhookHandler provides common utilities for webhook processing.
func NewWebhookHandler ¶ added in v0.21.0
func NewWebhookHandler(logger *slog.Logger, verifier SignatureVerifier) *WebhookHandler
NewWebhookHandler creates a new WebhookHandler.
func (*WebhookHandler) RespondJSON ¶ added in v0.21.0
func (h *WebhookHandler) RespondJSON(w http.ResponseWriter, status int, data any)
RespondJSON writes a JSON response.
func (*WebhookHandler) RespondOK ¶ added in v0.21.0
func (h *WebhookHandler) RespondOK(w http.ResponseWriter)
RespondOK writes a simple OK response.
func (*WebhookHandler) RespondText ¶ added in v0.21.0
func (h *WebhookHandler) RespondText(w http.ResponseWriter, status int, text string)
RespondText writes a plain text response.
type WebhookProvider ¶
WebhookProvider is an OPTIONAL interface for adapters that use webhooks. Implement this if your platform receives events via HTTP webhooks.
Platforms NOT requiring this: Socket Mode (Slack), long polling (Telegram)
type WebhookRunner ¶
type WebhookRunner struct {
// contains filtered or unexported fields
}
WebhookRunner manages the lifecycle of webhook processing goroutines. This eliminates the duplicate webhookWg pattern across all adapters.
func NewWebhookRunner ¶
func NewWebhookRunner(logger *slog.Logger, opts ...WebhookRunnerOption) *WebhookRunner
NewWebhookRunner creates a new WebhookRunner.
func (*WebhookRunner) Run ¶
func (r *WebhookRunner) Run(ctx context.Context, handler MessageHandler, msg *ChatMessage)
Run executes the handler in a goroutine and tracks its completion. If handler is nil, this is a no-op. Implements event deduplication to prevent duplicate processing.
func (*WebhookRunner) Stop ¶
func (r *WebhookRunner) Stop() bool
Stop is an alias for WaitDefault for API consistency with adapters.
func (*WebhookRunner) Wait ¶
func (r *WebhookRunner) Wait(timeout time.Duration) bool
Wait blocks until all running goroutines complete or timeout occurs. Returns true if all goroutines completed, false if timeout occurred.
func (*WebhookRunner) WaitDefault ¶
func (r *WebhookRunner) WaitDefault() bool
WaitDefault blocks with the default 5 second timeout.
type WebhookRunnerOption ¶ added in v0.21.0
type WebhookRunnerOption func(*WebhookRunner)
WebhookRunnerOption configures the WebhookRunner
func WithDeduplication ¶ added in v0.21.0
func WithDeduplication(window, cleanup time.Duration, strategy dedup.KeyStrategy) WebhookRunnerOption
WithDeduplication enables event deduplication with custom settings