feat: re-enable cronTool service after refactor completion
Re-enable cronTool service integration after completing the ToolResult refactor (US-016). Removed all temporary disable comments and restored full cron service lifecycle including start/stop operations. Additional improvements: - Add thread-safe access to onHeartbeatWithTools handler - Fix channel parsing to handle user IDs with special characters - Add error handling for state file loading failures
This commit is contained in:
@@ -30,8 +30,7 @@ import (
|
|||||||
"github.com/sipeed/picoclaw/pkg/migrate"
|
"github.com/sipeed/picoclaw/pkg/migrate"
|
||||||
"github.com/sipeed/picoclaw/pkg/providers"
|
"github.com/sipeed/picoclaw/pkg/providers"
|
||||||
"github.com/sipeed/picoclaw/pkg/skills"
|
"github.com/sipeed/picoclaw/pkg/skills"
|
||||||
// TEMPORARILY DISABLED - cronTool is being refactored to use ToolResult (US-016)
|
"github.com/sipeed/picoclaw/pkg/tools"
|
||||||
toolsPkg "github.com/sipeed/picoclaw/pkg/tools" // nolint: unused
|
|
||||||
"github.com/sipeed/picoclaw/pkg/voice"
|
"github.com/sipeed/picoclaw/pkg/voice"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -39,8 +38,6 @@ var (
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
buildTime string
|
buildTime string
|
||||||
goVersion string
|
goVersion string
|
||||||
// TEMPORARILY DISABLED - cronTool is being refactored to use ToolResult (US-016)
|
|
||||||
_ = toolsPkg.ErrorResult // nolint: unused
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const logo = "🦞"
|
const logo = "🦞"
|
||||||
@@ -653,8 +650,7 @@ func gatewayCmd() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Setup cron tool and service
|
// Setup cron tool and service
|
||||||
// TEMPORARILY DISABLED - cronTool is being refactored to use ToolResult (US-016)
|
cronService := setupCronTool(agentLoop, msgBus, cfg.WorkspacePath())
|
||||||
// cronService := setupCronTool(agentLoop, msgBus, cfg.WorkspacePath())
|
|
||||||
|
|
||||||
heartbeatService := heartbeat.NewHeartbeatService(
|
heartbeatService := heartbeat.NewHeartbeatService(
|
||||||
cfg.WorkspacePath(),
|
cfg.WorkspacePath(),
|
||||||
@@ -709,11 +705,10 @@ func gatewayCmd() {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
// TEMPORARILY DISABLED - cronTool is being refactored to use ToolResult (US-016)
|
if err := cronService.Start(); err != nil {
|
||||||
// if err := cronService.Start(); err != nil {
|
fmt.Printf("Error starting cron service: %v\n", err)
|
||||||
// fmt.Printf("Error starting cron service: %v\n", err)
|
}
|
||||||
// }
|
fmt.Println("✓ Cron service started")
|
||||||
// fmt.Println("✓ Cron service started")
|
|
||||||
|
|
||||||
if err := heartbeatService.Start(); err != nil {
|
if err := heartbeatService.Start(); err != nil {
|
||||||
fmt.Printf("Error starting heartbeat service: %v\n", err)
|
fmt.Printf("Error starting heartbeat service: %v\n", err)
|
||||||
@@ -733,8 +728,7 @@ func gatewayCmd() {
|
|||||||
fmt.Println("\nShutting down...")
|
fmt.Println("\nShutting down...")
|
||||||
cancel()
|
cancel()
|
||||||
heartbeatService.Stop()
|
heartbeatService.Stop()
|
||||||
// TEMPORARILY DISABLED - cronTool is being refactored to use ToolResult (US-016)
|
cronService.Stop()
|
||||||
// cronService.Stop()
|
|
||||||
agentLoop.Stop()
|
agentLoop.Stop()
|
||||||
channelManager.StopAll(ctx)
|
channelManager.StopAll(ctx)
|
||||||
fmt.Println("✓ Gateway stopped")
|
fmt.Println("✓ Gateway stopped")
|
||||||
@@ -1040,7 +1034,7 @@ func setupCronTool(agentLoop *agent.AgentLoop, msgBus *bus.MessageBus, workspace
|
|||||||
cronService := cron.NewCronService(cronStorePath, nil)
|
cronService := cron.NewCronService(cronStorePath, nil)
|
||||||
|
|
||||||
// Create and register CronTool
|
// Create and register CronTool
|
||||||
cronTool := toolsPkg.NewCronTool(cronService, agentLoop, msgBus, workspace)
|
cronTool := tools.NewCronTool(cronService, agentLoop, msgBus, workspace)
|
||||||
agentLoop.RegisterTool(cronTool)
|
agentLoop.RegisterTool(cronTool)
|
||||||
|
|
||||||
// Set the onJob handler
|
// Set the onJob handler
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -203,13 +204,17 @@ func (hs *HeartbeatService) ExecuteHeartbeatWithTools(prompt string) {
|
|||||||
|
|
||||||
// executeHeartbeatWithTools is the internal implementation of tool-supporting heartbeat.
|
// executeHeartbeatWithTools is the internal implementation of tool-supporting heartbeat.
|
||||||
func (hs *HeartbeatService) executeHeartbeatWithTools(prompt string) {
|
func (hs *HeartbeatService) executeHeartbeatWithTools(prompt string) {
|
||||||
// Check if handler is configured
|
// Check if handler is configured (thread-safe read)
|
||||||
if hs.onHeartbeatWithTools == nil {
|
hs.mu.RLock()
|
||||||
|
handler := hs.onHeartbeatWithTools
|
||||||
|
hs.mu.RUnlock()
|
||||||
|
|
||||||
|
if handler == nil {
|
||||||
hs.logError("onHeartbeatWithTools handler not configured")
|
hs.logError("onHeartbeatWithTools handler not configured")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
result := hs.onHeartbeatWithTools(prompt)
|
result := handler(prompt)
|
||||||
|
|
||||||
if result == nil {
|
if result == nil {
|
||||||
hs.logInfo("Heartbeat handler returned nil result")
|
hs.logInfo("Heartbeat handler returned nil result")
|
||||||
@@ -343,12 +348,13 @@ func (hs *HeartbeatService) sendResponse(response string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse channel format: "platform:user_id" (e.g., "telegram:123456")
|
// Parse channel format: "platform:user_id" (e.g., "telegram:123456")
|
||||||
var platform, userID string
|
// Use SplitN to handle user IDs that may contain special characters
|
||||||
n, err := fmt.Sscanf(lastChannel, "%[^:]:%s", &platform, &userID)
|
parts := strings.SplitN(lastChannel, ":", 2)
|
||||||
if err != nil || n != 2 {
|
if len(parts) != 2 || parts[0] == "" || parts[1] == "" {
|
||||||
hs.logError("Invalid last channel format: %s", lastChannel)
|
hs.logError("Invalid last channel format: %s", lastChannel)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
platform, userID := parts[0], parts[1]
|
||||||
|
|
||||||
// Send to channel
|
// Send to channel
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package state
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -45,7 +46,10 @@ func NewManager(workspace string) *Manager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load existing state if available
|
// Load existing state if available
|
||||||
sm.load()
|
if err := sm.load(); err != nil {
|
||||||
|
// Log warning but continue with empty state
|
||||||
|
log.Printf("[WARN] state: failed to load state file, starting fresh: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
return sm
|
return sm
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user