Documentation
¶
Index ¶
- Constants
- func ExtractInt64FromMetadata(msg *ChatMessage, key string) int64
- func ExtractStringFromMetadata(msg *ChatMessage, key string) string
- func ReadBody(r *http.Request) ([]byte, error)
- 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)
- type Adapter
- func (a *Adapter) AddReaction(ctx context.Context, reaction Reaction) 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 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) RemoveReaction(ctx context.Context, reaction Reaction) error
- func (a *Adapter) SendMessage(ctx context.Context, sessionID string, msg *ChatMessage) error
- func (a *Adapter) SetHandler(handler MessageHandler)
- func (a *Adapter) SetLogger(logger *slog.Logger)
- func (a *Adapter) Start(ctx context.Context) error
- func (a *Adapter) Stop() 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 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 Config
- type EngineSupport
- 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 MessageHandler
- type MessageOperations
- type MessageParser
- type MessageSender
- type MessageType
- type MetadataExtractor
- type ParseMode
- type PendingMessage
- type PendingMessageStore
- type Reaction
- type RichContent
- type SenderFunc
- type SenderWithMutex
- type Session
- type SessionIDGenerator
- type SessionOperations
- type SimpleKeyGenerator
- type UUID5Generator
- type WebhookProvider
- type WebhookRunner
Constants ¶
const ErrSenderNotConfigured = "sender not configured"
ErrSenderNotConfigured is returned when SendMessage is called but no sender function has been configured.
Variables ¶
This section is empty.
Functions ¶
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 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)
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) AddReaction ¶ added in v0.15.5
AddReaction 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)
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) RemoveReaction ¶ added in v0.15.5
RemoveReaction is a no-op by default, overridden by platforms that support it
func (*Adapter) SendMessage ¶
SendMessage sends a message (requires messageSender to be set)
func (*Adapter) SetHandler ¶
func (a *Adapter) SetHandler(handler MessageHandler)
SetHandler sets the message handler (thread-safe)
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 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 ChatMessage ¶
type EngineSupport ¶ added in v0.15.5
EngineSupport defines optional interface for adapters that need engine integration
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 MessageHandler ¶
type MessageHandler func(ctx context.Context, msg *ChatMessage) error
type MessageOperations ¶ added in v0.15.5
type MessageOperations interface {
DeleteMessage(ctx context.Context, channelID, messageTS string) error
AddReaction(ctx context.Context, reaction Reaction) error
RemoveReaction(ctx context.Context, reaction Reaction) error
UpdateMessage(ctx context.Context, channelID, messageTS string, msg *ChatMessage) error
}
MessageOperations defines platform-specific message 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 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 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) Store ¶ added in v0.15.7
func (s *PendingMessageStore) Store(sessionID string, msg *PendingMessage)
Store adds a pending message to the store
type Reaction ¶ added in v0.11.1
type Reaction struct {
Name string // emoji name (e.g., "thumbsup", "+1")
Channel string
Timestamp string // message timestamp to react to
}
Reaction represents a reaction to add to a message
type RichContent ¶
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 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)
Generate(platform, userID, botUserID, channelID 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 defines platform-specific session operations Note: Session is defined in base/adapter.go to avoid circular dependencies
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 string) string
Generate creates a session ID by concatenating all components Format: platform:userID:botUserID:channelID
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 string) string
Generate creates a deterministic session ID Format: UUID5(namespace + ":session:" + platform + ":" + userID + ":" + botUserID + ":" + channelID)
type WebhookProvider ¶
WebhookProvider exposes HTTP handlers for unified server integration
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) *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.
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.