Signed-off-by: Kai Xia <kaix+github@fastmail.com>
This commit is contained in:
Kai Xia 2026-02-19 21:40:20 +11:00
parent 7ba0330fd7
commit f21906c2c1
5 changed files with 29 additions and 69 deletions

View file

@ -4,8 +4,6 @@
package main
import (
"fmt"
authpkg "github.com/sipeed/picoclaw/cmd/picoclaw/auth"
"github.com/spf13/cobra"
)
@ -14,9 +12,6 @@ var authCmd = &cobra.Command{
Use: "auth",
Short: "Manage authentication",
Long: `Manage authentication for different providers (login, logout, status).`,
Run: func(cmd *cobra.Command, args []string) {
authHelp()
},
}
func init() {
@ -28,21 +23,3 @@ func init() {
authCmd.AddCommand(authpkg.LogoutCmd)
authCmd.AddCommand(authpkg.StatusCmd)
}
func authHelp() {
fmt.Println("\nAuth commands:")
fmt.Println(" login Login via OAuth or paste token")
fmt.Println(" logout Remove stored credentials")
fmt.Println(" status Show current auth status")
fmt.Println()
fmt.Println("Login options:")
fmt.Println(" --provider <name> Provider to login with (openai, anthropic)")
fmt.Println(" --device-code Use device code flow (for headless environments)")
fmt.Println()
fmt.Println("Examples:")
fmt.Println(" picoclaw auth login --provider openai")
fmt.Println(" picoclaw auth login --provider openai --device-code")
fmt.Println(" picoclaw auth login --provider anthropic")
fmt.Println(" picoclaw auth logout --provider openai")
fmt.Println(" picoclaw auth status")
}

View file

@ -14,9 +14,6 @@ var cronCmd = &cobra.Command{
Use: "cron",
Short: "Manage scheduled tasks",
Long: `Manage cron jobs and scheduled tasks.`,
Run: func(cmd *cobra.Command, args []string) {
cronHelp()
},
}
func init() {
@ -36,21 +33,3 @@ func init() {
cronCmd.AddCommand(cronpkg.EnableCmd)
cronCmd.AddCommand(cronpkg.DisableCmd)
}
func cronHelp() {
fmt.Println("\nCron commands:")
fmt.Println(" list List all scheduled jobs")
fmt.Println(" add Add a new scheduled job")
fmt.Println(" remove <id> Remove a job by ID")
fmt.Println(" enable <id> Enable a job")
fmt.Println(" disable <id> Disable a job")
fmt.Println()
fmt.Println("Add options:")
fmt.Println(" -n, --name Job name")
fmt.Println(" -m, --message Message for agent")
fmt.Println(" -e, --every Run every N seconds")
fmt.Println(" -c, --cron Cron expression (e.g. '0 9 * * *')")
fmt.Println(" -d, --deliver Deliver response to channel")
fmt.Println(" --to Recipient for delivery")
fmt.Println(" --channel Channel for delivery")
}

View file

@ -3,10 +3,12 @@
package cronpkg
import "path/filepath"
var cronStorePath string
func SetCronStorePath(workspace string) {
cronStorePath = workspace + "/cron/jobs.json"
cronStorePath = filepath.Join(workspace, "cron", "jobs.json")
}
func GetCronStorePath() string {

View file

@ -6,15 +6,19 @@ package main
import (
"context"
"fmt"
"net/http"
"os"
"os/signal"
"path/filepath"
"time"
"github.com/sipeed/picoclaw/pkg/agent"
"github.com/sipeed/picoclaw/pkg/bus"
"github.com/sipeed/picoclaw/pkg/channels"
"github.com/sipeed/picoclaw/pkg/config"
"github.com/sipeed/picoclaw/pkg/cron"
"github.com/sipeed/picoclaw/pkg/devices"
"github.com/sipeed/picoclaw/pkg/health"
"github.com/sipeed/picoclaw/pkg/heartbeat"
"github.com/sipeed/picoclaw/pkg/logger"
"github.com/sipeed/picoclaw/pkg/providers"
@ -79,7 +83,8 @@ func gatewayImpl() {
})
// Setup cron tool and service
cronService := setupCronTool(agentLoop, msgBus, cfg.WorkspacePath())
execTimeout := time.Duration(cfg.Tools.Cron.ExecTimeoutMinutes) * time.Minute
cronService := setupCronTool(agentLoop, msgBus, cfg.WorkspacePath(), cfg.Agents.Defaults.RestrictToWorkspace, execTimeout, cfg)
heartbeatService := heartbeat.NewHeartbeatService(
cfg.WorkspacePath(),
@ -111,6 +116,9 @@ func gatewayImpl() {
os.Exit(1)
}
// Inject channel manager into agent loop for command handling
agentLoop.SetChannelManager(channelManager)
var transcriber *voice.GroqTranscriber
if cfg.Providers.Groq.APIKey != "" {
transcriber = voice.NewGroqTranscriber(cfg.Providers.Groq.APIKey)
@ -136,6 +144,12 @@ func gatewayImpl() {
logger.InfoC("voice", "Groq transcription attached to Slack channel")
}
}
if onebotChannel, ok := channelManager.GetChannel("onebot"); ok {
if oc, ok := onebotChannel.(*channels.OneBotChannel); ok {
oc.SetTranscriber(transcriber)
logger.InfoC("voice", "Groq transcription attached to OneBot channel")
}
}
}
enabledChannels := channelManager.GetEnabledChannels()
@ -177,6 +191,14 @@ func gatewayImpl() {
fmt.Printf("Error starting channels: %v\n", err)
}
healthServer := health.NewServer(cfg.Gateway.Host, cfg.Gateway.Port)
go func() {
if err := healthServer.Start(); err != nil && err != http.ErrServerClosed {
logger.ErrorCF("health", "Health server error", map[string]interface{}{"error": err.Error()})
}
}()
fmt.Printf("✓ Health endpoints available at http://%s:%d/health and /ready\n", cfg.Gateway.Host, cfg.Gateway.Port)
go agentLoop.Run(ctx)
sigChan := make(chan os.Signal, 1)
@ -185,6 +207,7 @@ func gatewayImpl() {
fmt.Println("\nShutting down...")
cancel()
healthServer.Stop(context.Background())
deviceService.Stop()
heartbeatService.Stop()
cronService.Stop()
@ -193,14 +216,14 @@ func gatewayImpl() {
fmt.Println("✓ Gateway stopped")
}
func setupCronTool(agentLoop *agent.AgentLoop, msgBus *bus.MessageBus, workspace string) *cron.CronService {
func setupCronTool(agentLoop *agent.AgentLoop, msgBus *bus.MessageBus, workspace string, restrict bool, execTimeout time.Duration, config *config.Config) *cron.CronService {
cronStorePath := filepath.Join(workspace, "cron", "jobs.json")
// Create cron service
cronService := cron.NewCronService(cronStorePath, nil)
// Create and register CronTool
cronTool := tools.NewCronTool(cronService, agentLoop, msgBus, workspace)
cronTool := tools.NewCronTool(cronService, agentLoop, msgBus, workspace, restrict, execTimeout, config)
agentLoop.RegisterTool(cronTool)
// Set the onJob handler

View file

@ -15,9 +15,6 @@ var skillsCmd = &cobra.Command{
Use: "skills",
Short: "Manage skills",
Long: `Manage skills installation and listing.`,
Run: func(cmd *cobra.Command, args []string) {
skillsHelp()
},
}
func init() {
@ -47,21 +44,3 @@ func init() {
skillsCmd.AddCommand(skillspkg.SearchCmd)
skillsCmd.AddCommand(skillspkg.ShowCmd)
}
func skillsHelp() {
fmt.Println("\nSkills commands:")
fmt.Println(" list List installed skills")
fmt.Println(" install <repo> Install skill from GitHub")
fmt.Println(" install-builtin Install all builtin skills to workspace")
fmt.Println(" list-builtin List available builtin skills")
fmt.Println(" remove <name> Remove installed skill")
fmt.Println(" search Search available skills")
fmt.Println(" show <name> Show skill details")
fmt.Println()
fmt.Println("Examples:")
fmt.Println(" picoclaw skills list")
fmt.Println(" picoclaw skills install sipeed/picoclaw-skills/weather")
fmt.Println(" picoclaw skills install-builtin")
fmt.Println(" picoclaw skills list-builtin")
fmt.Println(" picoclaw skills remove weather")
}