Documentation
¶
Overview ¶
Package slackchat connects initech to Slack via Socket Mode. It receives @mention events from Slack and dispatches them to agent panes. The client is started as a goroutine from TUI.Run() when Slack tokens are configured.
responder.go posts agent completion output back to Slack threads. It consumes AgentEvent copies from the TUI fan-out channel and posts threaded replies when a tracked agent completes work.
tracker.go maps Slack threads to agents. When a user @mentions the bot to dispatch work, the tracker records the agent name -> (channel, threadTS) mapping. When the agent completes, the responder looks up the thread to post the result. Conversations expire after a TTL to prevent stale threads.
Index ¶
- func FetchThreadContext(api SlackAPI, cache *UserCache, channel, threadTS, currentTS string) string
- func ParseMention(text string) (agent, body string)
- type AgentHost
- type AgentInfo
- type Client
- type Conversation
- type ConversationLookup
- type ConversationTracker
- type PanePeeker
- type Responder
- type ResponderEvent
- type SlackAPI
- type UserCache
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func FetchThreadContext ¶ added in v1.10.3
FetchThreadContext retrieves messages from a Slack thread and formats them as a context block. Returns an empty string if the thread has no messages or the API call fails. The current message (identified by the @mention) is excluded from the context since it will be sent as the body.
func ParseMention ¶
ParseMention strips the <@BOTID> prefix from Slack message text and extracts the agent name (first word, lowercased) and message body (rest). Returns empty strings when the input has no content after the mention.
Types ¶
type AgentHost ¶
type AgentHost interface {
// FindAgent returns info for the named agent, or false if not found.
FindAgent(name string) (AgentInfo, bool)
// AllAgents returns info for all managed agents.
AllAgents() []AgentInfo
// SendToAgent delivers text to the named agent's PTY (with Enter).
// Returns an error if the agent is not found.
SendToAgent(name, text string) error
}
AgentHost provides agent lookup and delivery for Slack dispatch. Implemented by the TUI bridge adapter.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client manages the Slack Socket Mode connection and event loop.
func NewClient ¶
func NewClient(appToken, botToken string, host AgentHost, allowedUsers []string, logger *slog.Logger) *Client
NewClient creates a Slack client configured for Socket Mode. The appToken (xapp-...) is used to establish the WebSocket connection. The botToken (xoxb-...) is used for Web API calls (posting messages, adding reactions). The host provides agent lookup and delivery; pass nil to defer wiring. allowedUsers is a list of Slack user IDs permitted to dispatch. Empty = all.
func (*Client) API ¶ added in v1.10.2
API returns the underlying Slack Web API client for use by the responder.
func (*Client) Run ¶
Run connects to Slack via Socket Mode and processes events until the context is cancelled. It blocks, so call it in a goroutine. Reconnection is handled automatically by the slack-go library.
func (*Client) SetThreadContext ¶ added in v1.10.3
SetThreadContext enables or disables thread history fetching for dispatch.
func (*Client) Tracker ¶ added in v1.10.2
func (c *Client) Tracker() *ConversationTracker
Tracker returns the conversation tracker shared between dispatcher and responder.
type Conversation ¶ added in v1.10.2
Conversation represents an active Slack thread associated with an agent.
type ConversationLookup ¶ added in v1.10.2
type ConversationLookup interface {
// Lookup returns the active conversation for the named agent, or false
// if no conversation is tracked (expired or never started).
Lookup(agent string) (channel string, threadTS string, ok bool)
// Complete marks the conversation for the named agent as finished.
// Safe to call if no conversation exists.
Complete(agent string)
}
ConversationLookup provides read access to the conversation tracker. The full tracker is owned by the Client; the responder only needs lookup.
type ConversationTracker ¶ added in v1.10.2
type ConversationTracker struct {
// contains filtered or unexported fields
}
ConversationTracker maps agent names to active Slack threads. Thread-safe for concurrent access from the dispatcher and responder.
func NewConversationTracker ¶ added in v1.10.2
func NewConversationTracker() *ConversationTracker
NewConversationTracker creates an empty tracker.
func (*ConversationTracker) Complete ¶ added in v1.10.2
func (t *ConversationTracker) Complete(agent string)
Complete marks the conversation for the named agent as finished. Removes it from the tracker. Safe to call if no conversation exists.
func (*ConversationTracker) Lookup ¶ added in v1.10.2
func (t *ConversationTracker) Lookup(agent string) (channel string, threadTS string, ok bool)
Lookup returns the channel and threadTS for the named agent's active conversation. Returns false if no conversation exists or it has expired.
func (*ConversationTracker) Track ¶ added in v1.10.2
func (t *ConversationTracker) Track(agent, channel, threadTS, userID string)
Track records a conversation for the named agent. Overwrites any existing conversation for that agent (new @mention supersedes the old one).
type PanePeeker ¶ added in v1.10.2
type PanePeeker interface {
// PeekOutput returns the last n lines from the named agent's terminal.
// Returns empty string and nil error if the pane has no output.
// Returns an error if the pane is not found.
PeekOutput(agentName string, lines int) (string, error)
}
PanePeeker reads recent output from an agent's terminal.
type Responder ¶ added in v1.10.2
type Responder struct {
// contains filtered or unexported fields
}
Responder watches agent events and posts completion output to Slack threads.
func NewResponder ¶ added in v1.10.2
func NewResponder(api *slack.Client, tracker ConversationLookup, peeker PanePeeker, mode string, logger *slog.Logger) *Responder
NewResponder creates a responder. Mode is "completion" (default) or "off".
type ResponderEvent ¶ added in v1.10.2
type ResponderEvent struct {
Type string // "completed", "failed", "stuck", "idle"
Pane string // Agent name.
BeadID string
Detail string
}
ResponderEvent is the subset of TUI AgentEvent fields needed by the responder. Avoids importing the tui package.
type SlackAPI ¶ added in v1.10.3
type SlackAPI interface {
GetConversationReplies(params *slack.GetConversationRepliesParameters) ([]slack.Message, bool, string, error)
GetUserInfo(userID string) (*slack.User, error)
}
SlackAPI abstracts the Slack Web API methods needed for thread context. The real implementation is *slack.Client; tests provide a fake.
type UserCache ¶ added in v1.10.3
type UserCache struct {
// contains filtered or unexported fields
}
UserCache caches Slack user ID to display name lookups. Thread-safe. User names don't change during a session, so no TTL is needed.
func NewUserCache ¶ added in v1.10.3
NewUserCache creates a cache backed by the given Slack API client.
func (*UserCache) DisplayName ¶ added in v1.10.3
DisplayName returns the display name for a Slack user ID. Falls back to the raw ID (e.g. "<@U123>") if the lookup fails.