yao/agent/robot/api/lifecycle.go
Max ea9e070f29 Enhance robot integration with Telegram and improve event handling
- Add Telegram integration support by introducing a dispatcher for handling Telegram events and messages.
- Implement event notifications for robot configuration changes (creation, update, deletion) to facilitate integration with external services.
- Refactor the robot initialization process to load robots into cache and start the dispatcher, improving the overall system setup.
- Update the delivery event structure to include additional metadata for better context during message handling.
- Enhance logging capabilities for better observability during robot execution and event processing.
2026-03-01 22:03:25 +08:00

137 lines
3.3 KiB
Go

package api
import (
"context"
"fmt"
"sync"
robotevents "github.com/yaoapp/yao/agent/robot/events"
"github.com/yaoapp/yao/agent/robot/events/integrations"
"github.com/yaoapp/yao/agent/robot/events/integrations/telegram"
"github.com/yaoapp/yao/agent/robot/logger"
"github.com/yaoapp/yao/agent/robot/manager"
"github.com/yaoapp/yao/agent/robot/types"
)
var log = logger.New("robot")
func init() {
robotevents.RegisterTriggerFunc(func(ctx *types.Context, memberID string, triggerType types.TriggerType, data interface{}) (string, bool, error) {
result, err := TriggerManual(ctx, memberID, triggerType, data)
if err != nil {
return "", false, err
}
return result.ExecutionID, result.Accepted, nil
})
}
// ==================== Lifecycle API ====================
// These functions manage the robot agent system lifecycle
var (
globalManager *manager.Manager
globalDispatcher *integrations.Dispatcher
managerMu sync.RWMutex
)
// Start starts the robot agent system
// This initializes and starts the manager which handles:
// - Robot cache loading
// - Worker pool
// - Clock ticker for scheduled triggers
func Start() error {
managerMu.Lock()
defer managerMu.Unlock()
if globalManager != nil && globalManager.IsStarted() {
return fmt.Errorf("robot agent system already started")
}
// Create new manager if not exists
if globalManager == nil {
globalManager = manager.New()
}
if err := globalManager.Start(); err != nil {
return err
}
// Start integration dispatcher (Telegram polling, webhook subscriptions, etc.)
adapters := map[string]integrations.Adapter{
"telegram": telegram.NewAdapter(),
}
globalDispatcher = integrations.NewDispatcher(globalManager.Cache(), adapters)
if err := globalDispatcher.Start(context.Background()); err != nil {
log.Error("failed to start integration dispatcher: %v", err)
}
return nil
}
// StartWithConfig starts the robot agent system with custom configuration
func StartWithConfig(config *manager.Config) error {
managerMu.Lock()
defer managerMu.Unlock()
if globalManager != nil && globalManager.IsStarted() {
return fmt.Errorf("robot agent system already started")
}
globalManager = manager.NewWithConfig(config)
return globalManager.Start()
}
// Stop stops the robot agent system gracefully
// This will:
// - Stop the clock ticker
// - Stop cache auto-refresh
// - Wait for running jobs to complete
// - Stop the worker pool
func Stop() error {
managerMu.Lock()
defer managerMu.Unlock()
if globalManager == nil {
return nil
}
if globalDispatcher != nil {
globalDispatcher.Stop()
globalDispatcher = nil
}
err := globalManager.Stop()
if err != nil {
return err
}
globalManager = nil
return nil
}
// IsRunning returns true if the robot agent system is running
func IsRunning() bool {
managerMu.RLock()
defer managerMu.RUnlock()
return globalManager != nil && globalManager.IsStarted()
}
// getManager returns the global manager instance
// Returns error if manager is not started
func getManager() (*manager.Manager, error) {
managerMu.RLock()
defer managerMu.RUnlock()
if globalManager == nil || !globalManager.IsStarted() {
return nil, fmt.Errorf("robot agent system not started")
}
return globalManager, nil
}
// SetManager sets the global manager instance (for testing)
func SetManager(m *manager.Manager) {
managerMu.Lock()
defer managerMu.Unlock()
globalManager = m
}