bot

package
v0.260324.0 Latest Latest
Warning

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

Go to latest
Published: Mar 23, 2026 License: MPL-2.0 Imports: 30 Imported by: 0

Documentation

Overview

Package command provides built-in command definitions for the remote control bot.

Index

Constants

View Source
const (
	DefaultMaxImageSize = 25 * 1024 * 1024 // 25MB
	DefaultMaxDocSize   = 50 * 1024 * 1024 // 50MB
)
View Source
const (
	// Icons
	IconProject = "📁"  // Project/folder
	IconChat    = "💬"  // Chat/conversation
	IconUser    = "👤"  // User
	IconSession = "🔄"  // Session
	IconAgentTB = "🎯"  // Tingly-Box agent (@tb)
	IconAgentCC = "💬"  // Claude Code agent (@cc)
	IconDone    = "✅"  // Task completed
	IconError   = "❌"  // Error
	IconWarning = "⚠️" // Warning
	IconStop    = "🛑"  // Stopped
	IconProcess = "⏳"  // Processing
	IconMock    = "🧪"  // Mock agent
)

Output format constants for bot messages Centralized for easy customization and i18n support

View Source
const (
	AgentNameTB        = "@tb" // Tingly-Box short name
	AgentNameCC        = "@cc" // Claude Code short name
	AgentNameTinglyBox = "tingly-box"
	AgentNameClaude    = "claude"
)

Agent display names

View Source
const (
	SeparatorLine = "───────────────"
	SeparatorFull = "━━━━━━━━━━━━━━━━━━━━"
)

Separator line for message formatting

View Source
const (
	MsgProcessing     = "Processing..."
	MsgTaskDone       = "Task done"
	MsgTaskStopped    = "Task stopped"
	MsgContinueOrHelp = "Continue or /help."
	MsgNoRunningTask  = "No running task to stop."
)

Status messages

View Source
const (
	// Status line formats
	FormatProjectLine = "%s %s\n" // icon + path
	FormatAgentLine   = "%s %s\n" // icon + agent name
	FormatDebugLine   = "%s %s\n" // icon + id value

	// Completion message formats
	FormatDoneWithCtx  = "%s %s done | %s %s\n%s" // icon + agent + path_icon + path + continue_msg
	FormatDoneSimple   = "%s %s done\n%s"         // icon + agent + continue_msg
	FormatDoneWithProj = "%s %s done | %s %s"     // icon + agent + path_icon + path (single line)
)

Format templates (use with fmt.Sprintf)

Variables

View Source
var AllowedMIMETypes = map[string]string{

	"image/jpeg": "image",
	"image/png":  "image",
	"image/gif":  "image",
	"image/webp": "image",

	"application/pdf": "document",
	"text/plain":      "document",
	"text/markdown":   "document",
	"text/csv":        "document",

	"application/msword": "document",
	"application/vnd.openxmlformats-officedocument.wordprocessingml.document": "document",

	"application/vnd.ms-excel": "document",
	"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": "document",
}

AllowedMIMETypes lists supported file types

Functions

func BuildActionKeyboard

func BuildActionKeyboard() *imbot.KeyboardBuilder

BuildActionKeyboard builds the inline keyboard for actions (Clear/Bind)

func BuildBindConfirmKeyboard

func BuildBindConfirmKeyboard() *imbot.KeyboardBuilder

BuildBindConfirmKeyboard builds the confirmation keyboard for binding to current directory

func BuildBindConfirmPrompt

func BuildBindConfirmPrompt(proposedPath string) string

BuildBindConfirmPrompt returns the text for bind confirmation prompt

func BuildCancelKeyboard

func BuildCancelKeyboard() *imbot.KeyboardBuilder

BuildCancelKeyboard builds a simple cancel keyboard

func BuildCreateConfirmKeyboard

func BuildCreateConfirmKeyboard(path string) (*imbot.KeyboardBuilder, string)

BuildCreateConfirmKeyboard builds the confirmation keyboard for creating a directory

func BuildCustomPathPrompt

func BuildCustomPathPrompt() string

BuildCustomPathPrompt returns the text for custom path input prompt

func BuildDoneMessage added in v0.260311.2200

func BuildDoneMessage(agentType, projectPath string, behavior OutputBehavior) string

BuildDoneMessage creates a completion message with optional context

func ExpandPath

func ExpandPath(path string) (string, error)

ExpandPath expands ~ and environment variables in a path

func GetAgentDisplayName

func GetAgentDisplayName(agentType string) string

GetAgentDisplayName returns the short display name for an agent type

func GetAgentIcon

func GetAgentIcon(agentType string) string

GetAgentIcon returns the icon for an agent type

func ParseTextResponse

func ParseTextResponse(text string) (approved bool, remember bool, isValid bool)

ParseTextResponse parses user text input as a permission response Returns: (approved, remember, isValid)

func RegisterBuiltinCommands

func RegisterBuiltinCommands(registry *imbot.CommandRegistry, botHandler BotHandlerAdapter) error

RegisterBuiltinCommands registers all built-in commands to the registry.

func RegisterCommand added in v0.260324.0

func RegisterCommand(config CommandMenuConfig)

RegisterCommand registers a command in the default registry

func RegisterMenu

func RegisterMenu(config MenuButtonConfig)

RegisterMenu registers a menu in the default registry

func SendDirectoryBrowser

func SendDirectoryBrowser(ctx context.Context, bot imbot.Bot, browser *DirectoryBrowser, chatID string, editMessageID string) (string, error)

SendDirectoryBrowser sends or updates the directory browser message

func SetupMenuButtonForBot

func SetupMenuButtonForBot(manager *imbot.Manager, uuid string) error

SetupMenuButtonForBot configures the menu button for a bot This should be called when the bot starts or when settings change

func ShortenID

func ShortenID(id string, maxLen int) string

ShortenID truncates an ID to a readable length e.g., "a1b2c3d4e5f6g7h8" -> "a1b2c3d4"

func ShortenPath

func ShortenPath(path string) string

ShortenPath shortens a path for display

func ValidateProjectPath

func ValidateProjectPath(path string) error

ValidateProjectPath validates that a path is a valid project directory

Types

type BindFlowState

type BindFlowState struct {
	ChatID       string
	CurrentPath  string
	Page         int
	TotalDirs    int
	PageSize     int
	MessageID    string // Message ID to edit
	ExpiresAt    time.Time
	WaitingInput bool     // Waiting for custom path input
	PromptMsgID  string   // Prompt message ID for cleanup
	Dirs         []string // Current directory list (for navigation by index)
}

BindFlowState represents the state of an ongoing bind flow

type BotHandler

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

BotHandler encapsulates all bot message handling logic and dependencies

func NewBotHandler

func NewBotHandler(
	ctx context.Context,
	botSetting BotSetting,
	chatStore ChatStoreInterface,
	sessionMgr *session.Manager,
	agentBoot *agentboot.AgentBoot,
	directoryBrowser *DirectoryBrowser,
	manager *imbot.Manager,
	tbClient tbclient.TBClient,
) *BotHandler

NewBotHandler creates a new bot handler with all dependencies

func (*BotHandler) GetCommandRegistry

func (h *BotHandler) GetCommandRegistry() *imbot.CommandRegistry

GetCommandRegistry returns the command registry.

func (*BotHandler) GetVerbose

func (h *BotHandler) GetVerbose(chatID string) bool

GetVerbose returns the current verbose mode setting for a chat Checks chat store first, then bot setting default

func (*BotHandler) HandleCommandViaRegistry

func (h *BotHandler) HandleCommandViaRegistry(hCtx HandlerContext, cmdName string, args []string) error

HandleCommandViaRegistry handles a command using the new command registry.

func (*BotHandler) HandleMessage

func (h *BotHandler) HandleMessage(msg imbot.Message, platform imbot.Platform, botUUID string)

HandleMessage is the main entry point for handling bot messages

func (*BotHandler) InitCommandRegistry

func (h *BotHandler) InitCommandRegistry() error

InitCommandRegistry initializes the command registry with built-in commands.

func (*BotHandler) RequestConfirmation

func (h *BotHandler) RequestConfirmation(ctx context.Context, hCtx HandlerContext, message, requestID string) (bool, error)

RequestConfirmation requests a yes/no confirmation from the user Uses the new interaction system with platform-agnostic UI

func (*BotHandler) RequestInteraction

RequestInteraction sends an interaction request using the new interaction system This is a convenience method for BotHandler to request platform-agnostic interactions

func (*BotHandler) RequestOptionSelection

func (h *BotHandler) RequestOptionSelection(ctx context.Context, hCtx HandlerContext, message, requestID string, options []imbot.Option) (int, *imbot.Interaction, error)

RequestOptionSelection requests the user to select from a list of options Uses the new interaction system with platform-agnostic UI

func (*BotHandler) SendText

func (h *BotHandler) SendText(hCtx HandlerContext, text string)

SendText sends a plain text message Note: Platform handles chunking internally via BaseBot.ChunkText()

func (*BotHandler) SetVerbose

func (h *BotHandler) SetVerbose(chatID string, verbose bool)

SetVerbose sets the verbose mode for a chat

type BotHandlerAdapter

type BotHandlerAdapter interface {
	// SendText sends a text message to a chat
	SendText(chatID, text string) error

	// GetProjectPath gets the current project path for a chat
	GetProjectPath(chatID string) (string, error)

	// SetProjectPath sets the project path for a chat
	SetProjectPath(chatID, path string) error

	// GetSession gets session info
	GetSession(chatID, agentType, projectPath string) (*SessionInfo, error)

	// ClearSession clears a session
	ClearSession(chatID, agentType string) error

	// GetCurrentAgent gets the current agent for a chat
	GetCurrentAgent(chatID string) (string, error)

	// SetVerbose sets verbose mode for a chat
	SetVerbose(chatID string, enabled bool)

	// IsWhitelisted checks if a group is whitelisted
	IsWhitelisted(groupID string) bool

	// AddToWhitelist adds a group to whitelist
	AddToWhitelist(groupID, platform, userID string) error

	// GetBashCwd gets the bash working directory
	GetBashCwd(chatID string) (string, error)

	// SetBashCwd sets the bash working directory
	SetBashCwd(chatID, path string) error

	// ResolveChatID resolves a chat ID (for Telegram join command)
	ResolveChatID(input string) (string, error)
}

BotHandlerAdapter provides methods needed by command handlers. This allows commands to interact with the bot without direct coupling.

func NewBotHandlerAdapter

func NewBotHandlerAdapter(handler *BotHandler) BotHandlerAdapter

NewBotHandlerAdapter creates a new adapter for the given handler.

type BotSetting

type BotSetting struct {
	UUID          string            `json:"uuid,omitempty"`           // UUID for bot identification
	Name          string            `json:"name,omitempty"`           // User-defined name for the bot
	Token         string            `json:"token,omitempty"`          // Legacy: for backward compatibility
	Platform      string            `json:"platform"`                 // Platform identifier
	AuthType      string            `json:"auth_type"`                // Auth type: token, oauth, qr
	Auth          map[string]string `json:"auth"`                     // Dynamic auth fields based on platform
	ProxyURL      string            `json:"proxy_url,omitempty"`      // Optional proxy URL
	ChatIDLock    string            `json:"chat_id,omitempty"`        // Optional chat ID lock
	BashAllowlist []string          `json:"bash_allowlist,omitempty"` // Optional bash command allowlist
	DefaultCwd    string            `json:"default_cwd,omitempty"`    // Default working directory if no project bound
	Enabled       bool              `json:"enabled"`                  // Whether this bot is enabled

	// Output behavior settings
	Debug   bool  `json:"debug,omitempty"`   // Show message IDs in output (chat_id, session_id, etc.)
	Verbose *bool `json:"verbose,omitempty"` // Send intermediate messages (nil = true default)

	// SmartGuide model configuration (required for @tb agent)
	SmartGuideProvider string `json:"smartguide_provider,omitempty"` // Provider UUID
	SmartGuideModel    string `json:"smartguide_model,omitempty"`    // Model identifier

	CreatedAt string `json:"created_at,omitempty"`
	UpdatedAt string `json:"updated_at,omitempty"`
}

BotSetting represents bot configuration with platform-specific auth

func (BotSetting) GetOutputBehavior

func (s BotSetting) GetOutputBehavior() OutputBehavior

GetOutputBehavior extracts output behavior from bot setting

type Chat

type Chat struct {
	ChatID      string `json:"chat_id"`
	Platform    string `json:"platform"`
	ProjectPath string `json:"project_path,omitempty"`
	OwnerID     string `json:"owner_id,omitempty"`

	// Group-specific
	IsWhitelisted bool   `json:"is_whitelisted"`
	WhitelistedBy string `json:"whitelisted_by,omitempty"`

	// Bash state
	BashCwd string `json:"bash_cwd,omitempty"`

	// Agent state (for smart guide handoff)
	CurrentAgent string `json:"current_agent,omitempty"` // "tingly-box" or "claude"
	AgentState   []byte `json:"agent_state,omitempty"`   // JSON-encoded agent-specific state

	// Chat-level settings
	Verbose *bool `json:"verbose,omitempty"` // Verbose mode: nil=use bot default, true=verbose, false=quiet

	CreatedAt time.Time `json:"created_at"`
	UpdatedAt time.Time `json:"updated_at"`
}

Chat represents all state associated with a chat (direct or group)

type ChatStoreInterface

type ChatStoreInterface interface {
	// Close ensures data is persisted before closing
	Close() error

	// GetChat retrieves a chat by ID
	GetChat(chatID string) (*Chat, error)

	// GetOrCreateChat gets a chat or creates it if not exists
	GetOrCreateChat(chatID, platform string) (*Chat, error)

	// UpsertChat creates or updates a chat
	UpsertChat(chat *Chat) error

	// UpdateChat updates specific fields of a chat
	UpdateChat(chatID string, fn func(*Chat)) error

	// BindProject binds a project to a chat
	BindProject(chatID, platform, projectPath, ownerID string) error

	// GetProjectPath retrieves the project path for a chat
	GetProjectPath(chatID string) (string, bool, error)

	// ListChatsByOwner lists all chats owned by a user
	ListChatsByOwner(ownerID, platform string) ([]*Chat, error)

	// AddToWhitelist adds a chat to the whitelist
	AddToWhitelist(chatID, platform, addedBy string) error

	// RemoveFromWhitelist removes a chat from the whitelist
	RemoveFromWhitelist(chatID string) error

	// IsWhitelisted checks if a chat is whitelisted
	IsWhitelisted(chatID string) bool

	// SetBashCwd sets the bash working directory for a chat
	SetBashCwd(chatID, cwd string) error

	// GetBashCwd retrieves the bash working directory for a chat
	GetBashCwd(chatID string) (string, bool, error)

	// SetCurrentAgent sets the current agent for a chat
	SetCurrentAgent(chatID, agentType string) error

	// GetCurrentAgent retrieves the current agent for a chat
	GetCurrentAgent(chatID string) (string, error)

	// SetAgentState sets the agent-specific state for a chat
	SetAgentState(chatID string, state []byte) error

	// GetAgentState retrieves the agent-specific state for a chat
	GetAgentState(chatID string) ([]byte, error)

	// ListWhitelistedGroups returns all whitelisted groups
	ListWhitelistedGroups() ([]struct {
		GroupID   string
		Platform  string
		AddedBy   string
		CreatedAt string
	}, error)
}

ChatStoreInterface defines the interface for chat persistence This allows both SQLite-based ChatStore and JSON-based ChatStoreJSON to be used interchangeably

type ChatStoreJSON

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

ChatStoreJSON handles unified chat persistence using JSON file storage This is the new implementation replacing the SQLite-based ChatStore

func NewChatStoreJSON

func NewChatStoreJSON(filePath string) (*ChatStoreJSON, error)

NewChatStoreJSON creates a new JSON-based chat store

func (*ChatStoreJSON) AddToWhitelist

func (s *ChatStoreJSON) AddToWhitelist(chatID, platform, addedBy string) error

AddToWhitelist adds a chat to the whitelist

func (*ChatStoreJSON) BindProject

func (s *ChatStoreJSON) BindProject(chatID, platform, projectPath, ownerID string) error

BindProject binds a project to a chat (creates chat if not exists)

func (*ChatStoreJSON) Close

func (s *ChatStoreJSON) Close() error

Close ensures data is persisted before closing

func (*ChatStoreJSON) GetAgentState

func (s *ChatStoreJSON) GetAgentState(chatID string) ([]byte, error)

GetAgentState retrieves the agent-specific state for a chat

func (*ChatStoreJSON) GetBashCwd

func (s *ChatStoreJSON) GetBashCwd(chatID string) (string, bool, error)

GetBashCwd retrieves the bash working directory for a chat

func (*ChatStoreJSON) GetChat

func (s *ChatStoreJSON) GetChat(chatID string) (*Chat, error)

GetChat retrieves a chat by ID

func (*ChatStoreJSON) GetCurrentAgent

func (s *ChatStoreJSON) GetCurrentAgent(chatID string) (string, error)

GetCurrentAgent retrieves the current agent for a chat Returns "tingly-box" as default (Smart Guide is the entry point)

func (*ChatStoreJSON) GetOrCreateChat

func (s *ChatStoreJSON) GetOrCreateChat(chatID, platform string) (*Chat, error)

GetOrCreateChat gets a chat or creates it if not exists

func (*ChatStoreJSON) GetProjectPath

func (s *ChatStoreJSON) GetProjectPath(chatID string) (string, bool, error)

GetProjectPath retrieves the project path for a chat

func (*ChatStoreJSON) IsWhitelisted

func (s *ChatStoreJSON) IsWhitelisted(chatID string) bool

IsWhitelisted checks if a chat is whitelisted

func (*ChatStoreJSON) ListChatsByOwner

func (s *ChatStoreJSON) ListChatsByOwner(ownerID, platform string) ([]*Chat, error)

ListChatsByOwner lists all chats owned by a user

func (*ChatStoreJSON) ListWhitelistedGroups

func (s *ChatStoreJSON) ListWhitelistedGroups() ([]struct {
	GroupID   string
	Platform  string
	AddedBy   string
	CreatedAt string
}, error)

ListWhitelistedGroups returns all whitelisted groups

func (*ChatStoreJSON) RemoveFromWhitelist

func (s *ChatStoreJSON) RemoveFromWhitelist(chatID string) error

RemoveFromWhitelist removes a chat from the whitelist

func (*ChatStoreJSON) SetAgentState

func (s *ChatStoreJSON) SetAgentState(chatID string, state []byte) error

SetAgentState sets the agent-specific state for a chat

func (*ChatStoreJSON) SetBashCwd

func (s *ChatStoreJSON) SetBashCwd(chatID, cwd string) error

SetBashCwd sets the bash working directory for a chat

func (*ChatStoreJSON) SetCurrentAgent

func (s *ChatStoreJSON) SetCurrentAgent(chatID, agentType string) error

SetCurrentAgent sets the current agent for a chat

func (*ChatStoreJSON) UpdateChat

func (s *ChatStoreJSON) UpdateChat(chatID string, fn func(*Chat)) error

UpdateChat updates specific fields of a chat

func (*ChatStoreJSON) UpsertChat

func (s *ChatStoreJSON) UpsertChat(chat *Chat) error

UpsertChat creates or updates a chat

type CommandMenuConfig added in v0.260324.0

type CommandMenuConfig struct {
	// Command is the command name (without slash, e.g., "help", "cd")
	Command string

	// Description is shown to users
	Description string

	// Aliases are alternative names for this command
	Aliases []string

	// Platforms where this command is available
	// If nil, available on all platforms
	Platforms []imbot.Platform

	// PlatformSpecific provides platform-specific overrides
	PlatformSpecific map[imbot.Platform]CommandOverride

	// Handler is the function to execute when command is invoked
	// This is for reference; actual handling is done in bot_command.go
	Handler string // e.g., "handleHelpCommand"

	// Priority determines order in menu (higher = first)
	// If 0, uses default ordering
	Priority int

	// Category groups related commands together
	// e.g., "session", "project", "system"
	Category string

	// Hidden hides this command from the menu (but command still works)
	Hidden bool
}

CommandMenuConfig defines a command that appears in platform menus Each platform can choose how to display these commands: - Telegram: BotCommand list (shows in command palette) - Lark/Feishu: Quick Actions - Slack: Slash Commands

func GetCommand added in v0.260324.0

func GetCommand(command string) (*CommandMenuConfig, bool)

GetCommand returns a command from the default registry

func GetCommandByAlias added in v0.260324.0

func GetCommandByAlias(alias string) (*CommandMenuConfig, bool)

GetCommandByAlias returns a command by alias from the default registry

type CommandOverride added in v0.260324.0

type CommandOverride struct {
	// Override description if needed
	Description string

	// Different command name for this platform
	Command string

	// Additional platform-specific parameters
	Params map[string]interface{}
}

CommandOverride provides platform-specific configuration

type CommandRegistry added in v0.260324.0

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

CommandRegistry manages command menu configurations

func GetCommandRegistry added in v0.260324.0

func GetCommandRegistry() *CommandRegistry

GetCommandRegistry returns the default command registry

func NewCommandRegistry added in v0.260324.0

func NewCommandRegistry() *CommandRegistry

NewCommandRegistry creates a new command registry

func (*CommandRegistry) AllCommands added in v0.260324.0

func (r *CommandRegistry) AllCommands() []CommandMenuConfig

AllCommands returns all registered commands

func (*CommandRegistry) BuildFeishuQuickActions added in v0.260324.0

func (r *CommandRegistry) BuildFeishuQuickActions() []map[string]interface{}

BuildFeishuQuickActions returns commands formatted for Feishu/Lark Quick Actions

func (*CommandRegistry) BuildHelpText added in v0.260324.0

func (r *CommandRegistry) BuildHelpText(platform imbot.Platform, isDirectMessage bool) string

BuildHelpText generates help text for a platform and chat type

func (*CommandRegistry) BuildSlackCommands added in v0.260324.0

func (r *CommandRegistry) BuildSlackCommands() []map[string]string

BuildSlackCommands returns commands formatted for Slack manifest

func (*CommandRegistry) BuildTelegramCommands added in v0.260324.0

func (r *CommandRegistry) BuildTelegramCommands() []map[string]string

BuildTelegramCommands returns commands formatted for Telegram Bot API

func (*CommandRegistry) ForCategory added in v0.260324.0

func (r *CommandRegistry) ForCategory(category string) []CommandMenuConfig

ForCategory returns commands in a specific category

func (*CommandRegistry) ForPlatform added in v0.260324.0

func (r *CommandRegistry) ForPlatform(platform imbot.Platform) []CommandMenuConfig

ForPlatform returns commands visible for a specific platform, ordered by priority

func (*CommandRegistry) Get added in v0.260324.0

func (r *CommandRegistry) Get(command string) (*CommandMenuConfig, bool)

Get returns a command configuration by name

func (*CommandRegistry) GetByAlias added in v0.260324.0

func (r *CommandRegistry) GetByAlias(alias string) (*CommandMenuConfig, bool)

GetByAlias returns a command configuration by alias

func (*CommandRegistry) Register added in v0.260324.0

func (r *CommandRegistry) Register(config CommandMenuConfig)

Register adds a new command to the registry

type CompletionCallback

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

func (*CompletionCallback) OnComplete

func (c *CompletionCallback) OnComplete(result *agentboot.CompletionResult)

type DirectoryBrowser

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

DirectoryBrowser manages directory navigation for bind flow

func NewDirectoryBrowser

func NewDirectoryBrowser() *DirectoryBrowser

NewDirectoryBrowser creates a new directory browser

func (*DirectoryBrowser) BuildKeyboard

func (b *DirectoryBrowser) BuildKeyboard(chatID string) (*BindFlowState, *imbot.KeyboardBuilder, string, error)

BuildKeyboard builds the inline keyboard for directory browsing

func (*DirectoryBrowser) Clear

func (b *DirectoryBrowser) Clear(chatID string)

Clear removes the state for a chat

func (*DirectoryBrowser) GetCurrentPath

func (b *DirectoryBrowser) GetCurrentPath(chatID string) string

GetCurrentPath returns the current path for a chat

func (*DirectoryBrowser) GetState

func (b *DirectoryBrowser) GetState(chatID string) *BindFlowState

GetState returns the current state for a chat

func (*DirectoryBrowser) IsWaitingInput

func (b *DirectoryBrowser) IsWaitingInput(chatID string) bool

IsWaitingInput checks if the chat is waiting for custom path input

func (*DirectoryBrowser) Navigate

func (b *DirectoryBrowser) Navigate(chatID string, path string) error

Navigate navigates to a subdirectory

func (*DirectoryBrowser) NavigateByIndex

func (b *DirectoryBrowser) NavigateByIndex(chatID string, index int) error

NavigateByIndex navigates to a subdirectory by index (stored in state.Dirs)

func (*DirectoryBrowser) NavigateUp

func (b *DirectoryBrowser) NavigateUp(chatID string) error

NavigateUp navigates to the parent directory

func (*DirectoryBrowser) NextPage

func (b *DirectoryBrowser) NextPage(chatID string) error

NextPage moves to the next page of directories

func (*DirectoryBrowser) PrevPage

func (b *DirectoryBrowser) PrevPage(chatID string) error

PrevPage moves to the previous page of directories

func (*DirectoryBrowser) SetMessageID

func (b *DirectoryBrowser) SetMessageID(chatID string, messageID string)

SetMessageID sets the message ID for editing

func (*DirectoryBrowser) SetWaitingInput

func (b *DirectoryBrowser) SetWaitingInput(chatID string, waiting bool, promptMsgID string)

SetWaitingInput sets the waiting for input state

func (*DirectoryBrowser) Start

func (b *DirectoryBrowser) Start(chatID string) (*BindFlowState, error)

Start begins a new bind flow for a chat

type FileStore

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

FileStore handles project-based file storage for bot media

func NewFileStore

func NewFileStore() *FileStore

NewFileStore creates a new file store with default limits

func NewFileStoreWithLimits

func NewFileStoreWithLimits(maxImageSize, maxDocSize int64) *FileStore

NewFileStoreWithLimits creates a new file store with custom limits

func NewFileStoreWithProxy

func NewFileStoreWithProxy(proxyURL string) (*FileStore, error)

NewFileStoreWithProxy creates a new file store with proxy support

func (*FileStore) DownloadFile

func (s *FileStore) DownloadFile(ctx context.Context, projectPath, url, mimeType string) (*StoredFile, error)

DownloadFile downloads a file from a URL to the project's .download directory Returns an error if file size exceeds limits

func (*FileStore) GetDownloadDir

func (s *FileStore) GetDownloadDir(projectPath string) string

GetDownloadDir returns the .download directory for a project

func (*FileStore) IsAllowedSize

func (s *FileStore) IsAllowedSize(mimeType string, size int64) bool

IsAllowedSize checks if the size is within limits for the mime type

func (*FileStore) IsAllowedType

func (s *FileStore) IsAllowedType(mimeType string) bool

IsAllowedType checks if the mime type is allowed

func (*FileStore) SetTelegramToken

func (s *FileStore) SetTelegramToken(token string)

SetTelegramToken sets the Telegram bot token for resolving file URLs

func (*FileStore) StoreFile

func (s *FileStore) StoreFile(ctx context.Context, projectPath string, reader io.Reader, filename, mimeType string) (*StoredFile, error)

StoreFile stores a file from a reader to the project's .download directory

type HandlerContext

type HandlerContext struct {
	Bot       imbot.Bot
	BotUUID   string
	ChatID    string
	SenderID  string
	MessageID string
	Platform  imbot.Platform
	Message   imbot.Message
}

HandlerContext contains per-message context data

func (*HandlerContext) IsDirect

func (c *HandlerContext) IsDirect() bool

func (*HandlerContext) IsGroup

func (c *HandlerContext) IsGroup() bool

func (*HandlerContext) Text

func (c *HandlerContext) Text() string

type IMPrompter

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

IMPrompter implements ask.Prompter using IM (Telegram, etc.) for user interaction

func NewIMPrompter

func NewIMPrompter(manager *imbot.Manager) *IMPrompter

NewIMPrompter creates a new IM-based prompter

func (*IMPrompter) AddToWhitelist

func (p *IMPrompter) AddToWhitelist(toolName string)

AddToWhitelist adds a tool to the whitelist

func (*IMPrompter) ClearWhitelist

func (p *IMPrompter) ClearWhitelist()

ClearWhitelist clears all tools from the whitelist

func (*IMPrompter) GetPendingRequest

func (p *IMPrompter) GetPendingRequest(requestID string) (*ask.Request, bool)

GetPendingRequest returns a pending request by ID

func (*IMPrompter) GetPendingRequestsForChat

func (p *IMPrompter) GetPendingRequestsForChat(chatID string) []ask.Request

GetPendingRequestsForChat returns all pending requests for a specific chat

func (*IMPrompter) GetWhitelist

func (p *IMPrompter) GetWhitelist() []string

GetWhitelist returns the list of whitelisted tools

func (*IMPrompter) IsWhitelisted

func (p *IMPrompter) IsWhitelisted(toolName string) bool

IsWhitelisted checks if a tool is in the whitelist

func (*IMPrompter) OnApproval

OnApproval implements agentboot.ApprovalHandler. It handles permission confirmation requests via IM.

func (*IMPrompter) OnAsk

OnAsk implements agentboot.AskHandler. It handles user questions/selections via IM.

func (*IMPrompter) Prompt

func (p *IMPrompter) Prompt(ctx context.Context, req ask.Request) (ask.Result, error)

Prompt prompts the user via IM for response This implements the ask.Prompter interface

func (*IMPrompter) PromptPermission

PromptPermission implements the legacy agentboot.UserPrompter interface

func (*IMPrompter) RemoveFromWhitelist

func (p *IMPrompter) RemoveFromWhitelist(toolName string)

RemoveFromWhitelist removes a tool from the whitelist

func (*IMPrompter) SetDefaultTimeout

func (p *IMPrompter) SetDefaultTimeout(timeout time.Duration)

SetDefaultTimeout sets the default timeout for requests

func (*IMPrompter) SubmitDecision

func (p *IMPrompter) SubmitDecision(requestID string, approved bool, remember bool, reason string) error

SubmitDecision submits a user's decision for a pending request

func (*IMPrompter) SubmitResult

func (p *IMPrompter) SubmitResult(requestID string, result ask.Result) error

SubmitResult submits a result for a pending request

func (*IMPrompter) SubmitUserResponse

func (p *IMPrompter) SubmitUserResponse(requestID string, response ask.Response) error

SubmitUserResponse submits a user response for a pending request This parses the response using the appropriate tool handler

type Lifecycle

type Lifecycle interface {
	// Start starts a bot by UUID
	Start(ctx context.Context, uuid string) error
	// Stop stops a bot by UUID
	Stop(uuid string)
	// IsRunning checks if a bot is running
	IsRunning(uuid string) bool
	// Sync ensures running bots match the enabled settings
	Sync(ctx context.Context) error
}

Lifecycle defines the interface for controlling bot lifecycle This allows the API layer to control bot startup/shutdown without direct dependency on the Manager type

type Manager

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

Manager manages the lifecycle of running bot instances

func NewManager

func NewManager(store SettingsStore, sessionMgr *session.Manager, agentBoot *agentboot.AgentBoot,
) *Manager

NewManager creates a new bot manager with a settings store

func (*Manager) IsRunning

func (m *Manager) IsRunning(uuid string) bool

IsRunning checks if a bot is running

func (*Manager) SetDataPath

func (m *Manager) SetDataPath(dataPath string)

SetDataPath sets the data path for JSON chat store operations

func (*Manager) SetTBClient

func (m *Manager) SetTBClient(tbClient tbclient.TBClient)

SetTBClient sets the TBClient for SmartGuide configuration

func (*Manager) Start

func (m *Manager) Start(parentCtx context.Context, uuid string) error

Start starts a bot by UUID

func (*Manager) StartEnabled

func (m *Manager) StartEnabled(ctx context.Context) error

StartEnabled starts all enabled bots

func (*Manager) StartEnabledStopDisabled

func (m *Manager) StartEnabledStopDisabled(ctx context.Context) error

StartEnabledStopDisabled is a convenience method that ensures running bots match enabled settings. It's an alias for Sync() with clearer naming for specific use cases.

func (*Manager) Stop

func (m *Manager) Stop(uuid string)

Stop stops a bot by UUID

func (*Manager) StopAll

func (m *Manager) StopAll()

StopAll stops all running bots

func (*Manager) Sync

func (m *Manager) Sync(ctx context.Context) error

Sync ensures the running bots match the enabled settings in the store. It starts bots that are enabled but not running, and stops bots that are running but disabled.

func (*Manager) WaitForStop

func (m *Manager) WaitForStop(uuid string, timeout time.Duration) bool

WaitForStop waits for a bot to finish stopping (with timeout)

type MenuButtonConfig struct {
	// ID identifies this menu configuration
	ID string

	// Type determines what kind of menu this is
	Type MenuButtonType

	// ButtonText is the label shown on the menu button itself
	// e.g., "Menu", "Commands", "Actions"
	ButtonText string

	// Items are the menu items to show when button is tapped
	Items []MenuItemConfig

	// Platforms where this menu is available
	// If empty, shows on all platforms
	Platforms []imbot.Platform

	// Priority determines which config to use if multiple are registered
	// Higher priority wins. If 0, uses default priority.
	Priority int

	// Context filters when this menu should be shown
	Context *MenuContext
}

MenuButtonConfig configures the menu button for different platforms The menu button appears near the message input field and provides quick access to commands

Platform support: - Telegram: Menu Button (Commands / Web App) - Feishu/Lark: Quick Actions / Card Menu - Slack: App Shortcut / Slash Commands

func DefaultActionMenu

func DefaultActionMenu() MenuButtonConfig

DefaultActionMenu returns the default action menu (with callback buttons)

func DefaultCommandMenu

func DefaultCommandMenu() MenuButtonConfig

DefaultCommandMenu returns the default command menu configuration

func GetMenuForPlatform

func GetMenuForPlatform(platform imbot.Platform, context *MenuContext) *MenuButtonConfig

GetMenuForPlatform returns the best menu for a platform

type MenuButtonType string

MenuButtonType defines the type of menu button

const (
	// MenuTypeCommands shows a list of bot commands
	MenuTypeCommands MenuButtonType = "commands"

	// MenuTypeWebApp opens a Mini App / Web App
	MenuTypeWebApp MenuButtonType = "webapp"

	// MenuTypeCallbacks shows custom callback buttons
	MenuTypeCallbacks MenuButtonType = "callbacks"

	// MenuTypeDefault uses the platform default menu
	MenuTypeDefault MenuButtonType = "default"
)
type MenuContext struct {
	// ChatType restricts to specific chat types
	// "direct", "group", "channel", "all"
	ChatType string

	// UserIDs restricts to specific users (for personalization)
	UserIDs []string

	// ChatIDs restricts to specific chats
	ChatIDs []string

	// LanguageCode for localized menus (e.g., "en", "zh", "es")
	LanguageCode string
}

MenuContext filters when a menu should be shown

type MenuItemConfig struct {
	// ID is the unique identifier for this item
	ID string

	// Label is the display text
	Label string

	// Description is optional helper text (shown below label on some platforms)
	Description string

	// Value is the callback value or command to execute
	// For commands: "/help"
	// For callbacks: "action:confirm"
	Value string

	// URL opens a URL instead of executing a command (webapp buttons)
	URL string

	// Icon for platforms that support it (Feishu/Lark)
	Icon string

	// Group related items together (optional)
	Group string

	// Hidden skips this item but keeps it in registry
	Hidden bool
}

MenuItemConfig defines a single item in the menu

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

MenuRegistry manages menu button configurations

func GetMenuRegistry

func GetMenuRegistry() *MenuRegistry

GetMenuRegistry returns the default menu registry

func NewMenuRegistry

func NewMenuRegistry() *MenuRegistry

NewMenuRegistry creates a new menu registry

func (r *MenuRegistry) BuildForFeishu(context *MenuContext) map[string]interface{}

BuildForFeishu returns the Feishu/Lark configuration for quick actions

func (r *MenuRegistry) BuildForSlack(context *MenuContext) map[string]interface{}

BuildForSlack returns the Slack configuration for app shortcuts

func (r *MenuRegistry) BuildForTelegram(context *MenuContext) map[string]interface{}

BuildForTelegram returns the Telegram Bot API configuration for the menu button

func (r *MenuRegistry) GetForPlatform(platform imbot.Platform, context *MenuContext) *MenuButtonConfig

GetForPlatform returns the best menu configuration for a platform Uses priority to select the highest priority config that matches the context

func (r *MenuRegistry) Register(config MenuButtonConfig)

Register adds a menu configuration to the registry

type OutputBehavior

type OutputBehavior struct {
	Debug   bool // Show message IDs (chat_id, user_id, session_id)
	Verbose bool // Send intermediate processing messages
}

OutputBehavior controls what is shown in bot messages

func DefaultOutputBehavior

func DefaultOutputBehavior() OutputBehavior

DefaultOutputBehavior returns the default output behavior

type PendingBind

type PendingBind struct {
	OriginalMessage string
	ProposedPath    string
	ExpiresAt       time.Time
}

PendingBind represents a pending bind confirmation request

type ResponseMeta

type ResponseMeta struct {
	ProjectPath string
	ChatID      string
	UserID      string
	SessionID   string
	AgentType   string // Current agent identifier (e.g., "tingly-box", "claude")
}

ResponseMeta contains metadata for response formatting

type SessionInfo

type SessionInfo struct {
	ID             string
	Status         string
	Project        string
	Request        string
	Error          string
	PermissionMode string
}

SessionInfo holds session information.

type SettingsStore

type SettingsStore interface {
	// GetSettingsByUUIDInterface returns settings by UUID as interface{}
	GetSettingsByUUIDInterface(uuid string) (interface{}, error)
	// ListEnabledSettingsInterface returns all enabled settings as interface{}
	ListEnabledSettingsInterface() (interface{}, error)
}

SettingsStore defines the interface for bot settings storage This allows both the legacy bot.Store and the new db.ImBotSettingsStore to be used

type SmartGuideCompletionCallback

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

SmartGuideCompletionCallback handles completion events for SmartGuide agent It saves messages to session, updates project path if changed, and sends response + action keyboard

func (*SmartGuideCompletionCallback) OnComplete

OnComplete implements agentboot.CompletionCallback

type StoredFile

type StoredFile struct {
	Path     string // Full path: {projectPath}/.agent/{filename}
	RelPath  string // Relative path for agent: .agent/{filename}
	URL      string // Original URL
	Filename string
	Size     int64
	MimeType string
}

StoredFile represents a stored file

type TelegramFile

type TelegramFile struct {
	Ok     bool `json:"ok"`
	Result struct {
		FileID   string `json:"file_id"`
		FileSize int    `json:"file_size"`
		FilePath string `json:"file_path"`
	} `json:"result"`
}

TelegramFile represents the response from Telegram's getFile API

Jump to

Keyboard shortcuts

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