smart_guide

package
v0.260414.2000 Latest Latest
Warning

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

Go to latest
Published: Apr 14, 2026 License: MPL-2.0 Imports: 21 Imported by: 0

Documentation

Index

Constants

View Source
const (
	AgentTypeTinglyBox  = "tingly-box" // @tb
	AgentTypeClaudeCode = "claude"     // @cc
	AgentTypeMock       = "mock"
)

AgentType constants AgentTypeTinglyBox is the agent type identifier for SmartGuide (TB) agent Defined here to allow external extension without modifying agentboot core types

View Source
const SendFileMaxSize int64 = 50 * 1024 * 1024

SendFileMaxSize is the default maximum file size for outbound file sends (50MB).

Variables

View Source
var DefaultBashAllowlist = []string{

	"ls", "pwd", "cd", "cat", "tree",

	"mkdir", "rm", "cp", "mv", "touch", "chmod",

	"git",

	"curl", "wget",

	"echo", "which", "env", "head", "tail", "wc", "find", "grep",
}

DefaultBashAllowlist defines the default allowed bash commands These are commands useful for preparation/guide work

View Source
var PromptFS embed.FS

Functions

func CanCreateAgent

func CanCreateAgent(baseURL, apiKey, smartGuideProvider, smartGuideModel string) bool

CanCreateAgent checks if a SmartGuide agent can be created with the given configuration Returns true if all required dependencies are available, false otherwise Note: Model validation should be done by the caller (e.g., BotHandler using TBClient)

func DefaultGreeting

func DefaultGreeting() string

DefaultGreeting returns the default greeting for new users

func DefaultSystemPrompt

func DefaultSystemPrompt() string

DefaultSystemPrompt returns the default system prompt for @tb

func DetectHandoffCommand

func DetectHandoffCommand(text string) (agentboot.AgentType, bool, string)

DetectHandoffCommand detects if text is a handoff command. Returns the target agent type, whether it's a handoff, and any remaining text after the command. Examples:

  • "@cc" -> (AgentTypeClaudeCode, true, "")
  • "@cc help me" -> (AgentTypeClaudeCode, true, "help me")
  • "@mock test" -> (AgentTypeMock, true, "test")
  • "hello" -> ("", false, "")

func DetectMediaType added in v0.260414.2000

func DetectMediaType(path string) string

DetectMediaType returns "image" for image file extensions, "document" for all others.

func GetAgentTypeString

func GetAgentTypeString(agentType agentboot.AgentType) string

GetAgentTypeString returns the string representation of an agent type

func HandoffToCCPrompt

func HandoffToCCPrompt() string

HandoffToCCPrompt returns the handoff prompt when switching to Claude Code

func HandoffToTBPrompt

func HandoffToTBPrompt() string

HandoffToTBPrompt returns the handoff prompt when returning to Smart Guide

func LoadPrompt

func LoadPrompt(name string) (string, error)

LoadPrompt reads a prompt file from the embedded filesystem

func MustLoadPrompt

func MustLoadPrompt(name string) string

MustLoadPrompt reads a prompt file or panics

func RegisterTools

func RegisterTools(
	toolkit *tool.Toolkit, executor *ToolExecutor, chatID string,
	getStatusFunc func(chatID string) (*StatusInfo, error),
	updateProjectFunc func(chatID string, projectPath string) error,
	toolCtx *ToolContext,
) error

RegisterTools registers all smart guide tools with a toolkit

func SerializeState

func SerializeState(state *HandoffState) ([]byte, error)

SerializeState serializes handoff state to JSON

Types

type AgentConfig

type AgentConfig struct {
	SmartGuideConfig *SmartGuideConfig
	// HTTP endpoint configuration (resolved from TBClient by caller)
	BaseURL      string // e.g., "http://localhost:12580/tingly/_smart_guide"
	APIKey       string // Tingly-box authentication token
	ToolExecutor *ToolExecutor
	// SmartGuide model configuration (required from bot setting)
	Provider string // Provider UUID
	Model    string // Model identifier
	// Callback functions for internal tools
	GetStatusFunc     func(chatID string) (*StatusInfo, error)
	GetProjectFunc    func(chatID string) (string, bool, error)
	UpdateProjectFunc func(chatID string, projectPath string) error // Updates project path in chat store

	// Approval context for non-allowlisted commands
	Handler  agentboot.MessageHandler // Message handler for approval requests
	ChatID   string                   // Chat ID for approval routing
	Platform string                   // Platform identifier
	BotUUID  string                   // Bot UUID for routing

	// ToolContext for injecting file send capability and cross-path approval.
	// If nil, send_file tool will not be registered.
	ToolCtx *ToolContext
}

AgentConfig holds the configuration for creating a TinglyBoxAgent

type AgentFactory

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

AgentFactory creates TinglyBoxAgent instances

func NewAgentFactory

func NewAgentFactory(config *SmartGuideConfig, baseURL, apiKey string, smartGuideProvider, smartGuideModel string) *AgentFactory

NewAgentFactory creates a new agent factory

func (*AgentFactory) CreateAgent

func (f *AgentFactory) CreateAgent(getStatusFunc func(chatID string) (*StatusInfo, error),
	getProjectFunc func(chatID string) (string, bool, error),
	updateProjectFunc func(chatID string, projectPath string) error) (*TinglyBoxAgent, error)

CreateAgent creates a new TinglyBoxAgent with the given callbacks

type ApprovalCallback

type ApprovalCallback func(ctx context.Context, req ApprovalRequest) (approved bool, err error)

ApprovalCallback is called when a command requires user approval Returns (approved, error) - if error is non-nil, the approval process failed

type ApprovalRequest

type ApprovalRequest struct {
	Command string   // Command to execute
	Args    []string // Command arguments
	Reason  string   // Reason for approval request
}

ApprovalRequest represents a request for user approval

type BashParams

type BashParams struct {
	Command string `json:"command" required:"true" jsonschema:"description=The bash command to execute (e.g., 'ls -la', 'git status')"`
}

BashParams defines the parameters for bash tool

type BashTool

type BashTool struct {
	Executor        *ToolExecutor
	AllowedCommands []string
}

BashTool wraps extension's BashTool with Smart Guide specific behavior

func NewBashTool

func NewBashTool(executor *ToolExecutor, allowlist []string) *BashTool

NewBashTool creates a new bash tool wrapper

func (*BashTool) Call

func (t *BashTool) Call(ctx context.Context, params BashParams) (*tool.ToolResponse, error)

Call executes a bash command with Smart Guide specific enhancements

func (*BashTool) Description

func (t *BashTool) Description() string

Description returns the bash tool description

func (*BashTool) Name

func (t *BashTool) Name() string

Name returns the bash tool name

type ChangeDirParams

type ChangeDirParams struct {
	Path   string `json:"path" jsonschema:"description=The directory path to change to (absolute or relative to current directory)"`
	ChatID string `json:"chat_id,omitempty" jsonschema:"description=(internal) Chat ID for persistence"`
}

ChangeDirParams defines the parameters for change_workdir tool

type ChangeDirTool

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

ChangeDirTool changes the bound project directory

func NewChangeDirTool

func NewChangeDirTool(executor *ToolExecutor, chatID string, updateProjectFunc func(chatID string, projectPath string) error) *ChangeDirTool

NewChangeDirTool creates a new ChangeDirTool

func (*ChangeDirTool) Call

Call changes the working directory and persists the change

func (*ChangeDirTool) Description

func (t *ChangeDirTool) Description() string

Description returns the change_workdir tool description

func (*ChangeDirTool) Name

func (t *ChangeDirTool) Name() string

Name returns the change_workdir tool name

type GetStatusParams

type GetStatusParams struct {
	ChatID string `json:"chat_id,omitempty" jsonschema:"description=Chat ID to get status for"`
}

GetStatusParams defines the parameters for get_status tool

type GetStatusTool

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

GetStatusTool returns current bot status

func NewGetStatusTool

func NewGetStatusTool(executor *ToolExecutor, getStatusFunc func(chatID string) (*StatusInfo, error)) *GetStatusTool

NewGetStatusTool creates a new GetStatusTool

func (*GetStatusTool) Call

Call returns the current bot status

func (*GetStatusTool) Description

func (t *GetStatusTool) Description() string

Description returns the get_status tool description

func (*GetStatusTool) Name

func (t *GetStatusTool) Name() string

Name returns the get_status tool name

type HandoffManager

type HandoffManager struct {
}

HandoffManager handles handoff operations between agents

func NewHandoffManager

func NewHandoffManager() *HandoffManager

NewHandoffManager creates a new handoff manager

func (*HandoffManager) ExecuteHandoff

func (hm *HandoffManager) ExecuteHandoff(ctx context.Context, state *HandoffState) *HandoffResult

ExecuteHandoff performs a handoff from one agent to another

type HandoffParams

type HandoffParams struct{}

HandoffParams defines the parameters for handoff_to_cc tool

type HandoffResult

type HandoffResult struct {
	Success   bool   `json:"success"`
	FromAgent string `json:"from_agent"`
	ToAgent   string `json:"to_agent"`
	Message   string `json:"message"`
	NextHint  string `json:"next_hint"`
	Error     string `json:"error,omitempty"`
}

HandoffResult represents the result of a handoff operation

type HandoffState

type HandoffState struct {
	FromAgent        string    `json:"from_agent"`
	ToAgent          string    `json:"to_agent"`
	Timestamp        time.Time `json:"timestamp"`
	ProjectPath      string    `json:"project_path"`
	SessionID        string    `json:"session_id"`
	ChatID           string    `json:"chat_id"`
	PreservedContext []byte    `json:"preserved_context,omitempty"`
}

HandoffState represents the state during a handoff

func DeserializeState

func DeserializeState(data []byte) (*HandoffState, error)

DeserializeState deserializes handoff state from JSON

type HandoffToCCTool

type HandoffToCCTool struct{}

HandoffToCCTool provides handoff to Claude Code Note: Currently not registered, kept for future use

func NewHandoffToCCTool

func NewHandoffToCCTool() *HandoffToCCTool

NewHandoffToCCTool creates a new handoff tool

func (*HandoffToCCTool) Call

Call implements the tool interface

func (*HandoffToCCTool) Description

func (t *HandoffToCCTool) Description() string

Description returns the tool description

func (*HandoffToCCTool) Name

func (t *HandoffToCCTool) Name() string

Name returns the tool name

type ModelConfig

type ModelConfig struct {
	Provider string `json:"provider"` // "openai", "anthropic", etc.
	Model    string `json:"model"`
	APIKey   string `json:"api_key"`
	BaseURL  string `json:"base_url,omitempty"`
}

ModelConfig holds the model configuration

type SendFileParams added in v0.260414.2000

type SendFileParams struct {
	FilePath string `json:"file_path" jsonschema:"description=Path to the local file to send (absolute or relative to working directory)"`
	Caption  string `json:"caption,omitempty" jsonschema:"description=Optional caption or message to accompany the file"`
}

SendFileParams defines the parameters for the send_file tool.

type SendFileTool added in v0.260414.2000

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

SendFileTool sends a local file to the user via the IM bot.

func NewSendFileTool added in v0.260414.2000

func NewSendFileTool(executor *ToolExecutor, toolCtx *ToolContext) *SendFileTool

NewSendFileTool creates a SendFileTool with the default 50MB limit.

func NewSendFileToolWithLimit added in v0.260414.2000

func NewSendFileToolWithLimit(executor *ToolExecutor, toolCtx *ToolContext, maxSize int64) *SendFileTool

NewSendFileToolWithLimit creates a SendFileTool with a custom size limit (for testing).

func (*SendFileTool) Call added in v0.260414.2000

Call executes the send_file tool.

func (*SendFileTool) Description added in v0.260414.2000

func (t *SendFileTool) Description() string

Description returns the tool description.

func (*SendFileTool) Name added in v0.260414.2000

func (t *SendFileTool) Name() string

Name returns the tool name.

type SessionStore

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

SessionStore wraps agentscope session for SmartGuide message persistence Uses agentscope.Msg directly for message storage

func NewSessionStore

func NewSessionStore(dataDir string) (*SessionStore, error)

NewSessionStore creates a new session store using agentscope

func (*SessionStore) AddMessage

func (s *SessionStore) AddMessage(chatID string, msg *message.Msg) error

AddMessage adds a single message to the session

func (*SessionStore) AddMessages

func (s *SessionStore) AddMessages(chatID string, newMessages []*message.Msg) error

AddMessages adds multiple messages to the session

func (*SessionStore) ClearMessages

func (s *SessionStore) ClearMessages(chatID string) error

ClearMessages removes all messages for a chatID

func (*SessionStore) Delete

func (s *SessionStore) Delete(chatID string) error

Delete removes the session for a chatID

func (*SessionStore) GetMessages

func (s *SessionStore) GetMessages(chatID string) ([]*message.Msg, error)

GetMessages retrieves all messages for a chatID

func (*SessionStore) List

func (s *SessionStore) List() ([]string, error)

List returns all chat IDs with sessions

func (*SessionStore) Load

func (s *SessionStore) Load(chatID string) ([]*message.Msg, error)

Load loads messages for a chatID, returns nil slice on error

func (*SessionStore) Save

func (s *SessionStore) Save(chatID string, messages []*message.Msg) error

Save saves messages for a chatID

func (*SessionStore) UpdateCurrentProject

func (s *SessionStore) UpdateCurrentProject(chatID, projectPath string) error

UpdateCurrentProject is a no-op (project is now managed by ChatStore)

type SmartGuideConfig

type SmartGuideConfig struct {
	// Enabled determines if smart guide is active
	Enabled bool `json:"enabled"`

	// SystemPrompt is the custom system prompt (optional)
	SystemPrompt string `json:"system_prompt,omitempty"`

	// MaxIterations is the maximum number of tool use iterations
	MaxIterations int `json:"max_iterations"`

	// Temperature for LLM responses
	Temperature float64 `json:"temperature"`

	// ToolsEnabled maps tool names to enabled state
	ToolsEnabled map[string]bool `json:"tools_enabled"`

	// HandoffCommands are the commands that trigger handoff
	HandoffCommands []string `json:"handoff_commands"`

	// Model configuration
	Model ModelConfig `json:"model"`

	// SessionTimeout is how long to remember context
	SessionTimeout time.Duration `json:"session_timeout"`
}

SmartGuideConfig holds the configuration for the smart guide agent

func DefaultSmartGuideConfig

func DefaultSmartGuideConfig() *SmartGuideConfig

DefaultSmartGuideConfig returns the default configuration

func LoadSmartGuideConfig

func LoadSmartGuideConfig() *SmartGuideConfig

LoadSmartGuideConfig loads smart guide config with custom settings For now, returns default config - settings will be loaded externally

func (*SmartGuideConfig) GetSystemPrompt

func (c *SmartGuideConfig) GetSystemPrompt() string

GetSystemPrompt returns the system prompt to use

func (*SmartGuideConfig) IsHandoffCommand

func (c *SmartGuideConfig) IsHandoffCommand(text string) bool

IsHandoffCommand checks if text is a handoff command

func (*SmartGuideConfig) IsToolEnabled

func (c *SmartGuideConfig) IsToolEnabled(toolName string) bool

IsToolEnabled checks if a tool is enabled

type StatusInfo

type StatusInfo struct {
	CurrentAgent   string `json:"current_agent"`
	SessionID      string `json:"session_id"`
	ProjectPath    string `json:"project_path"`
	WorkingDir     string `json:"working_dir"`
	HasRunningTask bool   `json:"has_running_task"`
	Whitelisted    bool   `json:"whitelisted"`
}

StatusInfo holds bot status information

type TinglyBoxAgent

type TinglyBoxAgent struct {
	*agent.ReActAgent
	// contains filtered or unexported fields
}

TinglyBoxAgent is the smart guide agent (@tb)

func NewTinglyBoxAgent

func NewTinglyBoxAgent(config *AgentConfig) (*TinglyBoxAgent, error)

NewTinglyBoxAgent creates a new smart guide agent

func NewTinglyBoxAgentWithSession

func NewTinglyBoxAgentWithSession(config *AgentConfig, messages []*message.Msg) (*TinglyBoxAgent, error)

NewTinglyBoxAgentWithSession creates a new smart guide agent with conversation history from session

func (*TinglyBoxAgent) Execute

func (a *TinglyBoxAgent) Execute(
	ctx context.Context,
	prompt string,
	opts agentboot.ExecutionOptions,
) (*agentboot.Result, error)

Execute implements agentboot.Agent interface for TinglyBoxAgent This allows SmartGuide to be used with the same callback mechanism as Claude Code and Mock Agent

func (*TinglyBoxAgent) ExecuteWithHandler

func (a *TinglyBoxAgent) ExecuteWithHandler(
	ctx context.Context,
	prompt string,
	toolCtx *ToolContext,
	handler agentboot.MessageHandler,
) (*agentboot.Result, error)

ExecuteWithHandler executes the agent with callback support This enables streaming messages, completion callbacks, and error handling

func (*TinglyBoxAgent) GetConfig

func (a *TinglyBoxAgent) GetConfig() *SmartGuideConfig

GetConfig returns the agent's configuration

func (*TinglyBoxAgent) GetDefaultFormat

func (a *TinglyBoxAgent) GetDefaultFormat() agentboot.OutputFormat

GetDefaultFormat returns the current default format

func (*TinglyBoxAgent) GetExecutor

func (a *TinglyBoxAgent) GetExecutor() *ToolExecutor

GetExecutor returns the tool executor

func (*TinglyBoxAgent) GetGreeting

func (a *TinglyBoxAgent) GetGreeting() string

GetGreeting returns the default greeting for new users

func (*TinglyBoxAgent) GetToolkit

func (a *TinglyBoxAgent) GetToolkit() *tool.Toolkit

GetToolkit returns the agent's toolkit

func (*TinglyBoxAgent) IsAvailable

func (a *TinglyBoxAgent) IsAvailable() bool

IsAvailable returns true if the agent is available for execution

func (*TinglyBoxAgent) IsEnabled

func (a *TinglyBoxAgent) IsEnabled() bool

IsEnabled returns whether the smart guide is enabled

func (*TinglyBoxAgent) ReplyWithContext

func (a *TinglyBoxAgent) ReplyWithContext(ctx context.Context, text string, toolCtx *ToolContext) (*message.Msg, error)

ReplyWithContext handles a user message with additional context

func (*TinglyBoxAgent) SetDefaultFormat

func (a *TinglyBoxAgent) SetDefaultFormat(format agentboot.OutputFormat)

SetDefaultFormat sets the default output format (no-op for SmartGuide)

func (*TinglyBoxAgent) Type

Type returns the agent type for agentboot.Agent interface

type ToolContext

type ToolContext struct {
	ChatID      string
	ProjectPath string
	SessionID   string

	// SendFile sends a local file to the user via the IM bot.
	// Injected by the bot layer; nil if file sending is not available.
	SendFile func(ctx context.Context, filePath, caption string) error

	// RequestApproval requests explicit user approval for sensitive operations
	// (e.g. sending files outside the project path). This callback must NOT be
	// bypassed by yolo mode — it is distinct from the bash approval callback.
	// Returns (false, nil) if denied. Returns (false, err) on failure.
	RequestApproval func(ctx context.Context, prompt string) (approved bool, err error)
}

ToolContext provides context for tool execution

type ToolExecutor

type ToolExecutor struct {
	BashAllowlist map[string]struct{}
	BashCwd       string // Per-execution working directory
	// contains filtered or unexported fields
}

ToolExecutor handles tool execution with proper context

func NewToolExecutor

func NewToolExecutor(allowlist []string) *ToolExecutor

NewToolExecutor creates a new tool executor

func (*ToolExecutor) ExecuteBash

func (e *ToolExecutor) ExecuteBash(ctx context.Context, cmd string, args ...string) (string, error)

ExecuteBash executes a bash command with allowlist checking

func (*ToolExecutor) GetAllowedCommands

func (e *ToolExecutor) GetAllowedCommands() []string

GetAllowedCommands returns the list of allowed commands

func (*ToolExecutor) GetWorkingDirectory

func (e *ToolExecutor) GetWorkingDirectory() string

GetWorkingDirectory returns the current working directory

func (*ToolExecutor) HasApprovalCallback

func (e *ToolExecutor) HasApprovalCallback() bool

HasApprovalCallback returns true if an approval callback is set

func (*ToolExecutor) ResolvePath

func (e *ToolExecutor) ResolvePath(path string) string

ResolvePath resolves a path to an absolute path If the path is relative, it's joined with the current working directory

func (*ToolExecutor) SetApprovalCallback

func (e *ToolExecutor) SetApprovalCallback(callback ApprovalCallback)

SetApprovalCallback sets the approval callback for non-allowlisted commands

func (*ToolExecutor) SetApprovalTimeout

func (e *ToolExecutor) SetApprovalTimeout(timeout time.Duration)

SetApprovalTimeout sets the timeout for approval requests

func (*ToolExecutor) SetWorkingDirectory

func (e *ToolExecutor) SetWorkingDirectory(cwd string)

SetWorkingDirectory sets the current working directory

Jump to

Keyboard shortcuts

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